101 lines
3.6 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|