ProjetThe/ProjetTheAlone/ViewModel/TextDefilant.cs

101 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace ProjetTheAlone.ViewModel
{
public class TextDefilant : BasePropriete
{
public event TickHandler Tick;
public EventArgs e = null;
public delegate void TickHandler(object o, EventArgs e);
public Timer aTimer;
public TextBlock textContainer;
char[] textAfficherBuffer;
string textAfficher;
public string TextAfficher { set { fillBuffer(value); textAfficher = value; } get { return new string(textAfficherBuffer); } }
public TextDefilant(TextBlock tb, string text, int timeMs)
{
this.textContainer = tb;
TextAfficher = text;
SetTimer(timeMs);
aTimer.Enabled = true;
}
private void SetTimer(int timeMs)
{
// Create a timer with a two second interval.
aTimer = new System.Timers.Timer(timeMs);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
}
private void OnTimedEvent(Object source, ElapsedEventArgs e)
{
textAfficherBuffer = RotateChar(textAfficherBuffer);
Tick?.Invoke(this, null);
OnPropertyChanged("TextAfficher");
}
private void fillBuffer(string text)
{
char[] charToTrim = { '\r', '\n' };
text = text.Trim(charToTrim);
double WTB = textContainer.ActualWidth; //With of textBlock container
double WT = MeasureString(text).Width; //With of Text
double WS = MeasureString(" ").Width; //With of whiteSpace
int nbSp = (int)Math.Ceiling((WTB-WT) / WS); //number of space need to fill textBlock
char[] spText = new string(' ', nbSp).ToCharArray();
this.textAfficherBuffer = new char[nbSp + text.ToCharArray().Length];
Array.Copy(text.ToCharArray(), 0, this.textAfficherBuffer, 0, text.Length);
Array.Copy(spText, 0, this.textAfficherBuffer, text.Length, spText.Length);
}
private char[] RotateChar(char[] txt)
{
char[] oldTxt = txt;
char[] newTxt = new char[oldTxt.Length];
char fc = txt[0];
for (int i = oldTxt.Length - 1; i > 0; i--)
newTxt[((i+1)%oldTxt.Length)] = oldTxt[i];
newTxt[1] = fc;
return newTxt;
}
//https://stackoverflow.com/questions/9264398/how-to-calculate-wpf-textblock-width-for-its-known-font-size-and-characters
private Size MeasureString(string candidate)
{
FormattedText formattedText = null;
this.textContainer.Dispatcher.Invoke(() =>
{
formattedText = new FormattedText(
candidate,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface(this.textContainer.FontFamily, this.textContainer.FontStyle, this.textContainer.FontWeight, this.textContainer.FontStretch),
this.textContainer.FontSize,
Brushes.Black,
new NumberSubstitution(), (TextFormattingMode)1);
});
return new Size(formattedText.WidthIncludingTrailingWhitespace, formattedText.Height);
}
}
}