private void OutputTester_Load(object sender, EventArgs e) { // set up the pin display object pinDisplay = new KL25ZPinDisplay(picKl25z); // note layout items for resizing purposes int w = ClientRectangle.Width, h = ClientRectangle.Height; icon1MarginX = w - icon1.Right; bar2MarginY = h - bar2.Top; btnMarginX = w - btnClose.Right; btnSpacingX = btnClose.Left - btnHelp.Right; bottomPanelMarginY = h - bottomPanel.Top; // current row controls Panel outPanel = outPanel1; Label outNum = outNum1; Label outPin = outPin1; Label outLevel = outLevel1; TrackBar outBar = outBar1; CheckBox outOnOff = outOnOff1; // row copying functions Func <Panel, Panel> CopyPanel = (p) => { Panel n = new Panel(); outputListPanel.Controls.Add(n); n.Left = p.Left; n.Top = p.Top + p.Height; n.Width = p.Width; n.Height = p.Height; return(n); }; Func <Label, Label> CopyLabel = (l) => { Label n = new Label(); outPanel.Controls.Add(n); n.AutoSize = false; n.TextAlign = ContentAlignment.MiddleCenter; n.Left = l.Left; n.Width = l.Width; n.Height = l.Height; n.Top = l.Top; n.Font = l.Font; n.Padding = l.Padding; return(n); }; Func <CheckBox, CheckBox> CopyCheckbox = (c) => { CheckBox n = new CheckBox(); outPanel.Controls.Add(n); n.AutoSize = false; n.TextAlign = ContentAlignment.MiddleCenter; n.Left = c.Left; n.Width = c.Width; n.Height = c.Height; n.Top = c.Top; n.Text = c.Text; n.Appearance = c.Appearance; return(n); }; Func <TrackBar, TrackBar> CopyBar = (b) => { TrackBar n = new TrackBar(); outPanel.Controls.Add(n); n.Left = b.Left; n.Top = b.Top; n.Width = b.Width; n.Height = b.Height; n.TickFrequency = b.TickFrequency; n.TickStyle = b.TickStyle; n.Minimum = b.Minimum; n.Maximum = b.Maximum; return(n); }; // Mouse enter/leave handler generators Action <String, bool> SetPinHover = (pin, hilite) => { pinDisplay.SetHover(pin, hilite); }; Func <String, EventHandler> PanelMouseEnter = (pin) => { EventHandler h1 = (object s1, EventArgs e1) => { SetPinHover(pin, true); outputListPanel.Focus(); }; return(new EventHandler(h1)); }; Func <String, EventHandler> PanelMouseLeave = (pin) => { EventHandler h1 = (object s1, EventArgs e1) => { SetPinHover(pin, false); }; return(new EventHandler(h1)); }; // TrackBar and CheckBox handler generators Func <int, TrackBar, Label, EventHandler> TrackChange = (port, bar, levelLabel) => { EventHandler h1 = (object s1, EventArgs e1) => { SetPort(port, bar.Value); levelLabel.Text = bar.Value.ToString(); }; return(new EventHandler(h1)); }; Func <int, TrackBar, Label, MouseEventHandler> TrackMouseDown = (port, bar, levelLabel) => { MouseEventHandler h1 = (object s1, MouseEventArgs e1) => { const int marginLeft = 12, marginRight = 16; double x = Math.Max(0, e1.X - marginLeft); double wid = bar.Width - marginLeft - marginRight; bar.Value = (int)Math.Round(Math.Min(1.0, x / wid) * (bar.Maximum - bar.Minimum) + bar.Minimum); SetPort(port, bar.Value); levelLabel.Text = bar.Value.ToString(); }; return(new MouseEventHandler(h1)); }; Func <int, CheckBox, EventHandler> CheckBoxChange = (port, ck) => { EventHandler h1 = (object s1, EventArgs e1) => { bool on = ck.Checked; SetPort(port, on ? 255 : 0); ck.BackColor = on ? Color.Yellow : ck.Parent.BackColor; ck.Text = on ? "ON" : "Off"; }; return(new EventHandler(h1)); }; // populate the output port list byte[] buf = dev.QueryConfigVar(255, 0); int nPorts = 0; if (buf != null) { byte nOutputs = buf[0]; for (byte i = 1; i <= nOutputs; ++i) { // retrieve this output description buf = dev.QueryConfigVar(255, i); byte typ = buf[0]; // 0=disabled, 1=GPIO PWM, 2=GPIO Digital, 3=TLC5940, 4=74HC595, 5=virtual, 6=TLC59116 byte pin = buf[1]; // GPIO pin ID (wire format), or TLC/HC595 pin number bool pwm = false; // presume it's not a PWM port String klPin = null; // presume it's not a KL25Z pin // if the output is type 0 = disabled, it marks the end of the // output list if (typ == 0) { break; } // count the port ++nPorts; // figure the pin name String pinName = null; switch (typ) { case 1: // KL25Z GPIO PWM klPin = DeviceInfo.WireToPinName(pin); pinName = klPin + "\r\n" + "(PWM)"; pwm = true; break; case 2: // KL25Z GPIO Digital klPin = DeviceInfo.WireToPinName(pin); pinName = klPin + "\r\n" + "(Digital)"; break; case 3: // TLC5940. These have 16 outputs per chip, and we number the ports // sequentially across the daisy chain: pins 0-15 are chip 1, pins // 16-31 are chip 2, etc. pinName = "TLC5940 #" + ((pin / 16) + 1) + "\r\n" + "OUT" + (pin % 16); pwm = true; break; case 4: // 74HC595. These have 8 outputs per chip, numbered sequentially // across the daisy chain as with the TLC5940. pinName = "74HC595 #" + ((pin / 8) + 1) + "\r\n" + "OUT" + (pin % 8); break; case 5: // virtual output pinName = "Virtual"; pwm = true; break; case 6: // TLC59116. These have 16 outputs per chip. Each chip has a 4-bit // address (the low 4 bits of its I2C address). The pin number // encodes the address in the high 4 bits and the output number in // the low 4 bits. pinName = "TLC59116 @" + ((pin >> 4) & 0x0F) + "\r\n" + "OUT" + (pin & 0x0F); pwm = true; break; } // if this isn't the first row, copy the prototype if (i > 1) { outPanel = CopyPanel(outPanel); outNum = CopyLabel(outNum); outPin = CopyLabel(outPin); outLevel = CopyLabel(outLevel); outBar = CopyBar(outBar); outOnOff = CopyCheckbox(outOnOff); } // set the labels outNum.Text = i.ToString(); outPin.Text = pinName; outLevel.Text = "0"; // show the trackbar or on/off button, according to the PWM status outBar.Visible = outBar.Enabled = outLevel.Visible = pwm; outOnOff.Visible = outOnOff.Enabled = !pwm; // set the event handlers if (pwm) { outBar.ValueChanged += TrackChange(i, outBar, outLevel); outBar.MouseDown += TrackMouseDown(i, outBar, outLevel); } else { outOnOff.CheckedChanged += CheckBoxChange(i, outOnOff); } // if it's a KL25Z pin, attach the mouse methods to connect the pin if (klPin != null) { // Add the MouseEnter and MouseLeave handlers to the panel and // all of its children. We have to repeat the handlers on the // children because the event model doesn't nest: entering a // child leaves the parent. We want the whole area within the // panel to act the same way, so we need to populate all of // the child controls with the same handlers as the parent. EventHandler enter = PanelMouseEnter(klPin); EventHandler leave = PanelMouseLeave(klPin); outPanel.MouseEnter += enter; outPanel.MouseLeave += leave; foreach (Control chi in outPanel.Controls) { chi.MouseEnter += enter; chi.MouseLeave += leave; } } } } // create the output port level arrays newLevel = new int[nPorts]; oldLevel = new int[nPorts]; // start the update timer updateTimer.Enabled = true; }
private void ButtonStatus_Load(object sender, EventArgs e) { // load the small on-screen keyboard image kbPic.Image = new Bitmap("html\\kbSmall.png"); // figure the scale relative to the full keyboard image, which is // what the layout coordinates in the keycaps are based on kbPicScale = (float)kbPic.Image.Width / kbImage.Width; // set up the pin display object pinDisplay = new KL25ZPinDisplay(picKl25z); // note layout items for resizing purposes int w = ClientRectangle.Width, h = ClientRectangle.Height; icon1MarginX = w - icon1.Right; btnMarginX = w - btnClose.Right; btnSpacingX = btnClose.Left - btnHelp.Right; bottomPanelMarginY = h - bottomPanel.Top; // start with the prototype row Panel btnPanel = btnPanel1; Label btnNum = btnNum1; Label btnPort = btnPort1; Label btnState = btnState1; PictureBox btnKeyA = btnKey1a; PictureBox btnKeyB = btnKey1b; PictureBox btnShift = btnShift1; // row copying functions Func <Panel, Panel> CopyPanel = (p) => { Panel n = new Panel(); btnListPanel.Controls.Add(n); n.Left = p.Left; n.Top = p.Top + p.Height; n.Width = p.Width; n.Height = p.Height; return(n); }; Func <Label, Label> CopyLabel = (l) => { Label n = new Label(); btnPanel.Controls.Add(n); n.AutoSize = false; n.TextAlign = ContentAlignment.MiddleCenter; n.Left = l.Left; n.Width = l.Width; n.Height = l.Height; n.Top = l.Top; n.Font = l.Font; n.Padding = l.Padding; return(n); }; Func <PictureBox, PictureBox> CopyPic = (p) => { PictureBox n = new PictureBox(); btnPanel.Controls.Add(n); n.Left = p.Left; n.Top = p.Top; n.Width = p.Width; n.Height = p.Height; n.SizeMode = PictureBoxSizeMode.StretchImage; return(n); }; StringFormat centerText = new StringFormat(); centerText.Alignment = StringAlignment.Center; centerText.LineAlignment = StringAlignment.Center; Action <PictureBox, int, int> SetKeyCap = (pic, keyType, keyCode) => { switch (keyType) { case 0: // no key assignment break; case 1: // joystick pic.Image = new Bitmap(jsImage); using (var g = Graphics.FromImage(pic.Image)) { Font font = captionFont; String num = keyCode.ToString(); g.MeasureString(num, font); g.DrawString(num, font, Brushes.White, new Point(jsImage.Height / 2, jsImage.Width / 2), centerText); } break; case 2: case 3: // keyboard or media key Dictionary <int, KeyCap> dict = keyType == 2 ? keyCaps : mediaCaps; if (dict.ContainsKey(keyCode)) { KeyCap kc = dict[keyCode]; Bitmap cb = new Bitmap(kc.cwid, kc.cht); Rectangle src = new Rectangle(kc.cx, kc.cy, kc.cwid, kc.cht); Rectangle dst = new Rectangle(0, 0, kc.cwid, kc.cht); using (var g = Graphics.FromImage(cb)) { g.DrawImage(kbImage, dst, src, GraphicsUnit.Pixel); } pic.Image = cb; } break; } }; // check to see if a shift button is enabled int shiftButtonIdx = 0; byte[] buf = dev.QueryConfigVar(16); if (buf != null) { shiftButtonIdx = buf[0]; } // gray out the "Shifted" column header if there's no shift button if (shiftButtonIdx == 0) { lblShifted.ForeColor = Color.Gray; } // Mouse enter/leave handler generators. Highlight the associated pin // on the KL25Z diagram. Action <String, bool> SetPinHover = (pin, hilite) => { pinDisplay.SetHover(pin, hilite); }; Func <String, EventHandler> PanelMouseEnter = (pin) => { EventHandler h1 = (object s1, EventArgs e1) => { SetPinHover(pin, true); btnListPanel.Focus(); }; return(new EventHandler(h1)); }; Func <String, EventHandler> PanelMouseLeave = (pin) => { EventHandler h1 = (object s1, EventArgs e1) => { SetPinHover(pin, false); }; return(new EventHandler(h1)); }; // load the button configuration buf = dev.QueryConfigVar(254, 0); if (buf != null) { byte nButtons = buf[0]; statusLabels = new Label[nButtons]; pinNames = new String[nButtons]; for (byte i = 1; i <= nButtons; ++i) { // if this isn't the first row, copy the prototype if (i > 1) { btnPanel = CopyPanel(btnPanel); btnNum = CopyLabel(btnNum); btnPort = CopyLabel(btnPort); btnState = CopyLabel(btnState); btnKeyA = CopyPic(btnKeyA); btnKeyB = CopyPic(btnKeyB); btnShift = CopyPic(btnShift); } if ((i & 1) == 0) { btnPanel.BackColor = Color.GhostWhite; } // retrieve the button description buf = dev.QueryConfigVar(254, i); byte[] xbuf = dev.QueryConfigVar(253, i); // fill in the labels btnNum.Text = i.ToString(); String pin = DeviceInfo.WireToPinName(buf[0]); btnPort.Text = (pin == "NC" ? "None" : pin); btnState.Text = "Off"; // Set up the mouse event handlers on the panel and its children. // It's a little tedious, but we have to install the handlers on // all of the children, because the event model doesn't stack: the // mouse is only in one control at a time, so it leaves the parent // when entering a child. We want the parent and all children to // be the same for the purposes of the hovering, so we need the same // handlers on all of them. EventHandler enter = PanelMouseEnter(pin); EventHandler leave = PanelMouseLeave(pin); btnPanel.MouseEnter += enter; btnPanel.MouseLeave += leave; foreach (Control chi in btnPanel.Controls) { chi.MouseEnter += enter; chi.MouseLeave += leave; } // set the key caps SetKeyCap(btnKeyA, buf[1], buf[2]); if (shiftButtonIdx != 0 && shiftButtonIdx != i) { SetKeyCap(btnKeyB, xbuf[0], xbuf[1]); } // if this is the shift button, set the shift button image if (i == shiftButtonIdx) { btnShift.Image = new Bitmap("html\\shiftButtonSmall.png"); } // remember the status label and pin name statusLabels[i - 1] = btnState; pinNames[i - 1] = pin; } } }