diff --git a/CodeMatrix/CodeMatrix.csproj b/CodeMatrix/CodeMatrix.csproj index 078ea8d..76d7ba6 100644 --- a/CodeMatrix/CodeMatrix.csproj +++ b/CodeMatrix/CodeMatrix.csproj @@ -46,6 +46,7 @@ + Form @@ -61,6 +62,9 @@ Component + + Component + FormMain.cs diff --git a/CodeMatrix/Common.cs b/CodeMatrix/Common.cs new file mode 100644 index 0000000..55a1af4 --- /dev/null +++ b/CodeMatrix/Common.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeMatrix +{ + public static class Common + { + public static byte[] Codes { get; } = new byte[] { 0x55, 0x1C, 0xBD, 0xE9, 0x7A }; + + public static Random Random { get; } = new Random(); + } +} diff --git a/CodeMatrix/FormMain.cs b/CodeMatrix/FormMain.cs index df564d2..d9d5bd3 100644 --- a/CodeMatrix/FormMain.cs +++ b/CodeMatrix/FormMain.cs @@ -19,14 +19,37 @@ namespace CodeMatrix BackColor = Styles.Default.BackColor; var codeMatrix = new UCCodeMatrix(); - var codeQueue = new UCCodeQueue(); + var codeQueue = new UCCodeQueue + { + Location = new Point(codeMatrix.Size.Width, 0) + }; + var codeTargets = new UCCodeTarget[3]; + for (int i = 0, y = codeQueue.Size.Height; i < codeTargets.Length; y += codeTargets[i++].Size.Height) + { + codeTargets[i] = new UCCodeTarget + { + Location = new Point(codeQueue.Location.X, y) + }; + } + + codeMatrix.HoverValueChangedEvent += (_, value) => + { + codeQueue.HoverCode = value; + foreach (var codeTarget in codeTargets) + codeTarget.HoverCode = value; + }; + codeMatrix.CodeSelectedEvent += (_, value) => + { + codeQueue.InputCode(value); + foreach (var codeTarget in codeTargets) + codeTarget.InputCode(value); + }; + - codeMatrix.HoverValueChangedEvent += (_, value) => codeQueue.HoverCode = value; - codeMatrix.CodeSelectedEvent += (_, value) => codeQueue.InputCode(value); - codeQueue.Location = new Point(codeMatrix.Size.Width, 0); Controls.Add(codeMatrix); Controls.Add(codeQueue); + Controls.AddRange(codeTargets); var size = codeMatrix.Size; size.Width += codeQueue.Width; diff --git a/CodeMatrix/Styles.cs b/CodeMatrix/Styles.cs index d00deee..14e6895 100644 --- a/CodeMatrix/Styles.cs +++ b/CodeMatrix/Styles.cs @@ -10,38 +10,47 @@ namespace CodeMatrix { CodeFontA = new Font("微软雅黑", 14); CodeFontB = new Font("微软雅黑", 12); + CellSizeA = new Size(40, 40); + CellSizeB = new Size(25, 25); BackColor = Color.FromArgb(18, 13, 25); CodeColor = Color.FromArgb(208, 236, 92); SelectColor = Color.FromArgb(109, 232, 228); CodeBrush = new SolidBrush(CodeColor); SelectBrush = new SolidBrush(SelectColor); + ToBeSelectBrush = Brushes.White; EmptyCellBrush = new SolidBrush(Color.FromArgb(65, 52, 76)); - DefaultLineBackColor = new SolidBrush(Color.FromArgb(42, 43, 60)); - SelectLineBackColor = new SolidBrush(Color.FromArgb(32, 31, 28)); + DefaultLineBrush = new SolidBrush(Color.FromArgb(42, 43, 60)); + SelectLineBrush = new SolidBrush(Color.FromArgb(32, 31, 28)); + PassBrush = new SolidBrush(Color.FromArgb(31, 248, 136)); + RejectBrush = new SolidBrush(Color.FromArgb(255, 100, 92)); + CurrIndexBrush = new SolidBrush(Color.FromArgb(26, 27, 46)); SelectCellBorderPen = new Pen(SelectColor, 1); EmptyCellBorderPen = new Pen(Color.FromArgb(116, 144, 0), 1) { DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, - DashPattern = new float[2] { 4, 4 } - }; - SelectedCellBorderPen = new Pen(CodeColor, 1) - { - DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, - DashPattern = new float[2] { 3, 3 } + DashPattern = new float[2] { 6, 6 }, + DashOffset = 3F }; + SelectedCellBorderPen = new Pen(CodeColor, 1); DefaultBorderPen = new Pen(CodeColor, 1); } public Font CodeFontA { get; set; } public Font CodeFontB { get; set; } + public Size CellSizeA { get; set; } + public Size CellSizeB { get; set; } public Color BackColor { get; set; } public Color CodeColor { get; set; } public Color SelectColor { get; set; } public Brush CodeBrush { get; set; } public Brush SelectBrush { get; set; } + public Brush ToBeSelectBrush { get; set; } public Brush EmptyCellBrush { get; set; } - public Brush DefaultLineBackColor { get; set; } - public Brush SelectLineBackColor { get; set; } + public Brush DefaultLineBrush { get; set; } + public Brush SelectLineBrush { get; set; } + public Brush PassBrush { get; set; } + public Brush RejectBrush { get; set; } + public Brush CurrIndexBrush { get; set; } public Pen SelectCellBorderPen { get; set; } public Pen EmptyCellBorderPen { get; set; } public Pen SelectedCellBorderPen { get; set; } diff --git a/CodeMatrix/UCCodeMatrix.cs b/CodeMatrix/UCCodeMatrix.cs index bb635e0..8ae7f61 100644 --- a/CodeMatrix/UCCodeMatrix.cs +++ b/CodeMatrix/UCCodeMatrix.cs @@ -6,10 +6,7 @@ namespace CodeMatrix { internal class UCCodeMatrix : Control { - private static readonly byte[] Codes = new byte[] { 0x55, 0x1C, 0xBD, 0xE9, 0x7A }; - - private static readonly Random Random = new Random(); - public SizeF CellSize { get; set; } + public Size CellSize { get; set; } public int Columns { get; set; } public int Rows { get; set; } public byte[,] Matrix { get; set; } @@ -58,16 +55,16 @@ namespace CodeMatrix private void InitData() { - Rows = 7; - Columns = 7; - CellSize = new SizeF(40, 40); + Rows = 5; + Columns = 5; _currDir = Directions.Horizontal; HoverPoint = new Point(-1, -1); } private void InitComponent() { - MinimumSize = new Size((int)(CellSize.Width * Columns + 100), (int)(CellSize.Height * Rows + 10)); + CellSize = Styles.Default.CellSizeA; + MinimumSize = new Size(CellSize.Width * Columns + 100, CellSize.Height * Rows + 10); Margin = Padding.Empty; DoubleBuffered = true; @@ -93,7 +90,7 @@ namespace CodeMatrix Matrix = new byte[Columns, Rows]; for (int col = 0; col < Columns; col++) for (int row = 0; row < Rows; row++) - Matrix[col, row] = Codes[Random.Next(Codes.Length)]; + 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); @@ -108,9 +105,9 @@ namespace CodeMatrix var offset = new PointF(SelectPoint.X*CellSize.Width, SelectPoint.Y*CellSize.Height); if (_currDir == Directions.Horizontal) - e.Graphics.FillRectangle(Styles.Default.DefaultLineBackColor, 0, offset.Y + CodeMatrixRect.Y, Width, CellSize.Height); + e.Graphics.FillRectangle(Styles.Default.DefaultLineBrush, 0, offset.Y + CodeMatrixRect.Y, Width, CellSize.Height); else if (_currDir == Directions.Vertical) - e.Graphics.FillRectangle(Styles.Default.DefaultLineBackColor, offset.X + CodeMatrixRect.X, 0, CellSize.Width, Height); + e.Graphics.FillRectangle(Styles.Default.DefaultLineBrush, offset.X + CodeMatrixRect.X, 0, CellSize.Width, Height); if (HoverPoint.X >= 0) { @@ -118,18 +115,18 @@ namespace CodeMatrix if (_currDir == Directions.Horizontal) { offset.X = HoverPoint.X * CellSize.Width; - e.Graphics.FillRectangle(Styles.Default.SelectLineBackColor, offset.X + CodeMatrixRect.X, 0, CellSize.Width, Height); + 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.SelectLineBackColor, 0, offset.Y + CodeMatrixRect.Y, Width, 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 + 4, offset.Y + 4, CellSize.Width - 8 - 1, CellSize.Height - 8 - 1); + e.Graphics.DrawRectangle(Styles.Default.SelectCellBorderPen, offset.X + 3, offset.Y + 3, CellSize.Width - 6 - 1, CellSize.Height - 6 - 1); } else { @@ -180,14 +177,15 @@ namespace CodeMatrix if (CursorPoint != current) { CursorPoint = current; - var hoverPoint = new Point(-1, -1); - if (Matrix[CursorPoint.X, CursorPoint.Y] != 0) - { - if (_currDir == Directions.Horizontal && CursorPoint.Y == SelectPoint.Y) - hoverPoint = CursorPoint; - else if (_currDir == Directions.Vertical && CursorPoint.X == SelectPoint.X) - hoverPoint = CursorPoint; - } + Point hoverPoint; + if (_currDir == Directions.Vertical) + 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(-1, -1); + if (HoverPoint != hoverPoint) { HoverPoint = hoverPoint; @@ -211,9 +209,9 @@ namespace CodeMatrix if (HoverPoint.X >= 0) { SelectPoint = HoverPoint; - HoverPoint = new Point(-1, -1); _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(); } diff --git a/CodeMatrix/UCCodeQueue.cs b/CodeMatrix/UCCodeQueue.cs index 5a1bbb2..75233da 100644 --- a/CodeMatrix/UCCodeQueue.cs +++ b/CodeMatrix/UCCodeQueue.cs @@ -34,15 +34,14 @@ namespace CodeMatrix private void InitData() { - CellSize = new Size(25, 25); - BufferSize = 7; - + BufferSize = 4; CurrIndex = 0; HoverCode = 0; } private void InitComponent() { + CellSize = Styles.Default.CellSizeB; Margin = Padding.Empty; Padding = new Padding(10); CellMargin = new Padding(3); @@ -75,18 +74,20 @@ namespace CodeMatrix if (CurrIndex < BufferSize) { - e.Graphics.DrawRectangle(Styles.Default.SelectCellBorderPen, cellOffset); + 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 codePoint = new PointF(codeOffset.X+cellOffset.X, codeOffset.Y+cellOffset.Y); e.Graphics.DrawString(code, Font, Styles.Default.SelectBrush, codePoint); + cellOffset.X += cellOffsetWidth; } - cellOffset.X += cellOffsetWidth; - for (int i = CurrIndex+1; i < BufferSize; i++) + for (; i < BufferSize; i++) { e.Graphics.DrawRectangle(Styles.Default.EmptyCellBorderPen, cellOffset); cellOffset.X += cellOffsetWidth; @@ -102,10 +103,7 @@ namespace CodeMatrix public void InputCode(byte code) { if (CurrIndex < BufferSize) - { Buffer[CurrIndex++] = code; - HoverCode = 0; - } } public void ClearBuffer() diff --git a/CodeMatrix/UCCodeTarget.cs b/CodeMatrix/UCCodeTarget.cs new file mode 100644 index 0000000..de30884 --- /dev/null +++ b/CodeMatrix/UCCodeTarget.cs @@ -0,0 +1,162 @@ +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; } + private byte _HoverCode; + public byte HoverCode + { + get => _HoverCode; + set + { + if (_HoverCode != value) + { + _HoverCode = value; + Invalidate(); + } + } + } + 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]; + + public enum State + { + Input, + Pass, + Reject, + } + public State CurrState { get; private set; } + + public UCCodeTarget() + { + InitData(); + InitComponent(); + } + + + private void InitData() + { + BufferSize = 4; + TargetLength = Common.Random.Next(2) + 2; + 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)]; + } + + 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); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + + //HoverCodeEvent?.Invoke(this, _HoverCode); + + + base.OnMouseMove(e); + } + + public void InputCode(byte code) + { + if (CurrState == State.Input) + { + if (code == TargetCodes[CurrIndex]) + CurrIndex++; + else + OffsetIndex++; + + if (OffsetIndex + TargetLength > BufferSize) + CurrState = State.Reject; + else if (CurrIndex == TargetLength) + CurrState = State.Pass; + } + } + + public void ClearBuffer() + { + CurrIndex = 0; + HoverCode = 0; + } + } +} diff --git a/Images/CodeMatrix2.gif b/Images/CodeMatrix2.gif new file mode 100644 index 0000000..4ae4a06 Binary files /dev/null and b/Images/CodeMatrix2.gif differ diff --git a/Images/CodeMatrix3.gif b/Images/CodeMatrix3.gif new file mode 100644 index 0000000..217617b Binary files /dev/null and b/Images/CodeMatrix3.gif differ diff --git a/README.md b/README.md index 59bc278..9c9aa07 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,4 @@ 示例图片: -![演示动图](images/codeMatrix.gif) -![演示截图1](images/codeMatrix_116.png) \ No newline at end of file +![演示动图](images/CodeMatrix3.gif) \ No newline at end of file