From f50732f708181cc9e4d027e4afd35c5821f26c6f Mon Sep 17 00:00:00 2001 From: jie65535 <840465812@qq.com> Date: Fri, 22 Jan 2021 00:15:50 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=20=E6=89=80=E6=9C=89?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84=EF=BC=8C=E5=87=8F=E5=B0=91?= =?UTF-8?q?=E6=9A=B4=E9=9C=B2=E5=B1=9E=E6=80=A7=EF=BC=8C=E5=B9=B6=E4=B8=BA?= =?UTF-8?q?=E6=AF=8F=E4=B8=AA=E6=96=B9=E6=B3=95=E6=B7=BB=E5=8A=A0=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeMatrix/FormMain.cs | 14 +- CodeMatrix/UCCodeMatrix.cs | 477 +++++++++++++++++++++----------- CodeMatrix/UCCodeQueue.cs | 217 +++++++++++---- CodeMatrix/UCCodeTarget.cs | 552 +++++++++++++++++++++++++------------ 4 files changed, 859 insertions(+), 401 deletions(-) diff --git a/CodeMatrix/FormMain.cs b/CodeMatrix/FormMain.cs index f4c8fc2..4308c6b 100644 --- a/CodeMatrix/FormMain.cs +++ b/CodeMatrix/FormMain.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Drawing; using System.Windows.Forms; namespace CodeMatrix @@ -49,8 +42,6 @@ namespace CodeMatrix codeTarget.InputCode(value); }; - - Controls.Add(codeMatrix); Controls.Add(codeQueue); Controls.AddRange(codeTargets); @@ -59,6 +50,5 @@ namespace CodeMatrix size.Width += codeQueue.Width; ClientSize = size; } - } -} +} \ No newline at end of file diff --git a/CodeMatrix/UCCodeMatrix.cs b/CodeMatrix/UCCodeMatrix.cs index fa00a18..d66646e 100644 --- a/CodeMatrix/UCCodeMatrix.cs +++ b/CodeMatrix/UCCodeMatrix.cs @@ -4,45 +4,88 @@ using System.Windows.Forms; namespace CodeMatrix { + /// + /// 表示代码矩阵控件 游戏中的代码矩阵 + /// + /// internal class UCCodeMatrix : Control { - public Size CellSize { get; set; } - public int Columns { get; set; } - public int Rows { get; set; } - public byte[,] Matrix { get; set; } - public Point SelectPoint { get; private set; } - public Point CursorPoint { get; private set; } - private Point _HoverPoint; - public Point HoverPoint - { - get => _HoverPoint; - set - { - _HoverPoint = value; - if (HoverPoint.X >= 0) - HoverValueChangedEvent?.Invoke(this, Matrix[HoverPoint.X, HoverPoint.Y]); - else - HoverValueChangedEvent?.Invoke(this, 0); - } - } - public RectangleF CodeMatrixRect { get; private set; } + private static readonly Size MaximumMatrixSize = new Size(10, 10); + private static readonly Size MinimumMatrixSize = new Size(5, 5); + + /// + /// The cell size + /// + private Size _CellSize; + + /// + /// The code matrix rect + /// + private RectangleF _CodeMatrixRect; + + /// + /// The columns + /// + private int _Columns = 5; + + /// + /// The curr dir + /// + private Directions _currDir; + + /// + /// The cursor point + /// + private Point _CursorPoint; + + /// + /// The highlight code + /// private byte _HighlightCode; - public byte HighlightCode + + /// + /// The hover point + /// + private Point _HoverPoint; + + /// + /// The is loaded + /// + private bool _IsLoaded; + + /// + /// The matrix + /// + private byte[,] _Matrix; + + /// + /// The rows + /// + private int _Rows = 5; + + /// + /// The select point + /// + private Point _SelectPoint; + + /// + /// Initializes a new instance of the class. + /// + public UCCodeMatrix() { - get => _HighlightCode; - set - { - if (_HighlightCode != value) - { - _HighlightCode = value; - Invalidate(); - } - } + InitComponent(); } - public event EventHandler HoverValueChangedEvent; + /// + /// Occurs when [code selected event]. + /// public event EventHandler CodeSelectedEvent; + /// + /// Occurs when [hover value changed event]. + /// + public event EventHandler HoverValueChangedEvent; + /// /// 方向 /// @@ -59,153 +102,131 @@ namespace CodeMatrix Horizontal, } - private Directions _currDir; - - public UCCodeMatrix() + /// + /// Gets or sets the columns. + /// + /// + /// The columns. + /// + /// Columns - 设置矩阵大小数值不能小于 {MinimumMatrixSize.Width} 或者大于 {MaximumMatrixSize.Width} + public int Columns { - InitData(); - InitComponent(); + get => _Columns; + set + { + if (_Columns != value) + { + if (value < MinimumMatrixSize.Width || value > MaximumMatrixSize.Width) + throw new ArgumentOutOfRangeException("Columns", value, $"设置矩阵大小数值不能小于 {MinimumMatrixSize.Width} 或者大于 {MaximumMatrixSize.Width}"); + _Columns = value; + OnCodeMatrixSizeChanged(); + } + } } - private void InitData() + /// + /// Gets or sets the highlight code. + /// + /// + /// The highlight code. + /// + public byte HighlightCode + { + get => _HighlightCode; + set + { + if (_HighlightCode != value) + { + _HighlightCode = value; + Invalidate(); + } + } + } + + /// + /// Gets or sets the rows. + /// + /// + /// The rows. + /// + public int Rows + { + get => _Rows; + set + { + if (_Rows != value) + { + if (value < MinimumMatrixSize.Height || value > MaximumMatrixSize.Height) + throw new ArgumentOutOfRangeException("value", value, $"设置矩阵大小数值不能小于 {MinimumMatrixSize.Height} 或者大于 {MaximumMatrixSize.Height}"); + _Rows = value; + OnCodeMatrixSizeChanged(); + } + } + } + + /// + /// Gets or sets the hover point. + /// + /// + /// The hover point. + /// + private Point HoverPoint + { + get => _HoverPoint; + set + { + _HoverPoint = value; + if (HoverPoint.X >= 0) + HoverValueChangedEvent?.Invoke(this, _Matrix[HoverPoint.X, HoverPoint.Y]); + else + HoverValueChangedEvent?.Invoke(this, 0); + } + } + + /// + /// Reloads the code matrix. + /// + public void ReloadCodeMatrix() { - Rows = 7; - Columns = 7; _currDir = Directions.Horizontal; HoverPoint = new Point(-1, -1); + GenerateCodeMatrix(); + CalcCodeMatrixRect(); } - private void InitComponent() + protected override void OnMouseClick(MouseEventArgs e) { - CellSize = Styles.Default.CellSizeA; - MinimumSize = new Size(CellSize.Width * Columns + 100, CellSize.Height * Rows + 10); - Margin = Padding.Empty; - DoubleBuffered = true; - - Font = Styles.Default.CodeFontA; - BackColor = Styles.Default.BackColor; - ForeColor = Styles.Default.CodeColor; - } - - private bool _IsLoaded; - - protected override void OnVisibleChanged(EventArgs e) - { - if (Visible && !_IsLoaded) - { - Load(); - _IsLoaded = true; - } - base.OnVisibleChanged(e); - } - - private void Load() - { - Matrix = new byte[Columns, Rows]; - for (int col = 0; col < Columns; col++) - for (int row = 0; row < Rows; row++) - Matrix[col, row] = Common.Codes[Common.Random.Next(Common.Codes.Length)]; - - var blockSize = new SizeF(Columns*CellSize.Width, Rows*CellSize.Height); - var blockOffset = new PointF((Width-blockSize.Width)/2, (Height-blockSize.Height)/2); - CodeMatrixRect = new RectangleF(blockOffset, blockSize); - } - - //int _paintCount; - protected override void OnPaint(PaintEventArgs e) - { - if (!_IsLoaded) return; - //_paintCount++; - - var offset = new PointF(SelectPoint.X*CellSize.Width, SelectPoint.Y*CellSize.Height); - if (_currDir == Directions.Horizontal) - e.Graphics.FillRectangle(Styles.Default.DefaultLineBrush, 0, offset.Y + CodeMatrixRect.Y, Width, CellSize.Height); - else if (_currDir == Directions.Vertical) - e.Graphics.FillRectangle(Styles.Default.DefaultLineBrush, offset.X + CodeMatrixRect.X, 0, CellSize.Width, Height); - if (HoverPoint.X >= 0) { - Cursor = Cursors.Hand; - if (_currDir == Directions.Horizontal) - { - offset.X = HoverPoint.X * CellSize.Width; - e.Graphics.FillRectangle(Styles.Default.SelectLineBrush, offset.X + CodeMatrixRect.X, 0, CellSize.Width, Height); - } - else if (_currDir == Directions.Vertical) - { - offset.Y = HoverPoint.Y * CellSize.Height; - e.Graphics.FillRectangle(Styles.Default.SelectLineBrush, 0, offset.Y + CodeMatrixRect.Y, Width, CellSize.Height); - } - - offset.X += CodeMatrixRect.X; - offset.Y += CodeMatrixRect.Y; - e.Graphics.DrawRectangle(Styles.Default.SelectCellBorderPen, offset.X, offset.Y, CellSize.Width - 1, CellSize.Height - 1); - e.Graphics.DrawRectangle(Styles.Default.SelectCellBorderPen, offset.X + 3, offset.Y + 3, CellSize.Width - 6 - 1, CellSize.Height - 6 - 1); + _SelectPoint = HoverPoint; + _currDir = _currDir == Directions.Horizontal ? Directions.Vertical : Directions.Horizontal; + CodeSelectedEvent?.Invoke(this, _Matrix[_SelectPoint.X, _SelectPoint.Y]); + HoverPoint = _CursorPoint = new Point(-1, -1); + _Matrix[_SelectPoint.X, _SelectPoint.Y] = 0; + Invalidate(); } - else - { - Cursor = Cursors.Default; - } - - for (int col = 0; col < Columns; col++) - { - for (int row = 0; row < Rows; row++) - { - var cellOffset = new PointF(col*CellSize.Width, row*CellSize.Height); - //var cellRect = new RectangleF(cellOffset, CellSize); - Brush brush; - string code; - if (Matrix[col, row] == 0) - { - code = "[ ]"; - brush = Styles.Default.EmptyCellBrush; - } - else - { - if (HoverPoint.X == col && HoverPoint.Y == row) - brush = Styles.Default.SelectBrush; - else - brush = Styles.Default.CodeBrush; - code = Matrix[col, row].ToString("X2"); - } - if (HighlightCode != 0 && HighlightCode == Matrix[col, row]) - { - e.Graphics.DrawRectangle(Styles.Default.SelectedCellBorderPen, - CodeMatrixRect.X+cellOffset.X+1, - CodeMatrixRect.Y+cellOffset.Y+1, - CellSize.Width - 3, - CellSize.Height - 3); - } - var codeSize = e.Graphics.MeasureString(code, Font); - var codeOffset = new PointF((CellSize.Width-codeSize.Width)/2, (CellSize.Height-codeSize.Height)/2); - var codePoint = new PointF(codeOffset.X+cellOffset.X+CodeMatrixRect.X, codeOffset.Y+cellOffset.Y+CodeMatrixRect.Y); - e.Graphics.DrawString(code, Font, brush, codePoint); - } - } - - e.Graphics.DrawRectangle(Styles.Default.DefaultBorderPen, 0, 0, Width - 1, Height - 1); - //e.Graphics.DrawString(_paintCount.ToString(), Font, Styles.Default.CodeBrush, 0, 0); + base.OnMouseClick(e); } protected override void OnMouseMove(MouseEventArgs e) { - if (CodeMatrixRect.Left <= e.X - && CodeMatrixRect.Top <= e.Y - && CodeMatrixRect.Right > e.X - && CodeMatrixRect.Bottom > e.Y) + if (_CodeMatrixRect.Left <= e.X + && _CodeMatrixRect.Top <= e.Y + && _CodeMatrixRect.Right > e.X + && _CodeMatrixRect.Bottom > e.Y) { - var offset = new PointF(e.X-CodeMatrixRect.X, e.Y-CodeMatrixRect.Y); - var current = new Point((int)(offset.X / CellSize.Width), (int)(offset.Y / CellSize.Height)); - if (CursorPoint != current) + var offset = new PointF(e.X-_CodeMatrixRect.X, e.Y-_CodeMatrixRect.Y); + var current = new Point((int)(offset.X / _CellSize.Width), (int)(offset.Y / _CellSize.Height)); + if (_CursorPoint != current) { - CursorPoint = current; + _CursorPoint = current; Point hoverPoint; if (_currDir == Directions.Vertical) - hoverPoint = new Point(SelectPoint.X, CursorPoint.Y); + hoverPoint = new Point(_SelectPoint.X, _CursorPoint.Y); else - hoverPoint = new Point(CursorPoint.X, SelectPoint.Y); - - if (Matrix[hoverPoint.X, hoverPoint.Y] == 0) + hoverPoint = new Point(_CursorPoint.X, _SelectPoint.Y); + + if (_Matrix[hoverPoint.X, hoverPoint.Y] == 0) hoverPoint = new Point(-1, -1); if (HoverPoint != hoverPoint) @@ -219,25 +240,149 @@ namespace CodeMatrix { if (HoverPoint.X >= 0) { - HoverPoint = CursorPoint = new Point(-1, -1); + HoverPoint = _CursorPoint = new Point(-1, -1); Invalidate(); } } base.OnMouseMove(e); } - protected override void OnMouseClick(MouseEventArgs e) + protected override void OnPaint(PaintEventArgs e) { + if (!_IsLoaded) return; + + var offset = new PointF(_SelectPoint.X*_CellSize.Width, _SelectPoint.Y*_CellSize.Height); + if (_currDir == Directions.Horizontal) + e.Graphics.FillRectangle(Styles.Default.DefaultLineBrush, 0, offset.Y + _CodeMatrixRect.Y, Width, _CellSize.Height); + else if (_currDir == Directions.Vertical) + e.Graphics.FillRectangle(Styles.Default.DefaultLineBrush, offset.X + _CodeMatrixRect.X, 0, _CellSize.Width, Height); + if (HoverPoint.X >= 0) { - SelectPoint = HoverPoint; - _currDir = _currDir == Directions.Horizontal ? Directions.Vertical : Directions.Horizontal; - CodeSelectedEvent?.Invoke(this, Matrix[SelectPoint.X, SelectPoint.Y]); - HoverPoint = CursorPoint = new Point(-1, -1); - Matrix[SelectPoint.X, SelectPoint.Y] = 0; - Invalidate(); + Cursor = Cursors.Hand; + if (_currDir == Directions.Horizontal) + { + offset.X = HoverPoint.X * _CellSize.Width; + e.Graphics.FillRectangle(Styles.Default.SelectLineBrush, offset.X + _CodeMatrixRect.X, 0, _CellSize.Width, Height); + } + else if (_currDir == Directions.Vertical) + { + offset.Y = HoverPoint.Y * _CellSize.Height; + e.Graphics.FillRectangle(Styles.Default.SelectLineBrush, 0, offset.Y + _CodeMatrixRect.Y, Width, _CellSize.Height); + } + + offset.X += _CodeMatrixRect.X; + offset.Y += _CodeMatrixRect.Y; + e.Graphics.DrawRectangle(Styles.Default.SelectCellBorderPen, offset.X, offset.Y, _CellSize.Width - 1, _CellSize.Height - 1); + e.Graphics.DrawRectangle(Styles.Default.SelectCellBorderPen, offset.X + 3, offset.Y + 3, _CellSize.Width - 6 - 1, _CellSize.Height - 6 - 1); } - base.OnMouseClick(e); + else + { + Cursor = Cursors.Default; + } + + for (int col = 0; col < Columns; col++) + { + for (int row = 0; row < Rows; row++) + { + var cellOffset = new PointF(col*_CellSize.Width, row*_CellSize.Height); + //var cellRect = new RectangleF(cellOffset, CellSize); + Brush brush; + string code; + if (_Matrix[col, row] == 0) + { + code = "[ ]"; + brush = Styles.Default.EmptyCellBrush; + } + else + { + if (HoverPoint.X == col && HoverPoint.Y == row) + brush = Styles.Default.SelectBrush; + else + brush = Styles.Default.CodeBrush; + code = _Matrix[col, row].ToString("X2"); + } + if (HighlightCode != 0 && HighlightCode == _Matrix[col, row]) + { + e.Graphics.DrawRectangle(Styles.Default.SelectedCellBorderPen, + _CodeMatrixRect.X + cellOffset.X + 1, + _CodeMatrixRect.Y + cellOffset.Y + 1, + _CellSize.Width - 3, + _CellSize.Height - 3); + } + var codeSize = e.Graphics.MeasureString(code, Font); + var codeOffset = new PointF((_CellSize.Width-codeSize.Width)/2, (_CellSize.Height-codeSize.Height)/2); + var codePoint = new PointF(codeOffset.X+cellOffset.X+_CodeMatrixRect.X, codeOffset.Y+cellOffset.Y+_CodeMatrixRect.Y); + e.Graphics.DrawString(code, Font, brush, codePoint); + } + } + + e.Graphics.DrawRectangle(Styles.Default.DefaultBorderPen, 0, 0, Width - 1, Height - 1); + } + + protected override void OnVisibleChanged(EventArgs e) + { + if (Visible && !_IsLoaded) + { + OnLoad(); + _IsLoaded = true; + } + base.OnVisibleChanged(e); + } + + /// + /// Calculates the code matrix rect. + /// + private void CalcCodeMatrixRect() + { + var blockSize = new SizeF(Columns*_CellSize.Width, Rows*_CellSize.Height); + var blockOffset = new PointF((Width-blockSize.Width)/2, (Height-blockSize.Height)/2); + _CodeMatrixRect = new RectangleF(blockOffset, blockSize); + } + + /// + /// Generates the code matrix. + /// + private void GenerateCodeMatrix() + { + _Matrix = new byte[Columns, Rows]; + for (int col = 0; col < Columns; col++) + for (int row = 0; row < Rows; row++) + _Matrix[col, row] = Common.Codes[Common.Random.Next(Common.Codes.Length)]; + } + + /// + /// Initializes the component. + /// + private void InitComponent() + { + _CellSize = Styles.Default.CellSizeA; + MinimumSize = new Size(_CellSize.Width * Columns, _CellSize.Height * Rows); + Size = MinimumSize + new Size(100, 10); + Margin = Padding.Empty; + DoubleBuffered = true; + + Font = Styles.Default.CodeFontA; + BackColor = Styles.Default.BackColor; + ForeColor = Styles.Default.CodeColor; + } + + /// + /// Called when [code matrix size changed]. + /// + private void OnCodeMatrixSizeChanged() + { + MinimumSize = new Size(_CellSize.Width * Columns, _CellSize.Height * Rows); + if (_IsLoaded) + ReloadCodeMatrix(); + } + + /// + /// Called when [load]. + /// + private void OnLoad() + { + ReloadCodeMatrix(); } } } \ No newline at end of file diff --git a/CodeMatrix/UCCodeQueue.cs b/CodeMatrix/UCCodeQueue.cs index bfe9027..81f6b8a 100644 --- a/CodeMatrix/UCCodeQueue.cs +++ b/CodeMatrix/UCCodeQueue.cs @@ -1,87 +1,157 @@ using System; -using System.Collections.Generic; using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace CodeMatrix { - class UCCodeQueue : Control + /// + /// 表示代码队列控件 游戏中的输入缓冲区 + /// + /// + internal class UCCodeQueue : Control { - public Size CellSize { get; private set; } - public Padding CellMargin { get; set; } + /// + /// The maximum buffer size + /// + private const int MaximumBufferSize = 10; + + /// + /// The minimum buffer size + /// + private const int MinimumBufferSize = 4; + + /// + /// The buffer + /// + private byte[] _Buffer = new byte[MaximumBufferSize]; + + /// + /// The buffer size + /// + private int _BufferSize = 4; + + /// + /// The cell margin + /// + private Padding _CellMargin; + + /// + /// The cell size + /// + private Size _CellSize; + + /// + /// The curr index + /// + private int _CurrIndex; + + /// + /// The hover code + /// private byte _HoverCode; + + /// + /// The is loaded/ + /// + private bool _IsLoaded; + + /// + /// Initializes a new instance of the class. + /// + public UCCodeQueue() + { + InitComponent(); + } + + /// + /// Gets or sets the size of the buffer. + /// + /// + /// The size of the buffer. + /// + /// BufferSize - 设置缓冲区大小数值不能小于 {MinimumBufferSize} 或者大于 {MaximumBufferSize} + public int BufferSize + { + get => _BufferSize; + set + { + if (_BufferSize != value) + { + if (value < MinimumBufferSize || value > MaximumBufferSize) + throw new ArgumentOutOfRangeException("BufferSize", value, $"设置缓冲区大小数值不能小于 {MinimumBufferSize} 或者大于 {MaximumBufferSize}"); + _BufferSize = value; + OnBufferSizeChanged(); + } + } + } + + /// + /// Gets or sets the hover code. + /// + /// + /// The hover code. + /// public byte HoverCode { get => _HoverCode; set { - _HoverCode = value; - Invalidate(); + if (_HoverCode != value) + { + _HoverCode = value; + OnHoverCodeChanged(); + } } } - public int BufferSize { get; set; } - public int CurrIndex { get; private set; } - public byte[] Buffer { get; } = new byte[32]; - public UCCodeQueue() + /// + /// Inputs the code. + /// + /// The code. + public void InputCode(byte code) { - InitData(); - InitComponent(); + if (_CurrIndex < BufferSize) + _Buffer[_CurrIndex++] = code; } - private void InitData() + /// + /// Reloads the code queue. + /// + public void ReloadCodeQueue() { - BufferSize = 9; - CurrIndex = 0; + _CurrIndex = 0; HoverCode = 0; - } - - private void InitComponent() - { - CellSize = Styles.Default.CellSizeB; - Margin = Padding.Empty; - Padding = new Padding(10); - CellMargin = new Padding(3); - MinimumSize = new Size((CellSize.Width + CellMargin.Horizontal) * BufferSize + Padding.Horizontal, - CellSize.Height + CellMargin.Vertical + Padding.Vertical); - DoubleBuffered = true; - - Font = Styles.Default.CodeFontB; - BackColor = Styles.Default.BackColor; - ForeColor = Styles.Default.CodeColor; + Invalidate(); } protected override void OnPaint(PaintEventArgs e) { - var cellOffset = new Rectangle(Padding.Left + CellMargin.Left, - Padding.Top + CellMargin.Top, - CellSize.Width-1, - CellSize.Height-1); - var cellOffsetWidth = CellSize.Width + CellMargin.Horizontal; - for (int i = 0; i < CurrIndex && i < BufferSize; i++) + var cellOffset = new Rectangle(Padding.Left + _CellMargin.Left, + Padding.Top + _CellMargin.Top, + _CellSize.Width-1, + _CellSize.Height-1); + var cellOffsetWidth = _CellSize.Width + _CellMargin.Horizontal; + for (int i = 0; i < _CurrIndex && i < BufferSize; i++) { e.Graphics.DrawRectangle(Styles.Default.SelectedCellBorderPen, cellOffset); - var code = Buffer[i].ToString("X2"); + var code = _Buffer[i].ToString("X2"); var codeSize = e.Graphics.MeasureString(code, Font); - var codeOffset = new PointF((CellSize.Width-codeSize.Width)/2, (CellSize.Height-codeSize.Height)/2); + var codeOffset = new PointF((_CellSize.Width-codeSize.Width)/2, (_CellSize.Height-codeSize.Height)/2); var codePoint = new PointF(codeOffset.X+cellOffset.X, codeOffset.Y+cellOffset.Y); e.Graphics.DrawString(code, Font, Styles.Default.CodeBrush, codePoint); cellOffset.X += cellOffsetWidth; } - - if (CurrIndex < BufferSize) + + if (_CurrIndex < BufferSize) { - int i = CurrIndex; + int i = _CurrIndex; if (HoverCode > 0) { i++; e.Graphics.DrawRectangle(Styles.Default.SelectCellBorderPen, cellOffset); var code = HoverCode.ToString("X2"); var codeSize = e.Graphics.MeasureString(code, Font); - var codeOffset = new PointF((CellSize.Width-codeSize.Width)/2, (CellSize.Height-codeSize.Height)/2); + var codeOffset = new PointF((_CellSize.Width-codeSize.Width)/2, (_CellSize.Height-codeSize.Height)/2); var codePoint = new PointF(codeOffset.X+cellOffset.X, codeOffset.Y+cellOffset.Y); e.Graphics.DrawString(code, Font, Styles.Default.SelectBrush, codePoint); cellOffset.X += cellOffsetWidth; @@ -94,22 +164,63 @@ namespace CodeMatrix } } - e.Graphics.DrawRectangle(Styles.Default.DefaultBorderPen, 0, 0, Width - 1, Height - 1); base.OnPaint(e); } - public void InputCode(byte code) + protected override void OnVisibleChanged(EventArgs e) { - if (CurrIndex < BufferSize) - Buffer[CurrIndex++] = code; + if (Visible && !_IsLoaded) + { + OnLoad(); + _IsLoaded = true; + } + base.OnVisibleChanged(e); } - public void ClearBuffer() + /// + /// Initializes the component. + /// + private void InitComponent() { - CurrIndex = 0; - HoverCode = 0; + _CellSize = Styles.Default.CellSizeB; + Margin = Padding.Empty; + Padding = new Padding(10); + _CellMargin = new Padding(3); + MinimumSize = new Size((_CellSize.Width + _CellMargin.Horizontal) * BufferSize + Padding.Horizontal, + _CellSize.Height + _CellMargin.Vertical + Padding.Vertical); + DoubleBuffered = true; + + Font = Styles.Default.CodeFontB; + BackColor = Styles.Default.BackColor; + ForeColor = Styles.Default.CodeColor; + } + + /// + /// Called when [buffer size changed]. + /// + private void OnBufferSizeChanged() + { + MinimumSize = new Size((_CellSize.Width + _CellMargin.Horizontal) * BufferSize + Padding.Horizontal, + _CellSize.Height + _CellMargin.Vertical + Padding.Vertical); + ReloadCodeQueue(); + } + + /// + /// Called when [hover code changed]. + /// + private void OnHoverCodeChanged() + { + Invalidate(); + } + + /// + /// Called when [load]. + /// + private void OnLoad() + { + ReloadCodeQueue(); } } -} +} \ No newline at end of file diff --git a/CodeMatrix/UCCodeTarget.cs b/CodeMatrix/UCCodeTarget.cs index 01ed319..4208acc 100644 --- a/CodeMatrix/UCCodeTarget.cs +++ b/CodeMatrix/UCCodeTarget.cs @@ -1,18 +1,179 @@ using System; -using System.Collections.Generic; using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace CodeMatrix { + /// + /// 表示代码目标序列控件 游戏中的目标序列 + /// + /// public class UCCodeTarget : Control { - public Size CellSize { get; private set; } - public Padding CellMargin { get; set; } + /// + /// The maximum buffer size + /// + private const int MaximumBufferSize = 10; + + /// + /// The minimum buffer size + /// + private const int MinimumBufferSize = 4; + + /// + /// The minimum target length + /// + private const int MinimumTargetLength = 2; + + /// + /// The KMP next Array + /// + private readonly int[] _Next = new int[MaximumBufferSize]; + + /// + /// The target codes + /// + private readonly byte[] _TargetCodes = new byte[MaximumBufferSize]; + + /// + /// The buffer size + /// + private int _BufferSize = 4; + + /// + /// The cell margin + /// + private Padding _CellMargin; + + /// + /// The cell size + /// + private Size _CellSize; + + /// + /// The curr state + /// + private State _CurrState; + + /// + /// The hover code + /// private byte _HoverCode; + + /// + /// The is loaded + /// + private bool _IsLoaded; + + /// + /// The offset index + /// + private int _OffsetIndex; + + /// + /// The target length + /// + private int _TargetLength = 3; + + /// + /// The hover index + /// + private int HoverIndex = -1; + + /// + /// Initializes a new instance of the class. + /// + public UCCodeTarget() + { + InitComponent(); + } + + /// + /// Occurs when [code target state changed event]. + /// + public event EventHandler CodeTargetStateChangedEvent; + + /// + /// Occurs when [hover code event]. + /// + public event EventHandler HoverCodeEvent; + + /// + /// 状态枚举 + /// + public enum State + { + /// + /// 输入中 + /// + Input, + + /// + /// 已通过/已安装 + /// + Pass, + + /// + /// 已拒绝 + /// + Reject, + } + + /// + /// Gets or sets the size of the buffer. + /// + /// + /// The size of the buffer. + /// + /// BufferSize - 设置缓冲区大小数值不能小于 {MinimumBufferSize} 或者大于 {MaximumBufferSize} + public int BufferSize + { + get => _BufferSize; + set + { + if (_BufferSize != value) + { + if (value < MinimumBufferSize || value > MaximumBufferSize) + throw new ArgumentOutOfRangeException("BufferSize", value, $"设置缓冲区大小数值不能小于 {MinimumBufferSize} 或者大于 {MaximumBufferSize}"); + _BufferSize = value; + OnBufferSizeChanged(); + } + } + } + + /// + /// 获取当前正在输入的下标位置 + /// + /// + /// 当前正在输入的下标位置 + /// + public int CurrIndex { get; private set; } + + /// + /// 获取当前序列的输入状态 + /// + /// + /// 当前序列的输入状态 + /// + public State CurrState + { + get => _CurrState; + private set + { + if (_CurrState != value) + { + _CurrState = value; + OnTargetStateChanged(); + } + } + } + + /// + /// Gets or sets the hover code. + /// + /// + /// The hover code. + /// public byte HoverCode { get => _HoverCode; @@ -25,173 +186,33 @@ namespace CodeMatrix } } } - public event EventHandler HoverCodeEvent; - public int BufferSize { get; set; } - public int TargetLength { get; set; } - public int OffsetIndex { get; private set; } - public int CurrIndex { get; private set; } - public byte[] TargetCodes { get; } = new byte[32]; - private int[] _Next = new int[32]; - public enum State + /// + /// Gets or sets the length of the target. + /// + /// + /// The length of the target. + /// + /// TargetLength - 设置目标序列长度不能小于 {MinimumTargetLength} 或者大于缓冲区大小 + public int TargetLength { - Input, - Pass, - Reject, - } - public State CurrState { get; private set; } - - public UCCodeTarget() - { - InitData(); - InitComponent(); - } - - - private void InitData() - { - BufferSize = 9; - TargetLength = Common.Random.Next(3, 6); - OffsetIndex = 0; - CurrIndex = 0; - HoverCode = 0; - CurrState = State.Input; - for (int i = 0; i < TargetLength; i++) - TargetCodes[i] = Common.Codes[Common.Random.Next(Common.Codes.Length)]; - _Next[0] = -1; - _Next[1] = 0; - for (int i = 1, j = 0; i < TargetLength;) + get => _TargetLength; + set { - if (j == -1 || TargetCodes[i] == TargetCodes[j]) + if (_TargetLength != value) { - i++; - j++; - if (TargetCodes[i] != TargetCodes[j]) - _Next[i] = j; - else - _Next[i] = _Next[j]; - } - else - { - j = _Next[j]; + if (value < MinimumBufferSize || value > BufferSize) + throw new ArgumentOutOfRangeException("TargetLength", value, $"设置目标序列长度不能小于 {MinimumTargetLength} 或者大于缓冲区大小"); + _TargetLength = value; + OnTargetLengthChanged(); } } } - private void InitComponent() - { - CellSize = Styles.Default.CellSizeB; - Margin = Padding.Empty; - Padding = new Padding(10, 5, 10, 5); - CellMargin = new Padding(3); - MinimumSize = new Size((CellSize.Width + CellMargin.Horizontal) * BufferSize + Padding.Horizontal, - CellSize.Height + CellMargin.Vertical + Padding.Vertical); - DoubleBuffered = true; - - Font = Styles.Default.CodeFontB; - BackColor = Styles.Default.BackColor; - ForeColor = Styles.Default.CodeColor; - } - - protected override void OnPaint(PaintEventArgs e) - { - if (CurrState == State.Pass) - { - e.Graphics.FillRectangle(Styles.Default.PassBrush, ClientRectangle); - } - else if (CurrState == State.Reject) - { - e.Graphics.FillRectangle(Styles.Default.RejectBrush, ClientRectangle); - } - else - { - var cellOffset = new Rectangle(Padding.Left + CellMargin.Left, - Padding.Top + CellMargin.Top, - CellSize.Width-1, - CellSize.Height-1); - var cellOffsetWidth = CellSize.Width + CellMargin.Horizontal; - cellOffset.X += cellOffsetWidth * OffsetIndex; - int i = 0; - for (; i < CurrIndex && i < TargetLength; i++) - { - DrawCode(e.Graphics, TargetCodes[i], Font, Styles.Default.CodeBrush, cellOffset, Styles.Default.SelectedCellBorderPen); - cellOffset.X += cellOffsetWidth; - } - - e.Graphics.FillRectangle(Styles.Default.CurrIndexBrush, cellOffset.X, 0, cellOffset.Width, this.Height); - - if (i == CurrIndex && HoverCode == TargetCodes[i]) - { - DrawCode(e.Graphics, TargetCodes[CurrIndex], Font, Styles.Default.SelectBrush, cellOffset, Styles.Default.SelectCellBorderPen); - cellOffset.X += cellOffsetWidth; - i++; - } - - for (; i < TargetLength; i++) - { - DrawCode(e.Graphics, TargetCodes[i], Font, Styles.Default.ToBeSelectBrush, cellOffset); - cellOffset.X += cellOffsetWidth; - } - } - base.OnPaint(e); - } - - private void DrawCode(Graphics g, byte code, Font font, Brush brush, Rectangle cellRect, Pen borderPen = null) - { - if (borderPen != null) - g.DrawRectangle(borderPen, cellRect); - var codeStr = code.ToString("X2"); - var codeSize = g.MeasureString(codeStr, font); - var codeOffset = new PointF((CellSize.Width-codeSize.Width)/2, (CellSize.Height-codeSize.Height)/2); - var codePoint = new PointF(codeOffset.X+cellRect.X, codeOffset.Y+cellRect.Y); - g.DrawString(codeStr, font, brush, codePoint); - } - - private int HoverIndex = -1; - protected override void OnMouseMove(MouseEventArgs e) - { - if (CurrState == State.Input) - { - int hoverIndex = -1; - //Point currPoint = new Point(e.X - Padding.Left, e.Y - Padding.Top - CellMargin.Top); - //if (currPoint.X >= 0 && currPoint.Y >= 0 && currPoint.Y < CellSize.Height) - //{ - // int cellfullwidth = CellSize.Width + CellMargin.Horizontal; - // int index = currPoint.X / cellfullwidth - OffsetIndex; - // int offset = currPoint.X % cellfullwidth; - // if (offset > CellMargin.Left && offset < cellfullwidth - CellMargin.Left) - // { - // if (index >= 0 && index < TargetLength) - // { - // hoverIndex = index; - // } - // } - //} - Point currPoint = new Point(e.X - Padding.Left, e.Y - Padding.Top); - if (currPoint.X >= 0 && currPoint.Y >= 0 && currPoint.Y < CellSize.Height) - { - int cellfullwidth = CellSize.Width + CellMargin.Horizontal; - int index = currPoint.X / cellfullwidth - OffsetIndex; - if (index >= 0 && index < TargetLength) - { - hoverIndex = index; - } - } - - if (HoverIndex != hoverIndex) - { - HoverIndex = hoverIndex; - if (HoverIndex >= 0) - HoverCodeEvent?.Invoke(this, TargetCodes[HoverIndex]); - else - HoverCodeEvent?.Invoke(this, 0); - } - } - - - base.OnMouseMove(e); - } - + /// + /// Inputs the code. + /// + /// The code. public void InputCode(byte code) { if (CurrState == State.Input) @@ -203,7 +224,7 @@ namespace CodeMatrix CurrIndex = 0; break; } - if (code == TargetCodes[CurrIndex]) + if (code == _TargetCodes[CurrIndex]) { CurrIndex++; break; @@ -211,22 +232,213 @@ namespace CodeMatrix else { var next = _Next[CurrIndex]; - OffsetIndex += CurrIndex - next; + _OffsetIndex += CurrIndex - next; CurrIndex = next; } } - if (OffsetIndex + TargetLength > BufferSize) + if (_OffsetIndex + TargetLength > BufferSize) CurrState = State.Reject; else if (CurrIndex == TargetLength) CurrState = State.Pass; } } - public void ClearBuffer() + /// + /// Reloads the target sequence. + /// + public void ReloadTargetSequence() { + _OffsetIndex = 0; CurrIndex = 0; HoverCode = 0; + CurrState = State.Input; + GenerateTargetSequence(); + Invalidate(); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if (CurrState == State.Input) + { + int hoverIndex = -1; + Point currPoint = new Point(e.X - Padding.Left, e.Y - Padding.Top); + if (currPoint.X >= 0 && currPoint.Y >= 0 && currPoint.Y < _CellSize.Height) + { + int cellfullwidth = _CellSize.Width + _CellMargin.Horizontal; + int index = currPoint.X / cellfullwidth - _OffsetIndex; + if (index >= 0 && index < TargetLength) + { + hoverIndex = index; + } + } + + if (HoverIndex != hoverIndex) + { + HoverIndex = hoverIndex; + if (HoverIndex >= 0) + HoverCodeEvent?.Invoke(this, _TargetCodes[HoverIndex]); + else + HoverCodeEvent?.Invoke(this, 0); + } + } + + base.OnMouseMove(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + if (CurrState == State.Pass) + { + e.Graphics.FillRectangle(Styles.Default.PassBrush, ClientRectangle); + e.Graphics.DrawString("已安装", Font, Brushes.Black, 20, 8); + } + else if (CurrState == State.Reject) + { + e.Graphics.FillRectangle(Styles.Default.RejectBrush, ClientRectangle); + e.Graphics.DrawString("失败", Font, Brushes.Black, 20, 8); + } + else + { + var cellOffset = new Rectangle(Padding.Left + _CellMargin.Left, + Padding.Top + _CellMargin.Top, + _CellSize.Width-1, + _CellSize.Height-1); + var cellOffsetWidth = _CellSize.Width + _CellMargin.Horizontal; + cellOffset.X += cellOffsetWidth * _OffsetIndex; + int i = 0; + for (; i < CurrIndex && i < TargetLength; i++) + { + DrawCode(e.Graphics, _TargetCodes[i], Font, Styles.Default.CodeBrush, cellOffset, Styles.Default.SelectedCellBorderPen); + cellOffset.X += cellOffsetWidth; + } + + e.Graphics.FillRectangle(Styles.Default.CurrIndexBrush, cellOffset.X, 0, cellOffset.Width, this.Height); + + if (i == CurrIndex && HoverCode == _TargetCodes[i]) + { + DrawCode(e.Graphics, _TargetCodes[CurrIndex], Font, Styles.Default.SelectBrush, cellOffset, Styles.Default.SelectCellBorderPen); + cellOffset.X += cellOffsetWidth; + i++; + } + + for (; i < TargetLength; i++) + { + DrawCode(e.Graphics, _TargetCodes[i], Font, Styles.Default.ToBeSelectBrush, cellOffset); + cellOffset.X += cellOffsetWidth; + } + } + base.OnPaint(e); + } + + protected override void OnVisibleChanged(EventArgs e) + { + if (Visible && !_IsLoaded) + { + OnLoad(); + _IsLoaded = true; + } + base.OnVisibleChanged(e); + } + + /// + /// Draws the code. + /// + /// The graphics. + /// The code. + /// The font. + /// The brush. + /// The cell rect. + /// The border pen. + private void DrawCode(Graphics g, byte code, Font font, Brush brush, Rectangle cellRect, Pen borderPen = null) + { + if (borderPen != null) + g.DrawRectangle(borderPen, cellRect); + var codeStr = code.ToString("X2"); + var codeSize = g.MeasureString(codeStr, font); + var codeOffset = new PointF((_CellSize.Width-codeSize.Width)/2, (_CellSize.Height-codeSize.Height)/2); + var codePoint = new PointF(codeOffset.X+cellRect.X, codeOffset.Y+cellRect.Y); + g.DrawString(codeStr, font, brush, codePoint); + } + + /// + /// Generates the target sequence. + /// + private void GenerateTargetSequence() + { + for (int i = 0; i < TargetLength; i++) + _TargetCodes[i] = Common.Codes[Common.Random.Next(Common.Codes.Length)]; + _Next[0] = -1; + _Next[1] = 0; + for (int i = 1, j = 0; i < TargetLength;) + { + if (j == -1 || _TargetCodes[i] == _TargetCodes[j]) + { + i++; + j++; + if (_TargetCodes[i] != _TargetCodes[j]) + _Next[i] = j; + else + _Next[i] = _Next[j]; + } + else + { + j = _Next[j]; + } + } + } + + /// + /// Initializes the component. + /// + private void InitComponent() + { + _CellSize = Styles.Default.CellSizeB; + Margin = Padding.Empty; + Padding = new Padding(10, 5, 10, 5); + _CellMargin = new Padding(3); + MinimumSize = new Size((_CellSize.Width + _CellMargin.Horizontal) * BufferSize + Padding.Horizontal, + _CellSize.Height + _CellMargin.Vertical + Padding.Vertical); + DoubleBuffered = true; + + Font = Styles.Default.CodeFontB; + BackColor = Styles.Default.BackColor; + ForeColor = Styles.Default.CodeColor; + } + + /// + /// Called when [buffer size changed]. + /// + private void OnBufferSizeChanged() + { + if (TargetLength > BufferSize) + TargetLength = BufferSize; + else + ReloadTargetSequence(); + } + + /// + /// Called when [load]. + /// + private void OnLoad() + { + ReloadTargetSequence(); + } + + /// + /// Called when [target length changed]. + /// + private void OnTargetLengthChanged() + { + ReloadTargetSequence(); + } + + /// + /// Called when [target state changed]. + /// + private void OnTargetStateChanged() + { + CodeTargetStateChangedEvent?.Invoke(this, EventArgs.Empty); } } -} +} \ No newline at end of file