Adding persistent settings and marquee separator.
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Diagnostics;
7 using System.Threading.Tasks;
9 using System.Windows.Forms;
12 namespace SharpDisplayManager
14 class MarqueeLabel : Label
16 private bool iOwnTimer;
17 private StringFormat iStringFormat;
18 private SolidBrush iBrush;
19 private SizeF iTextSize;
20 private SizeF iSeparatorSize;
22 [Category("Appearance")]
23 [Description("Separator in our scrolling loop.")]
25 [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
26 public string Separator { get; set; }
28 [Category("Behavior")]
29 [Description("How fast is our text scrolling, in pixels per second.")]
31 [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
32 public int PixelsPerSecond { get; set; }
34 [Category("Behavior")]
35 [Description("Use an internal or an external timer.")]
37 [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
52 Timer.Tick += new EventHandler(Timer_Tick);
65 private int CurrentPosition { get; set; }
66 private Timer Timer { get; set; }
67 private DateTime LastTickTime { get; set; }
68 private double PixelsLeft { get; set; }
69 //DateTime a = new DateTime(2010, 05, 12, 13, 15, 00);
70 //DateTime b = new DateTime(2010, 05, 12, 13, 45, 00);
71 //Console.WriteLine(b.Subtract(a).TotalMinutes);
75 UseCompatibleTextRendering = true;
76 //PixelsPerSecond = 32;
77 LastTickTime = DateTime.Now;
79 iBrush = new SolidBrush(ForeColor);
82 public void UpdateAnimation(DateTime aLastTickTime, DateTime aNewTickTime)
90 while (CurrentPosition > (iTextSize.Width + iSeparatorSize.Width))
92 CurrentPosition -= ((int)(iTextSize.Width + iSeparatorSize.Width));
95 PixelsLeft += aNewTickTime.Subtract(aLastTickTime).TotalSeconds * PixelsPerSecond;
97 //Keep track of our pixels left over
98 //PixelsLeft = offset - Math.Truncate(offset);
99 double offset = Math.Truncate(PixelsLeft);
100 PixelsLeft -= offset;
102 CurrentPosition += Convert.ToInt32(offset);
107 BackColor = Color.Red;
109 else if (offset==1.0)
111 if (BackColor != Color.White)
113 BackColor = Color.White;
120 //BackColor = Color.Green;
123 //Only redraw if something has changed
130 void Timer_Tick(object sender, EventArgs e)
132 DateTime NewTickTime = DateTime.Now;
134 UpdateAnimation(LastTickTime, NewTickTime);
136 LastTickTime = NewTickTime;
139 private StringFormat GetStringFormatFromContentAllignment(ContentAlignment ca)
141 StringFormat format = new StringFormat();
144 case ContentAlignment.TopCenter:
145 format.Alignment = StringAlignment.Near;
146 format.LineAlignment = StringAlignment.Center;
148 case ContentAlignment.TopLeft:
149 format.Alignment = StringAlignment.Near;
150 format.LineAlignment = StringAlignment.Near;
152 case ContentAlignment.TopRight:
153 format.Alignment = StringAlignment.Near;
154 format.LineAlignment = StringAlignment.Far;
156 case ContentAlignment.MiddleCenter:
157 format.Alignment = StringAlignment.Center;
158 format.LineAlignment = StringAlignment.Center;
160 case ContentAlignment.MiddleLeft:
161 format.Alignment = StringAlignment.Center;
162 format.LineAlignment = StringAlignment.Near;
164 case ContentAlignment.MiddleRight:
165 format.Alignment = StringAlignment.Center;
166 format.LineAlignment = StringAlignment.Far;
168 case ContentAlignment.BottomCenter:
169 format.Alignment = StringAlignment.Far;
170 format.LineAlignment = StringAlignment.Center;
172 case ContentAlignment.BottomLeft:
173 format.Alignment = StringAlignment.Far;
174 format.LineAlignment = StringAlignment.Near;
176 case ContentAlignment.BottomRight:
177 format.Alignment = StringAlignment.Far;
178 format.LineAlignment = StringAlignment.Far;
182 format.FormatFlags |= StringFormatFlags.NoWrap;
183 format.FormatFlags |= StringFormatFlags.NoClip;
184 format.Trimming = StringTrimming.None;
189 protected override void OnForeColorChanged(EventArgs e)
191 //Color has changed recreate our brush
192 iBrush = new SolidBrush(ForeColor);
194 base.OnForeColorChanged(e);
198 private void HandleTextSizeChange()
200 //Update text size according to text and font
201 Graphics g = this.CreateGraphics();
202 g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
203 iTextSize = g.MeasureString(Text, Font);
204 iSeparatorSize = g.MeasureString(Separator, Font);
205 iStringFormat = GetStringFormatFromContentAllignment(TextAlign);
209 //Always align left when scrolling
210 iStringFormat.Alignment = StringAlignment.Near;
214 protected override void OnTextChanged(EventArgs e)
216 HandleTextSizeChange();
218 base.OnTextChanged(e);
221 protected override void OnFontChanged(EventArgs e)
223 HandleTextSizeChange();
225 base.OnFontChanged(e);
228 protected override void OnTextAlignChanged(EventArgs e)
230 iStringFormat = GetStringFormatFromContentAllignment(TextAlign);
232 base.OnTextAlignChanged(e);
236 protected override void OnPaint(PaintEventArgs e)
238 //Disable anti-aliasing
239 e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
243 e.Graphics.TranslateTransform(-(float)CurrentPosition, 0);
244 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
246 e.Graphics.TranslateTransform(iTextSize.Width, 0);
247 e.Graphics.DrawString(Separator, Font, iBrush, ClientRectangle, iStringFormat);
249 e.Graphics.TranslateTransform(iSeparatorSize.Width, 0);
250 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
254 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
259 //DrawText is not working without anti-aliasing. See: stackoverflow.com/questions/8283631/graphics-drawstring-vs-textrenderer-drawtextwhich-can-deliver-better-quality
260 //TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, ForeColor, BackColor, iTextFormatFlags);
265 public bool NeedToScroll()
267 //if (Width < e.Graphics.MeasureString(Text, Font).Width)
268 if (Width < iTextSize.Width)
275 protected override void Dispose(bool disposing)