# HG changeset patch # User sl # Date 1408307430 -7200 # Node ID 59bfa4ebcbbbad9393af9a6413783f8d7a7ea2e1 # Parent 1363bda20171c7df580692bcd648b8ca9fb2cb1b Adding text field support to our tree view. Trying to fix our messy text alignment issue causing loop problems. diff -r 1363bda20171 -r 59bfa4ebcbbb Server/MainForm.Designer.cs --- a/Server/MainForm.Designer.cs Sat Aug 16 11:15:42 2014 +0200 +++ b/Server/MainForm.Designer.cs Sun Aug 17 22:30:30 2014 +0200 @@ -396,6 +396,9 @@ // // treeViewClients // + this.treeViewClients.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.treeViewClients.Location = new System.Drawing.Point(6, 6); this.treeViewClients.Name = "treeViewClients"; this.treeViewClients.Size = new System.Drawing.Size(439, 357); diff -r 1363bda20171 -r 59bfa4ebcbbb Server/MainForm.cs --- a/Server/MainForm.cs Sat Aug 16 11:15:42 2014 +0200 +++ b/Server/MainForm.cs Sun Aug 17 22:30:30 2014 +0200 @@ -20,27 +20,6 @@ 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; @@ -478,8 +457,8 @@ //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); - public delegate void SetTextsDelegate(System.Collections.Generic.IList aTexts); + public delegate void SetTextDelegate(string SessionId, int aLineIndex, string aText); + public delegate void SetTextsDelegate(string SessionId, System.Collections.Generic.IList aTexts); public delegate void SetClientNameDelegate(string aSessionId, string aName); @@ -545,25 +524,39 @@ /// /// /// - public void SetTextThreadSafe(int aLineIndex, string aText) + public void SetTextThreadSafe(string aSessionId, int aLineIndex, string aText) { if (this.InvokeRequired) { //Not in the proper thread, invoke ourselves SetTextDelegate d = new SetTextDelegate(SetTextThreadSafe); - this.Invoke(d, new object[] { aLineIndex, aText }); + this.Invoke(d, new object[] { aSessionId, aLineIndex, aText }); } else { - //We are in the proper thread - //Only support two lines for now - if (aLineIndex == 0) + ClientData client = iClients[aSessionId]; + if (client != null) { - marqueeLabelTop.Text = aText; - } - else if (aLineIndex == 1) - { - marqueeLabelBottom.Text = aText; + //Make sure all our texts are in place + while (client.Texts.Count < (aLineIndex + 1)) + { + client.Texts.Add(""); + } + client.Texts[aLineIndex] = aText; + + //We are in the proper thread + //Only support two lines for now + if (aLineIndex == 0) + { + marqueeLabelTop.Text = aText; + } + else if (aLineIndex == 1) + { + marqueeLabelBottom.Text = aText; + } + + + UpdateClientTreeViewNode(client); } } } @@ -572,28 +565,49 @@ /// /// /// - public void SetTextsThreadSafe(System.Collections.Generic.IList aTexts) + public void SetTextsThreadSafe(string aSessionId, System.Collections.Generic.IList aTexts) { if (this.InvokeRequired) { //Not in the proper thread, invoke ourselves SetTextsDelegate d = new SetTextsDelegate(SetTextsThreadSafe); - this.Invoke(d, new object[] { aTexts }); + this.Invoke(d, new object[] { aSessionId, aTexts }); } else { - //We are in the proper thread - //Only support two lines for now - for (int i = 0; i < aTexts.Count; i++) + ClientData client = iClients[aSessionId]; + if (client != null) { - if (i == 0) + //Populate our client with the given texts + int j = 0; + foreach (string text in aTexts) { - marqueeLabelTop.Text = aTexts[i]; + if (client.Texts.Count < (j + 1)) + { + client.Texts.Add(text); + } + else + { + client.Texts[j]=text; + } + j++; } - else if (i == 1) + //We are in the proper thread + //Only support two lines for now + for (int i = 0; i < aTexts.Count; i++) { - marqueeLabelBottom.Text = aTexts[i]; + if (i == 0) + { + marqueeLabelTop.Text = aTexts[i]; + } + else if (i == 1) + { + marqueeLabelBottom.Text = aTexts[i]; + } } + + + UpdateClientTreeViewNode(client); } } } @@ -683,8 +697,30 @@ textsRoot.Nodes.Add(new TreeNode(text)); } } + + node.ExpandAll(); } } } + + /// + /// 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; } + } } diff -r 1363bda20171 -r 59bfa4ebcbbb Server/MarqueeLabel.cs --- a/Server/MarqueeLabel.cs Sat Aug 16 11:15:42 2014 +0200 +++ b/Server/MarqueeLabel.cs Sun Aug 17 22:30:30 2014 +0200 @@ -19,6 +19,8 @@ private SolidBrush iBrush; private SizeF iTextSize; private SizeF iSeparatorSize; + private SizeF iScrollSize; + //private ContentAlignment iRequestedContentAlignment; [Category("Appearance")] [Description("Separator in our scrolling loop.")] @@ -82,6 +84,7 @@ PixelsLeft = 0; CurrentPosition = 0; iBrush = new SolidBrush(ForeColor); + //iRequestedContentAlignment = TextAlign; } public void UpdateAnimation(DateTime aLastTickTime, DateTime aNewTickTime) @@ -92,10 +95,18 @@ return; } + /* while (CurrentPosition > (iTextSize.Width + iSeparatorSize.Width)) { CurrentPosition -= ((int)(iTextSize.Width + iSeparatorSize.Width)); } + */ + + while (CurrentPosition > iScrollSize.Width) + { + CurrentPosition -= (int)iScrollSize.Width; + } + PixelsLeft += aNewTickTime.Subtract(aLastTickTime).TotalSeconds * PixelsPerSecond; @@ -148,36 +159,36 @@ switch (ca) { case ContentAlignment.TopCenter: - format.Alignment = StringAlignment.Near; - format.LineAlignment = StringAlignment.Center; + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Near; break; case ContentAlignment.TopLeft: format.Alignment = StringAlignment.Near; format.LineAlignment = StringAlignment.Near; break; case ContentAlignment.TopRight: - format.Alignment = StringAlignment.Near; - format.LineAlignment = StringAlignment.Far; + format.Alignment = StringAlignment.Far; + format.LineAlignment = StringAlignment.Near; break; case ContentAlignment.MiddleCenter: format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; break; case ContentAlignment.MiddleLeft: - format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Near; + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; break; case ContentAlignment.MiddleRight: + format.Alignment = StringAlignment.Far; + format.LineAlignment = StringAlignment.Center; + break; + case ContentAlignment.BottomCenter: format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Far; break; - case ContentAlignment.BottomCenter: - format.Alignment = StringAlignment.Far; - format.LineAlignment = StringAlignment.Center; - break; case ContentAlignment.BottomLeft: - format.Alignment = StringAlignment.Far; - format.LineAlignment = StringAlignment.Near; + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Far; break; case ContentAlignment.BottomRight: format.Alignment = StringAlignment.Far; @@ -208,6 +219,8 @@ CurrentPosition = 0; LastTickTime = DateTime.Now; PixelsLeft = 0; + //Reset text align + //TextAlign = iRequestedContentAlignment; //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 @@ -217,11 +230,23 @@ iStringFormat = GetStringFormatFromContentAllignment(TextAlign); iTextSize = g.MeasureString(Text, Font, Int32.MaxValue, iStringFormat); iSeparatorSize = g.MeasureString(Separator, Font, Int32.MaxValue, iStringFormat); + //Scroll width is the width of our text and our separator without taking kerning into account since + //both text and separator are drawn independently from each other. + iScrollSize.Width = iSeparatorSize.Width + iTextSize.Width; + iScrollSize.Height = Math.Max(iSeparatorSize.Height, iTextSize.Height); //Not relevant for now + //We don't want scroll with to take kerning into account so we don't use the following + //iScrollSize = g.MeasureString(Text + Separator, Font, Int32.MaxValue, iStringFormat); if (NeedToScroll()) { //Always align left when scrolling - iStringFormat.Alignment = StringAlignment.Near; + //Somehow draw string still takes into our control alignment so we need to set it too + //ContentAlignment original = TextAlign; + TextAlign = ContentAlignment.MiddleLeft; + //Make sure our original text alignment remain the same even though we override it when scrolling + //iRequestedContentAlignment = original; + //iStringFormat will get updated in OnTextAlignChanged + //iStringFormat.Alignment = StringAlignment.Near; } } @@ -242,7 +267,7 @@ protected override void OnTextAlignChanged(EventArgs e) { iStringFormat = GetStringFormatFromContentAllignment(TextAlign); - + //iRequestedContentAlignment = TextAlign; base.OnTextAlignChanged(e); } @@ -253,18 +278,20 @@ e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; if (NeedToScroll()) { - //Draw it all in a single call + //Draw it all in a single call would take kerning into account + //e.Graphics.TranslateTransform(-(float)CurrentPosition, 0); + //e.Graphics.DrawString(Text + Separator + Text, Font, iBrush, ClientRectangle, iStringFormat); + + //Doing separate draw operation allows us not to take kerning into account between separator and string + //Draw the first one 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.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 { diff -r 1363bda20171 -r 59bfa4ebcbbb Server/Servers.cs --- a/Server/Servers.cs Sat Aug 16 11:15:42 2014 +0200 +++ b/Server/Servers.cs Sun Aug 17 22:30:30 2014 +0200 @@ -42,13 +42,13 @@ //From IDisplayService public void SetTexts(System.Collections.Generic.IList aTexts) { - Program.iMainForm.SetTextsThreadSafe(aTexts); + Program.iMainForm.SetTextsThreadSafe(SessionId, aTexts); } // public void SetText(int aLineIndex, string aText) { - Program.iMainForm.SetTextThreadSafe(aLineIndex, aText); + Program.iMainForm.SetTextThreadSafe(SessionId, aLineIndex, aText); } //