Adding and removing row is now working.
Can now have any number of text field.
2 using System.Collections.Generic;
3 using System.ComponentModel;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
11 using CodeProject.Dialog;
12 using System.Drawing.Imaging;
13 using System.ServiceModel;
14 using System.Threading;
15 using System.Diagnostics;
17 using SharpDisplayClient;
20 namespace SharpDisplayManager
23 public delegate uint ColorProcessingDelegate(int aX, int aY, uint aPixel);
24 public delegate int CoordinateTranslationDelegate(System.Drawing.Bitmap aBmp, int aInt);
27 /// Our Display manager main form
29 public partial class MainForm : Form
32 DateTime LastTickTime;
34 System.Drawing.Bitmap iBmp;
35 bool iCreateBitmap; //Workaround render to bitmap issues when minimized
36 ServiceHost iServiceHost;
38 /// Our collection of clients
40 public Dictionary<string, ClientData> iClients;
42 ColorProcessingDelegate iColorFx;
43 CoordinateTranslationDelegate iScreenX;
44 CoordinateTranslationDelegate iScreenY;
48 LastTickTime = DateTime.Now;
49 iDisplay = new Display();
50 iClients = new Dictionary<string, ClientData>();
52 InitializeComponent();
54 //We have a bug when drawing minimized and reusing our bitmap
55 iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
56 iCreateBitmap = false;
58 //this.tableLayoutPanel.CellPaint += new TableLayoutCellPaintEventHandler(tableLayoutPanel_CellPaint);
61 private void MainForm_Load(object sender, EventArgs e)
65 if (Properties.Settings.Default.DisplayConnectOnStartup)
67 OpenDisplayConnection();
72 private void tableLayoutPanel_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
74 var panel = sender as TableLayoutPanel;
75 //e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
76 var rectangle = e.CellBounds;
77 using (var pen = new Pen(Color.Black, 1))
79 pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;
80 pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
82 if (e.Row == (panel.RowCount - 1))
84 rectangle.Height -= 1;
87 if (e.Column == (panel.ColumnCount - 1))
92 e.Graphics.DrawRectangle(pen, rectangle);
97 private void buttonFont_Click(object sender, EventArgs e)
99 //fontDialog.ShowColor = true;
100 //fontDialog.ShowApply = true;
101 fontDialog.ShowEffects = true;
102 MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[0];
103 fontDialog.Font = label.Font;
105 fontDialog.FixedPitchOnly = checkBoxFixedPitchFontOnly.Checked;
107 //fontDialog.ShowHelp = true;
109 //fontDlg.MaxSize = 40;
110 //fontDlg.MinSize = 22;
112 //fontDialog.Parent = this;
113 //fontDialog.StartPosition = FormStartPosition.CenterParent;
115 //DlgBox.ShowDialog(fontDialog);
117 //if (fontDialog.ShowDialog(this) != DialogResult.Cancel)
118 if (DlgBox.ShowDialog(fontDialog) != DialogResult.Cancel)
121 //MsgBox.Show("MessageBox MsgBox", "MsgBox caption");
123 //MessageBox.Show("Ok");
124 foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
126 ctrl.Font = fontDialog.Font;
128 cds.Font = fontDialog.Font;
129 Properties.Settings.Default.Save();
138 void CheckFontHeight()
140 //Show font height and width
141 labelFontHeight.Text = "Font height: " + cds.Font.Height;
142 float charWidth = IsFixedWidth(cds.Font);
143 if (charWidth == 0.0f)
145 labelFontWidth.Visible = false;
149 labelFontWidth.Visible = true;
150 labelFontWidth.Text = "Font width: " + charWidth;
153 //Now check font height and show a warning if needed.
154 MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[0];
155 if (label.Font.Height > label.Height)
157 labelWarning.Text = "WARNING: Selected font is too height by " + (label.Font.Height - label.Height) + " pixels!";
158 labelWarning.Visible = true;
162 labelWarning.Visible = false;
167 private void buttonCapture_Click(object sender, EventArgs e)
169 System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height);
170 tableLayoutPanel.DrawToBitmap(bmp, tableLayoutPanel.ClientRectangle);
171 //Bitmap bmpToSave = new Bitmap(bmp);
172 bmp.Save("D:\\capture.png");
174 ((MarqueeLabel)tableLayoutPanel.Controls[0]).Text = "Captured";
177 string outputFileName = "d:\\capture.png";
178 using (MemoryStream memory = new MemoryStream())
180 using (FileStream fs = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
182 bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
183 byte[] bytes = memory.ToArray();
184 fs.Write(bytes, 0, bytes.Length);
191 private void CheckForRequestResults()
193 if (iDisplay.IsRequestPending())
195 switch (iDisplay.AttemptRequestCompletion())
197 case Display.TMiniDisplayRequest.EMiniDisplayRequestFirmwareRevision:
198 toolStripStatusLabelConnect.Text += " v" + iDisplay.FirmwareRevision();
199 //Issue next request then
200 iDisplay.RequestPowerSupplyStatus();
203 case Display.TMiniDisplayRequest.EMiniDisplayRequestPowerSupplyStatus:
204 if (iDisplay.PowerSupplyStatus())
206 toolStripStatusLabelPower.Text = "ON";
210 toolStripStatusLabelPower.Text = "OFF";
212 //Issue next request then
213 iDisplay.RequestDeviceId();
216 case Display.TMiniDisplayRequest.EMiniDisplayRequestDeviceId:
217 toolStripStatusLabelConnect.Text += " - " + iDisplay.DeviceId();
218 //No more request to issue
224 public static uint ColorWhiteIsOn(int aX, int aY, uint aPixel)
226 if ((aPixel & 0x00FFFFFF) == 0x00FFFFFF)
233 public static uint ColorUntouched(int aX, int aY, uint aPixel)
238 public static uint ColorInversed(int aX, int aY, uint aPixel)
243 public static uint ColorChessboard(int aX, int aY, uint aPixel)
245 if ((aX % 2 == 0) && (aY % 2 == 0))
249 else if ((aX % 2 != 0) && (aY % 2 != 0))
257 public static int ScreenReversedX(System.Drawing.Bitmap aBmp, int aX)
259 return aBmp.Width - aX - 1;
262 public int ScreenReversedY(System.Drawing.Bitmap aBmp, int aY)
264 return iBmp.Height - aY - 1;
267 public int ScreenX(System.Drawing.Bitmap aBmp, int aX)
272 public int ScreenY(System.Drawing.Bitmap aBmp, int aY)
278 /// Select proper pixel delegates according to our current settings.
280 private void SetupPixelDelegates()
282 //Select our pixel processing routine
283 if (cds.InverseColors)
285 //iColorFx = ColorChessboard;
286 iColorFx = ColorInversed;
290 iColorFx = ColorWhiteIsOn;
293 //Select proper coordinate translation functions
294 //We used delegate/function pointer to support reverse screen without doing an extra test on each pixels
295 if (cds.ReverseScreen)
297 iScreenX = ScreenReversedX;
298 iScreenY = ScreenReversedY;
308 //This is our timer tick responsible to perform our render
309 private void timer_Tick(object sender, EventArgs e)
311 //Update our animations
312 DateTime NewTickTime = DateTime.Now;
314 //Update animation for all our marquees
315 foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
317 ctrl.UpdateAnimation(LastTickTime, NewTickTime);
322 if (iDisplay.IsOpen())
324 CheckForRequestResults();
329 iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
331 tableLayoutPanel.DrawToBitmap(iBmp, tableLayoutPanel.ClientRectangle);
332 //iBmp.Save("D:\\capture.png");
334 //Send it to our display
335 for (int i = 0; i < iBmp.Width; i++)
337 for (int j = 0; j < iBmp.Height; j++)
341 //Get our processed pixel coordinates
342 int x = iScreenX(iBmp, i);
343 int y = iScreenY(iBmp, j);
345 uint color = (uint)iBmp.GetPixel(i, j).ToArgb();
346 //Apply color effects
347 color = iColorFx(x,y,color);
349 iDisplay.SetPixel(x, y, color);
354 iDisplay.SwapBuffers();
358 //Compute instant FPS
359 toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " / " + (1000/timer.Interval).ToString() + " FPS";
361 LastTickTime = NewTickTime;
365 private void OpenDisplayConnection()
367 CloseDisplayConnection();
369 if (iDisplay.Open((Display.TMiniDisplayType)cds.DisplayType))
372 iDisplay.RequestFirmwareRevision();
377 toolStripStatusLabelConnect.Text = "Connection error";
381 private void CloseDisplayConnection()
387 private void buttonOpen_Click(object sender, EventArgs e)
389 OpenDisplayConnection();
392 private void buttonClose_Click(object sender, EventArgs e)
394 CloseDisplayConnection();
397 private void buttonClear_Click(object sender, EventArgs e)
400 iDisplay.SwapBuffers();
403 private void buttonFill_Click(object sender, EventArgs e)
406 iDisplay.SwapBuffers();
409 private void trackBarBrightness_Scroll(object sender, EventArgs e)
411 cds.Brightness = trackBarBrightness.Value;
412 Properties.Settings.Default.Save();
413 iDisplay.SetBrightness(trackBarBrightness.Value);
419 /// CDS stands for Current Display Settings
421 private DisplaySettings cds
425 DisplaysSettings settings = Properties.Settings.Default.DisplaySettings;
426 if (settings == null)
428 settings = new DisplaysSettings();
430 Properties.Settings.Default.DisplaySettings = settings;
433 //Make sure all our settings have been created
434 while (settings.Displays.Count <= Properties.Settings.Default.CurrentDisplayIndex)
436 settings.Displays.Add(new DisplaySettings());
439 DisplaySettings displaySettings = settings.Displays[Properties.Settings.Default.CurrentDisplayIndex];
440 return displaySettings;
445 /// Check if the given font has a fixed character pitch.
447 /// <param name="ft"></param>
448 /// <returns>0.0f if this is not a monospace font, otherwise returns the character width.</returns>
449 public float IsFixedWidth(Font ft)
451 Graphics g = CreateGraphics();
452 char[] charSizes = new char[] { 'i', 'a', 'Z', '%', '#', 'a', 'B', 'l', 'm', ',', '.' };
453 float charWidth = g.MeasureString("I", ft, Int32.MaxValue, StringFormat.GenericTypographic).Width;
455 bool fixedWidth = true;
457 foreach (char c in charSizes)
458 if (g.MeasureString(c.ToString(), ft, Int32.MaxValue, StringFormat.GenericTypographic).Width != charWidth)
469 private void UpdateStatus()
471 //Synchronize UI with settings
473 checkBoxShowBorders.Checked = cds.ShowBorders;
474 tableLayoutPanel.CellBorderStyle = (cds.ShowBorders ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
476 //Set the proper font to each of our labels
477 foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
479 ctrl.Font = cds.Font;
483 checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup;
484 checkBoxReverseScreen.Checked = cds.ReverseScreen;
485 checkBoxInverseColors.Checked = cds.InverseColors;
486 comboBoxDisplayType.SelectedIndex = cds.DisplayType;
487 timer.Interval = cds.TimerInterval;
488 maskedTextBoxTimerInterval.Text = cds.TimerInterval.ToString();
490 SetupPixelDelegates();
492 if (iDisplay.IsOpen())
494 //Only setup brightness if display is open
495 trackBarBrightness.Minimum = iDisplay.MinBrightness();
496 trackBarBrightness.Maximum = iDisplay.MaxBrightness();
497 trackBarBrightness.Value = cds.Brightness;
498 trackBarBrightness.LargeChange = Math.Max(1, (iDisplay.MaxBrightness() - iDisplay.MinBrightness()) / 5);
499 trackBarBrightness.SmallChange = 1;
500 iDisplay.SetBrightness(cds.Brightness);
502 buttonFill.Enabled = true;
503 buttonClear.Enabled = true;
504 buttonOpen.Enabled = false;
505 buttonClose.Enabled = true;
506 trackBarBrightness.Enabled = true;
507 toolStripStatusLabelConnect.Text = "Connected - " + iDisplay.Vendor() + " - " + iDisplay.Product();
508 //+ " - " + iDisplay.SerialNumber();
510 if (iDisplay.SupportPowerOnOff())
512 buttonPowerOn.Enabled = true;
513 buttonPowerOff.Enabled = true;
517 buttonPowerOn.Enabled = false;
518 buttonPowerOff.Enabled = false;
521 if (iDisplay.SupportClock())
523 buttonShowClock.Enabled = true;
524 buttonHideClock.Enabled = true;
528 buttonShowClock.Enabled = false;
529 buttonHideClock.Enabled = false;
534 buttonFill.Enabled = false;
535 buttonClear.Enabled = false;
536 buttonOpen.Enabled = true;
537 buttonClose.Enabled = false;
538 trackBarBrightness.Enabled = false;
539 buttonPowerOn.Enabled = false;
540 buttonPowerOff.Enabled = false;
541 buttonShowClock.Enabled = false;
542 buttonHideClock.Enabled = false;
543 toolStripStatusLabelConnect.Text = "Disconnected";
544 toolStripStatusLabelPower.Text = "N/A";
550 private void checkBoxShowBorders_CheckedChanged(object sender, EventArgs e)
552 //Save our show borders setting
553 tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
554 cds.ShowBorders = checkBoxShowBorders.Checked;
555 Properties.Settings.Default.Save();
559 private void checkBoxConnectOnStartup_CheckedChanged(object sender, EventArgs e)
561 //Save our connect on startup setting
562 Properties.Settings.Default.DisplayConnectOnStartup = checkBoxConnectOnStartup.Checked;
563 Properties.Settings.Default.Save();
566 private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e)
568 //Save our reverse screen setting
569 cds.ReverseScreen = checkBoxReverseScreen.Checked;
570 Properties.Settings.Default.Save();
571 SetupPixelDelegates();
574 private void checkBoxInverseColors_CheckedChanged(object sender, EventArgs e)
576 //Save our inverse colors setting
577 cds.InverseColors = checkBoxInverseColors.Checked;
578 Properties.Settings.Default.Save();
579 SetupPixelDelegates();
582 private void MainForm_Resize(object sender, EventArgs e)
584 if (WindowState == FormWindowState.Minimized)
587 //iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
588 iCreateBitmap = true;
592 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
598 public void StartServer()
600 iServiceHost = new ServiceHost
603 new Uri[] { new Uri("net.tcp://localhost:8001/") }
606 iServiceHost.AddServiceEndpoint(typeof(IService), new NetTcpBinding(SecurityMode.None, true), "DisplayService");
610 public void StopServer()
612 if (iClients.Count > 0 && !iClosing)
616 BroadcastCloseEvent();
620 if (MessageBox.Show("Force exit?", "Waiting for clients...", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
622 iClosing = false; //We make sure we force close if asked twice
627 //We removed that as it often lags for some reason
628 //iServiceHost.Close();
632 public void BroadcastCloseEvent()
634 Trace.TraceInformation("BroadcastCloseEvent - start");
636 var inactiveClients = new List<string>();
637 foreach (var client in iClients)
639 //if (client.Key != eventData.ClientName)
643 Trace.TraceInformation("BroadcastCloseEvent - " + client.Key);
644 client.Value.Callback.OnCloseOrder(/*eventData*/);
648 inactiveClients.Add(client.Key);
653 if (inactiveClients.Count > 0)
655 foreach (var client in inactiveClients)
657 iClients.Remove(client);
658 Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(client, false)[0]);
663 private void buttonStartClient_Click(object sender, EventArgs e)
665 Thread clientThread = new Thread(SharpDisplayClient.Program.Main);
666 clientThread.Start();
670 private void buttonSuspend_Click(object sender, EventArgs e)
672 LastTickTime = DateTime.Now; //Reset timer to prevent jump
673 timer.Enabled = !timer.Enabled;
676 buttonSuspend.Text = "Run";
680 buttonSuspend.Text = "Pause";
684 private void buttonCloseClients_Click(object sender, EventArgs e)
686 BroadcastCloseEvent();
689 private void treeViewClients_AfterSelect(object sender, TreeViewEventArgs e)
694 //Delegates are used for our thread safe method
695 public delegate void AddClientDelegate(string aSessionId, ICallback aCallback);
696 public delegate void RemoveClientDelegate(string aSessionId);
697 public delegate void SetTextDelegate(string SessionId, TextField aTextField);
698 public delegate void SetTextsDelegate(string SessionId, System.Collections.Generic.IList<TextField> aTextFields);
699 public delegate void SetClientNameDelegate(string aSessionId, string aName);
705 /// <param name="aSessionId"></param>
706 /// <param name="aCallback"></param>
707 public void AddClientThreadSafe(string aSessionId, ICallback aCallback)
709 if (this.InvokeRequired)
711 //Not in the proper thread, invoke ourselves
712 AddClientDelegate d = new AddClientDelegate(AddClientThreadSafe);
713 this.Invoke(d, new object[] { aSessionId, aCallback });
717 //We are in the proper thread
718 //Add this session to our collection of clients
719 ClientData newClient = new ClientData(aSessionId, aCallback);
720 Program.iMainForm.iClients.Add(aSessionId, newClient);
721 //Add this session to our UI
722 UpdateClientTreeViewNode(newClient);
729 /// <param name="aSessionId"></param>
730 public void RemoveClientThreadSafe(string aSessionId)
732 if (this.InvokeRequired)
734 //Not in the proper thread, invoke ourselves
735 RemoveClientDelegate d = new RemoveClientDelegate(RemoveClientThreadSafe);
736 this.Invoke(d, new object[] { aSessionId });
740 //We are in the proper thread
741 //Remove this session from both client collection and UI tree view
742 if (Program.iMainForm.iClients.Keys.Contains(aSessionId))
744 Program.iMainForm.iClients.Remove(aSessionId);
745 Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]);
748 if (iClosing && iClients.Count == 0)
750 //We were closing our form
751 //All clients are now closed
752 //Just resume our close operation
762 /// <param name="aLineIndex"></param>
763 /// <param name="aText"></param>
764 public void SetTextThreadSafe(string aSessionId, TextField aTextField)
766 if (this.InvokeRequired)
768 //Not in the proper thread, invoke ourselves
769 SetTextDelegate d = new SetTextDelegate(SetTextThreadSafe);
770 this.Invoke(d, new object[] { aSessionId, aTextField });
774 ClientData client = iClients[aSessionId];
777 //Make sure all our texts are in place
778 while (client.Texts.Count < (aTextField.Index + 1))
780 //Add a text field with proper index
781 client.Texts.Add(new TextField(client.Texts.Count));
783 client.Texts[aTextField.Index] = aTextField;
785 //We are in the proper thread
786 MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[aTextField.Index];
787 label.Text = aTextField.Text;
788 label.TextAlign = aTextField.Alignment;
790 UpdateClientTreeViewNode(client);
798 /// <param name="aTexts"></param>
799 public void SetTextsThreadSafe(string aSessionId, System.Collections.Generic.IList<TextField> aTextFields)
801 if (this.InvokeRequired)
803 //Not in the proper thread, invoke ourselves
804 SetTextsDelegate d = new SetTextsDelegate(SetTextsThreadSafe);
805 this.Invoke(d, new object[] { aSessionId, aTextFields });
809 //We are in the proper thread
810 ClientData client = iClients[aSessionId];
813 //Populate our client with the given text fields
815 foreach (TextField textField in aTextFields)
817 if (client.Texts.Count < (j + 1))
819 client.Texts.Add(textField);
823 client.Texts[j] = textField;
827 //Only support two lines for now
828 for (int i = 0; i < aTextFields.Count; i++)
830 MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[aTextFields[i].Index];
831 label.Text = aTextFields[i].Text;
832 label.TextAlign = aTextFields[i].Alignment;
836 UpdateClientTreeViewNode(client);
845 /// <param name="aSessionId"></param>
846 /// <param name="aName"></param>
847 public void SetClientNameThreadSafe(string aSessionId, string aName)
849 if (this.InvokeRequired)
851 //Not in the proper thread, invoke ourselves
852 SetClientNameDelegate d = new SetClientNameDelegate(SetClientNameThreadSafe);
853 this.Invoke(d, new object[] { aSessionId, aName });
857 //We are in the proper thread
859 ClientData client = iClients[aSessionId];
864 //Update our tree-view
865 UpdateClientTreeViewNode(client);
873 /// <param name="aClient"></param>
874 private void UpdateClientTreeViewNode(ClientData aClient)
881 TreeNode node = null;
882 //Check that our client node already exists
883 //Get our client root node using its key which is our session ID
884 TreeNode[] nodes = treeViewClients.Nodes.Find(aClient.SessionId, false);
887 //We already have a node for that client
889 //Clear children as we are going to recreate them below
894 //Client node does not exists create a new one
895 treeViewClients.Nodes.Add(aClient.SessionId, aClient.SessionId);
896 node = treeViewClients.Nodes.Find(aClient.SessionId, false)[0];
902 if (aClient.Name != "")
904 //We have a name, us it as text for our root node
905 node.Text = aClient.Name;
906 //Add a child with SessionId
907 node.Nodes.Add(new TreeNode(aClient.SessionId));
911 //No name, use session ID instead
912 node.Text = aClient.SessionId;
915 if (aClient.Texts.Count > 0)
917 //Create root node for our texts
918 TreeNode textsRoot = new TreeNode("Text");
919 node.Nodes.Add(textsRoot);
920 //For each text add a new entry
921 foreach (TextField field in aClient.Texts)
923 textsRoot.Nodes.Add(new TreeNode(field.Text));
931 private void buttonAddRow_Click(object sender, EventArgs e)
933 if (tableLayoutPanel.RowCount < 6)
935 CreateMarqueeForCell(0, tableLayoutPanel.RowCount);
940 private void buttonRemoveRow_Click(object sender, EventArgs e)
942 if (tableLayoutPanel.RowCount > 1)
944 tableLayoutPanel.RowStyles.RemoveAt(tableLayoutPanel.RowCount-1);
945 tableLayoutPanel.Controls.RemoveAt(tableLayoutPanel.RowCount-1);
946 tableLayoutPanel.RowCount--;
950 UpdateTableLayoutRowStyles();
954 /// Update our table layout row styles to make sure each rows have similar height
956 private void UpdateTableLayoutRowStyles()
958 foreach (RowStyle rowStyle in tableLayoutPanel.RowStyles)
960 rowStyle.SizeType = SizeType.Percent;
961 rowStyle.Height = 100 / tableLayoutPanel.RowCount;
966 /// Create the specified cell in our table layout and add a marquee label to it.
968 /// <param name="aColumn"></param>
969 /// <param name="aRow"></param>
970 private void CreateMarqueeForCell(int aColumn, int aRow)
972 this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.AutoSize));
973 MarqueeLabel control = new SharpDisplayManager.MarqueeLabel();
974 control.AutoEllipsis = true;
975 control.AutoSize = true;
976 control.BackColor = System.Drawing.Color.Transparent;
977 control.Dock = System.Windows.Forms.DockStyle.Fill;
978 control.Location = new System.Drawing.Point(1, 1);
979 control.Margin = new System.Windows.Forms.Padding(0);
980 control.Name = "marqueeLabelCol" + aColumn + "Row" + aRow;
981 control.OwnTimer = false;
982 control.PixelsPerSecond = 64;
983 control.Separator = "|";
984 //control.Size = new System.Drawing.Size(254, 30);
985 //control.TabIndex = 2;
986 control.Font = cds.Font;
987 control.Text = "ABCDEFGHIJKLMNOPQRST-0123456789";
988 control.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
989 control.UseCompatibleTextRendering = true;
991 tableLayoutPanel.RowCount++;
992 tableLayoutPanel.Controls.Add(control, aColumn, aRow);
994 UpdateTableLayoutRowStyles();
998 private void buttonAddColumn_Click(object sender, EventArgs e)
1000 if (tableLayoutPanel.ColumnCount < 8)
1002 tableLayoutPanel.ColumnCount++;
1003 //CheckFontHeight();
1007 private void buttonRemoveColumn_Click(object sender, EventArgs e)
1009 if (tableLayoutPanel.ColumnCount > 1)
1011 tableLayoutPanel.ColumnCount--;
1012 //CheckFontHeight();
1016 private void buttonAlignLeft_Click(object sender, EventArgs e)
1018 foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
1020 ctrl.TextAlign = ContentAlignment.MiddleLeft;
1024 private void buttonAlignCenter_Click(object sender, EventArgs e)
1026 foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
1028 ctrl.TextAlign = ContentAlignment.MiddleCenter;
1032 private void buttonAlignRight_Click(object sender, EventArgs e)
1034 foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
1036 ctrl.TextAlign = ContentAlignment.MiddleRight;
1040 private void comboBoxDisplayType_SelectedIndexChanged(object sender, EventArgs e)
1042 Properties.Settings.Default.CurrentDisplayIndex = comboBoxDisplayType.SelectedIndex;
1043 cds.DisplayType = comboBoxDisplayType.SelectedIndex;
1044 Properties.Settings.Default.Save();
1045 if (iDisplay.IsOpen())
1047 OpenDisplayConnection();
1056 private void maskedTextBoxTimerInterval_TextChanged(object sender, EventArgs e)
1058 if (maskedTextBoxTimerInterval.Text != "")
1060 int interval = Convert.ToInt32(maskedTextBoxTimerInterval.Text);
1064 timer.Interval = interval;
1065 cds.TimerInterval = timer.Interval;
1066 Properties.Settings.Default.Save();
1071 private void buttonPowerOn_Click(object sender, EventArgs e)
1076 private void buttonPowerOff_Click(object sender, EventArgs e)
1078 iDisplay.PowerOff();
1081 private void buttonShowClock_Click(object sender, EventArgs e)
1083 iDisplay.ShowClock();
1086 private void buttonHideClock_Click(object sender, EventArgs e)
1088 iDisplay.HideClock();
1093 /// A UI thread copy of a client relevant data.
1094 /// Keeping this copy in the UI thread helps us deal with threading issues.
1096 public class ClientData
1098 public ClientData(string aSessionId, ICallback aCallback)
1100 SessionId = aSessionId;
1102 Texts = new List<TextField>();
1103 Callback = aCallback;
1106 public string SessionId { get; set; }
1107 public string Name { get; set; }
1108 public List<TextField> Texts { get; set; }
1109 public ICallback Callback { get; set; }