From f112668147e97921d07f17c1e2a85df2bd6319f6 Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 2 Jul 2026 11:44:47 +0200 Subject: [PATCH] Phase 5-UI: Launcher auf Toolstrip-Modell + SettingsView (Designer-first) - LauncherForm: lstView-Ansatz entfernt (lstViews/colName/pnlBottom/btnOpen raus). Fenster werden ueber toolstrip_windows-Buttons geoeffnet/fokussiert: btn_settings -> Settings, btn_terminal -> Terminal (Bindung per stabiler View-ID). - statusStrip_info: Live-Status (Trading, Modul-Anzahl, API WSS/Polling) via 1s-Timer. - toolstrip_quickbar bleibt fuer Schnellaktionen (Trading an/aus) reserviert. - Neue SettingsView (UserControl + Designer): ServerSettings-PropertyGrid + Speichern/Neu laden; Verhalten wie bisheriger Settings-Tab. In Program.cs registriert. - Build 0 Fehler. Co-Authored-By: Claude Opus 4.8 --- Program.cs | 18 +++ Properties/Resources.Designer.cs | 26 ++-- Properties/Resources.resx | 7 +- Resources/setting_tools.png | Bin 0 -> 2315 bytes Ui/LauncherForm.Designer.cs | 196 ++++++++++++++++++------------ Ui/LauncherForm.cs | 66 +++++----- Ui/LauncherForm.resx | 69 +++++++---- Ui/Views/SettingsView.Designer.cs | 82 +++++++++++++ Ui/Views/SettingsView.cs | 61 ++++++++++ 9 files changed, 378 insertions(+), 147 deletions(-) create mode 100644 Resources/setting_tools.png create mode 100644 Ui/Views/SettingsView.Designer.cs create mode 100644 Ui/Views/SettingsView.cs diff --git a/Program.cs b/Program.cs index 112e2c2..69da252 100644 --- a/Program.cs +++ b/Program.cs @@ -143,6 +143,24 @@ internal static class Program return view; } }); + uiHost.RegisterView(new PolyTrader.Core.Modularity.ModuleView + { + Id = "core.settings", + Title = "Server Settings", + Group = "Core", + Order = 20, + PreferredWidth = 720, + PreferredHeight = 720, + CreateControl = () => + { + var view = new PolyTraderSharp.Ui.Views.SettingsView(); + view.Initialize( + viewServices.GetRequiredService(), + viewServices.GetRequiredService(), + viewServices.GetRequiredService()); + return view; + } + }); // TODO Phase 5-UI: registrierte IPolyTraderModule durchlaufen und module.RegisterUi(uiHost) aufrufen. var launcher = AppHost.Services.GetRequiredService(); diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index f72d07d..386f5ab 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -1,11 +1,9 @@ -using MongoDB.Driver; -using PolyTraderSharp.Extensions; -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Dieser Code wurde von einem Tool generiert. // Laufzeitversion:4.0.30319.42000 // -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // der Code erneut generiert wird. // //------------------------------------------------------------------------------ @@ -18,10 +16,10 @@ namespace PolyTraderSharp.Properties { /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. /// // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -35,7 +33,7 @@ namespace PolyTraderSharp.Properties { } /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { @@ -49,7 +47,7 @@ namespace PolyTraderSharp.Properties { } /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] @@ -172,6 +170,16 @@ namespace PolyTraderSharp.Properties { } } + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap setting_tools { + get { + object obj = ResourceManager.GetObject("setting_tools", 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 042b0f6..c6f6195 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -118,6 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\stop.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 @@ -163,7 +166,7 @@ ..\Resources\accept_button.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\stop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\setting_tools.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/setting_tools.png b/Resources/setting_tools.png new file mode 100644 index 0000000000000000000000000000000000000000..2a1e72744479f7980973cc388a14300bb0a4bef4 GIT binary patch literal 2315 zcmV+m3H0`fP)Ran$O@M`*`EZE8B1X%mg1D)>ymAr_M{CaIk`W%965Q81mxv`xZe zQKX=gqVirrfqgH#?C#z7tLMMDo2-b)w7oNDcK6=@{@-_A-}#pZQ@plq-w~OZka$8Q z5)~&TB#4q{B*C<4(}1RFkl(upJw3g$lYe+~B`)0EEC!8613Vr+ z@Oo?Q4#xpp*N^M`WMAGCu;~M3hyExK2zE&~Zh-l@Il!YRP$-qq+WIg2R6$=~U*mhH zPwl|9hVtWY_9Z1GCM;XN6vT0H;P?9xoCi*)6Z-q_!PoT-pim5Fo_YVhK0<>3B=CI) z%4+iS@(_DH3v6YqP~X@DvgT&!>g=p!7|U?8tf>Xpy5Fd%?3*`tZbD(<66m;n7p`A# z1&jo1@zdiWH#-ZGlat_svw!Zv^&&LqWCZB_r3Y*B3-Y9!q#I#$)Bpyf5gHJ@x3^dS zR@I3uxJHL&Mq~Dt?0(Ei527iwbg!!*?`v zVoe6N1c>)Sp&-~}?L?s-AAwLFkK(`w5!{5;>j0<2 z33~k~7T$H(^qiDzzK*O7evuI1(|oqAz6IyAHSnZHqsA3ob$;FgP^#20Hf9F9!vzk9 z1MGwZwvk4wgRklvSun1Ozq`C1muhfu0OGOl1p+>jK;zTk_xUCzKo9~4v`FApIF%;&G0||ZrHPSCA6s+XdhBRidzM*X82%8qlf0}EsDs<$QZ1Y&}m^|=!}I0!=i5a;7@1v z;nxRT8@qU1D@LKEAc?nU&(0`JPELl7jt)3fw*P6oujfRBlyuD2&6|()F50!`x6dwv zyE;3l83(xi6x_Tw2h{R2Dn9eSYwuMTAFzY}f#e zZj~ZC1j$}lF%YJ@gRyv;>U}5>D}4s*?IjH>wgSa z2D#niBz=C@aT#4Xb{Q!KmEgK|~d6~1~#hHJvZ>XINc%leQC{(fg&KEDr zoLl|!@`dolIB+k5t8q?v3=iN`o&ac`4}O%t0CxVh58CxUFqzF)bjQ|h;qnhtk>ZD* z#gv@ezI=X8b=k8E;cCBu&3Q1m&TNEXtr8@+s{d)wsX>4Ov+=`r7^5QKFWZ;GvUzD6 z;||tc92e=wrr;s)=-18_uUI(0diRQKxNz6NR=d~#J-FU%0Ht~aj31U2-ERK!YM4+k z>u-YWG(mhC{C-sq{6lVmUo1!lwbd)pNmk|BWEU3z>hAgyZB;Zfpl$dGFC2@7 z>3(bk=;+egnmwx*OMjY~2p79XLGw89Pb;?A?l!mKJL*8E@N!lZT{Ay7uXfP7m2_iv1 z?viW|Uzi#qie%$!cTG+rK!6sP)t=q;lSM@<(ep>au`d}5C{z!?*?H}_{?qc0IDv8m zc|%CJnH!(AhU6@fxM^XkF!aeJ0tBYTu6f~N>FNboaKYey)^i3ABqPcJaNLnq=+7Vj zm;<+uE2{4lbutn!APKF_C(&oG&a*b1uL-oFXpT4vAK=cI^KV=2d+_@s{oppJWe9$b zlUOSUIR5em6jXI`=N?AUBhzY!!HU9bMI{(EIpA`)5lU8N;U5A4d#VZ$pwt!{P&k$d zII&=G&!|eKs@nbvm-EMgPfEguBy31R$++N^+FQV5j7?;~1yT^kEBN`AteJ698ap4H zxP=*y;X{ghsB)@i)yW-uaLq6`l)O{;H|2jM9sH0~QCKvx8iEmdr%Y2-{4zct4d?(S z3NjMPF4yuzVJUc`W{*x@?eG_>Q@ajwL&-QraF}4gr6j)g(P^PL`5BjPq(xO#{5x*X zu>b)w>toSoaFdYYMy8P~xUtFfe2OFjQ`XGY5$jN}5(>C;nvhdSAJ=B~|HAV})RjBN l3pmH@|ARyS-|IgD3;=X$f&6|~5VHUP002ovPDHLkV1lF~V^078 literal 0 HcmV?d00001 diff --git a/Ui/LauncherForm.Designer.cs b/Ui/LauncherForm.Designer.cs index a1e8c99..ef6838c 100644 --- a/Ui/LauncherForm.Designer.cs +++ b/Ui/LauncherForm.Designer.cs @@ -17,102 +17,140 @@ namespace PolyTraderSharp.Ui private void InitializeComponent() { - this.menuStrip = new System.Windows.Forms.MenuStrip(); - this.miDatei = new System.Windows.Forms.ToolStripMenuItem(); - this.miLegacy = new System.Windows.Forms.ToolStripMenuItem(); - this.miBeenden = new System.Windows.Forms.ToolStripMenuItem(); - this.lstViews = new System.Windows.Forms.ListView(); - this.colName = new System.Windows.Forms.ColumnHeader(); - this.pnlBottom = new System.Windows.Forms.Panel(); - this.btnOpen = new System.Windows.Forms.Button(); - this.menuStrip.SuspendLayout(); - this.pnlBottom.SuspendLayout(); - this.SuspendLayout(); + menuStrip = new MenuStrip(); + miDatei = new ToolStripMenuItem(); + miLegacy = new ToolStripMenuItem(); + miBeenden = new ToolStripMenuItem(); + toolstrip_windows = new ToolStrip(); + btn_settings = new ToolStripButton(); + btn_terminal = new ToolStripButton(); + toolstrip_quickbar = new ToolStrip(); + statusStrip_info = new StatusStrip(); + lbl_trading = new ToolStripStatusLabel(); + lbl_modules = new ToolStripStatusLabel(); + lbl_ratelimit = new ToolStripStatusLabel(); + menuStrip.SuspendLayout(); + toolstrip_windows.SuspendLayout(); + statusStrip_info.SuspendLayout(); + SuspendLayout(); // // menuStrip // - this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.miDatei}); - this.menuStrip.Location = new System.Drawing.Point(0, 0); - this.menuStrip.Name = "menuStrip"; - this.menuStrip.Size = new System.Drawing.Size(360, 24); - this.menuStrip.TabIndex = 0; + menuStrip.ImageScalingSize = new Size(24, 24); + menuStrip.Items.AddRange(new ToolStripItem[] { miDatei }); + menuStrip.Location = new Point(0, 0); + menuStrip.Name = "menuStrip"; + menuStrip.Padding = new Padding(9, 3, 0, 3); + menuStrip.Size = new Size(2599, 35); + menuStrip.TabIndex = 0; // // miDatei // - this.miDatei.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.miLegacy, - this.miBeenden}); - this.miDatei.Name = "miDatei"; - this.miDatei.Text = "Datei"; + miDatei.DropDownItems.AddRange(new ToolStripItem[] { miLegacy, miBeenden }); + miDatei.Name = "miDatei"; + miDatei.Size = new Size(69, 29); + miDatei.Text = "Datei"; // // miLegacy // - this.miLegacy.Name = "miLegacy"; - this.miLegacy.Text = "Legacy-UI (alte Tabs)"; + miLegacy.Name = "miLegacy"; + miLegacy.Size = new Size(275, 34); + miLegacy.Text = "Legacy-UI (alte Tabs)"; // // miBeenden // - this.miBeenden.Name = "miBeenden"; - this.miBeenden.Text = "Beenden"; + miBeenden.Name = "miBeenden"; + miBeenden.Size = new Size(275, 34); + miBeenden.Text = "Beenden"; // - // lstViews + // toolstrip_windows // - this.lstViews.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.colName}); - this.lstViews.Dock = System.Windows.Forms.DockStyle.Fill; - this.lstViews.FullRowSelect = true; - this.lstViews.HideSelection = false; - this.lstViews.Location = new System.Drawing.Point(0, 24); - this.lstViews.MultiSelect = false; - this.lstViews.Name = "lstViews"; - this.lstViews.Size = new System.Drawing.Size(360, 420); - this.lstViews.TabIndex = 1; - this.lstViews.UseCompatibleStateImageBehavior = false; - this.lstViews.View = System.Windows.Forms.View.Details; + toolstrip_windows.AutoSize = false; + toolstrip_windows.ImageScalingSize = new Size(64, 64); + toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_settings, btn_terminal }); + 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"; // - // colName + // btn_settings // - this.colName.Text = "Ansicht"; - this.colName.Width = 330; + btn_settings.BackColor = SystemColors.Control; + btn_settings.Image = Properties.Resources.setting_tools; + btn_settings.ImageScaling = ToolStripItemImageScaling.None; + btn_settings.ImageTransparentColor = Color.Magenta; + btn_settings.Name = "btn_settings"; + btn_settings.Size = new Size(112, 65); + btn_settings.Text = "Settings"; + btn_settings.TextImageRelation = TextImageRelation.ImageAboveText; // - // pnlBottom + // btn_terminal // - this.pnlBottom.Controls.Add(this.btnOpen); - this.pnlBottom.Dock = System.Windows.Forms.DockStyle.Bottom; - this.pnlBottom.Location = new System.Drawing.Point(0, 444); - this.pnlBottom.Name = "pnlBottom"; - this.pnlBottom.Size = new System.Drawing.Size(360, 44); - this.pnlBottom.TabIndex = 2; + btn_terminal.DisplayStyle = ToolStripItemDisplayStyle.Text; + btn_terminal.Name = "btn_terminal"; + btn_terminal.Size = new Size(112, 65); + btn_terminal.Text = "Terminal"; // - // btnOpen + // toolstrip_quickbar // - this.btnOpen.Location = new System.Drawing.Point(12, 8); - this.btnOpen.Name = "btnOpen"; - this.btnOpen.Size = new System.Drawing.Size(336, 30); - this.btnOpen.TabIndex = 0; - this.btnOpen.Text = "Öffnen"; - this.btnOpen.UseVisualStyleBackColor = true; + toolstrip_quickbar.ImageScalingSize = new Size(24, 24); + toolstrip_quickbar.Location = new Point(0, 105); + toolstrip_quickbar.Name = "toolstrip_quickbar"; + toolstrip_quickbar.Size = new Size(2599, 25); + toolstrip_quickbar.TabIndex = 4; + toolstrip_quickbar.Text = "toolStrip2"; + // + // statusStrip_info + // + 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, 924); + statusStrip_info.Name = "statusStrip_info"; + statusStrip_info.Size = new Size(2599, 22); + statusStrip_info.TabIndex = 5; + statusStrip_info.Text = "statusStrip1"; + // + // lbl_trading + // + lbl_trading.Name = "lbl_trading"; + lbl_trading.Size = new Size(100, 16); + lbl_trading.Text = "Trading: —"; + // + // lbl_modules + // + lbl_modules.Name = "lbl_modules"; + lbl_modules.Size = new Size(90, 16); + lbl_modules.Text = "Module: —"; + // + // lbl_ratelimit + // + lbl_ratelimit.Name = "lbl_ratelimit"; + lbl_ratelimit.Size = new Size(80, 16); + lbl_ratelimit.Text = "API: —"; // // LauncherForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(360, 488); - this.Controls.Add(this.lstViews); - this.Controls.Add(this.pnlBottom); - this.Controls.Add(this.menuStrip); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MainMenuStrip = this.menuStrip; - this.MaximizeBox = false; - this.Name = "LauncherForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "PolyTrader"; - this.menuStrip.ResumeLayout(false); - this.menuStrip.PerformLayout(); - this.pnlBottom.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); + AutoScaleDimensions = new SizeF(10F, 25F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(2599, 946); + Controls.Add(statusStrip_info); + Controls.Add(toolstrip_quickbar); + Controls.Add(toolstrip_windows); + Controls.Add(menuStrip); + MainMenuStrip = menuStrip; + Margin = new Padding(4, 5, 4, 5); + Name = "LauncherForm"; + StartPosition = FormStartPosition.CenterScreen; + Text = "PolyTrader"; + menuStrip.ResumeLayout(false); + menuStrip.PerformLayout(); + toolstrip_windows.ResumeLayout(false); + toolstrip_windows.PerformLayout(); + statusStrip_info.ResumeLayout(false); + statusStrip_info.PerformLayout(); + ResumeLayout(false); + PerformLayout(); } #endregion @@ -121,9 +159,13 @@ namespace PolyTraderSharp.Ui private System.Windows.Forms.ToolStripMenuItem miDatei; private System.Windows.Forms.ToolStripMenuItem miLegacy; private System.Windows.Forms.ToolStripMenuItem miBeenden; - private System.Windows.Forms.ListView lstViews; - private System.Windows.Forms.ColumnHeader colName; - private System.Windows.Forms.Panel pnlBottom; - private System.Windows.Forms.Button btnOpen; + private ToolStrip toolstrip_windows; + private ToolStripButton btn_settings; + private ToolStripButton btn_terminal; + private ToolStrip toolstrip_quickbar; + private StatusStrip statusStrip_info; + private ToolStripStatusLabel lbl_trading; + private ToolStripStatusLabel lbl_modules; + private ToolStripStatusLabel lbl_ratelimit; } } diff --git a/Ui/LauncherForm.cs b/Ui/LauncherForm.cs index 32320d4..80b4ec5 100644 --- a/Ui/LauncherForm.cs +++ b/Ui/LauncherForm.cs @@ -7,58 +7,60 @@ using PolyTrader.Core.Modularity; namespace PolyTraderSharp.Ui { /// - /// Schlanke „Startleiste" der PolyTrader.App. Das Layout (ListView, Menü, Button) liegt - /// im Designer (LauncherForm.Designer.cs). Zur Laufzeit werden ausschließlich die - /// Listeneinträge (Daten) aus den registrierten Views befüllt — keine Steuerelemente. - /// Kennt selbst kein Modul. + /// „Startleiste" der PolyTrader.App. Fenster werden über die im Designer platzierten + /// Buttons in toolstrip_windows geöffnet bzw. in den Vordergrund geholt. + /// toolstrip_quickbar ist für Schnellaktionen (z.B. Trading an/aus) reserviert, + /// statusStrip_info zeigt Kernkennzahlen. Der Launcher kennt selbst kein Modul — + /// Buttons werden per stabiler View-ID an registrierte Views gebunden. /// public partial class LauncherForm : Form { private readonly ShellUiHost _uiHost; private readonly IServiceProvider _services; + private readonly TradingState _state; + private readonly System.Windows.Forms.Timer _statusTimer = new() { Interval = 1000 }; private frm_main? _legacyForm; public LauncherForm(ShellUiHost uiHost, IServiceProvider services) { _uiHost = uiHost; _services = services; + _state = services.GetRequiredService(); InitializeComponent(); - PopulateViews(); - lstViews.DoubleClick += (_, _) => OpenSelected(); - btnOpen.Click += (_, _) => OpenSelected(); + btn_settings.Click += (_, _) => OpenView("core.settings"); + btn_terminal.Click += (_, _) => OpenView("core.terminal"); miLegacy.Click += (_, _) => OpenLegacy(); miBeenden.Click += (_, _) => Close(); + + _statusTimer.Tick += (_, _) => UpdateStatus(); + _statusTimer.Start(); + UpdateStatus(); } - private void PopulateViews() + /// Öffnet die Ansicht mit der angegebenen ID (bzw. fokussiert das offene Fenster). + private void OpenView(string viewId) { - lstViews.BeginUpdate(); - lstViews.Groups.Clear(); - lstViews.Items.Clear(); - - foreach (var group in _uiHost.Views - .GroupBy(v => string.IsNullOrEmpty(v.Group) ? "Allgemein" : v.Group!) - .OrderBy(g => g.Key)) - { - var lvGroup = new ListViewGroup(group.Key) { Header = group.Key }; - lstViews.Groups.Add(lvGroup); - - foreach (var view in group.OrderBy(v => v.Order).ThenBy(v => v.Title)) - { - lstViews.Items.Add(new ListViewItem(view.Title, lvGroup) { Tag = view }); - } - } - - lstViews.EndUpdate(); - } - - private void OpenSelected() - { - if (lstViews.SelectedItems.Count == 0) return; - if (lstViews.SelectedItems[0].Tag is ModuleView view) + 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 + ? "Pausiert" + : $"Live={_state.LiveTradingMode} / Demo={_state.DemoTradingMode}"; + lbl_trading.Text = $"Trading: {trading}"; + + int moduleCount = _services.GetServices().Count(); + lbl_modules.Text = $"Module: {moduleCount}"; + + lbl_ratelimit.Text = $"API: {(_state.IsAlchemyHealthy ? "WSS aktiv" : "Polling")}"; } private void OpenLegacy() diff --git a/Ui/LauncherForm.resx b/Ui/LauncherForm.resx index 1af7de1..585575f 100644 --- a/Ui/LauncherForm.resx +++ b/Ui/LauncherForm.resx @@ -1,17 +1,17 @@  - @@ -117,4 +117,19 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 585, 0 + + + 733, 0 + + + 376, 0 + + + 944, 0 + + + 25 + \ No newline at end of file diff --git a/Ui/Views/SettingsView.Designer.cs b/Ui/Views/SettingsView.Designer.cs new file mode 100644 index 0000000..4031f18 --- /dev/null +++ b/Ui/Views/SettingsView.Designer.cs @@ -0,0 +1,82 @@ +namespace PolyTraderSharp.Ui.Views +{ + partial class SettingsView + { + private System.ComponentModel.IContainer components = null; + + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Vom Komponenten-Designer generierter Code + + private void InitializeComponent() + { + this.pnlTop = new System.Windows.Forms.Panel(); + this.btnReload = new System.Windows.Forms.Button(); + this.btnSave = new System.Windows.Forms.Button(); + this.propertyGrid = new System.Windows.Forms.PropertyGrid(); + this.pnlTop.SuspendLayout(); + this.SuspendLayout(); + // + // pnlTop + // + this.pnlTop.Controls.Add(this.btnReload); + this.pnlTop.Controls.Add(this.btnSave); + this.pnlTop.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTop.Location = new System.Drawing.Point(0, 0); + this.pnlTop.Name = "pnlTop"; + this.pnlTop.Size = new System.Drawing.Size(700, 44); + this.pnlTop.TabIndex = 0; + // + // btnReload + // + this.btnReload.Location = new System.Drawing.Point(140, 8); + this.btnReload.Name = "btnReload"; + this.btnReload.Size = new System.Drawing.Size(120, 28); + this.btnReload.TabIndex = 1; + this.btnReload.Text = "Neu laden"; + this.btnReload.UseVisualStyleBackColor = true; + // + // btnSave + // + this.btnSave.Location = new System.Drawing.Point(12, 8); + this.btnSave.Name = "btnSave"; + this.btnSave.Size = new System.Drawing.Size(120, 28); + this.btnSave.TabIndex = 0; + this.btnSave.Text = "Speichern"; + this.btnSave.UseVisualStyleBackColor = true; + // + // propertyGrid + // + this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.propertyGrid.Location = new System.Drawing.Point(0, 44); + this.propertyGrid.Name = "propertyGrid"; + this.propertyGrid.Size = new System.Drawing.Size(700, 556); + this.propertyGrid.TabIndex = 1; + // + // SettingsView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.propertyGrid); + this.Controls.Add(this.pnlTop); + this.Name = "SettingsView"; + this.Size = new System.Drawing.Size(700, 600); + this.pnlTop.ResumeLayout(false); + this.ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.Panel pnlTop; + private System.Windows.Forms.Button btnSave; + private System.Windows.Forms.Button btnReload; + private System.Windows.Forms.PropertyGrid propertyGrid; + } +} diff --git a/Ui/Views/SettingsView.cs b/Ui/Views/SettingsView.cs new file mode 100644 index 0000000..0292e7b --- /dev/null +++ b/Ui/Views/SettingsView.cs @@ -0,0 +1,61 @@ +using System; +using System.Windows.Forms; +using PolyTraderSharp.Models; +using PolyTraderSharp.Services; + +namespace PolyTraderSharp.Ui.Views +{ + /// + /// Core-Settings-Ansicht: bearbeitet die ServerSettings über ein PropertyGrid. + /// 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 + { + private const string SettingsPath = "server_settings.xml"; + + private ServerSettings _settings = new(); + private ThreemaService? _threema; + private MullvadVpnService? _vpn; + private TerminalLogger? _logger; + + public SettingsView() + { + InitializeComponent(); + btnSave.Click += (_, _) => Save(); + btnReload.Click += (_, _) => Reload(); + } + + public void Initialize(ThreemaService threema, MullvadVpnService vpn, TerminalLogger logger) + { + _threema = threema; + _vpn = vpn; + _logger = logger; + Reload(); + } + + private void Reload() + { + _settings = ServerSettings.Load(SettingsPath); + propertyGrid.SelectedObject = _settings; + } + + private void Save() + { + try + { + _settings.Save(SettingsPath); + _threema?.ReloadSettings(); + _vpn?.ReloadSettings(); + _logger?.Info("Server-Einstellungen gespeichert und Services neu geladen."); + MessageBox.Show("Server-Einstellungen gespeichert.", "Erfolg", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show($"Fehler beim Speichern: {ex.Message}", "Fehler", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +}