diff --git a/FrEee.Core.Domain/Utility/DIRoot.cs b/FrEee.Core.Domain/Utility/DIRoot.cs index 1dc9607f..5b4e6927 100644 --- a/FrEee.Core.Domain/Utility/DIRoot.cs +++ b/FrEee.Core.Domain/Utility/DIRoot.cs @@ -92,4 +92,9 @@ public static class DIRoot /// Creates construction queues. /// public static IConstructionQueueFactory ConstructionQueues => DI.Get(); + + /// + /// Manages the GUI. Only available when there is a GUI. + /// + public static IGuiController Gui => DI.Get(); } diff --git a/FrEee.Core.Domain/Utility/IGuiController.cs b/FrEee.Core.Domain/Utility/IGuiController.cs new file mode 100644 index 00000000..2b09d349 --- /dev/null +++ b/FrEee.Core.Domain/Utility/IGuiController.cs @@ -0,0 +1,79 @@ +using FrEee.Objects.Civilization.Diplomacy.Messages; +using FrEee.Objects.Space; +using FrEee.Objects.Technology; +using FrEee.Processes.Combat; +using FrEee.Vehicles; + +namespace FrEee.Utility; + +public interface IGuiController +{ + /// + /// Shows a particular screen. + /// + /// + void Show(Screen screen); + + /// + /// Hides a particular screen. + /// + /// + void Hide(Screen screen); + + /// + /// Closes a particular screen. + /// + /// + void Close(Screen screen); + + /// + /// Exits the game. + /// + void Exit(); + + /// + /// Closes all windows except the main menu. Shows the main menu. + /// + void ReturnToMainMenu(); + + /// + /// Exits or returns to the main menu, per the player's preference. + /// + void CloseGame(); + + /// + /// Focuses a space object on the map. + /// + /// + void Focus(ISpaceObject context); + + /// + /// Focuses a star system on the map. + /// + /// + void Focus(StarSystem context); + + /// + /// Focuses a technology on the research screen. + /// + /// + void Focus(Technology context); + + /// + /// Focuses a hull on the design screen. + /// + /// + void Focus(IHull context); + + /// + /// Focuses a battle on the battle summary screen. + /// + /// + void Focus(IBattle context); + + /// + /// Focuses a message on the diplomacy screen. + /// + /// + void Focus(IMessage context); +} \ No newline at end of file diff --git a/FrEee.Core.Domain/Utility/Screen.cs b/FrEee.Core.Domain/Utility/Screen.cs new file mode 100644 index 00000000..1557a5f4 --- /dev/null +++ b/FrEee.Core.Domain/Utility/Screen.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FrEee.Utility; + +/// +/// The various screens in the UI. +/// +public enum Screen +{ + ActivateAbility, + BattleReplay, + BattleResults, + BlazorTest, + CargoTransfer, + CombatSimulator, + Commands, + ConstructionQueue, + ConstructionQueueList, + CultureComparison, + Debug, + DesignList, + Diplomacy, + Editor, + EmpireList, + EmpireSetup, + FleetTransfer, + GameOver, + GameSetup, + HostConsole, + HullPicker, + Log, + MainGame, + MainMenu, + Ministers, + ModErrors, + ModPicker, + MountPicker, + Options, + PlanetList, + Recycle, + Research, + Scores, + SearchBoxResults, + ShipList, + SpaceObjectPicker, + Status, + TechTree, + VehicleDesign +} diff --git a/FrEee.Root/Configuration.cs b/FrEee.Root/Configuration.cs index aba511ee..3fee2d87 100644 --- a/FrEee.Root/Configuration.cs +++ b/FrEee.Root/Configuration.cs @@ -28,7 +28,7 @@ public static class Configuration /// /// Sets up any dependencies which need to be injected. /// - public static void ConfigureDI() + public static void ConfigureDI(Action additionlConfig = null) { // TODO: load dependencies from configuration file in mod data so we can really modularize this thing! @@ -55,6 +55,9 @@ public static void ConfigureDI() DI.RegisterSingleton(); DI.RegisterSingleton(); + // addtional configuration for the GUI or whatever + additionlConfig?.Invoke(); + // run this in the background, without awaiting it DI.Run(); } diff --git a/FrEee.UI.Blazor/FrEee.UI.Blazor.csproj b/FrEee.UI.Blazor/FrEee.UI.Blazor.csproj index c47287f6..f55e6403 100644 --- a/FrEee.UI.Blazor/FrEee.UI.Blazor.csproj +++ b/FrEee.UI.Blazor/FrEee.UI.Blazor.csproj @@ -6,6 +6,7 @@ enable + diff --git a/FrEee.UI.Blazor/Views/HistoryLogViewModel.cs b/FrEee.UI.Blazor/Views/HistoryLogViewModel.cs index 2b6c918a..02d91063 100644 --- a/FrEee.UI.Blazor/Views/HistoryLogViewModel.cs +++ b/FrEee.UI.Blazor/Views/HistoryLogViewModel.cs @@ -15,6 +15,7 @@ using FrEee.Vehicles.Types; using FrEee.Vehicles; using FrEee.Extensions; +using FrEee.Utility; namespace FrEee.UI.Blazor.Views; @@ -39,7 +40,7 @@ public void Navigate(LogMessage message) if (context is ISpaceObject sobj) { // go to space object - OnSpaceObjectSelected(this, sobj); + DIRoot.Gui.Focus(sobj); } else if (context is IUnit unit) { @@ -49,11 +50,11 @@ public void Navigate(LogMessage message) { if (container is Sector) { - OnSpaceObjectSelected(this, (ISpaceObject)unit); + DIRoot.Gui.Focus((ISpaceObject)unit); } else { - OnSpaceObjectSelected(this, (ISpaceObject)container); + DIRoot.Gui.Focus((ISpaceObject)container); } } } @@ -61,37 +62,37 @@ public void Navigate(LogMessage message) { // go to the planet var container = facility.Container; - OnSpaceObjectSelected(this, container); + DIRoot.Gui.Focus(container); } else if (context is Technology tech) { // go to research screen - OnTechnologySelected(this, tech); + DIRoot.Gui.Focus(tech); } else if (context is IHull hull) { // go to design screen and create a new design using this hull - OnHullSelected(this, hull); + DIRoot.Gui.Focus(hull); } else if (context is ComponentTemplate || context is Mount) { // go to design screen - OnHullSelected(this, null); + DIRoot.Gui.Show(Screen.VehicleDesign); } else if (context is IBattle battle) { // show battle results - OnBattleSelected(this, battle); + DIRoot.Gui.Focus(battle); } else if (context is IMessage msg) { // show diplomacy screen - OnMessageSelected(this, msg); + DIRoot.Gui.Focus(msg); } else if (context is StarSystem sys) { // navigate game form to that system - OnStarSystemSelected(this, sys); + DIRoot.Gui.Focus(sys); } // TODO - more types of goto-messages @@ -115,16 +116,4 @@ public bool CanNavigate(LogMessage message) } return false; } - - public event EventHandler OnSpaceObjectSelected = (sender, e) => { }; - - public event EventHandler OnTechnologySelected = (sender, e) => { }; - - public event EventHandler OnHullSelected = (sender, e) => { }; - - public event EventHandler OnBattleSelected = (sender, e) => { }; - - public event EventHandler OnMessageSelected = (sender, e) => { }; - - public event EventHandler OnStarSystemSelected = (sender, e) => { }; } diff --git a/FrEee.UI.WinForms/Forms/LogForm.cs b/FrEee.UI.WinForms/Forms/LogForm.cs index 00c8952d..9c15841c 100644 --- a/FrEee.UI.WinForms/Forms/LogForm.cs +++ b/FrEee.UI.WinForms/Forms/LogForm.cs @@ -39,25 +39,11 @@ public LogForm(MainGameForm mainGameForm, IList log) ShowInTaskbar = !mainGameForm.HasLogBeenShown; VM.Messages = log; - VM.OnBattleSelected += VM_OnBattleSelected; - VM.OnHullSelected += VM_OnHullSelected; - VM.OnMessageSelected += VM_OnMessageSelected; - VM.OnSpaceObjectSelected += VM_OnSpaceObjectSelected; - VM.OnStarSystemSelected += VM_OnStarSystemSelected; - VM.OnTechnologySelected += VM_OnTechnologySelected; - } - - private void VM_OnTechnologySelected(object? sender, Technology e) - { - // go to research screen - mainGameForm.ShowResearchForm(); - Close(); } private void VM_OnStarSystemSelected(object? sender, StarSystem e) { - mainGameForm.SelectStarSystem(e); - Close(); + } private void VM_OnSpaceObjectSelected(object? sender, ISpaceObject e) diff --git a/FrEee.UI.WinForms/Forms/MainGameForm.cs b/FrEee.UI.WinForms/Forms/MainGameForm.cs index 49fdb934..8dccfdf5 100644 --- a/FrEee.UI.WinForms/Forms/MainGameForm.cs +++ b/FrEee.UI.WinForms/Forms/MainGameForm.cs @@ -807,7 +807,7 @@ private void GameForm_FormClosed(object sender, FormClosedEventArgs e) { Instance = null; if (QuitOnClose) - Gui.CloseGame(); + DIRoot.Gui.CloseGame(); } private void GameForm_FormClosing(object sender, FormClosingEventArgs e) diff --git a/FrEee.UI.WinForms/Forms/MainMenuForm.cs b/FrEee.UI.WinForms/Forms/MainMenuForm.cs index 446815a4..5a2f0f7e 100644 --- a/FrEee.UI.WinForms/Forms/MainMenuForm.cs +++ b/FrEee.UI.WinForms/Forms/MainMenuForm.cs @@ -178,7 +178,7 @@ private void LoadGalaxyFromFile(string filename, bool? loadPlr = null) private void btnQuit_Click(object sender, EventArgs e) { - Gui.Exit(); + DIRoot.Gui.Exit(); } private void btnMods_Click(object sender, EventArgs e) @@ -315,6 +315,6 @@ private void MainMenuForm_Load(object sender, EventArgs e) private void MainMenuForm_FormClosed(object sender, FormClosedEventArgs e) { ClientSettings.Save(); - Gui.Exit(); + DIRoot.Gui.Exit(); } } diff --git a/FrEee.UI.WinForms/Program.cs b/FrEee.UI.WinForms/Program.cs index 9d93b35b..c27dd424 100644 --- a/FrEee.UI.WinForms/Program.cs +++ b/FrEee.UI.WinForms/Program.cs @@ -94,7 +94,10 @@ void Log(Exception ex) }; // set up dependency injection - Configuration.ConfigureDI(); + Configuration.ConfigureDI(() => + { + DI.RegisterSingleton(); + }); // HACK - so many things are based on the working directory... Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); @@ -296,7 +299,7 @@ private static int ProcessTurn(bool safe) } Game.SaveAll(); Console.WriteLine("Turn processed successfully. It is now turn " + Game.Current.TurnNumber + " (stardate " + Game.Current.Stardate + ")."); - Gui.Exit(); + DIRoot.Gui.Exit(); return 0; } catch (Exception ex) diff --git a/FrEee.UI.WinForms/Utility/Extensions/GuiExtensions.cs b/FrEee.UI.WinForms/Utility/Extensions/GuiExtensions.cs index 6027e4ec..0b60e09b 100644 --- a/FrEee.UI.WinForms/Utility/Extensions/GuiExtensions.cs +++ b/FrEee.UI.WinForms/Utility/Extensions/GuiExtensions.cs @@ -7,6 +7,7 @@ using System.Windows.Forms; using Microsoft.AspNetCore.Components.WebView.WindowsForms; using Microsoft.Extensions.DependencyInjection; +using WFScreen = System.Windows.Forms.Screen; using FrEee.Gameplay; using FrEee.Gameplay.Commands.Fleets; @@ -100,10 +101,10 @@ public static Form CreatePopupForm(this Control control, string text = "") form.FormBorderStyle = FormBorderStyle.FixedDialog; form.ClientSize = control.Size; // TODO - deal with multiple screens - if (form.Width > Screen.PrimaryScreen.WorkingArea.Width) - form.Width = Screen.PrimaryScreen.WorkingArea.Width; - if (form.Height > Screen.PrimaryScreen.WorkingArea.Height) - form.Height = Screen.PrimaryScreen.WorkingArea.Height; + if (form.Width > WFScreen.PrimaryScreen.WorkingArea.Width) + form.Width = WFScreen.PrimaryScreen.WorkingArea.Width; + if (form.Height > WFScreen.PrimaryScreen.WorkingArea.Height) + form.Height = WFScreen.PrimaryScreen.WorkingArea.Height; form.StartPosition = FormStartPosition.CenterParent; form.Controls.Add(control); form.KeyPreview = true; diff --git a/FrEee.UI.WinForms/Utility/Gui.cs b/FrEee.UI.WinForms/Utility/Gui.cs deleted file mode 100644 index 02f48b78..00000000 --- a/FrEee.UI.WinForms/Utility/Gui.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Windows.Forms; -using FrEee.UI.WinForms.Forms; -using FrEee.UI.WinForms.Objects; - -namespace FrEee.UI.WinForms.Utility; - -/// -/// Non-extension utility methods for manipulating the GUI. -/// -public static class Gui -{ - /// - /// Exits the GUI. - /// - public static void Exit() - => Application.Exit(); - - /// - /// Closes all windows except the main menu. Shows the main menu. - /// - public static void ReturnToMainMenu() - { - foreach (Form form in Application.OpenForms) - { - if (form is MainMenuForm) - { - form.Show(); - } - else - { - form.Close(); - } - } - } - - /// - /// Exits or returns to the main menu, per the player's preference. - /// - public static void CloseGame() - { - if (ClientSettings.Instance.QuitToMainMenu) - { - ReturnToMainMenu(); - } - else - { - Exit(); - } - } -} diff --git a/FrEee.UI.WinForms/Utility/GuiController.cs b/FrEee.UI.WinForms/Utility/GuiController.cs new file mode 100644 index 00000000..f51f71dd --- /dev/null +++ b/FrEee.UI.WinForms/Utility/GuiController.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using FrEee.Objects.Civilization.Diplomacy.Messages; +using FrEee.Objects.Space; +using FrEee.Objects.Technology; +using FrEee.Processes.Combat; +using FrEee.UI.WinForms.Forms; +using FrEee.UI.WinForms.Objects; +using FrEee.Utility; +using FrEee.Vehicles; +using Screen = FrEee.Utility.Screen; + +namespace FrEee.UI.WinForms.Utility; + +public class GuiController + : IGuiController +{ + public void Close(Screen screen) + { + GetForm(screen)?.Close(); + } + + public void CloseGame() + { + if (ClientSettings.Instance.QuitToMainMenu) + { + ReturnToMainMenu(); + } + else + { + Exit(); + } + } + + public void Exit() + { + Application.Exit(); + } + + public void Focus(ISpaceObject context) + { + MainGameForm.SelectSpaceObject(context); + Close(Screen.Log); // if it's open... + } + + public void Focus(StarSystem context) + { + MainGameForm.SelectStarSystem(context); + Close(Screen.Log); // if it's open... + } + + public void Focus(Technology context) + { + Show(Screen.Research); + // TODO: focus the technology + Close(Screen.Log); // if it's open... + } + + public void Focus(IHull context) + { + new VehicleDesignForm(context).Show(); + Close(Screen.Log); // if it's open... + } + + public void Focus(IBattle context) + { + new BattleResultsForm(context).Show(); + Close(Screen.Log); // if it's open... + } + + public void Focus(IMessage context) + { + new DiplomacyForm(context).Show(); + Close(Screen.Log); + } + + public void Hide(Screen screen) + { + GetForm(screen)?.Hide(); + } + + public void ReturnToMainMenu() + { + foreach (Form form in Application.OpenForms) + { + if (form is MainMenuForm) + { + form.Show(); + } + else + { + form.Close(); + } + } + } + + public void Show(Screen screen) + { + var form = GetForm(screen); + if (form is null) + { + form = (Form)Activator.CreateInstance(GetFormType(screen)); + } + form.Show(); + } + + private Form? GetForm(Screen screen) + { + var type = GetFormType(screen); + return Application.OpenForms.Cast
().Where(q => q.GetType() == type).SingleOrDefault(); + } + + private Type GetFormType(Screen screen) + { + var tn = typeof(MainGameForm).FullName.Replace("MainGame", screen.ToString()); + return Type.GetType(tn); + } + + private MainGameForm MainGameForm => MainGameForm.Instance; +} diff --git a/FrEee.UI/FrEee.UI.csproj b/FrEee.UI/FrEee.UI.csproj new file mode 100644 index 00000000..29ac536a --- /dev/null +++ b/FrEee.UI/FrEee.UI.csproj @@ -0,0 +1,15 @@ + + + + net9.0 + enable + enable + + + + + + false + + + diff --git a/FrEee.UI/IGuiController.cs b/FrEee.UI/IGuiController.cs new file mode 100644 index 00000000..bba1be95 --- /dev/null +++ b/FrEee.UI/IGuiController.cs @@ -0,0 +1,9 @@ +namespace FrEee.UI; + +/// +/// Navigates between the various screens in the UI. +/// +public interface IGuiController +{ + +}