# HG changeset patch # User sl # Date 1408180542 -7200 # Node ID 1363bda20171c7df580692bcd648b8ca9fb2cb1b # Parent 4c416d2878dd7db3f14846d352f8a783171ebe6f Adding texts fields to our test client. Trying to fix bugs and optimize our marquee control. Creating a proper ClientData class to use in our UI thread client dictionary. Centralising tree-view update. diff -r 4c416d2878dd -r 1363bda20171 Client/MainForm.Designer.cs --- a/Client/MainForm.Designer.cs Fri Aug 15 13:26:38 2014 +0200 +++ b/Client/MainForm.Designer.cs Sat Aug 16 11:15:42 2014 +0200 @@ -29,11 +29,13 @@ private void InitializeComponent() { this.buttonSetText = new System.Windows.Forms.Button(); + this.textBoxTop = new System.Windows.Forms.TextBox(); + this.textBoxBottom = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // buttonSetText // - this.buttonSetText.Location = new System.Drawing.Point(170, 104); + this.buttonSetText.Location = new System.Drawing.Point(12, 132); this.buttonSetText.Name = "buttonSetText"; this.buttonSetText.Size = new System.Drawing.Size(75, 23); this.buttonSetText.TabIndex = 0; @@ -41,23 +43,42 @@ this.buttonSetText.UseVisualStyleBackColor = true; this.buttonSetText.Click += new System.EventHandler(this.buttonSetText_Click); // + // textBoxTop + // + this.textBoxTop.Location = new System.Drawing.Point(12, 31); + this.textBoxTop.Name = "textBoxTop"; + this.textBoxTop.Size = new System.Drawing.Size(419, 20); + this.textBoxTop.TabIndex = 1; + // + // textBoxBottom + // + this.textBoxBottom.Location = new System.Drawing.Point(12, 57); + this.textBoxBottom.Name = "textBoxBottom"; + this.textBoxBottom.Size = new System.Drawing.Size(419, 20); + this.textBoxBottom.TabIndex = 2; + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(443, 252); + this.Controls.Add(this.textBoxBottom); + this.Controls.Add(this.textBoxTop); this.Controls.Add(this.buttonSetText); this.Name = "MainForm"; this.Text = "Client"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); this.Load += new System.EventHandler(this.MainForm_Load); this.ResumeLayout(false); + this.PerformLayout(); } #endregion private System.Windows.Forms.Button buttonSetText; + private System.Windows.Forms.TextBox textBoxTop; + private System.Windows.Forms.TextBox textBoxBottom; } } diff -r 4c416d2878dd -r 1363bda20171 Client/MainForm.cs --- a/Client/MainForm.cs Fri Aug 15 13:26:38 2014 +0200 +++ b/Client/MainForm.cs Sat Aug 16 11:15:42 2014 +0200 @@ -28,7 +28,7 @@ { //iClient.SetText(0,"Top"); //iClient.SetText(1, "Bottom"); - iClient.SetTexts(new string[] { iClient.Name, iClient.SessionId }); + iClient.SetTexts(new string[] { textBoxTop.Text, textBoxBottom.Text }); } private void MainForm_Load(object sender, EventArgs e) @@ -45,6 +45,10 @@ //Text = Text + ": " + name; Text = "[[" + name + "]] " + iClient.SessionId; + // + textBoxTop.Text = iClient.Name; + textBoxBottom.Text = iClient.SessionId; + } diff -r 4c416d2878dd -r 1363bda20171 Server/MainForm.Designer.cs --- a/Server/MainForm.Designer.cs Fri Aug 15 13:26:38 2014 +0200 +++ b/Server/MainForm.Designer.cs Sat Aug 16 11:15:42 2014 +0200 @@ -39,6 +39,8 @@ this.checkBoxConnectOnStartup = new System.Windows.Forms.CheckBox(); this.panelDisplay = new System.Windows.Forms.Panel(); this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); + this.marqueeLabelTop = new SharpDisplayManager.MarqueeLabel(); + this.marqueeLabelBottom = new SharpDisplayManager.MarqueeLabel(); this.checkBoxShowBorders = new System.Windows.Forms.CheckBox(); this.trackBarBrightness = new System.Windows.Forms.TrackBar(); this.buttonFill = new System.Windows.Forms.Button(); @@ -48,6 +50,8 @@ this.buttonCapture = new System.Windows.Forms.Button(); this.buttonFont = new System.Windows.Forms.Button(); this.tabPageTests = new System.Windows.Forms.TabPage(); + this.tabPageClients = new System.Windows.Forms.TabPage(); + this.treeViewClients = new System.Windows.Forms.TreeView(); this.fontDialog = new System.Windows.Forms.FontDialog(); this.timer = new System.Windows.Forms.Timer(this.components); this.statusStrip = new System.Windows.Forms.StatusStrip(); @@ -55,17 +59,13 @@ this.toolStripStatusLabelSpring = new System.Windows.Forms.ToolStripStatusLabel(); this.toolStripStatusLabelPower = new System.Windows.Forms.ToolStripStatusLabel(); this.toolStripStatusLabelFps = new System.Windows.Forms.ToolStripStatusLabel(); - this.tabPageClients = new System.Windows.Forms.TabPage(); - this.treeViewClients = new System.Windows.Forms.TreeView(); - this.marqueeLabelTop = new SharpDisplayManager.MarqueeLabel(); - this.marqueeLabelBottom = new SharpDisplayManager.MarqueeLabel(); this.tabControl.SuspendLayout(); this.tabPageDisplay.SuspendLayout(); this.panelDisplay.SuspendLayout(); this.tableLayoutPanel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.trackBarBrightness)).BeginInit(); + this.tabPageClients.SuspendLayout(); this.statusStrip.SuspendLayout(); - this.tabPageClients.SuspendLayout(); this.SuspendLayout(); // // tabControl @@ -254,6 +254,39 @@ this.tableLayoutPanel.Size = new System.Drawing.Size(256, 64); this.tableLayoutPanel.TabIndex = 5; // + // marqueeLabelTop + // + this.marqueeLabelTop.AutoEllipsis = true; + this.marqueeLabelTop.BackColor = System.Drawing.Color.Transparent; + this.marqueeLabelTop.Dock = System.Windows.Forms.DockStyle.Fill; + this.marqueeLabelTop.Location = new System.Drawing.Point(1, 1); + this.marqueeLabelTop.Margin = new System.Windows.Forms.Padding(0); + this.marqueeLabelTop.Name = "marqueeLabelTop"; + this.marqueeLabelTop.OwnTimer = false; + this.marqueeLabelTop.PixelsPerSecond = 64; + this.marqueeLabelTop.Separator = "|"; + this.marqueeLabelTop.Size = new System.Drawing.Size(254, 30); + this.marqueeLabelTop.TabIndex = 2; + this.marqueeLabelTop.Text = "ABCDEFGHIJKLMNOPQRST-0123456789"; + this.marqueeLabelTop.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.marqueeLabelTop.UseCompatibleTextRendering = true; + // + // marqueeLabelBottom + // + this.marqueeLabelBottom.AutoEllipsis = true; + this.marqueeLabelBottom.Dock = System.Windows.Forms.DockStyle.Fill; + this.marqueeLabelBottom.Location = new System.Drawing.Point(1, 32); + this.marqueeLabelBottom.Margin = new System.Windows.Forms.Padding(0); + this.marqueeLabelBottom.Name = "marqueeLabelBottom"; + this.marqueeLabelBottom.OwnTimer = false; + this.marqueeLabelBottom.PixelsPerSecond = 64; + this.marqueeLabelBottom.Separator = "|"; + this.marqueeLabelBottom.Size = new System.Drawing.Size(254, 31); + this.marqueeLabelBottom.TabIndex = 3; + this.marqueeLabelBottom.Text = "abcdefghijklmnopqrst-0123456789"; + this.marqueeLabelBottom.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.marqueeLabelBottom.UseCompatibleTextRendering = true; + // // checkBoxShowBorders // this.checkBoxShowBorders.AutoSize = true; @@ -350,6 +383,25 @@ this.tabPageTests.Text = "Test"; this.tabPageTests.UseVisualStyleBackColor = true; // + // tabPageClients + // + this.tabPageClients.Controls.Add(this.treeViewClients); + this.tabPageClients.Location = new System.Drawing.Point(4, 22); + this.tabPageClients.Name = "tabPageClients"; + this.tabPageClients.Padding = new System.Windows.Forms.Padding(3); + this.tabPageClients.Size = new System.Drawing.Size(592, 369); + this.tabPageClients.TabIndex = 2; + this.tabPageClients.Text = "Clients"; + this.tabPageClients.UseVisualStyleBackColor = true; + // + // treeViewClients + // + this.treeViewClients.Location = new System.Drawing.Point(6, 6); + this.treeViewClients.Name = "treeViewClients"; + this.treeViewClients.Size = new System.Drawing.Size(439, 357); + this.treeViewClients.TabIndex = 0; + this.treeViewClients.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViewClients_AfterSelect); + // // timer // this.timer.Enabled = true; @@ -394,58 +446,6 @@ this.toolStripStatusLabelFps.Size = new System.Drawing.Size(26, 17); this.toolStripStatusLabelFps.Text = "FPS"; // - // tabPageClients - // - this.tabPageClients.Controls.Add(this.treeViewClients); - this.tabPageClients.Location = new System.Drawing.Point(4, 22); - this.tabPageClients.Name = "tabPageClients"; - this.tabPageClients.Padding = new System.Windows.Forms.Padding(3); - this.tabPageClients.Size = new System.Drawing.Size(592, 369); - this.tabPageClients.TabIndex = 2; - this.tabPageClients.Text = "Clients"; - this.tabPageClients.UseVisualStyleBackColor = true; - // - // treeViewClients - // - this.treeViewClients.Location = new System.Drawing.Point(6, 6); - this.treeViewClients.Name = "treeViewClients"; - this.treeViewClients.Size = new System.Drawing.Size(439, 357); - this.treeViewClients.TabIndex = 0; - this.treeViewClients.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViewClients_AfterSelect); - // - // marqueeLabelTop - // - this.marqueeLabelTop.AutoEllipsis = true; - this.marqueeLabelTop.BackColor = System.Drawing.Color.Transparent; - this.marqueeLabelTop.Dock = System.Windows.Forms.DockStyle.Fill; - this.marqueeLabelTop.Location = new System.Drawing.Point(1, 1); - this.marqueeLabelTop.Margin = new System.Windows.Forms.Padding(0); - this.marqueeLabelTop.Name = "marqueeLabelTop"; - this.marqueeLabelTop.OwnTimer = false; - this.marqueeLabelTop.PixelsPerSecond = 64; - this.marqueeLabelTop.Separator = "|"; - this.marqueeLabelTop.Size = new System.Drawing.Size(254, 9); - this.marqueeLabelTop.TabIndex = 2; - this.marqueeLabelTop.Text = "ABCDEFGHIJKLMNOPQRST-0123456789"; - this.marqueeLabelTop.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.marqueeLabelTop.UseCompatibleTextRendering = true; - // - // marqueeLabelBottom - // - this.marqueeLabelBottom.AutoEllipsis = true; - this.marqueeLabelBottom.Dock = System.Windows.Forms.DockStyle.Fill; - this.marqueeLabelBottom.Location = new System.Drawing.Point(1, 21); - this.marqueeLabelBottom.Margin = new System.Windows.Forms.Padding(0); - this.marqueeLabelBottom.Name = "marqueeLabelBottom"; - this.marqueeLabelBottom.OwnTimer = false; - this.marqueeLabelBottom.PixelsPerSecond = 64; - this.marqueeLabelBottom.Separator = null; - this.marqueeLabelBottom.Size = new System.Drawing.Size(254, 20); - this.marqueeLabelBottom.TabIndex = 3; - this.marqueeLabelBottom.Text = "abcdefghijklmnopqrst-0123456789"; - this.marqueeLabelBottom.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.marqueeLabelBottom.UseCompatibleTextRendering = true; - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -465,9 +465,9 @@ this.panelDisplay.ResumeLayout(false); this.tableLayoutPanel.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.trackBarBrightness)).EndInit(); + this.tabPageClients.ResumeLayout(false); this.statusStrip.ResumeLayout(false); this.statusStrip.PerformLayout(); - this.tabPageClients.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); diff -r 4c416d2878dd -r 1363bda20171 Server/MainForm.cs --- a/Server/MainForm.cs Fri Aug 15 13:26:38 2014 +0200 +++ b/Server/MainForm.cs Sat Aug 16 11:15:42 2014 +0200 @@ -20,6 +20,27 @@ namespace SharpDisplayManager { + /// + /// A UI thread copy of a client relevant data. + /// Keeping this copy in the UI thread helps us deal with threading issues. + /// + public class ClientData + { + public ClientData(string aSessionId, IDisplayServiceCallback aCallback) + { + SessionId = aSessionId; + Name = ""; + Texts = new List(); + Callback = aCallback; + } + + public string SessionId { get; set;} + public string Name { get; set;} + public List Texts { get; set;} + public IDisplayServiceCallback Callback { get; set;} + } + + public partial class MainForm : Form { DateTime LastTickTime; @@ -30,14 +51,14 @@ /// /// Our collection of clients /// - public Dictionary iClients; + public Dictionary iClients; public bool iClosing; public MainForm() { LastTickTime = DateTime.Now; iDisplay = new Display(); - iClients = new Dictionary(); + iClients = new Dictionary(); InitializeComponent(); UpdateStatus(); @@ -406,7 +427,7 @@ try { Trace.TraceInformation("BroadcastCloseEvent - " + client.Key); - client.Value.OnCloseOrder(/*eventData*/); + client.Value.Callback.OnCloseOrder(/*eventData*/); } catch (Exception ex) { @@ -454,6 +475,7 @@ } + //Delegates are used for our thread safe method public delegate void AddClientDelegate(string aSessionId, IDisplayServiceCallback aCallback); public delegate void RemoveClientDelegate(string aSessionId); public delegate void SetTextDelegate(int aLineIndex, string aText); @@ -468,7 +490,7 @@ /// public void AddClientThreadSafe(string aSessionId, IDisplayServiceCallback aCallback) { - if (this.treeViewClients.InvokeRequired) + if (this.InvokeRequired) { //Not in the proper thread, invoke ourselves AddClientDelegate d = new AddClientDelegate(AddClientThreadSafe); @@ -478,9 +500,10 @@ { //We are in the proper thread //Add this session to our collection of clients - Program.iMainForm.iClients.Add(aSessionId, aCallback); + ClientData newClient = new ClientData(aSessionId, aCallback); + Program.iMainForm.iClients.Add(aSessionId, newClient); //Add this session to our UI - Program.iMainForm.treeViewClients.Nodes.Add(aSessionId, aSessionId); + UpdateClientTreeViewNode(newClient); } } @@ -490,7 +513,7 @@ /// public void RemoveClientThreadSafe(string aSessionId) { - if (this.treeViewClients.InvokeRequired) + if (this.InvokeRequired) { //Not in the proper thread, invoke ourselves RemoveClientDelegate d = new RemoveClientDelegate(RemoveClientThreadSafe); @@ -499,7 +522,7 @@ else { //We are in the proper thread - //Remove this session from both client collection and UI tree view + //Remove this session from both client collection and UI tree view if (Program.iMainForm.iClients.Keys.Contains(aSessionId)) { Program.iMainForm.iClients.Remove(aSessionId); @@ -524,7 +547,7 @@ /// public void SetTextThreadSafe(int aLineIndex, string aText) { - if (this.treeViewClients.InvokeRequired) + if (this.InvokeRequired) { //Not in the proper thread, invoke ourselves SetTextDelegate d = new SetTextDelegate(SetTextThreadSafe); @@ -536,11 +559,11 @@ //Only support two lines for now if (aLineIndex == 0) { - Program.iMainForm.marqueeLabelTop.Text = aText; + marqueeLabelTop.Text = aText; } else if (aLineIndex == 1) { - Program.iMainForm.marqueeLabelBottom.Text = aText; + marqueeLabelBottom.Text = aText; } } } @@ -551,7 +574,7 @@ /// public void SetTextsThreadSafe(System.Collections.Generic.IList aTexts) { - if (this.treeViewClients.InvokeRequired) + if (this.InvokeRequired) { //Not in the proper thread, invoke ourselves SetTextsDelegate d = new SetTextsDelegate(SetTextsThreadSafe); @@ -565,11 +588,11 @@ { if (i == 0) { - Program.iMainForm.marqueeLabelTop.Text = aTexts[i]; + marqueeLabelTop.Text = aTexts[i]; } else if (i == 1) { - Program.iMainForm.marqueeLabelBottom.Text = aTexts[i]; + marqueeLabelBottom.Text = aTexts[i]; } } } @@ -592,17 +615,73 @@ else { //We are in the proper thread - //Remove this session from both client collection and UI tree view - if (Program.iMainForm.iClients.Keys.Contains(aSessionId)) + //Get our client + ClientData client = iClients[aSessionId]; + if (client != null) { - //Change our session node text - TreeNode node = Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]; - node.Text = aName; + //Set its name + client.Name = aName; + //Update our tree-view + UpdateClientTreeViewNode(client); + } + } + } + + /// + /// + /// + /// + private void UpdateClientTreeViewNode(ClientData aClient) + { + if (aClient == null) + { + return; + } + + TreeNode node = null; + //Check that our client node already exists + //Get our client root node using its key which is our session ID + TreeNode[] nodes = treeViewClients.Nodes.Find(aClient.SessionId, false); + if (nodes.Count()>0) + { + //We already have a node for that client + node = nodes[0]; + //Clear children as we are going to recreate them below + node.Nodes.Clear(); + } + else + { + //Client node does not exists create a new one + treeViewClients.Nodes.Add(aClient.SessionId, aClient.SessionId); + node = treeViewClients.Nodes.Find(aClient.SessionId, false)[0]; + } + + if (node != null) + { + //Change its name + if (aClient.Name != "") + { + //We have a name, us it as text for our root node + node.Text = aClient.Name; //Add a child with SessionId - node.Nodes.Add(new TreeNode(aSessionId)); - - //Program.iMainForm.iClients.Remove(aSessionId); - //Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]); + node.Nodes.Add(new TreeNode(aClient.SessionId)); + } + else + { + //No name, use session ID instead + node.Text = aClient.SessionId; + } + + if (aClient.Texts.Count > 0) + { + //Create root node for our texts + TreeNode textsRoot = new TreeNode("Text"); + node.Nodes.Add(textsRoot); + //For each text add a new entry + foreach (string text in aClient.Texts) + { + textsRoot.Nodes.Add(new TreeNode(text)); + } } } } diff -r 4c416d2878dd -r 1363bda20171 Server/MarqueeLabel.cs --- a/Server/MarqueeLabel.cs Fri Aug 15 13:26:38 2014 +0200 +++ b/Server/MarqueeLabel.cs Sat Aug 16 11:15:42 2014 +0200 @@ -80,6 +80,7 @@ //PixelsPerSecond = 32; LastTickTime = DateTime.Now; PixelsLeft = 0; + CurrentPosition = 0; iBrush = new SolidBrush(ForeColor); } @@ -203,7 +204,11 @@ private void HandleTextSizeChange() { + //Reset our timer whenever our text changes CurrentPosition = 0; + LastTickTime = DateTime.Now; + PixelsLeft = 0; + //For all string measurements and drawing issues refer to the following article: // http://stackoverflow.com/questions/1203087/why-is-graphics-measurestring-returning-a-higher-than-expected-number //Update text size according to text and font @@ -248,15 +253,18 @@ e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; if (NeedToScroll()) { + //Draw it all in a single call + e.Graphics.TranslateTransform(-(float)CurrentPosition, 0); + e.Graphics.DrawString(Text + Separator + Text, Font, iBrush, ClientRectangle, iStringFormat); //Draw the first one - e.Graphics.TranslateTransform(-(float)CurrentPosition, 0); - e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat); + //e.Graphics.TranslateTransform(-(float)CurrentPosition, 0); + //e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat); //Draw separator - e.Graphics.TranslateTransform(iTextSize.Width, 0); - e.Graphics.DrawString(Separator, Font, iBrush, ClientRectangle, iStringFormat); + //e.Graphics.TranslateTransform(iTextSize.Width, 0); + //e.Graphics.DrawString(Separator, Font, iBrush, ClientRectangle, iStringFormat); //Draw the last one - e.Graphics.TranslateTransform(iSeparatorSize.Width, 0); - e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat); + //e.Graphics.TranslateTransform(iSeparatorSize.Width, 0); + //e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat); } else {