UI Slice 1a: Shell-Fundament + Launcher-Buttons statisch + Fenster-Menue + maximiert
- IModuleUiHost (Core) um Navigation erweitert: Views/IsOpen/OpenView/ActivateMain/OpenStateChanged + optionales Icon je ModuleView. So kann JEDES Fenster (auch Modul-Fenster, die nur Core kennen) das gemeinsame Fenster-Menue bauen. - WindowMenu (Core): baut das 'Fenster'-Dropdown (Launcher + alle Views + Beenden), haakt offene Fenster an, markiert das aktuelle fett; Neuaufbau beim Aufklappen. - ShellUiHost: SetMainWindow/ActivateMain; oeffnet ALLE Fenster jetzt MAXIMIERT (Vorgabe). - Launcher: alle Modul-/Core-Buttons STATISCH im Designer (btn_copytrading/-resolutionfarming/ -supervisor ergaenzt), an View-IDs gebunden; fehlt eine View -> Button deaktiviert. Dynamischer Laufzeit-Anhang ENTFERNT -> kein doppelter Accounting-Button mehr; leerer btn_accounting_Click raus. Datei/Beenden -> Fenster-Menue (WindowMenu). Launcher startet maximiert (Sizable, MinSize 1280x720). Build 0 Fehler, --smoke-ui alle 6 Views + Launcher gruen. Fenster-Menue auf den uebrigen Fenstern folgt (1b). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ca0d4ceed0
commit
f54cd7423b
Generated
+72
-44
@@ -18,15 +18,17 @@ namespace PolyTraderSharp.Ui
|
|||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
menuStrip = new MenuStrip();
|
menuStrip = new MenuStrip();
|
||||||
miDatei = new ToolStripMenuItem();
|
miFenster = new ToolStripMenuItem();
|
||||||
miBeenden = new ToolStripMenuItem();
|
|
||||||
toolstrip_windows = new ToolStrip();
|
toolstrip_windows = new ToolStrip();
|
||||||
btn_dashboard = new ToolStripButton();
|
btn_dashboard = new ToolStripButton();
|
||||||
btn_settings = new ToolStripButton();
|
btn_settings = new ToolStripButton();
|
||||||
btn_terminal = new ToolStripButton();
|
btn_terminal = new ToolStripButton();
|
||||||
btn_jobs = new ToolStripButton();
|
btn_jobs = new ToolStripButton();
|
||||||
btn_accounting = new ToolStripButton();
|
|
||||||
toolStripSeparator1 = new ToolStripSeparator();
|
toolStripSeparator1 = new ToolStripSeparator();
|
||||||
|
btn_copytrading = new ToolStripButton();
|
||||||
|
btn_resolutionfarming = new ToolStripButton();
|
||||||
|
btn_supervisor = new ToolStripButton();
|
||||||
|
btn_accounting = new ToolStripButton();
|
||||||
toolstrip_quickbar = new ToolStrip();
|
toolstrip_quickbar = new ToolStrip();
|
||||||
btn_liveTrading = new ToolStripButton();
|
btn_liveTrading = new ToolStripButton();
|
||||||
btn_demoTrading = new ToolStripButton();
|
btn_demoTrading = new ToolStripButton();
|
||||||
@@ -52,31 +54,24 @@ namespace PolyTraderSharp.Ui
|
|||||||
// menuStrip
|
// menuStrip
|
||||||
//
|
//
|
||||||
menuStrip.ImageScalingSize = new Size(24, 24);
|
menuStrip.ImageScalingSize = new Size(24, 24);
|
||||||
menuStrip.Items.AddRange(new ToolStripItem[] { miDatei });
|
menuStrip.Items.AddRange(new ToolStripItem[] { miFenster });
|
||||||
menuStrip.Location = new Point(0, 0);
|
menuStrip.Location = new Point(0, 0);
|
||||||
menuStrip.Name = "menuStrip";
|
menuStrip.Name = "menuStrip";
|
||||||
menuStrip.Padding = new Padding(9, 3, 0, 3);
|
menuStrip.Padding = new Padding(9, 3, 0, 3);
|
||||||
menuStrip.Size = new Size(2599, 35);
|
menuStrip.Size = new Size(2599, 35);
|
||||||
menuStrip.TabIndex = 0;
|
menuStrip.TabIndex = 0;
|
||||||
//
|
//
|
||||||
// miDatei
|
// miFenster
|
||||||
//
|
//
|
||||||
miDatei.DropDownItems.AddRange(new ToolStripItem[] { miBeenden });
|
miFenster.Name = "miFenster";
|
||||||
miDatei.Name = "miDatei";
|
miFenster.Size = new Size(69, 29);
|
||||||
miDatei.Size = new Size(69, 29);
|
miFenster.Text = "Fenster";
|
||||||
miDatei.Text = "Datei";
|
//
|
||||||
//
|
|
||||||
// miBeenden
|
|
||||||
//
|
|
||||||
miBeenden.Name = "miBeenden";
|
|
||||||
miBeenden.Size = new Size(182, 34);
|
|
||||||
miBeenden.Text = "Beenden";
|
|
||||||
//
|
|
||||||
// toolstrip_windows
|
// toolstrip_windows
|
||||||
//
|
//
|
||||||
toolstrip_windows.AutoSize = false;
|
toolstrip_windows.AutoSize = false;
|
||||||
toolstrip_windows.ImageScalingSize = new Size(64, 64);
|
toolstrip_windows.ImageScalingSize = new Size(64, 64);
|
||||||
toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_dashboard, btn_settings, btn_terminal, btn_jobs, btn_accounting, toolStripSeparator1 });
|
toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_dashboard, btn_settings, btn_terminal, btn_jobs, toolStripSeparator1, btn_copytrading, btn_resolutionfarming, btn_supervisor, btn_accounting });
|
||||||
toolstrip_windows.Location = new Point(0, 35);
|
toolstrip_windows.Location = new Point(0, 35);
|
||||||
toolstrip_windows.Name = "toolstrip_windows";
|
toolstrip_windows.Name = "toolstrip_windows";
|
||||||
toolstrip_windows.Size = new Size(2599, 70);
|
toolstrip_windows.Size = new Size(2599, 70);
|
||||||
@@ -121,9 +116,39 @@ namespace PolyTraderSharp.Ui
|
|||||||
btn_jobs.Size = new Size(106, 65);
|
btn_jobs.Size = new Size(106, 65);
|
||||||
btn_jobs.Text = "Server Jobs";
|
btn_jobs.Text = "Server Jobs";
|
||||||
btn_jobs.TextImageRelation = TextImageRelation.ImageAboveText;
|
btn_jobs.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||||
//
|
//
|
||||||
|
// btn_copytrading
|
||||||
|
//
|
||||||
|
btn_copytrading.Image = Properties.Resources.money_dollar;
|
||||||
|
btn_copytrading.ImageScaling = ToolStripItemImageScaling.None;
|
||||||
|
btn_copytrading.ImageTransparentColor = Color.Magenta;
|
||||||
|
btn_copytrading.Name = "btn_copytrading";
|
||||||
|
btn_copytrading.Size = new Size(120, 65);
|
||||||
|
btn_copytrading.Text = "CopyTrading";
|
||||||
|
btn_copytrading.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||||
|
//
|
||||||
|
// btn_resolutionfarming
|
||||||
|
//
|
||||||
|
btn_resolutionfarming.Image = Properties.Resources.refresh_all;
|
||||||
|
btn_resolutionfarming.ImageScaling = ToolStripItemImageScaling.None;
|
||||||
|
btn_resolutionfarming.ImageTransparentColor = Color.Magenta;
|
||||||
|
btn_resolutionfarming.Name = "btn_resolutionfarming";
|
||||||
|
btn_resolutionfarming.Size = new Size(150, 65);
|
||||||
|
btn_resolutionfarming.Text = "ResolutionFarming";
|
||||||
|
btn_resolutionfarming.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||||
|
//
|
||||||
|
// btn_supervisor
|
||||||
|
//
|
||||||
|
btn_supervisor.Image = Properties.Resources.token_quantifier;
|
||||||
|
btn_supervisor.ImageScaling = ToolStripItemImageScaling.None;
|
||||||
|
btn_supervisor.ImageTransparentColor = Color.Magenta;
|
||||||
|
btn_supervisor.Name = "btn_supervisor";
|
||||||
|
btn_supervisor.Size = new Size(110, 65);
|
||||||
|
btn_supervisor.Text = "Supervisor";
|
||||||
|
btn_supervisor.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||||
|
//
|
||||||
// btn_accounting
|
// btn_accounting
|
||||||
//
|
//
|
||||||
btn_accounting.Image = Properties.Resources.coins_in_hand;
|
btn_accounting.Image = Properties.Resources.coins_in_hand;
|
||||||
btn_accounting.ImageScaling = ToolStripItemImageScaling.None;
|
btn_accounting.ImageScaling = ToolStripItemImageScaling.None;
|
||||||
btn_accounting.ImageTransparentColor = Color.Magenta;
|
btn_accounting.ImageTransparentColor = Color.Magenta;
|
||||||
@@ -131,7 +156,7 @@ namespace PolyTraderSharp.Ui
|
|||||||
btn_accounting.Size = new Size(106, 65);
|
btn_accounting.Size = new Size(106, 65);
|
||||||
btn_accounting.Text = "Accounting";
|
btn_accounting.Text = "Accounting";
|
||||||
btn_accounting.TextImageRelation = TextImageRelation.ImageAboveText;
|
btn_accounting.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||||
//
|
//
|
||||||
// toolStripSeparator1
|
// toolStripSeparator1
|
||||||
//
|
//
|
||||||
toolStripSeparator1.Name = "toolStripSeparator1";
|
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||||
@@ -208,25 +233,25 @@ namespace PolyTraderSharp.Ui
|
|||||||
dgv_accountlist.TabIndex = 6;
|
dgv_accountlist.TabIndex = 6;
|
||||||
//
|
//
|
||||||
// colAccName
|
// colAccName
|
||||||
//
|
//
|
||||||
colAccName.DataPropertyName = "Name";
|
colAccName.DataPropertyName = "Name";
|
||||||
colAccName.HeaderText = "Account";
|
colAccName.HeaderText = "Account";
|
||||||
colAccName.MinimumWidth = 8;
|
colAccName.MinimumWidth = 8;
|
||||||
colAccName.Name = "colAccName";
|
colAccName.Name = "colAccName";
|
||||||
colAccName.ReadOnly = true;
|
colAccName.ReadOnly = true;
|
||||||
colAccName.Width = 200;
|
colAccName.Width = 113;
|
||||||
//
|
//
|
||||||
// colAccModules
|
// colAccModules
|
||||||
//
|
//
|
||||||
colAccModules.DataPropertyName = "Modules";
|
colAccModules.DataPropertyName = "Modules";
|
||||||
colAccModules.HeaderText = "Module";
|
colAccModules.HeaderText = "Module";
|
||||||
colAccModules.MinimumWidth = 8;
|
colAccModules.MinimumWidth = 8;
|
||||||
colAccModules.Name = "colAccModules";
|
colAccModules.Name = "colAccModules";
|
||||||
colAccModules.ReadOnly = true;
|
colAccModules.ReadOnly = true;
|
||||||
colAccModules.Width = 220;
|
colAccModules.Width = 109;
|
||||||
//
|
//
|
||||||
// colAccPoly
|
// colAccPoly
|
||||||
//
|
//
|
||||||
colAccPoly.HeaderText = "Polymarket";
|
colAccPoly.HeaderText = "Polymarket";
|
||||||
colAccPoly.MinimumWidth = 8;
|
colAccPoly.MinimumWidth = 8;
|
||||||
colAccPoly.Name = "colAccPoly";
|
colAccPoly.Name = "colAccPoly";
|
||||||
@@ -234,42 +259,41 @@ namespace PolyTraderSharp.Ui
|
|||||||
colAccPoly.Text = "Öffnen";
|
colAccPoly.Text = "Öffnen";
|
||||||
colAccPoly.UseColumnTextForButtonValue = true;
|
colAccPoly.UseColumnTextForButtonValue = true;
|
||||||
colAccPoly.Width = 106;
|
colAccPoly.Width = 106;
|
||||||
//
|
//
|
||||||
// colAccBalance
|
// colAccBalance
|
||||||
//
|
//
|
||||||
colAccBalance.DataPropertyName = "Balance";
|
colAccBalance.DataPropertyName = "Balance";
|
||||||
colAccBalance.HeaderText = "Wallet (USDC)";
|
colAccBalance.HeaderText = "Wallet (USDC)";
|
||||||
colAccBalance.MinimumWidth = 8;
|
colAccBalance.MinimumWidth = 8;
|
||||||
colAccBalance.Name = "colAccBalance";
|
colAccBalance.Name = "colAccBalance";
|
||||||
colAccBalance.ReadOnly = true;
|
colAccBalance.ReadOnly = true;
|
||||||
colAccBalance.Width = 130;
|
colAccBalance.Width = 157;
|
||||||
//
|
//
|
||||||
// colAccPnl3d
|
// colAccPnl3d
|
||||||
//
|
//
|
||||||
colAccPnl3d.DataPropertyName = "Pnl3d";
|
colAccPnl3d.DataPropertyName = "Pnl3d";
|
||||||
colAccPnl3d.HeaderText = "3T PnL";
|
colAccPnl3d.HeaderText = "3T PnL";
|
||||||
colAccPnl3d.MinimumWidth = 8;
|
colAccPnl3d.MinimumWidth = 8;
|
||||||
colAccPnl3d.Name = "colAccPnl3d";
|
colAccPnl3d.Name = "colAccPnl3d";
|
||||||
colAccPnl3d.ReadOnly = true;
|
colAccPnl3d.ReadOnly = true;
|
||||||
colAccPnl3d.Width = 110;
|
//
|
||||||
//
|
|
||||||
// colAccWin3d
|
// colAccWin3d
|
||||||
//
|
//
|
||||||
colAccWin3d.DataPropertyName = "WinRate3d";
|
colAccWin3d.DataPropertyName = "WinRate3d";
|
||||||
colAccWin3d.HeaderText = "3T Winrate %";
|
colAccWin3d.HeaderText = "3T Winrate %";
|
||||||
colAccWin3d.MinimumWidth = 8;
|
colAccWin3d.MinimumWidth = 8;
|
||||||
colAccWin3d.Name = "colAccWin3d";
|
colAccWin3d.Name = "colAccWin3d";
|
||||||
colAccWin3d.ReadOnly = true;
|
colAccWin3d.ReadOnly = true;
|
||||||
colAccWin3d.Width = 110;
|
colAccWin3d.Width = 153;
|
||||||
//
|
//
|
||||||
// colAccOverall
|
// colAccOverall
|
||||||
//
|
//
|
||||||
colAccOverall.DataPropertyName = "OverallPnl";
|
colAccOverall.DataPropertyName = "OverallPnl";
|
||||||
colAccOverall.HeaderText = "Overall P/L";
|
colAccOverall.HeaderText = "Overall P/L";
|
||||||
colAccOverall.MinimumWidth = 8;
|
colAccOverall.MinimumWidth = 8;
|
||||||
colAccOverall.Name = "colAccOverall";
|
colAccOverall.Name = "colAccOverall";
|
||||||
colAccOverall.ReadOnly = true;
|
colAccOverall.ReadOnly = true;
|
||||||
colAccOverall.Width = 130;
|
colAccOverall.Width = 133;
|
||||||
//
|
//
|
||||||
// LauncherForm
|
// LauncherForm
|
||||||
//
|
//
|
||||||
@@ -281,12 +305,14 @@ namespace PolyTraderSharp.Ui
|
|||||||
Controls.Add(toolstrip_quickbar);
|
Controls.Add(toolstrip_quickbar);
|
||||||
Controls.Add(toolstrip_windows);
|
Controls.Add(toolstrip_windows);
|
||||||
Controls.Add(menuStrip);
|
Controls.Add(menuStrip);
|
||||||
FormBorderStyle = FormBorderStyle.FixedSingle;
|
FormBorderStyle = FormBorderStyle.Sizable;
|
||||||
MainMenuStrip = menuStrip;
|
MainMenuStrip = menuStrip;
|
||||||
Margin = new Padding(4, 5, 4, 5);
|
Margin = new Padding(4, 5, 4, 5);
|
||||||
|
MinimumSize = new Size(1280, 720);
|
||||||
Name = "LauncherForm";
|
Name = "LauncherForm";
|
||||||
StartPosition = FormStartPosition.CenterScreen;
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
Text = "PolyTrader";
|
Text = "PolyTrader";
|
||||||
|
WindowState = FormWindowState.Maximized;
|
||||||
menuStrip.ResumeLayout(false);
|
menuStrip.ResumeLayout(false);
|
||||||
menuStrip.PerformLayout();
|
menuStrip.PerformLayout();
|
||||||
toolstrip_windows.ResumeLayout(false);
|
toolstrip_windows.ResumeLayout(false);
|
||||||
@@ -303,13 +329,15 @@ namespace PolyTraderSharp.Ui
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private System.Windows.Forms.MenuStrip menuStrip;
|
private System.Windows.Forms.MenuStrip menuStrip;
|
||||||
private System.Windows.Forms.ToolStripMenuItem miDatei;
|
private System.Windows.Forms.ToolStripMenuItem miFenster;
|
||||||
private System.Windows.Forms.ToolStripMenuItem miBeenden;
|
|
||||||
private ToolStrip toolstrip_windows;
|
private ToolStrip toolstrip_windows;
|
||||||
private ToolStripButton btn_settings;
|
private ToolStripButton btn_settings;
|
||||||
private ToolStripButton btn_terminal;
|
private ToolStripButton btn_terminal;
|
||||||
private ToolStripButton btn_jobs;
|
private ToolStripButton btn_jobs;
|
||||||
private ToolStripButton btn_dashboard;
|
private ToolStripButton btn_dashboard;
|
||||||
|
private ToolStripButton btn_copytrading;
|
||||||
|
private ToolStripButton btn_resolutionfarming;
|
||||||
|
private ToolStripButton btn_supervisor;
|
||||||
private ToolStrip toolstrip_quickbar;
|
private ToolStrip toolstrip_quickbar;
|
||||||
private ToolStripButton btn_liveTrading;
|
private ToolStripButton btn_liveTrading;
|
||||||
private ToolStripButton btn_demoTrading;
|
private ToolStripButton btn_demoTrading;
|
||||||
|
|||||||
+15
-25
@@ -35,46 +35,36 @@ namespace PolyTraderSharp.Ui
|
|||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
// Fenster-Buttons an stabile View-IDs binden (Views werden per DI registriert).
|
_uiHost.SetMainWindow(this);
|
||||||
|
|
||||||
|
// Fenster-Buttons: ALLE statisch im Designer, an stabile View-IDs gebunden. Ist eine View
|
||||||
|
// nicht registriert (Modul fehlt), wird der Button deaktiviert – nichts wird zur Laufzeit angehängt.
|
||||||
_viewButtons = new Dictionary<string, ToolStripButton>
|
_viewButtons = new Dictionary<string, ToolStripButton>
|
||||||
{
|
{
|
||||||
["core.dashboard"] = btn_dashboard,
|
["core.dashboard"] = btn_dashboard,
|
||||||
["core.settings"] = btn_settings,
|
["core.settings"] = btn_settings,
|
||||||
["core.terminal"] = btn_terminal,
|
["core.terminal"] = btn_terminal,
|
||||||
["core.jobs"] = btn_jobs,
|
["core.jobs"] = btn_jobs,
|
||||||
|
["copytrading.main"] = btn_copytrading,
|
||||||
|
["resolutionfarming.main"] = btn_resolutionfarming,
|
||||||
|
["supervisor.main"] = btn_supervisor,
|
||||||
|
["accounting.main"] = btn_accounting,
|
||||||
};
|
};
|
||||||
|
var registered = _uiHost.Views.Select(v => v.Id).ToHashSet();
|
||||||
foreach (var (id, btn) in _viewButtons)
|
foreach (var (id, btn) in _viewButtons)
|
||||||
{
|
{
|
||||||
var viewId = id;
|
var viewId = id;
|
||||||
btn.Click += (_, _) => _uiHost.OpenView(viewId);
|
if (registered.Contains(viewId))
|
||||||
|
btn.Click += (_, _) => _uiHost.OpenView(viewId);
|
||||||
|
else
|
||||||
|
btn.Enabled = false; // Modul/View nicht verfügbar
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modul-Views dynamisch anhängen (der Launcher kennt keine Modulnamen; er bindet
|
// Gemeinsames „Fenster"-Menü (Launcher ist das aktuelle Fenster → currentViewId null).
|
||||||
// nur an registrierte View-IDs). Core-Views sind bereits fest verdrahtet.
|
PolyTrader.Core.Modularity.WindowMenu.Wire(miFenster, _uiHost, null);
|
||||||
var moduleViews = _uiHost.Views
|
|
||||||
.Where(v => !_viewButtons.ContainsKey(v.Id))
|
|
||||||
.OrderBy(v => v.Order)
|
|
||||||
.ToList();
|
|
||||||
if (moduleViews.Count > 0)
|
|
||||||
toolstrip_windows.Items.Add(new ToolStripSeparator());
|
|
||||||
foreach (var view in moduleViews)
|
|
||||||
{
|
|
||||||
var btn = new ToolStripButton(view.Title)
|
|
||||||
{
|
|
||||||
Name = "btn_" + view.Id,
|
|
||||||
Overflow = ToolStripItemOverflow.AsNeeded,
|
|
||||||
TextImageRelation = TextImageRelation.ImageAboveText,
|
|
||||||
AutoSize = true
|
|
||||||
};
|
|
||||||
var viewId = view.Id;
|
|
||||||
btn.Click += (_, _) => _uiHost.OpenView(viewId);
|
|
||||||
toolstrip_windows.Items.Add(btn);
|
|
||||||
_viewButtons[view.Id] = btn;
|
|
||||||
}
|
|
||||||
|
|
||||||
btn_liveTrading.Click += (_, _) => CycleLiveTrading();
|
btn_liveTrading.Click += (_, _) => CycleLiveTrading();
|
||||||
btn_demoTrading.Click += (_, _) => CycleDemoTrading();
|
btn_demoTrading.Click += (_, _) => CycleDemoTrading();
|
||||||
miBeenden.Click += (_, _) => Close();
|
|
||||||
|
|
||||||
// Offen-Status der Fenster spiegeln (Button „checked", wenn Fenster offen).
|
// Offen-Status der Fenster spiegeln (Button „checked", wenn Fenster offen).
|
||||||
_uiHost.OpenStateChanged += UpdateWindowButtonStates;
|
_uiHost.OpenStateChanged += UpdateWindowButtonStates;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace PolyTraderSharp.Ui
|
|||||||
{
|
{
|
||||||
private readonly List<ModuleView> _views = new();
|
private readonly List<ModuleView> _views = new();
|
||||||
private readonly Dictionary<string, Form> _open = new();
|
private readonly Dictionary<string, Form> _open = new();
|
||||||
|
private Form? _mainWindow;
|
||||||
|
|
||||||
/// <summary>Wird ausgelöst, wenn sich der Offen-Status irgendeiner View ändert.</summary>
|
/// <summary>Wird ausgelöst, wenn sich der Offen-Status irgendeiner View ändert.</summary>
|
||||||
public event Action? OpenStateChanged;
|
public event Action? OpenStateChanged;
|
||||||
@@ -24,6 +25,18 @@ namespace PolyTraderSharp.Ui
|
|||||||
|
|
||||||
public void RegisterView(ModuleView view) => _views.Add(view);
|
public void RegisterView(ModuleView view) => _views.Add(view);
|
||||||
|
|
||||||
|
/// <summary>Setzt das Hauptfenster (Launcher) – Ziel für <see cref="ActivateMain"/>.</summary>
|
||||||
|
public void SetMainWindow(Form main) => _mainWindow = main;
|
||||||
|
|
||||||
|
public void ActivateMain()
|
||||||
|
{
|
||||||
|
if (_mainWindow == null || _mainWindow.IsDisposed) return;
|
||||||
|
if (_mainWindow.WindowState == FormWindowState.Minimized)
|
||||||
|
_mainWindow.WindowState = FormWindowState.Maximized;
|
||||||
|
_mainWindow.BringToFront();
|
||||||
|
_mainWindow.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsOpen(string viewId) =>
|
public bool IsOpen(string viewId) =>
|
||||||
_open.TryGetValue(viewId, out var form) && !form.IsDisposed;
|
_open.TryGetValue(viewId, out var form) && !form.IsDisposed;
|
||||||
|
|
||||||
@@ -48,6 +61,10 @@ namespace PolyTraderSharp.Ui
|
|||||||
if (string.IsNullOrEmpty(form.Text) || form.Text == form.Name)
|
if (string.IsNullOrEmpty(form.Text) || form.Text == form.Name)
|
||||||
form.Text = view.Title;
|
form.Text = view.Title;
|
||||||
|
|
||||||
|
// Alle Fenster maximiert (Vorgabe): Full-HD-Ziel, skaliert auf größere Auflösungen.
|
||||||
|
form.StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
form.WindowState = FormWindowState.Maximized;
|
||||||
|
|
||||||
_open[view.Id] = form;
|
_open[view.Id] = form;
|
||||||
form.FormClosed += (_, _) =>
|
form.FormClosed += (_, _) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace PolyTrader.Core.Modularity
|
namespace PolyTrader.Core.Modularity
|
||||||
@@ -23,6 +24,9 @@ namespace PolyTrader.Core.Modularity
|
|||||||
/// <summary>Optionale Sortierreihenfolge.</summary>
|
/// <summary>Optionale Sortierreihenfolge.</summary>
|
||||||
public int Order { get; init; } = 0;
|
public int Order { get; init; } = 0;
|
||||||
|
|
||||||
|
/// <summary>Optionales Icon (16x16) für Menü/Buttons. Wird von der Shell/den Menüs genutzt.</summary>
|
||||||
|
public System.Drawing.Image? Icon { get; init; }
|
||||||
|
|
||||||
/// <summary>Erzeugt das anzuzeigende Fenster (frische Instanz je Öffnung).</summary>
|
/// <summary>Erzeugt das anzuzeigende Fenster (frische Instanz je Öffnung).</summary>
|
||||||
public Func<Form> CreateForm { get; init; } = () => new Form();
|
public Func<Form> CreateForm { get; init; } = () => new Form();
|
||||||
}
|
}
|
||||||
@@ -30,9 +34,26 @@ namespace PolyTrader.Core.Modularity
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Wird der Shell beim Start übergeben; Core und Module registrieren hier ihre Ansichten.
|
/// Wird der Shell beim Start übergeben; Core und Module registrieren hier ihre Ansichten.
|
||||||
/// Die Shell (Launcher) öffnet die Fenster auf Anforderung und verwaltet den Offen-Status.
|
/// Die Shell (Launcher) öffnet die Fenster auf Anforderung und verwaltet den Offen-Status.
|
||||||
|
/// Über die Navigations-Mitglieder kann JEDES Fenster (auch Modul-Fenster, die nur den Core
|
||||||
|
/// kennen) das gemeinsame „Fenster"-Menü bauen (siehe <see cref="WindowMenu"/>).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IModuleUiHost
|
public interface IModuleUiHost
|
||||||
{
|
{
|
||||||
void RegisterView(ModuleView view);
|
void RegisterView(ModuleView view);
|
||||||
|
|
||||||
|
/// <summary>Alle registrierten Ansichten (Core + Module).</summary>
|
||||||
|
IReadOnlyList<ModuleView> Views { get; }
|
||||||
|
|
||||||
|
/// <summary>Ist das Fenster dieser View gerade offen?</summary>
|
||||||
|
bool IsOpen(string viewId);
|
||||||
|
|
||||||
|
/// <summary>Öffnet die View bzw. holt ein bereits offenes Fenster in den Vordergrund (maximiert).</summary>
|
||||||
|
void OpenView(string viewId);
|
||||||
|
|
||||||
|
/// <summary>Holt das Hauptfenster (Launcher) in den Vordergrund.</summary>
|
||||||
|
void ActivateMain();
|
||||||
|
|
||||||
|
/// <summary>Feuert, wenn sich der Offen-Status irgendeiner View ändert.</summary>
|
||||||
|
event Action? OpenStateChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace PolyTrader.Core.Modularity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Baut das gemeinsame „Fenster"-Menü, das auf JEDEM PolyTrader-Fenster erscheint und das Wechseln
|
||||||
|
/// zwischen allen Fenstern (Launcher + Core + Module) erlaubt. Da es nur den Core-Contract
|
||||||
|
/// <see cref="IModuleUiHost"/> nutzt, funktioniert es auch aus Modul-Fenstern (die die App nicht kennen).
|
||||||
|
///
|
||||||
|
/// Der Menü-Container liegt im Designer jedes Fensters (ein <see cref="ToolStripMenuItem"/> „Fenster");
|
||||||
|
/// die dynamische Liste (Offen-Status ändert sich) wird hier beim Aufklappen frisch gefüllt:
|
||||||
|
/// offene Fenster sind angehakt, das aktuelle Fenster ist fett + angehakt markiert.
|
||||||
|
/// </summary>
|
||||||
|
public static class WindowMenu
|
||||||
|
{
|
||||||
|
/// <summary>Verdrahtet ein Designer-„Fenster"-Menüelement mit der Fensterliste (Neuaufbau beim Aufklappen).</summary>
|
||||||
|
public static void Wire(ToolStripMenuItem fensterMenu, IModuleUiHost host, string? currentViewId)
|
||||||
|
{
|
||||||
|
fensterMenu.DropDownOpening += (_, _) => Populate(fensterMenu, host, currentViewId);
|
||||||
|
Populate(fensterMenu, host, currentViewId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Populate(ToolStripMenuItem fensterMenu, IModuleUiHost host, string? currentViewId)
|
||||||
|
{
|
||||||
|
fensterMenu.DropDownItems.Clear();
|
||||||
|
|
||||||
|
var launcher = new ToolStripMenuItem("Launcher") { Checked = currentViewId == null };
|
||||||
|
if (currentViewId == null) launcher.Font = new Font(launcher.Font, FontStyle.Bold);
|
||||||
|
launcher.Click += (_, _) => host.ActivateMain();
|
||||||
|
fensterMenu.DropDownItems.Add(launcher);
|
||||||
|
fensterMenu.DropDownItems.Add(new ToolStripSeparator());
|
||||||
|
|
||||||
|
foreach (var view in host.Views.OrderBy(v => v.Order).ThenBy(v => v.Title))
|
||||||
|
{
|
||||||
|
bool isCurrent = view.Id == currentViewId;
|
||||||
|
var item = new ToolStripMenuItem(view.Title) { Image = view.Icon };
|
||||||
|
item.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);
|
||||||
|
fensterMenu.DropDownItems.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
fensterMenu.DropDownItems.Add(new ToolStripSeparator());
|
||||||
|
var exit = new ToolStripMenuItem("Beenden");
|
||||||
|
exit.Click += (_, _) => Application.Exit();
|
||||||
|
fensterMenu.DropDownItems.Add(exit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user