Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

16x16 DotMatrix

0.00/5 (No votes)
28 Mar 2011 1  
Building a 16x16 DotMatrix and a Matrix UserControl
16x16demo.png

Introduction

Actually, I just wanted to get some practice in coding user-controls. I started playing with Rectangles and Brushes and Pens in the onPaint method until I got the idea to set up my own dot-matrix control. A dot-matrix is used to display text and signs in dot-matrix style like LC displays do. As a spin-off product of this matrix, I got an editor to build a char-set for the matrix.

Let's Get Started

The dot-matrix is built by 16 rows, each containing 16 dots. To be more precise, 16x16 rectangles. Each rectangle might be filled completely or just with circle shape. As I needed at least some properties for each of the dots (rectangles), I started with my own rectangle-class. Let's call it RectangleXT.

Using the Code

class RectangleXT
    {
        public RectangleXT()
        {

        }

        private Rectangle _rect;
        public Rectangle Rect
        {
            get { return _rect; }
            set { _rect = value; }
        }

        private int _id;
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        private bool _enabled;
        public bool Enabled
        {
            get { return _enabled; }
            set { _enabled = value; }
        }

        private int _row;
        public int Row
        {
            get { return _row; }
            set { _row = value; }
        }

        private int _col;
        public int Column
        {
            get { return _col; }
            set { _col = value; }
        }

        private int _binVal;
        public int BinaryValue
        {
            get { return _binVal; }
            set { _binVal = value; }
        }

        private Color _color;
        public Color Color
        {
            get { return _color; }
            set { _color = value; }
        }
    }

Having this done, I could start building the matrix. The constructor of my Matrix16x16:Control is building a RectangleXT[] array first.

int row = 0;
int column = 0;
for (int i = 0; i < 256; i++)
{
    dotRects[i] = new RectangleXT();
    dotRects[i].Id = i;

    if (i % 16 == 0 && i != 0)
    {
        column = 0;
        row++;
    }
    dotRects[i].Column = column++;
    dotRects[i].Row = row;
    dotRects[i].BinaryValue = 15 - dotRects[i].Column;

    dotRects[i].Rect = new Rectangle(_dotRectWidth * dotRects[i].Column,
      _dotRectHeight * dotRects[i].Row, _dotRectWidth, _dotRectHeight);
}

Now we're ready to get it painted...

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics gr = e.Graphics;
Rectangle rect = ClientRectangle;
Brush brushEnabeld = new SolidBrush(ColorEnabled);
Brush brushDisabled = new SolidBrush(ColorDisabled);

int rw = rect.Width;
int refw = _dotRectWidth * 16;

for (int i = 0; i < 256; i++)
{
Rectangle rtmp = dotRects[i].Rect;

if (this.ShowBorders)
{
rtmp.Inflate(-1, -1);
}

if (dotRects[i].Enabled)
{
dotRects[i].Color = ColorEnabled;
switch (DisplayStyle)
{
case Style.Dots:
gr.FillEllipse(brushEnabeld, rtmp);
break;
case Style.Rectagles:
gr.FillRectangle(brushEnabeld, rtmp);
break;
default:
break;
}
}
else
{
dotRects[i].Color = ColorDisabled;
switch (DisplayStyle)
{
case Style.Dots:
gr.FillEllipse(brushDisabled, rtmp);
break;
case Style.Rectagles:
gr.FillRectangle(brushDisabled, rtmp);
break;
default:
break;
}
}
if (_teachMode && _showNumbers)
{
gr.DrawString((dotRects[i].Column + 1).ToString(),
this.Font, new SolidBrush(Color.Black),
dotRects[i].Rect.X + 5, dotRects[i].Rect.Y + 5);
}
}

onMatrixChanged();
}

Well, there are quite some things done in the onPaint method. There are some properties of the rectangles we have to deal with.

  • Enabled - Depending on this property, the dot will be drawn either in 'ColorEnabled' or 'ColorDisabled' color which both are properties of Matrix16x16.
  • DisplayStyle - Decides whether dots or rectangles are used to draw the matrix.
  • ShowBorders - Some border around each rectangle or not
  • TeachMode && ShowNumbers - These will be explained later when we build the character set to be displayed with the matrix. And finally, the onMatrixChanged() will notify anybody who wants to know, that some change to matrix has happened. Now that we have a matrix, it would be fine to display something. (Actually, the reason we build it) To get each dot addressed, it has a binary value. Starting with the leftmost dot with a value of 15, we count down to zero to rightmost dot. Having this, we're able to calculate the value of row. Let's do some binary math first.

The leftmost dot represents a value of 2^15 = 32768 and the rightmost dot a value of 2^0 = 1. So, if we want to display a row where the first and the last dot are enabled (lighted) the row-value is 2^15 + 2^0 = 32769. With an array of 16 integer values, we're now able to define all 16 rows of the matrix. This is done with:

public void setMatrix(int[] dots)
{
    for (int i = 0; i < 256; i++)  // all Dots
    {
        for (int j = 0; j < 16; j++) // 16 Rows
        {
            if (dotRects[i].Row == j)
            {
                if (dotRects[i].BinaryValue < 8) // LowByte
                {
                    byte value = (byte)(Math.Pow(2, dotRects[i].BinaryValue));

                    byte mask = (byte)dots[j];
                    byte check = (byte)(value & mask);

                    dotRects[i].Enabled = (check == value);
                }
                else  // HighByte
                {
                    int value = (int)(Math.Pow(2, dotRects[i].BinaryValue)) >> 8;
                    int mask = dots[j] >> 8;

                    byte check = (byte)(value & mask);

                    dotRects[i].Enabled = (check == value);
                }
            }
        }
    }
    this.Invalidate();
    onMatrixChanged();
}

To display the letter "A", we can just invoke setMatrix({ 0, 2016, 4080, 6168, 6168, 6168, 6168, 6168, 8184, 8184, 6168, 6168, 6168, 6168, 6168, 0 }) Quite easy, isn't it? But how about some more letters? OK, take some piece of paper and a pen and start calculating letter "B". Way too much work, you say? You're right.

I wouldn't have it done this way either. That's why I implemented the 'TeachMode'. In the demo app, you can enable TeachMode with a checkbox. In TeachMode, you can click on the dots in the Matrix to get them enabled or disabled. Keeping the left mouse button pressed, you can easily draw a line. With the right mouse button, you can disable several dots in row. The TextBox below the matrix will show the int[16] of your drawing. That's the way I set up a set of chars to display.

class Chars
    {
        private Dictionary<string,> stdChars = new Dictionary<string,>();

        public Chars()
        {
            buildStdCharset();
        }

        private void buildStdCharset()
        {
            stdChars.Add(" ", new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0,
                         0, 0, 0, 0, 0, 0, 0 });
            stdChars.Add("A", new int[] { 0, 2016, 4080, 6168, 6168,
                         6168, 6168, 6168, 8184, 8184, 6168, 6168, 6168,
			6168, 6168, 0 });
            stdChars.Add("B", new int[] { 0, 8160, 8176, 6168, 6168,
                         6168, 6168, 8184, 8184, 6168, 6168, 6168, 6168,
			8176, 8160, 0 });
            stdChars.Add("C", new int[] { 0, 1984, 4064, 6160, 6144,
                         6144, 6144, 6144, 6144, 6144, 6144, 6144, 6160,
			4064, 1984, 0 });
            stdChars.Add("D", new int[] { 0, 8160, 8176, 6168, 6168,
                         6168, 6168, 6168, 6168, 6168, 6168, 6168, 6168,
			8176, 8160, 0 });
            stdChars.Add("E", new int[] { 0, 8184, 8184, 6144, 6144,
                         6144, 6144, 8160, 8160, 6144, 6144, 6144, 6144,
			8184, 8184, 0 });
            stdChars.Add("F", new int[] { 0, 8184, 8184, 6144, 6144,
                         6144, 6144, 8160, 8160, 6144, 6144, 6144, 6144,
			6144, 6144, 0 });
            [...]
        }

        public Dictionary<string,int[]> Standard
        {
            get { return stdChars; }
        }

With the setChar() method, each of these chars can be displayed.

public void setChar(char character)
{
    try
    {
        setMatrix(_characters.Standard[character.ToString()]);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

The next step I did was just putting some of these matrixes into a UserControl.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here