mirror of
https://github.com/jie65535/CodeMatrix.git
synced 2025-06-01 17:29:10 +08:00
重构 所有代码结构,减少暴露属性,并为每个方法添加注释
This commit is contained in:
parent
877a92d727
commit
f50732f708
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -4,45 +4,88 @@ using System.Windows.Forms;
|
||||
|
||||
namespace CodeMatrix
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示代码矩阵控件 游戏中的代码矩阵
|
||||
/// </summary>
|
||||
/// <seealso cref="System.Windows.Forms.Control" />
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// The cell size
|
||||
/// </summary>
|
||||
private Size _CellSize;
|
||||
|
||||
/// <summary>
|
||||
/// The code matrix rect
|
||||
/// </summary>
|
||||
private RectangleF _CodeMatrixRect;
|
||||
|
||||
/// <summary>
|
||||
/// The columns
|
||||
/// </summary>
|
||||
private int _Columns = 5;
|
||||
|
||||
/// <summary>
|
||||
/// The curr dir
|
||||
/// </summary>
|
||||
private Directions _currDir;
|
||||
|
||||
/// <summary>
|
||||
/// The cursor point
|
||||
/// </summary>
|
||||
private Point _CursorPoint;
|
||||
|
||||
/// <summary>
|
||||
/// The highlight code
|
||||
/// </summary>
|
||||
private byte _HighlightCode;
|
||||
public byte HighlightCode
|
||||
|
||||
/// <summary>
|
||||
/// The hover point
|
||||
/// </summary>
|
||||
private Point _HoverPoint;
|
||||
|
||||
/// <summary>
|
||||
/// The is loaded
|
||||
/// </summary>
|
||||
private bool _IsLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// The matrix
|
||||
/// </summary>
|
||||
private byte[,] _Matrix;
|
||||
|
||||
/// <summary>
|
||||
/// The rows
|
||||
/// </summary>
|
||||
private int _Rows = 5;
|
||||
|
||||
/// <summary>
|
||||
/// The select point
|
||||
/// </summary>
|
||||
private Point _SelectPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UCCodeMatrix"/> class.
|
||||
/// </summary>
|
||||
public UCCodeMatrix()
|
||||
{
|
||||
get => _HighlightCode;
|
||||
set
|
||||
{
|
||||
if (_HighlightCode != value)
|
||||
{
|
||||
_HighlightCode = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
InitComponent();
|
||||
}
|
||||
|
||||
public event EventHandler<byte> HoverValueChangedEvent;
|
||||
/// <summary>
|
||||
/// Occurs when [code selected event].
|
||||
/// </summary>
|
||||
public event EventHandler<byte> CodeSelectedEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [hover value changed event].
|
||||
/// </summary>
|
||||
public event EventHandler<byte> HoverValueChangedEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 方向
|
||||
/// </summary>
|
||||
@ -59,153 +102,131 @@ namespace CodeMatrix
|
||||
Horizontal,
|
||||
}
|
||||
|
||||
private Directions _currDir;
|
||||
|
||||
public UCCodeMatrix()
|
||||
/// <summary>
|
||||
/// Gets or sets the columns.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The columns.
|
||||
/// </value>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Columns - 设置矩阵大小数值不能小于 {MinimumMatrixSize.Width} 或者大于 {MaximumMatrixSize.Width}</exception>
|
||||
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()
|
||||
/// <summary>
|
||||
/// Gets or sets the highlight code.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The highlight code.
|
||||
/// </value>
|
||||
public byte HighlightCode
|
||||
{
|
||||
get => _HighlightCode;
|
||||
set
|
||||
{
|
||||
if (_HighlightCode != value)
|
||||
{
|
||||
_HighlightCode = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the rows.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The rows.
|
||||
/// </value>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hover point.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The hover point.
|
||||
/// </value>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the code matrix.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the code matrix rect.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the code matrix.
|
||||
/// </summary>
|
||||
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)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the component.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [code matrix size changed].
|
||||
/// </summary>
|
||||
private void OnCodeMatrixSizeChanged()
|
||||
{
|
||||
MinimumSize = new Size(_CellSize.Width * Columns, _CellSize.Height * Rows);
|
||||
if (_IsLoaded)
|
||||
ReloadCodeMatrix();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [load].
|
||||
/// </summary>
|
||||
private void OnLoad()
|
||||
{
|
||||
ReloadCodeMatrix();
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
/// <summary>
|
||||
/// 表示代码队列控件 游戏中的输入缓冲区
|
||||
/// </summary>
|
||||
/// <seealso cref="System.Windows.Forms.Control" />
|
||||
internal class UCCodeQueue : Control
|
||||
{
|
||||
public Size CellSize { get; private set; }
|
||||
public Padding CellMargin { get; set; }
|
||||
/// <summary>
|
||||
/// The maximum buffer size
|
||||
/// </summary>
|
||||
private const int MaximumBufferSize = 10;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum buffer size
|
||||
/// </summary>
|
||||
private const int MinimumBufferSize = 4;
|
||||
|
||||
/// <summary>
|
||||
/// The buffer
|
||||
/// </summary>
|
||||
private byte[] _Buffer = new byte[MaximumBufferSize];
|
||||
|
||||
/// <summary>
|
||||
/// The buffer size
|
||||
/// </summary>
|
||||
private int _BufferSize = 4;
|
||||
|
||||
/// <summary>
|
||||
/// The cell margin
|
||||
/// </summary>
|
||||
private Padding _CellMargin;
|
||||
|
||||
/// <summary>
|
||||
/// The cell size
|
||||
/// </summary>
|
||||
private Size _CellSize;
|
||||
|
||||
/// <summary>
|
||||
/// The curr index
|
||||
/// </summary>
|
||||
private int _CurrIndex;
|
||||
|
||||
/// <summary>
|
||||
/// The hover code
|
||||
/// </summary>
|
||||
private byte _HoverCode;
|
||||
|
||||
/// <summary>
|
||||
/// The is loaded/
|
||||
/// </summary>
|
||||
private bool _IsLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UCCodeQueue"/> class.
|
||||
/// </summary>
|
||||
public UCCodeQueue()
|
||||
{
|
||||
InitComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the buffer.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size of the buffer.
|
||||
/// </value>
|
||||
/// <exception cref="ArgumentOutOfRangeException">BufferSize - 设置缓冲区大小数值不能小于 {MinimumBufferSize} 或者大于 {MaximumBufferSize}</exception>
|
||||
public int BufferSize
|
||||
{
|
||||
get => _BufferSize;
|
||||
set
|
||||
{
|
||||
if (_BufferSize != value)
|
||||
{
|
||||
if (value < MinimumBufferSize || value > MaximumBufferSize)
|
||||
throw new ArgumentOutOfRangeException("BufferSize", value, $"设置缓冲区大小数值不能小于 {MinimumBufferSize} 或者大于 {MaximumBufferSize}");
|
||||
_BufferSize = value;
|
||||
OnBufferSizeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hover code.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The hover code.
|
||||
/// </value>
|
||||
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()
|
||||
/// <summary>
|
||||
/// Inputs the code.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
public void InputCode(byte code)
|
||||
{
|
||||
InitData();
|
||||
InitComponent();
|
||||
if (_CurrIndex < BufferSize)
|
||||
_Buffer[_CurrIndex++] = code;
|
||||
}
|
||||
|
||||
private void InitData()
|
||||
/// <summary>
|
||||
/// Reloads the code queue.
|
||||
/// </summary>
|
||||
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()
|
||||
/// <summary>
|
||||
/// Initializes the component.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [buffer size changed].
|
||||
/// </summary>
|
||||
private void OnBufferSizeChanged()
|
||||
{
|
||||
MinimumSize = new Size((_CellSize.Width + _CellMargin.Horizontal) * BufferSize + Padding.Horizontal,
|
||||
_CellSize.Height + _CellMargin.Vertical + Padding.Vertical);
|
||||
ReloadCodeQueue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [hover code changed].
|
||||
/// </summary>
|
||||
private void OnHoverCodeChanged()
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [load].
|
||||
/// </summary>
|
||||
private void OnLoad()
|
||||
{
|
||||
ReloadCodeQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示代码目标序列控件 游戏中的目标序列
|
||||
/// </summary>
|
||||
/// <seealso cref="System.Windows.Forms.Control" />
|
||||
public class UCCodeTarget : Control
|
||||
{
|
||||
public Size CellSize { get; private set; }
|
||||
public Padding CellMargin { get; set; }
|
||||
/// <summary>
|
||||
/// The maximum buffer size
|
||||
/// </summary>
|
||||
private const int MaximumBufferSize = 10;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum buffer size
|
||||
/// </summary>
|
||||
private const int MinimumBufferSize = 4;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum target length
|
||||
/// </summary>
|
||||
private const int MinimumTargetLength = 2;
|
||||
|
||||
/// <summary>
|
||||
/// The KMP next Array
|
||||
/// </summary>
|
||||
private readonly int[] _Next = new int[MaximumBufferSize];
|
||||
|
||||
/// <summary>
|
||||
/// The target codes
|
||||
/// </summary>
|
||||
private readonly byte[] _TargetCodes = new byte[MaximumBufferSize];
|
||||
|
||||
/// <summary>
|
||||
/// The buffer size
|
||||
/// </summary>
|
||||
private int _BufferSize = 4;
|
||||
|
||||
/// <summary>
|
||||
/// The cell margin
|
||||
/// </summary>
|
||||
private Padding _CellMargin;
|
||||
|
||||
/// <summary>
|
||||
/// The cell size
|
||||
/// </summary>
|
||||
private Size _CellSize;
|
||||
|
||||
/// <summary>
|
||||
/// The curr state
|
||||
/// </summary>
|
||||
private State _CurrState;
|
||||
|
||||
/// <summary>
|
||||
/// The hover code
|
||||
/// </summary>
|
||||
private byte _HoverCode;
|
||||
|
||||
/// <summary>
|
||||
/// The is loaded
|
||||
/// </summary>
|
||||
private bool _IsLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// The offset index
|
||||
/// </summary>
|
||||
private int _OffsetIndex;
|
||||
|
||||
/// <summary>
|
||||
/// The target length
|
||||
/// </summary>
|
||||
private int _TargetLength = 3;
|
||||
|
||||
/// <summary>
|
||||
/// The hover index
|
||||
/// </summary>
|
||||
private int HoverIndex = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UCCodeTarget"/> class.
|
||||
/// </summary>
|
||||
public UCCodeTarget()
|
||||
{
|
||||
InitComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [code target state changed event].
|
||||
/// </summary>
|
||||
public event EventHandler CodeTargetStateChangedEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [hover code event].
|
||||
/// </summary>
|
||||
public event EventHandler<byte> HoverCodeEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 状态枚举
|
||||
/// </summary>
|
||||
public enum State
|
||||
{
|
||||
/// <summary>
|
||||
/// 输入中
|
||||
/// </summary>
|
||||
Input,
|
||||
|
||||
/// <summary>
|
||||
/// 已通过/已安装
|
||||
/// </summary>
|
||||
Pass,
|
||||
|
||||
/// <summary>
|
||||
/// 已拒绝
|
||||
/// </summary>
|
||||
Reject,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the buffer.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size of the buffer.
|
||||
/// </value>
|
||||
/// <exception cref="ArgumentOutOfRangeException">BufferSize - 设置缓冲区大小数值不能小于 {MinimumBufferSize} 或者大于 {MaximumBufferSize}</exception>
|
||||
public int BufferSize
|
||||
{
|
||||
get => _BufferSize;
|
||||
set
|
||||
{
|
||||
if (_BufferSize != value)
|
||||
{
|
||||
if (value < MinimumBufferSize || value > MaximumBufferSize)
|
||||
throw new ArgumentOutOfRangeException("BufferSize", value, $"设置缓冲区大小数值不能小于 {MinimumBufferSize} 或者大于 {MaximumBufferSize}");
|
||||
_BufferSize = value;
|
||||
OnBufferSizeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前正在输入的下标位置
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// 当前正在输入的下标位置
|
||||
/// </value>
|
||||
public int CurrIndex { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前序列的输入状态
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// 当前序列的输入状态
|
||||
/// </value>
|
||||
public State CurrState
|
||||
{
|
||||
get => _CurrState;
|
||||
private set
|
||||
{
|
||||
if (_CurrState != value)
|
||||
{
|
||||
_CurrState = value;
|
||||
OnTargetStateChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hover code.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The hover code.
|
||||
/// </value>
|
||||
public byte HoverCode
|
||||
{
|
||||
get => _HoverCode;
|
||||
@ -25,173 +186,33 @@ namespace CodeMatrix
|
||||
}
|
||||
}
|
||||
}
|
||||
public event EventHandler<byte> 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
|
||||
/// <summary>
|
||||
/// Gets or sets the length of the target.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The length of the target.
|
||||
/// </value>
|
||||
/// <exception cref="ArgumentOutOfRangeException">TargetLength - 设置目标序列长度不能小于 {MinimumTargetLength} 或者大于缓冲区大小</exception>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inputs the code.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
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()
|
||||
/// <summary>
|
||||
/// Reloads the target sequence.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the code.
|
||||
/// </summary>
|
||||
/// <param name="g">The graphics.</param>
|
||||
/// <param name="code">The code.</param>
|
||||
/// <param name="font">The font.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="cellRect">The cell rect.</param>
|
||||
/// <param name="borderPen">The border pen.</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the target sequence.
|
||||
/// </summary>
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the component.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [buffer size changed].
|
||||
/// </summary>
|
||||
private void OnBufferSizeChanged()
|
||||
{
|
||||
if (TargetLength > BufferSize)
|
||||
TargetLength = BufferSize;
|
||||
else
|
||||
ReloadTargetSequence();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [load].
|
||||
/// </summary>
|
||||
private void OnLoad()
|
||||
{
|
||||
ReloadTargetSequence();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [target length changed].
|
||||
/// </summary>
|
||||
private void OnTargetLengthChanged()
|
||||
{
|
||||
ReloadTargetSequence();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [target state changed].
|
||||
/// </summary>
|
||||
private void OnTargetStateChanged()
|
||||
{
|
||||
CodeTargetStateChangedEvent?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user