Adding option to reverse screen. That's useful to avoid having to set our
hardware the correct way up.
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 [System.ComponentModel.DesignerCategory("Code")]
15 class MarqueeLabel : Label
17 private bool iOwnTimer;
18 private StringFormat iStringFormat;
19 private SolidBrush iBrush;
20 private SizeF iTextSize;
21 private SizeF iSeparatorSize;
23 [Category("Appearance")]
24 [Description("Separator in our scrolling loop.")]
26 [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
27 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
28 public string Separator { get; set; }
30 [Category("Behavior")]
31 [Description("How fast is our text scrolling, in pixels per second.")]
33 [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
34 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
35 public int PixelsPerSecond { get; set; }
37 [Category("Behavior")]
38 [Description("Use an internal or an external timer.")]
40 [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
41 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
56 Timer.Tick += new EventHandler(Timer_Tick);
69 private int CurrentPosition { get; set; }
70 private Timer Timer { get; set; }
71 private DateTime LastTickTime { get; set; }
72 private double PixelsLeft { get; set; }
73 //DateTime a = new DateTime(2010, 05, 12, 13, 15, 00);
74 //DateTime b = new DateTime(2010, 05, 12, 13, 45, 00);
75 //Console.WriteLine(b.Subtract(a).TotalMinutes);
79 UseCompatibleTextRendering = true;
80 //PixelsPerSecond = 32;
81 LastTickTime = DateTime.Now;
83 iBrush = new SolidBrush(ForeColor);
86 public void UpdateAnimation(DateTime aLastTickTime, DateTime aNewTickTime)
94 while (CurrentPosition > (iTextSize.Width + iSeparatorSize.Width))
96 CurrentPosition -= ((int)(iTextSize.Width + iSeparatorSize.Width));
99 PixelsLeft += aNewTickTime.Subtract(aLastTickTime).TotalSeconds * PixelsPerSecond;
101 //Keep track of our pixels left over
102 //PixelsLeft = offset - Math.Truncate(offset);
103 double offset = Math.Truncate(PixelsLeft);
104 PixelsLeft -= offset;
106 CurrentPosition += Convert.ToInt32(offset);
111 BackColor = Color.Red;
113 else if (offset==1.0)
115 if (BackColor != Color.White)
117 BackColor = Color.White;
124 //BackColor = Color.Green;
127 //Only redraw if something has changed
134 void Timer_Tick(object sender, EventArgs e)
136 DateTime NewTickTime = DateTime.Now;
138 UpdateAnimation(LastTickTime, NewTickTime);
140 LastTickTime = NewTickTime;
143 private StringFormat GetStringFormatFromContentAllignment(ContentAlignment ca)
145 StringFormat format = new StringFormat();
146 format = StringFormat.GenericTypographic;
149 case ContentAlignment.TopCenter:
150 format.Alignment = StringAlignment.Near;
151 format.LineAlignment = StringAlignment.Center;
153 case ContentAlignment.TopLeft:
154 format.Alignment = StringAlignment.Near;
155 format.LineAlignment = StringAlignment.Near;
157 case ContentAlignment.TopRight:
158 format.Alignment = StringAlignment.Near;
159 format.LineAlignment = StringAlignment.Far;
161 case ContentAlignment.MiddleCenter:
162 format.Alignment = StringAlignment.Center;
163 format.LineAlignment = StringAlignment.Center;
165 case ContentAlignment.MiddleLeft:
166 format.Alignment = StringAlignment.Center;
167 format.LineAlignment = StringAlignment.Near;
169 case ContentAlignment.MiddleRight:
170 format.Alignment = StringAlignment.Center;
171 format.LineAlignment = StringAlignment.Far;
173 case ContentAlignment.BottomCenter:
174 format.Alignment = StringAlignment.Far;
175 format.LineAlignment = StringAlignment.Center;
177 case ContentAlignment.BottomLeft:
178 format.Alignment = StringAlignment.Far;
179 format.LineAlignment = StringAlignment.Near;
181 case ContentAlignment.BottomRight:
182 format.Alignment = StringAlignment.Far;
183 format.LineAlignment = StringAlignment.Far;
187 format.FormatFlags |= StringFormatFlags.NoWrap;
188 format.FormatFlags |= StringFormatFlags.NoClip;
189 format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
190 format.Trimming = StringTrimming.None;
195 protected override void OnForeColorChanged(EventArgs e)
197 //Color has changed recreate our brush
198 iBrush = new SolidBrush(ForeColor);
200 base.OnForeColorChanged(e);
204 private void HandleTextSizeChange()
206 //For all string measurements and drawing issues refer to the following article:
207 // http://stackoverflow.com/questions/1203087/why-is-graphics-measurestring-returning-a-higher-than-expected-number
208 //Update text size according to text and font
209 Graphics g = this.CreateGraphics();
210 g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
211 iStringFormat = GetStringFormatFromContentAllignment(TextAlign);
212 iTextSize = g.MeasureString(Text, Font, Int32.MaxValue, iStringFormat);
213 iSeparatorSize = g.MeasureString(Separator, Font, Int32.MaxValue, iStringFormat);
217 //Always align left when scrolling
218 iStringFormat.Alignment = StringAlignment.Near;
222 protected override void OnTextChanged(EventArgs e)
224 HandleTextSizeChange();
226 base.OnTextChanged(e);
229 protected override void OnFontChanged(EventArgs e)
231 HandleTextSizeChange();
233 base.OnFontChanged(e);
236 protected override void OnTextAlignChanged(EventArgs e)
238 iStringFormat = GetStringFormatFromContentAllignment(TextAlign);
240 base.OnTextAlignChanged(e);
244 protected override void OnPaint(PaintEventArgs e)
246 //Disable anti-aliasing
247 e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
251 e.Graphics.TranslateTransform(-(float)CurrentPosition, 0);
252 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
254 e.Graphics.TranslateTransform(iTextSize.Width, 0);
255 e.Graphics.DrawString(Separator, Font, iBrush, ClientRectangle, iStringFormat);
257 e.Graphics.TranslateTransform(iSeparatorSize.Width, 0);
258 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
262 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
267 //DrawText is not working without anti-aliasing. See: stackoverflow.com/questions/8283631/graphics-drawstring-vs-textrenderer-drawtextwhich-can-deliver-better-quality
268 //TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, ForeColor, BackColor, iTextFormatFlags);
273 public bool NeedToScroll()
275 //if (Width < e.Graphics.MeasureString(Text, Font).Width)
276 if (Width < iTextSize.Width)
283 protected override void Dispose(bool disposing)