Files
HawkeyeVision/VisionBuilder.UI.Avalonia.Uno/Views/MainWindow.axaml.cs
2026-04-01 09:34:02 +02:00

199 lines
7.0 KiB
C#

using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Threading;
using VisionBuilder.UI.Avalonia;
using VisionBuilder.UI.Common.ViewModel;
using VisionBuilder.UI.Common.ViewModel.Classes;
namespace VisionBuilder.UI.Avalonia.Uno.Views;
public partial class MainWindow : Window
{
private readonly MainWindowVM _mainWindowVm;
private readonly AvaloniaUISettings _avaloniaUiSettings;
private readonly Dictionary<string, Control> _dynamicButtonControls = new();
public MainWindow(MainWindowVM mainWindowVm, AvaloniaUISettings avaloniaUiSettings)
{
_mainWindowVm = mainWindowVm;
_avaloniaUiSettings = avaloniaUiSettings;
InitializeComponent();
DataContext = _mainWindowVm;
SingleCameraView.SetViewModel(_mainWindowVm.SingleCameraVms[0]);
BtnMinimize.Click += BtnMinimize_Click;
BtnExit.Click += BtnExit_Click;
var version = Assembly.GetExecutingAssembly().GetName().Version;
LblVersion.Text = version != null ? $"v{version.Major}.{version.Minor}.{version.Build}" : "v0.0.0";
_mainWindowVm.PropertyChanged += MainWindowVm_PropertyChanged;
_mainWindowVm.DynamicButtons.CollectionChanged += DynamicButtons_CollectionChanged;
foreach (var btn in _mainWindowVm.DynamicButtons)
AddDynamicButton(btn);
}
protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);
_mainWindowVm.OnProgramStarted();
if (_avaloniaUiSettings.FullScreen)
{
WindowState = WindowState.Maximized;
}
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
_mainWindowVm.OnProgramClosed();
Environment.Exit(0);
}
private void MainWindowVm_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(_mainWindowVm.TestMode))
{
// Toggle accent color for test mode visual indication
// Green background when test mode is active
if (_mainWindowVm.TestMode)
{
Background = new global::Avalonia.Media.SolidColorBrush(
global::Avalonia.Media.Color.FromRgb(0x2E, 0x7D, 0x32)); // Green800
}
else
{
Background = new global::Avalonia.Media.SolidColorBrush(
global::Avalonia.Media.Colors.White);
}
}
}
private void BtnMinimize_Click(object? sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
private void BtnExit_Click(object? sender, RoutedEventArgs e)
{
_mainWindowVm.OnProgramClosed();
Environment.Exit(0);
}
private void DynamicButtons_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
Dispatcher.UIThread.Post(() =>
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (ButtonDefinition btn in e.NewItems!)
AddDynamicButton(btn);
break;
case NotifyCollectionChangedAction.Remove:
foreach (ButtonDefinition btn in e.OldItems!)
RemoveDynamicButton(btn);
break;
case NotifyCollectionChangedAction.Reset:
foreach (var ctrl in _dynamicButtonControls.Values)
BottomBarPanel.Children.Remove(ctrl);
_dynamicButtonControls.Clear();
break;
}
});
}
private void AddDynamicButton(ButtonDefinition buttonDef)
{
Control control;
if (buttonDef.Type == EButtonType.Toggle)
{
var toggleBtn = new ToggleButton
{
Content = buttonDef.Title.ToUpperInvariant(),
Width = 176,
Height = 48,
FontSize = 14,
FontWeight = FontWeight.Bold,
HorizontalContentAlignment = global::Avalonia.Layout.HorizontalAlignment.Center,
VerticalContentAlignment = global::Avalonia.Layout.VerticalAlignment.Center,
IsChecked = buttonDef.IsToggled,
IsVisible = buttonDef.IsVisible,
BorderBrush = new SolidColorBrush(Color.FromRgb(0xD3, 0x2F, 0x2F)),
BorderThickness = new Thickness(2),
Background = Brushes.White,
Foreground = new SolidColorBrush(Color.FromRgb(0xD3, 0x2F, 0x2F))
};
toggleBtn.Click += (_, _) => buttonDef.Execute();
buttonDef.PropertyChanged += (_, args) =>
{
Dispatcher.UIThread.Post(() =>
{
if (args.PropertyName == nameof(ButtonDefinition.IsVisible))
toggleBtn.IsVisible = buttonDef.IsVisible;
else if (args.PropertyName == nameof(ButtonDefinition.IsToggled))
toggleBtn.IsChecked = buttonDef.IsToggled;
});
};
control = toggleBtn;
}
else
{
var btn = new Button
{
Content = buttonDef.Title.ToUpperInvariant(),
Width = 176,
Height = 48,
FontSize = 14,
FontWeight = FontWeight.Bold,
HorizontalContentAlignment = global::Avalonia.Layout.HorizontalAlignment.Center,
VerticalContentAlignment = global::Avalonia.Layout.VerticalAlignment.Center,
IsVisible = buttonDef.IsVisible,
BorderBrush = new SolidColorBrush(Color.FromRgb(0xD3, 0x2F, 0x2F)),
BorderThickness = new Thickness(2),
Background = Brushes.White,
Foreground = new SolidColorBrush(Color.FromRgb(0xD3, 0x2F, 0x2F))
};
btn.Click += (_, _) => buttonDef.Execute();
buttonDef.PropertyChanged += (_, args) =>
{
Dispatcher.UIThread.Post(() =>
{
if (args.PropertyName == nameof(ButtonDefinition.IsVisible))
btn.IsVisible = buttonDef.IsVisible;
});
};
control = btn;
}
// Insert before BtnMinimize
var minimizeIndex = BottomBarPanel.Children.IndexOf(BtnMinimize);
if (minimizeIndex >= 0)
BottomBarPanel.Children.Insert(minimizeIndex, control);
else
BottomBarPanel.Children.Add(control);
_dynamicButtonControls[buttonDef.Key] = control;
}
private void RemoveDynamicButton(ButtonDefinition buttonDef)
{
if (_dynamicButtonControls.TryGetValue(buttonDef.Key, out var ctrl))
{
BottomBarPanel.Children.Remove(ctrl);
_dynamicButtonControls.Remove(buttonDef.Key);
}
}
}