Subversion Repositories group.electronics

Rev

Rev 139 | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NITNavComm {
    public class SevenSegment : UserControl {
        public SevenSegment() {
            this.SuspendLayout();
            this.Name = "SevenSegment";
            this.Size = new System.Drawing.Size(32, 64);
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.SevenSegment_Paint);
            this.Resize += new System.EventHandler(this.SevenSegment_Resize);
            this.ResumeLayout(false);

            this.TabStop = false;
            this.Padding = new Padding(4, 4, 4, 4);
            this.DoubleBuffered = true;

            segPoints = new Point[7][];
            for (int i = 0; i < 7; i++) segPoints[i] = new Point[6];

            RecalculatePoints();
        }

        /// <summary>
        /// Recalculate the points that represent the polygons of the
        /// seven segments, whether we're just initializing or
        /// changing the segment width.
        /// </summary>
        private void RecalculatePoints() {
            int halfHeight = gridHeight / 2, halfWidth = elementWidth / 2;

            int p = 0;
            segPoints[p][0].X = elementWidth + 1; segPoints[p][0].Y = 0;
            segPoints[p][1].X = gridWidth - elementWidth - 1; segPoints[p][1].Y = 0;
            segPoints[p][2].X = gridWidth - halfWidth - 1; segPoints[p][2].Y = halfWidth;
            segPoints[p][3].X = gridWidth - elementWidth - 1; segPoints[p][3].Y = elementWidth;
            segPoints[p][4].X = elementWidth + 1; segPoints[p][4].Y = elementWidth;
            segPoints[p][5].X = halfWidth + 1; segPoints[p][5].Y = halfWidth;

            p++;
            segPoints[p][0].X = 0; segPoints[p][0].Y = elementWidth + 1;
            segPoints[p][1].X = halfWidth; segPoints[p][1].Y = halfWidth + 1;
            segPoints[p][2].X = elementWidth; segPoints[p][2].Y = elementWidth + 1;
            segPoints[p][3].X = elementWidth; segPoints[p][3].Y = halfHeight - halfWidth - 1;
            segPoints[p][4].X = 4; segPoints[p][4].Y = halfHeight - 1;
            segPoints[p][5].X = 0; segPoints[p][5].Y = halfHeight - 1;

            p++;
            segPoints[p][0].X = gridWidth - elementWidth; segPoints[p][0].Y = elementWidth + 1;
            segPoints[p][1].X = gridWidth - halfWidth; segPoints[p][1].Y = halfWidth + 1;
            segPoints[p][2].X = gridWidth; segPoints[p][2].Y = elementWidth + 1;
            segPoints[p][3].X = gridWidth; segPoints[p][3].Y = halfHeight - 1;
            segPoints[p][4].X = gridWidth - 4; segPoints[p][4].Y = halfHeight - 1;
            segPoints[p][5].X = gridWidth - elementWidth; segPoints[p][5].Y = halfHeight - halfWidth - 1;

            p++;
            segPoints[p][0].X = elementWidth + 1; segPoints[p][0].Y = halfHeight - halfWidth;
            segPoints[p][1].X = gridWidth - elementWidth - 1; segPoints[p][1].Y = halfHeight - halfWidth;
            segPoints[p][2].X = gridWidth - 5; segPoints[p][2].Y = halfHeight;
            segPoints[p][3].X = gridWidth - elementWidth - 1; segPoints[p][3].Y = halfHeight + halfWidth;
            segPoints[p][4].X = elementWidth + 1; segPoints[p][4].Y = halfHeight + halfWidth;
            segPoints[p][5].X = 5; segPoints[p][5].Y = halfHeight;

            p++;
            segPoints[p][0].X = 0; segPoints[p][0].Y = halfHeight + 1;
            segPoints[p][1].X = 4; segPoints[p][1].Y = halfHeight + 1;
            segPoints[p][2].X = elementWidth; segPoints[p][2].Y = halfHeight + halfWidth + 1;
            segPoints[p][3].X = elementWidth; segPoints[p][3].Y = gridHeight - elementWidth - 1;
            segPoints[p][4].X = halfWidth; segPoints[p][4].Y = gridHeight - halfWidth - 1;
            segPoints[p][5].X = 0; segPoints[p][5].Y = gridHeight - elementWidth - 1;

            p++;
            segPoints[p][0].X = gridWidth - elementWidth; segPoints[p][0].Y = halfHeight + halfWidth + 1;
            segPoints[p][1].X = gridWidth - 4; segPoints[p][1].Y = halfHeight + 1;
            segPoints[p][2].X = gridWidth; segPoints[p][2].Y = halfHeight + 1;
            segPoints[p][3].X = gridWidth; segPoints[p][3].Y = gridHeight - elementWidth - 1;
            segPoints[p][4].X = gridWidth - halfWidth; segPoints[p][4].Y = gridHeight - halfWidth - 1;
            segPoints[p][5].X = gridWidth - elementWidth; segPoints[p][5].Y = gridHeight - elementWidth - 1;

            p++;
            segPoints[p][0].X = elementWidth + 1; segPoints[p][0].Y = gridHeight - elementWidth;
            segPoints[p][1].X = gridWidth - elementWidth - 1; segPoints[p][1].Y = gridHeight - elementWidth;
            segPoints[p][2].X = gridWidth - halfWidth - 1; segPoints[p][2].Y = gridHeight - halfWidth;
            segPoints[p][3].X = gridWidth - elementWidth - 1; segPoints[p][3].Y = gridHeight;
            segPoints[p][4].X = elementWidth + 1; segPoints[p][4].Y = gridHeight;
            segPoints[p][5].X = halfWidth + 1; segPoints[p][5].Y = gridHeight - halfWidth;
        }

        private Point[][] segPoints;

        private int gridHeight = 80;
        private int gridWidth = 48;
        private int elementWidth = 10;
        private float italicFactor = 0.0F;
        private Color colorBackground = Color.DarkGray;
        private Color colorDark = Color.DimGray;
        private Color colorLight = Color.Red;


        /// <summary>
        /// Background color of the 7-segment display.
        /// </summary>
        public Color ColorBackground { get { return colorBackground; } set { colorBackground = value; Invalidate(); } }
        /// <summary>
        /// Color of inactive LED segments.
        /// </summary>
        public Color ColorDark { get { return colorDark; } set { colorDark = value; Invalidate(); } }
        /// <summary>
        /// Color of active LED segments.
        /// </summary>
        public Color ColorLight { get { return colorLight; } set { colorLight = value; Invalidate(); } }

        /// <summary>
        /// Width of LED segments.
        /// </summary>
        public int ElementWidth { get { return elementWidth; } set { elementWidth = value; RecalculatePoints(); Invalidate(); } }
        /// <summary>
        /// Shear coefficient for italicizing the displays. Try a value like -0.1.
        /// </summary>
        public float ItalicFactor { get { return italicFactor; } set { italicFactor = value; Invalidate(); } }

        private void SevenSegment_Resize(object sender, EventArgs e) { this.Invalidate(); }
        protected override void OnPaddingChanged(EventArgs e) { base.OnPaddingChanged(e); this.Invalidate(); }

        protected override void OnPaintBackground(PaintEventArgs e) {
            //base.OnPaintBackground(e);
            e.Graphics.Clear(colorBackground);
        }

        /// <summary>
        /// These are the various bit patterns that represent the characters
        /// that can be displayed in the seven segments. Bits 0 through 6
        /// correspond to each of the LEDs, from top to bottom!
        /// </summary>
        public enum ValuePattern {
            None = 0x0, Zero = 0x77, One = 0x24, Two = 0x5D, Three = 0x6D,
            Four = 0x2E, Five = 0x6B, Six = 0x7B, Seven = 0x25,
            Eight = 0x7F, Nine = 0x6F, A = 0x3F, B = 0x7A, C = 0x53,
            D = 0x7C, E = 0x5B, F = 0x1B, G = 0x73, H = 0x3E,
            J = 0x74, L = 0x52, N = 0x38, O = 0x78, P = 0x1F, Q = 0x2F, R = 0x18,
            T = 0x5A, U = 0x76, Y = 0x6E,
            Dash = 0x8, Equals = 0x48
        }

        private string theValue = null;

        /// <summary>
        /// Character to be displayed on the seven segments. Supported characters
        /// are digits and most letters.
        /// </summary>
        public string Value {
            get { return theValue; }
            set {
                customPattern = 0;
                if (value != null) {
                    //is it an integer?
                    bool success = false;
                    try {
                        int tempValue = Convert.ToInt32(value);
                        if (tempValue > 9) tempValue = 9; if (tempValue < 0) tempValue = 0;
                        switch (tempValue) {
                            case 0: customPattern = (int)ValuePattern.Zero; break;
                            case 1: customPattern = (int)ValuePattern.One; break;
                            case 2: customPattern = (int)ValuePattern.Two; break;
                            case 3: customPattern = (int)ValuePattern.Three; break;
                            case 4: customPattern = (int)ValuePattern.Four; break;
                            case 5: customPattern = (int)ValuePattern.Five; break;
                            case 6: customPattern = (int)ValuePattern.Six; break;
                            case 7: customPattern = (int)ValuePattern.Seven; break;
                            case 8: customPattern = (int)ValuePattern.Eight; break;
                            case 9: customPattern = (int)ValuePattern.Nine; break;
                        }
                        success = true;
                    } catch { }
                    if (!success) {
                        try {
                            //is it a letter?
                            string tempString = Convert.ToString(value);
                            switch (tempString.ToLower()[0]) {
                                case 'a': customPattern = (int)ValuePattern.A; break;
                                case 'b': customPattern = (int)ValuePattern.B; break;
                                case 'c': customPattern = (int)ValuePattern.C; break;
                                case 'd': customPattern = (int)ValuePattern.D; break;
                                case 'e': customPattern = (int)ValuePattern.E; break;
                                case 'f': customPattern = (int)ValuePattern.F; break;
                                case 'g': customPattern = (int)ValuePattern.G; break;
                                case 'h': customPattern = (int)ValuePattern.H; break;
                                case 'j': customPattern = (int)ValuePattern.J; break;
                                case 'l': customPattern = (int)ValuePattern.L; break;
                                case 'n': customPattern = (int)ValuePattern.N; break;
                                case 'o': customPattern = (int)ValuePattern.O; break;
                                case 'p': customPattern = (int)ValuePattern.P; break;
                                case 'q': customPattern = (int)ValuePattern.Q; break;
                                case 'r': customPattern = (int)ValuePattern.R; break;
                                case 't': customPattern = (int)ValuePattern.T; break;
                                case 'u': customPattern = (int)ValuePattern.U; break;
                                case 'y': customPattern = (int)ValuePattern.Y; break;
                                case '-': customPattern = (int)ValuePattern.Dash; break;
                                case '=': customPattern = (int)ValuePattern.Equals; break;
                            }
                        } catch { }
                    }
                }
                theValue = value; Invalidate();
            }
        }

        private int customPattern = 0;
        /// <summary>
        /// Set a custom bit pattern to be displayed on the seven segments. This is an
        /// integer value where bits 0 through 6 correspond to each respective LED
        /// segment.
        /// </summary>
        public int CustomPattern { get { return customPattern; } set { customPattern = value; Invalidate(); } }

        private bool showDot = true, dotOn = false;
        /// <summary>
        /// Specifies if the decimal point LED is displayed.
        /// </summary>
        public bool DecimalShow { get { return showDot; } set { showDot = value; Invalidate(); } }
        /// <summary>
        /// Specifies if the decimal point LED is active.
        /// </summary>
        public bool DecimalOn { get { return dotOn; } set { dotOn = value; Invalidate(); } }


        private void SevenSegment_Paint(object sender, PaintEventArgs e) {
            int useValue = customPattern;

            Brush brushLight = new SolidBrush(colorLight);
            Brush brushDark = new SolidBrush(colorDark);

            // Define transformation for our container...
            RectangleF srcRect = new RectangleF(0.0F, 0.0F, gridWidth, gridHeight);
            RectangleF destRect = new RectangleF(Padding.Left, Padding.Top, this.Width - Padding.Left - Padding.Right, this.Height - Padding.Top - Padding.Bottom);

            // Begin graphics container that remaps coordinates for our convenience
            GraphicsContainer containerState = e.Graphics.BeginContainer(destRect, srcRect, GraphicsUnit.Pixel);

            Matrix trans = new Matrix();
            trans.Shear(italicFactor, 0.0F);
            e.Graphics.Transform = trans;

            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.Default;

            // Draw elements based on whether the corresponding bit is high
            e.Graphics.FillPolygon((useValue & 0x1) == 0x1 ? brushLight : brushDark, segPoints[0]);
            e.Graphics.FillPolygon((useValue & 0x2) == 0x2 ? brushLight : brushDark, segPoints[1]);
            e.Graphics.FillPolygon((useValue & 0x4) == 0x4 ? brushLight : brushDark, segPoints[2]);
            e.Graphics.FillPolygon((useValue & 0x8) == 0x8 ? brushLight : brushDark, segPoints[3]);
            e.Graphics.FillPolygon((useValue & 0x10) == 0x10 ? brushLight : brushDark, segPoints[4]);
            e.Graphics.FillPolygon((useValue & 0x20) == 0x20 ? brushLight : brushDark, segPoints[5]);
            e.Graphics.FillPolygon((useValue & 0x40) == 0x40 ? brushLight : brushDark, segPoints[6]);

            if (showDot)
                e.Graphics.FillEllipse(dotOn ? brushLight : brushDark, gridWidth - 1, gridHeight - elementWidth + 1, elementWidth, elementWidth);

            e.Graphics.EndContainer(containerState);
        }


    }
}