using System.Drawing; using System.Windows.Forms; using IBKRTrader.Core.Modularity; namespace IBKRTrader.UI; /// /// Baut das gemeinsame Fenster-Menü, das auf JEDEM Fenster erscheint und das Wechseln zwischen allen /// Fenstern (Launcher + Core + Module) erlaubt. Es nutzt nur den Core-Contract /// und funktioniert deshalb aus jedem Fenster. /// /// Lag früher im Core. Verschoben in die Shell, weil er reine WinForms-Umsetzung ist – der /// Core soll keine UI-Abhängigkeit tragen (Linux-Portierung). Die Avalonia-Shell bekommt ein /// eigenes Gegenstück gegen denselben Contract. /// public static class WindowMenu { /// /// Verdrahtet einen mit der Fensterliste: füllt ihn sofort und baut ihn bei /// jeder Offen-Status-Änderung neu auf. Die Registrierung wird beim Entsorgen sauber gelöst. /// public static void Wire(MenuStrip menu, IModuleUiHost host, string? currentViewId) { void Refresh() { if (menu.IsDisposed) return; if (menu.IsHandleCreated && menu.InvokeRequired) { try { menu.BeginInvoke((Action)(() => Populate(menu, host, currentViewId))); } catch { /* Fenster wird gerade geschlossen */ } return; } Populate(menu, host, currentViewId); } Populate(menu, host, currentViewId); host.OpenStateChanged += Refresh; menu.Disposed += (_, _) => host.OpenStateChanged -= Refresh; } /// Baut die Menüleiste komplett neu auf (Launcher, alle Views nebeneinander, Aktion rechts). public static void Populate(MenuStrip menu, IModuleUiHost host, string? currentViewId) { menu.Items.Clear(); var launcher = new ToolStripMenuItem("Launcher") { Checked = currentViewId == null }; if (currentViewId == null) launcher.Font = new Font(launcher.Font, FontStyle.Bold); launcher.Click += (_, _) => host.ActivateMain(); menu.Items.Add(launcher); foreach (var view in host.Views.OrderBy(v => v.Order).ThenBy(v => v.Title)) { bool isCurrent = view.Id == currentViewId; var icon = ViewIcons.Resolve(view.IconKey); var item = new ToolStripMenuItem(view.Title) { Image = icon, ImageScaling = ToolStripItemImageScaling.SizeToFit, DisplayStyle = icon != null ? ToolStripItemDisplayStyle.ImageAndText : ToolStripItemDisplayStyle.Text, Checked = isCurrent || host.IsOpen(view.Id) }; if (isCurrent) item.Font = new Font(item.Font, FontStyle.Bold); string id = view.Id; item.Click += (_, _) => host.OpenView(id); menu.Items.Add(item); } // Kontextabhängige rechte Aktion: nur der Launcher darf die App beenden; jedes andere Fenster // bietet nur „Fenster schließen" (kein App-Shutdown, Module laufen weiter). if (currentViewId == null) { var exit = new ToolStripMenuItem("Beenden") { Alignment = ToolStripItemAlignment.Right }; exit.Click += (_, _) => host.RequestShutdown(); menu.Items.Add(exit); } else { var close = new ToolStripMenuItem("Fenster schließen") { Alignment = ToolStripItemAlignment.Right }; close.Click += (_, _) => menu.FindForm()?.Close(); menu.Items.Add(close); } } }