Marquee now implementing scroll loop properly.
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;
21 [Category("Behavior")]
22 [Description("How fast is our text scrolling, in pixels per second.")]
24 [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
25 public int PixelsPerSecond { get; set; }
27 [Category("Behavior")]
28 [Description("Use an internal or an external timer.")]
30 [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
45 Timer.Tick += new EventHandler(Timer_Tick);
58 private int CurrentPosition { get; set; }
59 private Timer Timer { get; set; }
60 private DateTime LastTickTime { get; set; }
61 private double PixelsLeft { get; set; }
62 //DateTime a = new DateTime(2010, 05, 12, 13, 15, 00);
63 //DateTime b = new DateTime(2010, 05, 12, 13, 45, 00);
64 //Console.WriteLine(b.Subtract(a).TotalMinutes);
68 UseCompatibleTextRendering = true;
69 //PixelsPerSecond = 32;
70 LastTickTime = DateTime.Now;
72 iBrush = new SolidBrush(ForeColor);
75 public void UpdateAnimation(DateTime aLastTickTime, DateTime aNewTickTime)
83 while (CurrentPosition > (iTextSize.Width))
85 CurrentPosition -= ((int)iTextSize.Width);
88 PixelsLeft += aNewTickTime.Subtract(aLastTickTime).TotalSeconds * PixelsPerSecond;
90 //Keep track of our pixels left over
91 //PixelsLeft = offset - Math.Truncate(offset);
92 double offset = Math.Truncate(PixelsLeft);
95 CurrentPosition += Convert.ToInt32(offset);
100 BackColor = Color.Red;
102 else if (offset==1.0)
104 if (BackColor != Color.White)
106 BackColor = Color.White;
113 //BackColor = Color.Green;
116 //Only redraw if something has changed
123 void Timer_Tick(object sender, EventArgs e)
125 DateTime NewTickTime = DateTime.Now;
127 UpdateAnimation(LastTickTime, NewTickTime);
129 LastTickTime = NewTickTime;
132 private StringFormat GetStringFormatFromContentAllignment(ContentAlignment ca)
134 StringFormat format = new StringFormat();
137 case ContentAlignment.TopCenter:
138 format.Alignment = StringAlignment.Near;
139 format.LineAlignment = StringAlignment.Center;
141 case ContentAlignment.TopLeft:
142 format.Alignment = StringAlignment.Near;
143 format.LineAlignment = StringAlignment.Near;
145 case ContentAlignment.TopRight:
146 format.Alignment = StringAlignment.Near;
147 format.LineAlignment = StringAlignment.Far;
149 case ContentAlignment.MiddleCenter:
150 format.Alignment = StringAlignment.Center;
151 format.LineAlignment = StringAlignment.Center;
153 case ContentAlignment.MiddleLeft:
154 format.Alignment = StringAlignment.Center;
155 format.LineAlignment = StringAlignment.Near;
157 case ContentAlignment.MiddleRight:
158 format.Alignment = StringAlignment.Center;
159 format.LineAlignment = StringAlignment.Far;
161 case ContentAlignment.BottomCenter:
162 format.Alignment = StringAlignment.Far;
163 format.LineAlignment = StringAlignment.Center;
165 case ContentAlignment.BottomLeft:
166 format.Alignment = StringAlignment.Far;
167 format.LineAlignment = StringAlignment.Near;
169 case ContentAlignment.BottomRight:
170 format.Alignment = StringAlignment.Far;
171 format.LineAlignment = StringAlignment.Far;
175 format.FormatFlags |= StringFormatFlags.NoWrap;
176 format.FormatFlags |= StringFormatFlags.NoClip;
177 format.Trimming = StringTrimming.None;
182 protected override void OnForeColorChanged(EventArgs e)
184 //Color has changed recreate our brush
185 iBrush = new SolidBrush(ForeColor);
187 base.OnForeColorChanged(e);
191 private void HandleTextSizeChange()
193 //Update text size according to text and font
194 Graphics g = this.CreateGraphics();
195 g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
196 iTextSize = g.MeasureString(Text, Font);
197 iStringFormat = GetStringFormatFromContentAllignment(TextAlign);
201 //Always align left when scrolling
202 iStringFormat.Alignment = StringAlignment.Near;
206 protected override void OnTextChanged(EventArgs e)
208 HandleTextSizeChange();
210 base.OnTextChanged(e);
213 protected override void OnFontChanged(EventArgs e)
215 HandleTextSizeChange();
217 base.OnFontChanged(e);
220 protected override void OnTextAlignChanged(EventArgs e)
222 iStringFormat = GetStringFormatFromContentAllignment(TextAlign);
224 base.OnTextAlignChanged(e);
228 protected override void OnPaint(PaintEventArgs e)
230 //Disable anti-aliasing
231 e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
235 e.Graphics.TranslateTransform(-(float)CurrentPosition, 0);
236 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
238 e.Graphics.TranslateTransform(iTextSize.Width, 0);
239 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
243 e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
248 //DrawText is not working without anti-aliasing. See: stackoverflow.com/questions/8283631/graphics-drawstring-vs-textrenderer-drawtextwhich-can-deliver-better-quality
249 //TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, ForeColor, BackColor, iTextFormatFlags);
254 public bool NeedToScroll()
256 //if (Width < e.Graphics.MeasureString(Text, Font).Width)
257 if (Width < iTextSize.Width)
264 protected override void Dispose(bool disposing)