using System.Collections.Specialized; using MaterialSkin; using MaterialSkin.Controls; using VisionBuilder.UI.Common; using VisionBuilder.UI.Common.Services; using VisionBuilder.UI.Common.ViewModel; using VisionBuilder.UI.Common.ViewModel.Classes; namespace VisionBuilder.UI.Windows.Duo { public partial class Form1 : MaterialForm { private readonly MainWindowVM _mainWindowVm; private readonly IPasswordInputService _passwordInputService; private readonly UIConfiguration _uiConfiguration; private readonly WindowsUISettings _windowsUiSettings; private readonly Dictionary _dynamicButtonControls = new(); public Form1(MainWindowVM mainWindowVm, IPasswordInputService passwordInputService, UIConfiguration uiConfiguration, WindowsUISettings windowsUiSettings) { _mainWindowVm = mainWindowVm; _passwordInputService = passwordInputService; _uiConfiguration = uiConfiguration; _windowsUiSettings = windowsUiSettings; MaterialSkin.MaterialSkinManager.ConfigureForInspectron(); InitializeComponent(); singleCameraControl1.SetViewModel(mainWindowVm.SingleCameraVms[0]); singleCameraControl2.SetViewModel(mainWindowVm.SingleCameraVms[1]); Load += Form1_Load; _mainWindowVm.PropertyChanged += _mainWindowVm_PropertyChanged; lblVersion.Text = $"v{Application.ProductVersion.Split('+')[0]}"; if(!_uiConfiguration.ShowTestModeButton) flowLayoutPanel1.Controls.Remove(btnTestMode); _mainWindowVm.DynamicButtons.CollectionChanged += DynamicButtons_CollectionChanged; foreach (var btn in _mainWindowVm.DynamicButtons) AddDynamicButton(btn); } private void _mainWindowVm_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(_mainWindowVm.TestMode)) { if (_mainWindowVm.TestMode) { MaterialSkinManager.Instance.ColorScheme = new ColorScheme(Primary.Green800, Primary.Green800, Primary.Green400, Accent.Green200, TextShade.WHITE); } else { MaterialSkinManager.ConfigureForInspectron(); } Refresh(); } } private void Form1_Load(object sender, EventArgs e) { _mainWindowVm.OnProgramStarted(); BringToFront(); if (_windowsUiSettings.FullScreen) { WindowState = FormWindowState.Maximized; } } protected override void OnShown(EventArgs e) { base.OnShown(e); flowLayoutPanel1.Left = (ClientSize.Width - flowLayoutPanel1.Width) / 2; } private void btnExit_Click(object sender, EventArgs e) { _mainWindowVm.OnProgramClosed(); Environment.Exit(0); } protected override void OnClosed(EventArgs e) { base.OnClosed(e); _mainWindowVm.OnProgramClosed(); Environment.Exit(0); } private void btnMinimize_Click(object sender, EventArgs e) { WindowState = FormWindowState.Minimized; } private async void btnSettings_Click(object sender, EventArgs e) { if (_uiConfiguration.ProtectSettingsWithPassword) { var passwordOk = await _passwordInputService.GetPasswordAsync() == _uiConfiguration.AdminPassword; if (!passwordOk) return; } _mainWindowVm.SettingsCommand.Execute(null); } private void btnTestMode_Click(object sender, EventArgs e) { _mainWindowVm.ToggleTestModeCommand.Execute(null); } public object GetHandle() { return this; } private void DynamicButtons_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { 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) flowLayoutPanel1.Controls.Remove(ctrl); _dynamicButtonControls.Clear(); break; } } private void AddDynamicButton(ButtonDefinition buttonDef) { var btn = new MaterialRaisedButton { Text = buttonDef.Title, Size = new Size(176, 64), Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold), DrawBorder = true, Primary = buttonDef.Type == EButtonType.Toggle && buttonDef.IsToggled, Visible = buttonDef.IsVisible }; btn.Click += (_, _) => { buttonDef.Execute(); if (buttonDef.Type == EButtonType.Toggle) btn.Primary = buttonDef.IsToggled; }; buttonDef.PropertyChanged += (_, args) => { if (args.PropertyName == nameof(ButtonDefinition.IsVisible)) btn.Visible = buttonDef.IsVisible; else if (args.PropertyName == nameof(ButtonDefinition.IsToggled)) btn.Primary = buttonDef.IsToggled; }; // Insert before Minimize button var minimizeIndex = flowLayoutPanel1.Controls.IndexOf(btnMinimize); if (minimizeIndex >= 0) flowLayoutPanel1.Controls.Add(btn); flowLayoutPanel1.Controls.SetChildIndex(btn, minimizeIndex >= 0 ? minimizeIndex : flowLayoutPanel1.Controls.Count - 1); _dynamicButtonControls[buttonDef.Key] = btn; } private void RemoveDynamicButton(ButtonDefinition buttonDef) { if (_dynamicButtonControls.TryGetValue(buttonDef.Key, out var ctrl)) { flowLayoutPanel1.Controls.Remove(ctrl); _dynamicButtonControls.Remove(buttonDef.Key); } } } }