From ad5ba34b5668d9ef8170e7b4d39fb4ddf95f277f Mon Sep 17 00:00:00 2001 From: Richard Date: Fri, 3 Jul 2026 09:19:13 +0200 Subject: [PATCH] Phase 5-UI: Views sind echte Forms + Launcher-Offen-Status - ModuleView liefert jetzt ein Form (CreateForm statt CreateControl); die 4 Views (Terminal, Settings, Jobs, Dashboard) von UserControl auf Form umgestellt (im Designer als Fenster bearbeitbar). ViewHostForm entfernt. - ShellUiHost verwaltet offene Forms: Einzelinstanz, bereits offenes Fenster wird in den Vordergrund geholt, OpenStateChanged-Event. - LauncherForm: Fenster-Buttons an View-IDs gebunden; offene Fenster werden am Button markiert (Checked), erneuter Klick holt das Fenster nach vorn. - Build 0 Fehler. Co-Authored-By: Claude Opus 4.8 --- Program.cs | 16 +-- Properties/Resources.Designer.cs | 10 ++ Properties/Resources.resx | 17 +-- Resources/dashboard.png | Bin 0 -> 2348 bytes Ui/LauncherForm.Designer.cs | 26 +++-- Ui/LauncherForm.cs | 43 +++++--- Ui/ShellUiHost.cs | 39 +++++-- Ui/ViewHostForm.cs | 28 ----- Ui/Views/DashboardView.Designer.cs | 3 +- Ui/Views/DashboardView.cs | 2 +- Ui/Views/JobsView.Designer.cs | 3 +- Ui/Views/JobsView.cs | 2 +- Ui/Views/JobsView.resx | 120 +++++++++++++++++++++ Ui/Views/SettingsView.Designer.cs | 3 +- Ui/Views/SettingsView.cs | 2 +- Ui/Views/TerminalView.Designer.cs | 3 +- Ui/Views/TerminalView.cs | 2 +- src/PolyTrader.Core/Modularity/ModuleUi.cs | 25 ++--- 18 files changed, 242 insertions(+), 102 deletions(-) create mode 100644 Resources/dashboard.png delete mode 100644 Ui/ViewHostForm.cs create mode 100644 Ui/Views/JobsView.resx diff --git a/Program.cs b/Program.cs index f5ca3b5..2b04c11 100644 --- a/Program.cs +++ b/Program.cs @@ -138,9 +138,7 @@ internal static class Program Title = "Terminal", Group = "Core", Order = 10, - PreferredWidth = 1000, - PreferredHeight = 650, - CreateControl = () => + CreateForm = () => { var view = new PolyTraderSharp.Ui.Views.TerminalView(); view.Initialize(viewServices.GetRequiredService()); @@ -153,9 +151,7 @@ internal static class Program Title = "Server Settings", Group = "Core", Order = 20, - PreferredWidth = 720, - PreferredHeight = 720, - CreateControl = () => + CreateForm = () => { var view = new PolyTraderSharp.Ui.Views.SettingsView(); view.Initialize( @@ -171,9 +167,7 @@ internal static class Program Title = "Server Jobs", Group = "Core", Order = 30, - PreferredWidth = 1000, - PreferredHeight = 500, - CreateControl = () => + CreateForm = () => { var view = new PolyTraderSharp.Ui.Views.JobsView(); view.Initialize(viewServices.GetRequiredService()); @@ -186,9 +180,7 @@ internal static class Program Title = "Dashboard", Group = "Core", Order = 5, - PreferredWidth = 1200, - PreferredHeight = 650, - CreateControl = () => + CreateForm = () => { var view = new PolyTraderSharp.Ui.Views.DashboardView(); view.Initialize( diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index b005fbd..91ec227 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -100,6 +100,16 @@ namespace PolyTraderSharp.Properties { } } + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap dashboard { + get { + object obj = ResourceManager.GetObject("dashboard", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index cad3e1e..f13c12e 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -118,20 +118,26 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\system_time.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\diskette.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\money.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\traffic_lights_green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\money_add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\token_quantifier.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\traffic_lights_green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\error_log.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\cancel.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -145,9 +151,6 @@ ..\Resources\coins_in_hand.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\error_log.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -172,7 +175,7 @@ ..\Resources\money_dollar.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\system_time.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\dashboard.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/Resources/dashboard.png b/Resources/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..12961f037de51ea528dbaa32fd601b360f574329 GIT binary patch literal 2348 zcmaJ@c|4T+9v&*miENic()5xo=AB_|lO<+`MuslR*2S24F_?Mh&WvWVoP;TJ?4@(; zp>kZ3(xQ(+SdMB7_o&^TLr92$fC_5ku| zY+4k~kKpkwmi*)l#BjMR90>AwJQU9c1+$|;jH9C?h_(i;t*zt;E6zS9m%_JVa*UQ0 z2oQ(Lrn9(on2B6cq(s6ATxUR@>7OMqSl?xtoNsNCHw@%cSRe+4UMguBNGAV(D1-4G z&Efh%f93l>g*gHHSPY zqA7K_0UF%ASY(cK1P z>yCA>v31AWFLMbnHGu&!xyxMIUtF6Xa+j>YV96sBAU1t3MDt+74CL36ar7VOg8rf2 zH!khRxnO?C1?9``yYV5W-0f_+tv`$v%^(n~DoF&l0RG5y z;7#9vXzed!?;IGO8e4$l1KTvzHM-nZy^Oery^u%L#bU_3hBx8QYeb?G^(gNWtS!pB zh1o*CjwL@(Qiv|n=<-7s&FP$IJ!pL^O+WEUXHPPxefCq|tkWz}ma-9) z9iC5X{C#DZW`4!ni0L3pO|?VqCu$sbcpb9s+(se^he|6d4l+tAe`x_pF?XWQO&BK~ zF8-31`heT?{!&d{AW+a<^=t2nTBn@?`-NAXqtliWX>?arb#-Jsh!Sny>gIly*x8|(&%&hrb>}-`R7+h2Z4F5+vFjwoXI<%e|hs|UOn%S;ZI%H))sU# z!j1+O9+yN|)y2i4?Obwaww4El^^UfU&3_c1f914A!CWWKa-w>DifT?yRZHjF#kU?? z4M%4Mb#=xndWDZ$Pzy6-TeLkqJ*&)AG-Qt)P{I`tlcZzk+`*&UpYFDNz0IE33Q8=l}fy9J-QZPYdq2zLmhWMmSv_+MIv;nT7vUMb%qlJKljdLH0&CHjNs5ssEP^2G3rHpMRVz zmgdves1UdHYuA>j1RoX5mCVi?9(#Q5RA)o*x0yW{MvbqscQ=by?f+tHG-Ll+c&oKDGC3@_8uGgO_4!xi}T5BDD!5^6=n%bdsh z2mbCWUihHhopVFqRUGUm!!!P|fjQA?j)463PAN-6O~^h%pm7x=MMDR5=QTlpF>>wr zlZk8%SB}z^e`!l3k`Ya3VSRF|x-D5;6;YMVkxKDnlP272h~+aNUfy$6AmF({E+eU&(HTC z-fmLwps4RwD04GJTL^-Upz`dOD?={tcWsG#G1sG5Zd`WE)Gsr-BJww<&*JlD`X=6* zS=A9@yJw?1_8=F6OqcXV#%?`{ z5A!IJ?I({YlqW`Qzbxf6opVn7%ZWwk`vuWJdw)nnpQu%F-|EQkL)OgYb z1BJo8(<@WjCpgWa2IF(Jg?293^kbSInT!*%yDx_G!(0ZVG)KZd)&FZQ1%v=%*66%f9XD+vgeq+#j*g+%lr JoOX{$`wvNo;*bCU literal 0 HcmV?d00001 diff --git a/Ui/LauncherForm.Designer.cs b/Ui/LauncherForm.Designer.cs index 4fe2fe7..3b320a7 100644 --- a/Ui/LauncherForm.Designer.cs +++ b/Ui/LauncherForm.Designer.cs @@ -22,10 +22,10 @@ namespace PolyTraderSharp.Ui miLegacy = new ToolStripMenuItem(); miBeenden = new ToolStripMenuItem(); toolstrip_windows = new ToolStrip(); + btn_dashboard = new ToolStripButton(); btn_settings = new ToolStripButton(); btn_terminal = new ToolStripButton(); btn_jobs = new ToolStripButton(); - btn_dashboard = new ToolStripButton(); toolstrip_quickbar = new ToolStrip(); btn_liveTrading = new ToolStripButton(); btn_demoTrading = new ToolStripButton(); @@ -72,13 +72,23 @@ namespace PolyTraderSharp.Ui // toolstrip_windows.AutoSize = false; toolstrip_windows.ImageScalingSize = new Size(64, 64); - toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_settings, btn_terminal, btn_jobs, btn_dashboard }); + toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_dashboard, btn_settings, btn_terminal, btn_jobs }); toolstrip_windows.Location = new Point(0, 35); toolstrip_windows.Name = "toolstrip_windows"; toolstrip_windows.Size = new Size(2599, 70); toolstrip_windows.TabIndex = 3; toolstrip_windows.Text = "toolStrip1"; // + // btn_dashboard + // + btn_dashboard.Image = Properties.Resources.dashboard; + btn_dashboard.ImageScaling = ToolStripItemImageScaling.None; + btn_dashboard.Name = "btn_dashboard"; + btn_dashboard.Overflow = ToolStripItemOverflow.Never; + btn_dashboard.Size = new Size(104, 65); + btn_dashboard.Text = "Dashboard"; + btn_dashboard.TextImageRelation = TextImageRelation.ImageAboveText; + // // btn_settings // btn_settings.BackColor = SystemColors.Control; @@ -107,13 +117,6 @@ namespace PolyTraderSharp.Ui btn_jobs.Size = new Size(106, 65); btn_jobs.Text = "Server Jobs"; btn_jobs.TextImageRelation = TextImageRelation.ImageAboveText; - // - // btn_dashboard - // - btn_dashboard.DisplayStyle = ToolStripItemDisplayStyle.Text; - btn_dashboard.Name = "btn_dashboard"; - btn_dashboard.Size = new Size(110, 65); - btn_dashboard.Text = "Dashboard"; // // toolstrip_quickbar // @@ -144,7 +147,7 @@ namespace PolyTraderSharp.Ui statusStrip_info.BackColor = Color.Gainsboro; statusStrip_info.ImageScalingSize = new Size(24, 24); statusStrip_info.Items.AddRange(new ToolStripItem[] { lbl_trading, lbl_modules, lbl_ratelimit }); - statusStrip_info.Location = new Point(0, 133); + statusStrip_info.Location = new Point(0, 140); statusStrip_info.Name = "statusStrip_info"; statusStrip_info.Size = new Size(2599, 32); statusStrip_info.TabIndex = 5; @@ -172,11 +175,12 @@ namespace PolyTraderSharp.Ui // AutoScaleDimensions = new SizeF(10F, 25F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(2599, 165); + ClientSize = new Size(2599, 172); Controls.Add(statusStrip_info); Controls.Add(toolstrip_quickbar); Controls.Add(toolstrip_windows); Controls.Add(menuStrip); + FormBorderStyle = FormBorderStyle.FixedSingle; MainMenuStrip = menuStrip; Margin = new Padding(4, 5, 4, 5); Name = "LauncherForm"; diff --git a/Ui/LauncherForm.cs b/Ui/LauncherForm.cs index d6260c3..f610a7c 100644 --- a/Ui/LauncherForm.cs +++ b/Ui/LauncherForm.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using Microsoft.Extensions.DependencyInjection; @@ -19,6 +20,7 @@ namespace PolyTraderSharp.Ui private readonly IServiceProvider _services; private readonly TradingState _state; private readonly System.Windows.Forms.Timer _statusTimer = new() { Interval = 1000 }; + private readonly Dictionary _viewButtons; private frm_main? _legacyForm; public LauncherForm(ShellUiHost uiHost, IServiceProvider services) @@ -29,19 +31,40 @@ namespace PolyTraderSharp.Ui InitializeComponent(); - btn_settings.Click += (_, _) => OpenView("core.settings"); - btn_terminal.Click += (_, _) => OpenView("core.terminal"); - btn_jobs.Click += (_, _) => OpenView("core.jobs"); - btn_dashboard.Click += (_, _) => OpenView("core.dashboard"); + // Fenster-Buttons an stabile View-IDs binden (Views werden per DI registriert). + _viewButtons = new Dictionary + { + ["core.dashboard"] = btn_dashboard, + ["core.settings"] = btn_settings, + ["core.terminal"] = btn_terminal, + ["core.jobs"] = btn_jobs, + }; + foreach (var (id, btn) in _viewButtons) + { + var viewId = id; + btn.Click += (_, _) => _uiHost.OpenView(viewId); + } + btn_liveTrading.Click += (_, _) => CycleLiveTrading(); btn_demoTrading.Click += (_, _) => CycleDemoTrading(); miLegacy.Click += (_, _) => OpenLegacy(); miBeenden.Click += (_, _) => Close(); + // Offen-Status der Fenster spiegeln (Button „checked", wenn Fenster offen). + _uiHost.OpenStateChanged += UpdateWindowButtonStates; + _statusTimer.Tick += (_, _) => UpdateStatus(); _statusTimer.Start(); UpdateStatus(); UpdateTradingToggles(); + UpdateWindowButtonStates(); + } + + private void UpdateWindowButtonStates() + { + if (IsDisposed) return; + foreach (var (id, btn) in _viewButtons) + btn.Checked = _uiHost.IsOpen(id); } private void CycleLiveTrading() @@ -91,17 +114,6 @@ namespace PolyTraderSharp.Ui } } - /// Öffnet die Ansicht mit der angegebenen ID (bzw. fokussiert das offene Fenster). - private void OpenView(string viewId) - { - var view = _uiHost.Views.FirstOrDefault(v => v.Id == viewId); - if (view != null) - _uiHost.OpenView(view); - else - MessageBox.Show($"Ansicht '{viewId}' ist (noch) nicht registriert.", "Hinweis", - MessageBoxButtons.OK, MessageBoxIcon.Information); - } - private void UpdateStatus() { string trading = _state.GlobalTradingPaused @@ -116,6 +128,7 @@ namespace PolyTraderSharp.Ui // Toggle-Buttons mit externem State synchron halten (z.B. Änderungen aus der Legacy-UI). UpdateTradingToggles(); + UpdateWindowButtonStates(); } private void OpenLegacy() diff --git a/Ui/ShellUiHost.cs b/Ui/ShellUiHost.cs index a501509..98faf55 100644 --- a/Ui/ShellUiHost.cs +++ b/Ui/ShellUiHost.cs @@ -1,22 +1,38 @@ +using System; using System.Collections.Generic; +using System.Linq; using System.Windows.Forms; using PolyTrader.Core.Modularity; namespace PolyTraderSharp.Ui { /// - /// Sammelt die von Core-App und Modulen registrierten Views und öffnet sie als - /// eigenständige Host-Fenster (Einzelinstanz je View). + /// Verwaltet die registrierten Fenster-Views: öffnet sie als eigenständige Forms, + /// hält je View höchstens eine Instanz offen und holt ein bereits offenes Fenster + /// wieder in den Vordergrund. Meldet Änderungen am Offen-Status (für die + /// Button-Markierung im Launcher). /// public class ShellUiHost : IModuleUiHost { private readonly List _views = new(); - private readonly Dictionary _open = new(); + private readonly Dictionary _open = new(); + + /// Wird ausgelöst, wenn sich der Offen-Status irgendeiner View ändert. + public event Action? OpenStateChanged; public IReadOnlyList Views => _views; public void RegisterView(ModuleView view) => _views.Add(view); + public bool IsOpen(string viewId) => + _open.TryGetValue(viewId, out var form) && !form.IsDisposed; + + public void OpenView(string viewId) + { + var view = _views.FirstOrDefault(v => v.Id == viewId); + if (view != null) OpenView(view); + } + public void OpenView(ModuleView view) { if (_open.TryGetValue(view.Id, out var existing) && !existing.IsDisposed) @@ -28,10 +44,19 @@ namespace PolyTraderSharp.Ui return; } - var host = new ViewHostForm(view); - host.FormClosed += (_, _) => _open.Remove(view.Id); - _open[view.Id] = host; - host.Show(); + var form = view.CreateForm(); + if (string.IsNullOrEmpty(form.Text) || form.Text == form.Name) + form.Text = view.Title; + + _open[view.Id] = form; + form.FormClosed += (_, _) => + { + _open.Remove(view.Id); + OpenStateChanged?.Invoke(); + }; + + form.Show(); + OpenStateChanged?.Invoke(); } } } diff --git a/Ui/ViewHostForm.cs b/Ui/ViewHostForm.cs deleted file mode 100644 index 4bb5443..0000000 --- a/Ui/ViewHostForm.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Windows.Forms; -using PolyTrader.Core.Modularity; - -namespace PolyTraderSharp.Ui -{ - /// - /// Generisches Host-Fenster für genau eine . Erzeugt das - /// (designbare) Control der View und dockt es formfüllend. Die Shell öffnet je View - /// höchstens eine Instanz (siehe ). - /// - public class ViewHostForm : Form - { - public string ViewId { get; } - - public ViewHostForm(ModuleView view) - { - ViewId = view.Id; - Text = view.Title; - Width = view.PreferredWidth; - Height = view.PreferredHeight; - StartPosition = FormStartPosition.CenterScreen; - - var control = view.CreateControl(); - control.Dock = DockStyle.Fill; - Controls.Add(control); - } - } -} diff --git a/Ui/Views/DashboardView.Designer.cs b/Ui/Views/DashboardView.Designer.cs index 428f1bd..fdb11b1 100644 --- a/Ui/Views/DashboardView.Designer.cs +++ b/Ui/Views/DashboardView.Designer.cs @@ -173,8 +173,9 @@ namespace PolyTraderSharp.Ui.Views this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.dgvTrades); this.Controls.Add(this.pnlTop); + this.ClientSize = new System.Drawing.Size(1200, 650); this.Name = "DashboardView"; - this.Size = new System.Drawing.Size(1100, 600); + this.Text = "Dashboard"; this.pnlTop.ResumeLayout(false); this.pnlTop.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.dgvTrades)).EndInit(); diff --git a/Ui/Views/DashboardView.cs b/Ui/Views/DashboardView.cs index a1bbcc6..ddeb3d2 100644 --- a/Ui/Views/DashboardView.cs +++ b/Ui/Views/DashboardView.cs @@ -11,7 +11,7 @@ namespace PolyTraderSharp.Ui.Views /// generischen Core-Trade-Log (ITradeLogRepository) und eine Kurzauswertung. /// Designbar (DashboardView.Designer.cs). /// - public partial class DashboardView : UserControl + public partial class DashboardView : Form { private ITradeLogRepository? _tradeLog; private TradingState? _state; diff --git a/Ui/Views/JobsView.Designer.cs b/Ui/Views/JobsView.Designer.cs index 0c49b9f..5d50296 100644 --- a/Ui/Views/JobsView.Designer.cs +++ b/Ui/Views/JobsView.Designer.cs @@ -109,8 +109,9 @@ namespace PolyTraderSharp.Ui.Views this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.dgvJobs); + this.ClientSize = new System.Drawing.Size(1000, 500); this.Name = "JobsView"; - this.Size = new System.Drawing.Size(900, 500); + this.Text = "Server Jobs"; ((System.ComponentModel.ISupportInitialize)(this.dgvJobs)).EndInit(); this.ResumeLayout(false); } diff --git a/Ui/Views/JobsView.cs b/Ui/Views/JobsView.cs index 42392d1..c3e0c35 100644 --- a/Ui/Views/JobsView.cs +++ b/Ui/Views/JobsView.cs @@ -10,7 +10,7 @@ namespace PolyTraderSharp.Ui.Views /// Verhalten wie der bisherige Jobs-Tab: „Run Now" löst den ManualTrigger aus, /// „Aktiv" schaltet den Job über die Bindung. /// - public partial class JobsView : UserControl + public partial class JobsView : Form { public JobsView() { diff --git a/Ui/Views/JobsView.resx b/Ui/Views/JobsView.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Ui/Views/JobsView.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Ui/Views/SettingsView.Designer.cs b/Ui/Views/SettingsView.Designer.cs index 4031f18..7eb9303 100644 --- a/Ui/Views/SettingsView.Designer.cs +++ b/Ui/Views/SettingsView.Designer.cs @@ -66,8 +66,9 @@ namespace PolyTraderSharp.Ui.Views this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.propertyGrid); this.Controls.Add(this.pnlTop); + this.ClientSize = new System.Drawing.Size(720, 720); this.Name = "SettingsView"; - this.Size = new System.Drawing.Size(700, 600); + this.Text = "Server Settings"; this.pnlTop.ResumeLayout(false); this.ResumeLayout(false); } diff --git a/Ui/Views/SettingsView.cs b/Ui/Views/SettingsView.cs index 0292e7b..3b125f7 100644 --- a/Ui/Views/SettingsView.cs +++ b/Ui/Views/SettingsView.cs @@ -10,7 +10,7 @@ namespace PolyTraderSharp.Ui.Views /// Designbar (siehe SettingsView.Designer.cs); Laufzeit-Abhängigkeiten via Initialize. /// Verhalten entspricht dem bisherigen Settings-Tab (Speichern -> XML + Services neu laden). /// - public partial class SettingsView : UserControl + public partial class SettingsView : Form { private const string SettingsPath = "server_settings.xml"; diff --git a/Ui/Views/TerminalView.Designer.cs b/Ui/Views/TerminalView.Designer.cs index e61c513..ae0035e 100644 --- a/Ui/Views/TerminalView.Designer.cs +++ b/Ui/Views/TerminalView.Designer.cs @@ -90,8 +90,9 @@ namespace PolyTraderSharp.Ui.Views this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.rtbTerminal); this.Controls.Add(this.pnlTop); + this.ClientSize = new System.Drawing.Size(1000, 650); this.Name = "TerminalView"; - this.Size = new System.Drawing.Size(900, 500); + this.Text = "Terminal / Logs"; this.pnlTop.ResumeLayout(false); this.pnlTop.PerformLayout(); this.ResumeLayout(false); diff --git a/Ui/Views/TerminalView.cs b/Ui/Views/TerminalView.cs index 3598ec0..5d3e0ec 100644 --- a/Ui/Views/TerminalView.cs +++ b/Ui/Views/TerminalView.cs @@ -10,7 +10,7 @@ namespace PolyTraderSharp.Ui.Views /// Abhängigkeit (TerminalLogger) wird per injiziert, damit der /// parameterlose Konstruktor für den VS-Designer nutzbar bleibt. /// - public partial class TerminalView : UserControl + public partial class TerminalView : Form { private TerminalLogger? _logger; private readonly ConcurrentQueue _logQueue = new(); diff --git a/src/PolyTrader.Core/Modularity/ModuleUi.cs b/src/PolyTrader.Core/Modularity/ModuleUi.cs index e6083fc..1aafffd 100644 --- a/src/PolyTrader.Core/Modularity/ModuleUi.cs +++ b/src/PolyTrader.Core/Modularity/ModuleUi.cs @@ -4,35 +4,32 @@ using System.Windows.Forms; namespace PolyTrader.Core.Modularity { /// - /// Eine vom Core oder einem Modul beigesteuerte UI-Ansicht. Die Shell entscheidet, - /// wie sie präsentiert wird (aktuell: eigenständiges Host-Fenster über den Launcher). - /// Die eigentliche UI ist ein designbares (i.d.R. ein UserControl), - /// das über erzeugt wird (mit DI-Abhängigkeiten). + /// Eine vom Core oder einem Modul beigesteuerte Fenster-Ansicht. Die eigentliche UI ist + /// ein designbares , das über erzeugt wird + /// (mit DI-Abhängigkeiten). Die Shell zeigt je View höchstens eine Instanz und holt ein + /// bereits offenes Fenster wieder in den Vordergrund. /// public sealed class ModuleView { /// Stabile ID für Einzelinstanz-Handling (nur ein Fenster je View). public string Id { get; init; } = Guid.NewGuid().ToString(); - /// Titel für Launcher-Eintrag und Fenstertitel. - public string Title { get; init; } = "View"; + /// Titel (Fallback-Fenstertitel, falls das Form keinen eigenen setzt). + public string Title { get; init; } = "Fenster"; - /// Optionale Gruppierung im Launcher (z.B. "Core", "CopyTrading"). + /// Optionale Gruppierung (z.B. "Core", "CopyTrading"). public string? Group { get; init; } - /// Optionale Sortierreihenfolge im Launcher. + /// Optionale Sortierreihenfolge. public int Order { get; init; } = 0; - /// Erzeugt das anzuzeigende Control (frische Instanz je Fensteröffnung). - public Func CreateControl { get; init; } = () => new Control(); - - public int PreferredWidth { get; init; } = 900; - public int PreferredHeight { get; init; } = 600; + /// Erzeugt das anzuzeigende Fenster (frische Instanz je Öffnung). + public Func
CreateForm { get; init; } = () => new Form(); } /// /// Wird der Shell beim Start übergeben; Core und Module registrieren hier ihre Ansichten. - /// Der Launcher rendert daraus seine Einträge und öffnet je View ein Host-Fenster. + /// Die Shell (Launcher) öffnet die Fenster auf Anforderung und verwaltet den Offen-Status. /// public interface IModuleUiHost {