using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Media; using System.Windows.Controls; using UserControl = System.Windows.Controls.UserControl; using Brush = System.Windows.Media.Brush; using Point = System.Windows.Point; namespace OperationControl.Controls.Pulverizador { public partial class BicoLequeIndicator : UserControl { public BicoLequeIndicator() { InitializeComponent(); Loaded += (_, __) => UpdateGeometry(); SizeChanged += (_, __) => UpdateGeometry(); } public bool IsCommandOn { get => (bool)GetValue(IsCommandOnProperty); set => SetValue(IsCommandOnProperty, value); } public static readonly DependencyProperty IsCommandOnProperty = DependencyProperty.Register(nameof(IsCommandOn), typeof(bool), typeof(BicoLequeIndicator), new PropertyMetadata(false, OnVisualPropertyChanged)); public bool IsSpraying { get => (bool)GetValue(IsSprayingProperty); set => SetValue(IsSprayingProperty, value); } public static readonly DependencyProperty IsSprayingProperty = DependencyProperty.Register(nameof(IsSpraying), typeof(bool), typeof(BicoLequeIndicator), new PropertyMetadata(false, OnVisualPropertyChanged)); public double AnguloControle { get => (double)GetValue(AnguloControleProperty); set => SetValue(AnguloControleProperty, value); } public static readonly DependencyProperty AnguloControleProperty = DependencyProperty.Register(nameof(AnguloControle), typeof(double), typeof(BicoLequeIndicator), new PropertyMetadata(0.0, OnGeometryPropertyChanged)); public double OpeningAngle { get => (double)GetValue(OpeningAngleProperty); set => SetValue(OpeningAngleProperty, value); } public static readonly DependencyProperty OpeningAngleProperty = DependencyProperty.Register(nameof(OpeningAngle), typeof(double), typeof(BicoLequeIndicator), new PropertyMetadata(110.0, OnGeometryPropertyChanged)); public double Vazao { get => (double)GetValue(VazaoProperty); set => SetValue(VazaoProperty, value); } public static readonly DependencyProperty VazaoProperty = DependencyProperty.Register(nameof(Vazao), typeof(double), typeof(BicoLequeIndicator), new PropertyMetadata(0.0)); public double TempoAtuado { get => (double)GetValue(TempoAtuadoProperty); set => SetValue(TempoAtuadoProperty, value); } public static readonly DependencyProperty TempoAtuadoProperty = DependencyProperty.Register(nameof(TempoAtuado), typeof(double), typeof(BicoLequeIndicator), new PropertyMetadata(0.0)); public int Atuacoes { get => (int)GetValue(AtuacoesProperty); set => SetValue(AtuacoesProperty, value); } public static readonly DependencyProperty AtuacoesProperty = DependencyProperty.Register(nameof(Atuacoes), typeof(int), typeof(BicoLequeIndicator), new PropertyMetadata(0)); private static void OnGeometryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is BicoLequeIndicator ctrl) ctrl.UpdateGeometry(); } private static void OnVisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is BicoLequeIndicator ctrl) ctrl.UpdateVisualState(); } private void UpdateVisualState() { if (SolenoidRect == null || SprayPolygon == null || CenterLine == null) return; var onBrush = (Brush)FindResource("CommandOnBrush"); var offBrush = (Brush)FindResource("CommandOffBrush"); SolenoidRect.Stroke = IsCommandOn ? onBrush : offBrush; SprayPolygon.Visibility = IsSpraying && OpeningAngle > 0 ? Visibility.Visible : Visibility.Collapsed; CenterLine.Visibility = IsSpraying ? Visibility.Visible : Visibility.Collapsed; } private void UpdateGeometry() { if (DrawCanvas == null || SprayPolygon == null || CenterLine == null || SolenoidRect == null) return; double width = DrawCanvas.ActualWidth; double height = DrawCanvas.ActualHeight; if (width <= 0) width = 60; if (height <= 0) height = 40; double originX = width / 2.0; double originY = 8.0; double length = Math.Max(16.0, height - 10.0); double halfAngleRad = OpeningAngle * 0.5 * Math.PI / 180.0; double dx = Math.Tan(halfAngleRad) * length; Point apex = new Point(0, 0); Point leftLocal = new Point(-dx, length); Point rightLocal = new Point(dx, length); Point centerLocal = new Point(0, length); double theta = AnguloControle * Math.PI / 180.0; double cos = Math.Cos(theta); double sin = Math.Sin(theta); Point Rotate(Point p) => new Point( p.X * cos - p.Y * sin, p.X * sin + p.Y * cos); Point apexR = Rotate(apex); Point leftR = Rotate(leftLocal); Point rightR = Rotate(rightLocal); Point centerR = Rotate(centerLocal); apexR.Offset(originX, originY); leftR.Offset(originX, originY); rightR.Offset(originX, originY); centerR.Offset(originX, originY); SprayPolygon.Points = new PointCollection { leftR, apexR, rightR }; CenterLine.X1 = apexR.X; CenterLine.Y1 = apexR.Y; CenterLine.X2 = centerR.X; CenterLine.Y2 = centerR.Y; Canvas.SetLeft(SolenoidRect, originX - SolenoidRect.Width / 2.0); Canvas.SetTop(SolenoidRect, originY - SolenoidRect.Height / 2.0); UpdateVisualState(); } } public class BicoModel : INotifyPropertyChanged { private int _index; public int Index { get => _index; set { _index = value; OnPropertyChanged(); } } private double _anguloControle; public double AnguloControle { get => _anguloControle; set { _anguloControle = value; OnPropertyChanged(); } } private double _openingAngle = 110; public double OpeningAngle { get => _openingAngle; set { _openingAngle = value; OnPropertyChanged(); } } private bool _isCommandOn; public bool IsCommandOn { get => _isCommandOn; set { _isCommandOn = value; OnPropertyChanged(); } } private bool _isSpraying; public bool IsSpraying { get => _isSpraying; set { _isSpraying = value; OnPropertyChanged(); } } private double _vazao; public double Vazao { get => _vazao; set { _vazao = value; OnPropertyChanged(); } } private double _tempoAtuado; public double TempoAtuado { get => _tempoAtuado; set { _tempoAtuado = value; OnPropertyChanged(); } } private int _atuacoes; public int Atuacoes { get => _atuacoes; set { _atuacoes = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); } }