using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace Signal_Generator { public class DrawTask : Task, INotifyPropertyChanged { Canvas canvas; MultiSignal multiSignal; ProcedureModel procedureModel; private State _state; public State state { get { return _state; } set { _state = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("state")); } } public event PropertyChangedEventHandler PropertyChanged; public enum State { Created, Running, Paused, Finished, Canceled } public DrawTask(Action a) : base(a) { } public void buildTask(ProcedureModel pm, Canvas c) { canvas = c; procedureModel = pm; multiSignal = MultiSignal.getInstance(); state = State.Running; drawSignalAtCanvas(); } private void drawSignalAtCanvas() { double lastX = 0, lastY = 0; double W = canvas.ActualWidth; double dX = (procedureModel.Duration / 1000) / W; for (int X = 0; X != (int)W; X++) { double Y = multiSignal.currentAmplitude(X * dX); updateTextBoxProps(Y, X * dX * 1000); drawLine(lastX, lastY, X, Y); lastX = X; lastY = Y; if (taskSemaphore() == false) return; } state = State.Finished; } private bool taskSemaphore() { Thread.Sleep(10); switch (state) { case State.Paused: while (state == State.Paused) Thread.Sleep(50); break; case State.Canceled: return false; } return true; } private void updateTextBoxProps(double amp, double time) { amp = Math.Round(amp, 2); time = Math.Round(time, 2); procedureModel.CurrentAmplitude = amp.ToString(); procedureModel.CurrentTime = time.ToString(); } private void drawLine(double x1, double y1, double x2, double y2) { Action a = () => { Line l = new Line(); l.StrokeThickness = 1; l.Stroke = Brushes.Red; l.X1 = x1; l.Y1 = remapOY(y1, 100, canvas.ActualHeight); l.X2 = x2; l.Y2 = remapOY(y2, 100, canvas.ActualHeight); canvas.Children.Add(l); }; canvas.Dispatcher.Invoke(a); } private double remapOY(double x, double amp = 100.0, double height = 100.0) { return height + (x + amp) * (-height) / (2 * amp); } } }