1.1 --- a/MarqueeLabel.cs Tue Aug 12 20:37:57 2014 +0200
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,293 +0,0 @@
1.4 -using System;
1.5 -using System.Collections.Generic;
1.6 -using System.ComponentModel;
1.7 -using System.Diagnostics;
1.8 -using System.Linq;
1.9 -using System.Text;
1.10 -using System.Threading.Tasks;
1.11 -//using System.Timers;
1.12 -using System.Windows.Forms;
1.13 -using System.Drawing;
1.14 -
1.15 -namespace SharpDisplayManager
1.16 -{
1.17 - [System.ComponentModel.DesignerCategory("Code")]
1.18 - public class MarqueeLabel : Label
1.19 - {
1.20 - private bool iOwnTimer;
1.21 - private StringFormat iStringFormat;
1.22 - private SolidBrush iBrush;
1.23 - private SizeF iTextSize;
1.24 - private SizeF iSeparatorSize;
1.25 -
1.26 - [Category("Appearance")]
1.27 - [Description("Separator in our scrolling loop.")]
1.28 - [DefaultValue(" | ")]
1.29 - [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
1.30 - [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
1.31 - public string Separator { get; set; }
1.32 -
1.33 - [Category("Behavior")]
1.34 - [Description("How fast is our text scrolling, in pixels per second.")]
1.35 - [DefaultValue(32)]
1.36 - [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
1.37 - [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
1.38 - public int PixelsPerSecond { get; set; }
1.39 -
1.40 - [Category("Behavior")]
1.41 - [Description("Use an internal or an external timer.")]
1.42 - [DefaultValue(true)]
1.43 - [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
1.44 - [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
1.45 - public bool OwnTimer
1.46 - {
1.47 - get
1.48 - {
1.49 - return iOwnTimer;
1.50 - }
1.51 - set
1.52 - {
1.53 - iOwnTimer = value;
1.54 -
1.55 - if (iOwnTimer)
1.56 - {
1.57 - Timer = new Timer();
1.58 - Timer.Interval = 10;
1.59 - Timer.Tick += new EventHandler(Timer_Tick);
1.60 - Timer.Start();
1.61 - }
1.62 - else
1.63 - {
1.64 - if (Timer != null)
1.65 - Timer.Dispose();
1.66 - Timer = null;
1.67 - }
1.68 -
1.69 - }
1.70 - }
1.71 -
1.72 - private int CurrentPosition { get; set; }
1.73 - private Timer Timer { get; set; }
1.74 - private DateTime LastTickTime { get; set; }
1.75 - private double PixelsLeft { get; set; }
1.76 - //DateTime a = new DateTime(2010, 05, 12, 13, 15, 00);
1.77 - //DateTime b = new DateTime(2010, 05, 12, 13, 45, 00);
1.78 - //Console.WriteLine(b.Subtract(a).TotalMinutes);
1.79 -
1.80 - public MarqueeLabel()
1.81 - {
1.82 - UseCompatibleTextRendering = true;
1.83 - //PixelsPerSecond = 32;
1.84 - LastTickTime = DateTime.Now;
1.85 - PixelsLeft = 0;
1.86 - iBrush = new SolidBrush(ForeColor);
1.87 - }
1.88 -
1.89 - public void UpdateAnimation(DateTime aLastTickTime, DateTime aNewTickTime)
1.90 - {
1.91 - if (!NeedToScroll())
1.92 - {
1.93 - CurrentPosition = 0;
1.94 - return;
1.95 - }
1.96 -
1.97 - while (CurrentPosition > (iTextSize.Width + iSeparatorSize.Width))
1.98 - {
1.99 - CurrentPosition -= ((int)(iTextSize.Width + iSeparatorSize.Width));
1.100 - }
1.101 -
1.102 - PixelsLeft += aNewTickTime.Subtract(aLastTickTime).TotalSeconds * PixelsPerSecond;
1.103 -
1.104 - //Keep track of our pixels left over
1.105 - //PixelsLeft = offset - Math.Truncate(offset);
1.106 - double offset = Math.Truncate(PixelsLeft);
1.107 - PixelsLeft -= offset;
1.108 -
1.109 - CurrentPosition += Convert.ToInt32(offset);
1.110 -
1.111 - /*
1.112 - if (offset > 1.0)
1.113 - {
1.114 - BackColor = Color.Red;
1.115 - }
1.116 - else if (offset==1.0)
1.117 - {
1.118 - if (BackColor != Color.White)
1.119 - {
1.120 - BackColor = Color.White;
1.121 - }
1.122 -
1.123 - }
1.124 - else
1.125 - {
1.126 - //Too slow
1.127 - //BackColor = Color.Green;
1.128 - }*/
1.129 -
1.130 - //Only redraw if something has changed
1.131 - if (offset != 0)
1.132 - {
1.133 - Invalidate();
1.134 - }
1.135 - }
1.136 -
1.137 - void Timer_Tick(object sender, EventArgs e)
1.138 - {
1.139 - DateTime NewTickTime = DateTime.Now;
1.140 - //
1.141 - UpdateAnimation(LastTickTime, NewTickTime);
1.142 - //
1.143 - LastTickTime = NewTickTime;
1.144 - }
1.145 -
1.146 - private StringFormat GetStringFormatFromContentAllignment(ContentAlignment ca)
1.147 - {
1.148 - StringFormat format = new StringFormat();
1.149 - format = StringFormat.GenericTypographic;
1.150 - switch (ca)
1.151 - {
1.152 - case ContentAlignment.TopCenter:
1.153 - format.Alignment = StringAlignment.Near;
1.154 - format.LineAlignment = StringAlignment.Center;
1.155 - break;
1.156 - case ContentAlignment.TopLeft:
1.157 - format.Alignment = StringAlignment.Near;
1.158 - format.LineAlignment = StringAlignment.Near;
1.159 - break;
1.160 - case ContentAlignment.TopRight:
1.161 - format.Alignment = StringAlignment.Near;
1.162 - format.LineAlignment = StringAlignment.Far;
1.163 - break;
1.164 - case ContentAlignment.MiddleCenter:
1.165 - format.Alignment = StringAlignment.Center;
1.166 - format.LineAlignment = StringAlignment.Center;
1.167 - break;
1.168 - case ContentAlignment.MiddleLeft:
1.169 - format.Alignment = StringAlignment.Center;
1.170 - format.LineAlignment = StringAlignment.Near;
1.171 - break;
1.172 - case ContentAlignment.MiddleRight:
1.173 - format.Alignment = StringAlignment.Center;
1.174 - format.LineAlignment = StringAlignment.Far;
1.175 - break;
1.176 - case ContentAlignment.BottomCenter:
1.177 - format.Alignment = StringAlignment.Far;
1.178 - format.LineAlignment = StringAlignment.Center;
1.179 - break;
1.180 - case ContentAlignment.BottomLeft:
1.181 - format.Alignment = StringAlignment.Far;
1.182 - format.LineAlignment = StringAlignment.Near;
1.183 - break;
1.184 - case ContentAlignment.BottomRight:
1.185 - format.Alignment = StringAlignment.Far;
1.186 - format.LineAlignment = StringAlignment.Far;
1.187 - break;
1.188 - }
1.189 -
1.190 - format.FormatFlags |= StringFormatFlags.NoWrap;
1.191 - format.FormatFlags |= StringFormatFlags.NoClip;
1.192 - format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
1.193 - format.Trimming = StringTrimming.None;
1.194 -
1.195 - return format;
1.196 - }
1.197 -
1.198 - protected override void OnForeColorChanged(EventArgs e)
1.199 - {
1.200 - //Color has changed recreate our brush
1.201 - iBrush = new SolidBrush(ForeColor);
1.202 -
1.203 - base.OnForeColorChanged(e);
1.204 - }
1.205 -
1.206 -
1.207 - private void HandleTextSizeChange()
1.208 - {
1.209 - //For all string measurements and drawing issues refer to the following article:
1.210 - // http://stackoverflow.com/questions/1203087/why-is-graphics-measurestring-returning-a-higher-than-expected-number
1.211 - //Update text size according to text and font
1.212 - Graphics g = this.CreateGraphics();
1.213 - g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
1.214 - iStringFormat = GetStringFormatFromContentAllignment(TextAlign);
1.215 - iTextSize = g.MeasureString(Text, Font, Int32.MaxValue, iStringFormat);
1.216 - iSeparatorSize = g.MeasureString(Separator, Font, Int32.MaxValue, iStringFormat);
1.217 -
1.218 - if (NeedToScroll())
1.219 - {
1.220 - //Always align left when scrolling
1.221 - iStringFormat.Alignment = StringAlignment.Near;
1.222 - }
1.223 - }
1.224 -
1.225 - protected override void OnTextChanged(EventArgs e)
1.226 - {
1.227 - HandleTextSizeChange();
1.228 -
1.229 - base.OnTextChanged(e);
1.230 - }
1.231 -
1.232 - protected override void OnFontChanged(EventArgs e)
1.233 - {
1.234 - HandleTextSizeChange();
1.235 -
1.236 - base.OnFontChanged(e);
1.237 - }
1.238 -
1.239 - protected override void OnTextAlignChanged(EventArgs e)
1.240 - {
1.241 - iStringFormat = GetStringFormatFromContentAllignment(TextAlign);
1.242 -
1.243 - base.OnTextAlignChanged(e);
1.244 -
1.245 - }
1.246 -
1.247 - protected override void OnPaint(PaintEventArgs e)
1.248 - {
1.249 - //Disable anti-aliasing
1.250 - e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
1.251 - if (NeedToScroll())
1.252 - {
1.253 - //Draw the first one
1.254 - e.Graphics.TranslateTransform(-(float)CurrentPosition, 0);
1.255 - e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
1.256 - //Draw separator
1.257 - e.Graphics.TranslateTransform(iTextSize.Width, 0);
1.258 - e.Graphics.DrawString(Separator, Font, iBrush, ClientRectangle, iStringFormat);
1.259 - //Draw the last one
1.260 - e.Graphics.TranslateTransform(iSeparatorSize.Width, 0);
1.261 - e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
1.262 - }
1.263 - else
1.264 - {
1.265 - e.Graphics.DrawString(Text, Font, iBrush, ClientRectangle, iStringFormat);
1.266 - }
1.267 -
1.268 -
1.269 -
1.270 - //DrawText is not working without anti-aliasing. See: stackoverflow.com/questions/8283631/graphics-drawstring-vs-textrenderer-drawtextwhich-can-deliver-better-quality
1.271 - //TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, ForeColor, BackColor, iTextFormatFlags);
1.272 -
1.273 - //base.OnPaint(e);
1.274 - }
1.275 -
1.276 - public bool NeedToScroll()
1.277 - {
1.278 - //if (Width < e.Graphics.MeasureString(Text, Font).Width)
1.279 - if (Width < iTextSize.Width)
1.280 - {
1.281 - return true;
1.282 - }
1.283 - return false;
1.284 - }
1.285 -
1.286 - protected override void Dispose(bool disposing)
1.287 - {
1.288 - if (disposing)
1.289 - {
1.290 - if (Timer != null)
1.291 - Timer.Dispose();
1.292 - }
1.293 - Timer = null;
1.294 - }
1.295 - }
1.296 -}