118 lines
4.5 KiB
C#
118 lines
4.5 KiB
C#
using System.Windows;
|
|
using System.ComponentModel;
|
|
using System.Windows.Media;
|
|
using UserControl = System.Windows.Controls.UserControl;
|
|
using Color = System.Windows.Media.Color;
|
|
|
|
namespace OperationControl.Controls
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for HeadingIndicator.xaml
|
|
/// </summary>
|
|
public partial class HeadingIndicator : UserControl, INotifyPropertyChanged
|
|
{
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
void Raise(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
|
|
|
public HeadingIndicator()
|
|
{
|
|
InitializeComponent();
|
|
|
|
DataContext = this;
|
|
MinorAngles = Enumerable.Range(0, 36).Select(i => i * 10.0).ToList(); // 0..350
|
|
MajorAngles = Enumerable.Range(0, 12).Select(i => i * 30.0).ToList(); // 0..330
|
|
}
|
|
|
|
public List<double> MinorAngles { get; }
|
|
public List<double> MajorAngles { get; }
|
|
|
|
// Mostra/oculta rótulos 0°,30°... (padrão: false)
|
|
public bool ShowDegreeLabels
|
|
{
|
|
get => (bool)GetValue(ShowDegreeLabelsProperty);
|
|
set => SetValue(ShowDegreeLabelsProperty, value);
|
|
}
|
|
public static readonly DependencyProperty ShowDegreeLabelsProperty = DependencyProperty.Register(nameof(ShowDegreeLabels), typeof(bool), typeof(HeadingIndicator), new PropertyMetadata(false));
|
|
public double Heading
|
|
{
|
|
get => (double)GetValue(HeadingProperty);
|
|
set => SetValue(HeadingProperty, value);
|
|
}
|
|
public double CourseHeading
|
|
{
|
|
get => (double)GetValue(CourseHeadingProperty);
|
|
set => SetValue(CourseHeadingProperty, value);
|
|
}
|
|
public double DifHeading { get; set; }
|
|
|
|
public static readonly DependencyProperty HeadingProperty = DependencyProperty.Register(nameof(Heading), typeof(double), typeof(HeadingIndicator), new PropertyMetadata(0.0, OnHeadingOrCourseChanged));
|
|
|
|
public static readonly DependencyProperty CourseHeadingProperty = DependencyProperty.Register(nameof(CourseHeading), typeof(double), typeof(HeadingIndicator), new PropertyMetadata(double.NaN, OnHeadingOrCourseChanged));
|
|
|
|
private static void OnHeadingOrCourseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
var ctrl = (HeadingIndicator)d;
|
|
|
|
// já faz o giro do dial, como antes
|
|
if (ctrl.DialRotation != null)
|
|
ctrl.DialRotation.Angle = -ctrl.Heading;
|
|
|
|
ctrl.UpdateCourseArrow();
|
|
|
|
// **importante**: avisa que DifHeading mudou
|
|
ctrl.Raise(nameof(DifHeading));
|
|
}
|
|
|
|
private static double NormalizeDelta(double deg)
|
|
{
|
|
deg %= 360.0;
|
|
if (deg >= 180.0) deg -= 360.0;
|
|
if (deg < -180.0) deg += 360.0;
|
|
return deg;
|
|
}
|
|
|
|
private void UpdateCourseArrow()
|
|
{
|
|
if (CourseArrow == null || CourseRotation == null)
|
|
return;
|
|
|
|
if (double.IsNaN(CourseHeading))
|
|
{
|
|
CourseArrow.Visibility = Visibility.Collapsed;
|
|
txtHeading.Visibility = Visibility.Collapsed;
|
|
txtHeadingCourse.Visibility = Visibility.Collapsed;
|
|
DifHeading = Heading;
|
|
UpdateChrome();
|
|
return;
|
|
}
|
|
|
|
// mostra a seta e gira pelo delta (curso - heading atual)
|
|
CourseArrow.Visibility = Visibility.Visible;
|
|
txtHeading.Visibility = Visibility.Visible;
|
|
txtHeadingCourse.Visibility = Visibility.Visible;
|
|
double delta = NormalizeDelta(CourseHeading - Heading);
|
|
CourseRotation.Angle = delta;
|
|
|
|
DifHeading = NormalizeDelta(Heading - CourseHeading);
|
|
UpdateChrome();
|
|
}
|
|
|
|
private void UpdateChrome()
|
|
{
|
|
if (Chrome == null) return;
|
|
|
|
bool no_course = double.IsNaN(CourseHeading);
|
|
var a = no_course ? 0 : Math.Abs(DifHeading);
|
|
var cor = new SolidColorBrush(Color.FromRgb(0x2E, 0xCC, 0x71)); // verde
|
|
if (a >= 10)
|
|
cor = new SolidColorBrush(Color.FromRgb(0xE7, 0x4C, 0x3C)); // vermelho
|
|
else if (a >= 5)
|
|
cor = new SolidColorBrush(Color.FromRgb(0xF1, 0xC4, 0x0F)); // amarelo
|
|
|
|
Chrome.BorderBrush = cor;
|
|
txtHeadingDif.Foreground = no_course ? new SolidColorBrush(Colors.White) : cor;
|
|
}
|
|
|
|
}
|
|
}
|