Files
PolyTraderSharp/src/PolyTrader.Core/Modularity/ModuleUi.cs
T
RichardandClaude Opus 4.8 039bc240f8 UI Slice 5: Menueleiste (Fenster nebeneinander), sicheres Beenden, Modul-Aktivierung
- Fenster-Menue: WindowMenu fuellt die oberste MenuStrip mit Top-Level-Eintraegen
  nebeneinander (mit Icon) statt Untermenue "Fenster"; ModuleView.Icon zentral in der
  App zugewiesen (AssignMenuIcons). Kein miFenster mehr im Launcher-Designer.
- Sicheres Beenden: ShutdownConfirmDialog (10s-Timer sperrt "Jetzt beenden", Abbrechen
  jederzeit) via IModuleUiHost.RequestShutdown(). Nur der Launcher (Hauptprozess) bietet
  "Beenden"; andere Fenster nur "Fenster schliessen" (kein App-Shutdown, Module laufen
  weiter). Launcher-Schliessen-X routet ueber dieselbe Abfrage.
- Modul-Aktivierung (restart-basiert): ServerSettings.DisabledModules, in Program.Main
  vor der DI-Registrierung gefiltert -> deaktivierte Module werden nicht geladen.
  Dashboard-Tab "Module" zeigt Status + schaltet um (Hinweis: greift nach Neustart).
  Optionaler IPolyTraderModule.GetActivationBlocker fuer "nicht aktivierbar"-Info.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 18:46:09 +02:00

71 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace PolyTrader.Core.Modularity
{
/// <summary>
/// Eine vom Core oder einem Modul beigesteuerte Fenster-Ansicht. Die eigentliche UI ist
/// ein designbares <see cref="Form"/>, das über <see cref="CreateForm"/> 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.
/// </summary>
public sealed class ModuleView
{
/// <summary>Stabile ID für Einzelinstanz-Handling (nur ein Fenster je View).</summary>
public string Id { get; init; } = Guid.NewGuid().ToString();
/// <summary>Titel (Fallback-Fenstertitel, falls das Form keinen eigenen setzt).</summary>
public string Title { get; init; } = "Fenster";
/// <summary>Optionale Gruppierung (z.B. "Core", "CopyTrading").</summary>
public string? Group { get; init; }
/// <summary>Optionale Sortierreihenfolge.</summary>
public int Order { get; init; } = 0;
/// <summary>
/// Optionales Icon für Menü/Buttons. Wird von der Shell/den Menüs genutzt. Settable, damit die
/// App den von Modulen registrierten Views zentral ein Icon aus ihren Ressourcen zuweisen kann
/// (Module referenzieren die App-Ressourcen nicht).
/// </summary>
public System.Drawing.Image? Icon { get; set; }
/// <summary>Erzeugt das anzuzeigende Fenster (frische Instanz je Öffnung).</summary>
public Func<Form> CreateForm { get; init; } = () => new Form();
}
/// <summary>
/// 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.
/// Ü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>
public interface IModuleUiHost
{
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>
/// Leitet das sichere Herunterfahren ein (Bestätigungsdialog mit Timer). Wird vom „Beenden"-
/// Eintrag JEDES Fensters aufgerufen auch aus Modul-Fenstern, die die App nicht kennen.
/// Die konkrete Shell zeigt den Dialog und fährt bei Bestätigung geordnet herunter.
/// </summary>
void RequestShutdown();
/// <summary>Feuert, wenn sich der Offen-Status irgendeiner View ändert.</summary>
event Action? OpenStateChanged;
}
}