Based upon 4 user defined LED states, 4 colours are used upon a rectangular format LED. The GenerateGreyLed() type functions are used to generate a bit map for each LED state. The LED does not have to be generated directly at the bitmap leve a complicated, shaded vector LED can be written to a memory stream, then the stream read back into the bitmap. Nether does the LED have to have the same shape for each state, though care that the container is sized to enclose all possible LED dimensions!
In this instance the LED state is defined by a colour. On setting the colour the appropiate bitmap is recovered and "Drawn" to the container ie the screen.
[Description("RectLed")] [Designer(typeof(LedDesigner))] public partial class RectLed : UserControl { private Bitmap GreyLed; private Bitmap RedLed; private Bitmap GreenLed; private Bitmap YellowLed; private Boolean bLed; private Int32 LedSize = 30; private Int32 Led_colour = 0; // 0 = grey, 1 = green, 2 = red, 3 = yellow etc... private delegate void LedFlashCallback(); public RectLed() { InitializeComponent(); // Get bitmap into LedStrip try { // Generate bitmaps on the fly 30*30 GreyLed = GenerateGreyLed(LedSize); GreenLed = GenerateGreenLed(LedSize); RedLed = GenerateRedLed(LedSize); YellowLed = GenerateYellowLed(LedSize); bLed = true; GreyLed.MakeTransparent(Color.Transparent); GreenLed.MakeTransparent(Color.Transparent); RedLed.MakeTransparent(Color.Transparent); } catch { LedSize = 0; bLed = false; } LedDraw(); } private Bitmap GenerateGreyLed(Int32 size) { // Assumes a square led are 30 x 30 with a centralised Led on 15 * 30 Bitmap map = new Bitmap(size, size); // Fill with transparent colour for (Int32 i = 0; i < size; i++) { for (Int32 j = 0; j < size; j++) { if (j < 8) map.SetPixel(i, j, Color.Transparent); else if (j < 10) map.SetPixel(i, j, Color.AntiqueWhite); else if (j < 22) { if (i < 2) map.SetPixel(i, j, Color.AntiqueWhite); else if (i > 28) map.SetPixel(i, j, Color.Gray); else { if (j < 20) map.SetPixel(i, j, Color.LightGray); else map.SetPixel(i, j, Color.Gray); } } else map.SetPixel(i, j, Color.Transparent); } } return map; } private Bitmap GenerateGreenLed(Int32 size) { // Assumes a square led are 30 x 30 with a centralised Led on 15 * 30 Bitmap map = new Bitmap(size, size); // Fill with transparent colour for (Int32 i = 0; i < size; i++) { for (Int32 j = 0; j < size; j++) { if (j < 8) map.SetPixel(i, j, Color.Transparent); else if (j < 10) map.SetPixel(i, j, Color.AntiqueWhite); else if (j < 22) { if (i < 2) map.SetPixel(i, j, Color.AntiqueWhite); else if (i > 28) map.SetPixel(i, j, Color.DarkGreen); else { if (j < 20) map.SetPixel(i, j, Color.LawnGreen); else map.SetPixel(i, j, Color.DarkGreen); } } else map.SetPixel(i, j, Color.Transparent); } } return map; } private Bitmap GenerateRedLed(Int32 size) { // Assumes a square led are 30 x 30 with a centralised Led on 15 * 30 Bitmap map = new Bitmap(size, size); // Fill with transparent colour for (Int32 i = 0; i < size; i++) { for (Int32 j = 0; j < size; j++) { if (j < 8) map.SetPixel(i, j, Color.Transparent); else if (j < 10) map.SetPixel(i, j, Color.AntiqueWhite); else if (j < 22) { if (i < 2) map.SetPixel(i, j, Color.AntiqueWhite); else if (i > 28) map.SetPixel(i, j, Color.DarkRed); else { if (j < 20) map.SetPixel(i, j, Color.Red); else map.SetPixel(i, j, Color.DarkRed); } } else map.SetPixel(i, j, Color.Transparent); } } return map; } private Bitmap GenerateYellowLed(Int32 size) { // Assumes a square led are 30 x 30 with a centralised Led on 15 * 30 Bitmap map = new Bitmap(size, size); // Fill with transparent colour for (Int32 i = 0; i < size; i++) { for (Int32 j = 0; j < size; j++) { if (j < 8) map.SetPixel(i, j, Color.Transparent); else if (j < 10) map.SetPixel(i, j, Color.AntiqueWhite); else if (j < 22) { if (i < 2) map.SetPixel(i, j, Color.AntiqueWhite); else if (i > 28) map.SetPixel(i, j, Color.DarkOrange); else { if (j < 20) map.SetPixel(i, j, Color.Orange); else map.SetPixel(i, j, Color.DarkOrange); } } else map.SetPixel(i, j, Color.Transparent); } } return map; } [Description("RectLed, the size of")] [Category("Layout")] public Size SizeOfLed { get { return this.picture.Size; } set { this.Size = value; this.MaximumSize = value; this.MinimumSize = value; this.picture.Size = value; this.picture.MaximumSize = value; this.picture.MinimumSize = value; } } public void LedInit(String sLedColour) { SetLedOn(sLedColour); } public void SetLedOn(String sLedColour) { // The leds are in position 0 Grey // 1 Green // 2 Red // 3 Yellow sLedColour = sLedColour.ToUpper(); if (sLedColour.Contains("RED")) Led_colour = 2; else if (sLedColour.Contains("GREEN")) Led_colour = 1; else if (sLedColour.Contains("YELLOW")) Led_colour = 3; else Led_colour = 0; LedDraw(); } public void SetLedOff() { Led_colour = 0; LedDraw(); } public String GetLedState() { string sValue; if (Led_colour == 0) sValue = "GREY"; else if (Led_colour == 1) sValue = "GREEN"; else if (Led_colour == 2) sValue = "RED"; else if (Led_colour == 3) sValue = "YELLOW"; else sValue = "GREY"; return sValue; } [Description("RectLed, Initial State")] [Category("Appearance")] public string State { get { return GetLedState(); } set { // The leds are in position 0 Grey // 1 Green // 2 Red // 3 Yellow string sLedColour; sLedColour = value.ToUpper(); if (sLedColour.Contains("YELLOW")) Led_colour = 3; else if (sLedColour.Contains("RED")) Led_colour = 2; else if (sLedColour.Contains("GREEN")) Led_colour = 1; else Led_colour = 0; LedDraw(); } } private void LedDraw() { // Called on every change to the displayed image // Attach correct image to picture box if (bLed == false) return; // Cannot dispose of the image since this contains a reference to one of the bitmaps // if(this.Image!=null)this.Image.Dispose(); this.picture.Image = null; if (Led_colour == 3) this.picture.Image = (Image)YellowLed; else if (Led_colour == 2) this.picture.Image = (Image)RedLed; else if (Led_colour == 1) this.picture.Image = (Image)GreenLed; else this.picture.Image = (Image)GreyLed; this.picture.Invalidate(); } public void Flash() { // Flash the Led but an invoke may be required if (this.picture.InvokeRequired) { LedFlashCallback d = new LedFlashCallback(_Flash); this.picture.Invoke(d, new object[] { }); } else { _Flash(); } } private void _Flash() { // Flashes the Led between the original colour and grey // If LedPosn = 0 if is off if (!this.picture.Visible) { // Turn Led on to original colour if (Led_colour == 1) SetLedOn("Green"); else if (Led_colour == 2) SetLedOn("Red"); else if (Led_colour == 3) SetLedOn("Yellow"); } else { // Turn Led off this.picture.Visible = false; } } }
The basic LED component software is made available, the remainder for registered users!
private void InitializeComponent() { this.picture = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)(this.picture)).BeginInit(); this.SuspendLayout(); // // picture // this.picture.Dock = System.Windows.Forms.DockStyle.Fill; this.picture.Location = new System.Drawing.Point(0, 0); this.picture.Margin = new System.Windows.Forms.Padding(0); this.picture.MinimumSize = new System.Drawing.Size(15, 10); this.picture.Name = "picture"; this.picture.Size = new System.Drawing.Size(15, 10); this.picture.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.picture.TabIndex = 0; this.picture.TabStop = false; // // RectLed // this.AutoSize = true; this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.Controls.Add(this.picture); this.MinimumSize = new System.Drawing.Size(15, 15); this.Name = "RectLed"; this.Size = new System.Drawing.Size(15, 15); ((System.ComponentModel.ISupportInitialize)(this.picture)).EndInit(); this.ResumeLayout(false); } private PictureBox picture;
The designer can be copied or the equivalent generated by hand by changing the properties of the designer form. The properties must coincide with that required by the .cs code. Note: only InitializeComponent() and declarations are here, the rest of the designer does not change!
internal class LedDesigner : System.Windows.Forms.Design.ControlDesigner { public void LedDesigned() { } // clean up some unnecessary properties protected override void PreFilterProperties(IDictionary Properties) { Properties.Remove("BackgroundImage"); Properties.Remove("BackColor"); Properties.Remove("BackgroundImageLayout"); Properties.Remove("Size"); Properties.Remove("MaximumSize"); Properties.Remove("MinimumSize"); Properties.Remove("TabStop"); Properties.Remove("TabIndex"); Properties.Remove("Font"); Properties.Remove("ForeColor"); Properties.Remove("Cursor"); Properties.Remove("RightToLeft"); Properties.Remove("ContextMenuStrip"); Properties.Remove("BorderStyle"); Properties.Remove("UseWaitCursor"); Properties.Remove("AllowDrop"); Properties.Remove("AutoScroll"); Properties.Remove("AutoScrollMargin"); Properties.Remove("AutoScrollMinSize"); Properties.Remove("Tag"); } }
A simple internal designer class override is used to remove non-required properties.