From 7394c9019f99232bf05bab023fbfc902224268f8 Mon Sep 17 00:00:00 2001 From: XanatosX <10531466+XanatosX@users.noreply.github.com> Date: Wed, 2 Aug 2023 20:57:21 +0200 Subject: [PATCH] Fix issue with application not starting minimized Rework window position on screen Add strategy to show window in bottom right corner Add structure to position the window baesed on a strategy --- .../DependencyInjectionExtension.cs | 6 ++- .../Enums/WindowPositionEnum.cs | 12 ++++++ .../DefaultWindowPositionStrategyFactory.cs | 20 ++++++++++ .../Services/Ui/IWindowManagementService.cs | 3 +- .../Services/Ui/IWindowPositionFactory.cs | 17 +++++++++ .../WindowPosition/BottomRightStrategy.cs | 24 ++++++++++++ .../WindowPosition/IWindowPositionStrategy.cs | 17 +++++++++ .../Views/MainWindow.axaml.cs | 37 ++++++++++++------- 8 files changed, 120 insertions(+), 16 deletions(-) create mode 100644 src/ModularToolManager/Enums/WindowPositionEnum.cs create mode 100644 src/ModularToolManager/Services/Ui/DefaultWindowPositionStrategyFactory.cs create mode 100644 src/ModularToolManager/Services/Ui/IWindowPositionFactory.cs create mode 100644 src/ModularToolManager/Strategies/WindowPosition/BottomRightStrategy.cs create mode 100644 src/ModularToolManager/Strategies/WindowPosition/IWindowPositionStrategy.cs diff --git a/src/ModularToolManager/DependencyInjection/DependencyInjectionExtension.cs b/src/ModularToolManager/DependencyInjection/DependencyInjectionExtension.cs index 95425eaf..01f2570e 100644 --- a/src/ModularToolManager/DependencyInjection/DependencyInjectionExtension.cs +++ b/src/ModularToolManager/DependencyInjection/DependencyInjectionExtension.cs @@ -68,7 +68,10 @@ public static IServiceCollection AddViewModels(this IServiceCollection collectio /// The extended collection public static IServiceCollection AddViews(this IServiceCollection collection) { - return collection.AddTransient(resolver => new MainWindow(resolver.GetRequiredService(), resolver.GetRequiredService()) + return collection.AddTransient(resolver => new MainWindow( + resolver.GetRequiredService(), + resolver.GetRequiredService(), + resolver.GetRequiredService()) { DataContext = resolver?.GetService(), }) @@ -96,6 +99,7 @@ public static IServiceCollection AddServices(this IServiceCollection collection) .AddSingleton() .AddSingleton() .AddSingleton() + .AddSingleton() .AddTransient() .AddTransient() .AddTransient() diff --git a/src/ModularToolManager/Enums/WindowPositionEnum.cs b/src/ModularToolManager/Enums/WindowPositionEnum.cs new file mode 100644 index 00000000..c02af711 --- /dev/null +++ b/src/ModularToolManager/Enums/WindowPositionEnum.cs @@ -0,0 +1,12 @@ +namespace ModularToolManager.Enums; + +/// +/// Enum for the correct position of the window +/// +public enum WindowPositionEnum +{ + TopLeft, + TopRight, + BottomLeft, + BottomRight, +} diff --git a/src/ModularToolManager/Services/Ui/DefaultWindowPositionStrategyFactory.cs b/src/ModularToolManager/Services/Ui/DefaultWindowPositionStrategyFactory.cs new file mode 100644 index 00000000..66510cee --- /dev/null +++ b/src/ModularToolManager/Services/Ui/DefaultWindowPositionStrategyFactory.cs @@ -0,0 +1,20 @@ +using ModularToolManager.Enums; +using ModularToolManager.Strategies.WindowPosition; + +namespace ModularToolManager.Services.Ui; + +/// +/// Default factory for getting the window position strategy +/// +public class DefaultWindowPositionStrategyFactory : IWindowPositionFactory +{ + /// + public IWindowPositionStrategy? GetWindowPositionStrategy(WindowPositionEnum positionEnum) + { + return positionEnum switch + { + WindowPositionEnum.BottomRight => new BottomRightStrategy(), + _ => new BottomRightStrategy() + }; + } +} diff --git a/src/ModularToolManager/Services/Ui/IWindowManagementService.cs b/src/ModularToolManager/Services/Ui/IWindowManagementService.cs index b3759271..3660f615 100644 --- a/src/ModularToolManager/Services/Ui/IWindowManagementService.cs +++ b/src/ModularToolManager/Services/Ui/IWindowManagementService.cs @@ -1,4 +1,5 @@ using Avalonia.Controls; +using ModularToolManager.Enums; using ModularToolManager.Models; using System.Collections; using System.Collections.Generic; @@ -26,7 +27,7 @@ public interface IWindowManagementService /// /// Get the main window of the application /// - /// + /// The main window or nothing if no main window was found Window? GetMainWindow(); /// diff --git a/src/ModularToolManager/Services/Ui/IWindowPositionFactory.cs b/src/ModularToolManager/Services/Ui/IWindowPositionFactory.cs new file mode 100644 index 00000000..b6734dfb --- /dev/null +++ b/src/ModularToolManager/Services/Ui/IWindowPositionFactory.cs @@ -0,0 +1,17 @@ +using ModularToolManager.Enums; +using ModularToolManager.Strategies.WindowPosition; + +namespace ModularToolManager.Services.Ui; + +/// +/// Factory to get a matching strategy for a requested window position +/// +public interface IWindowPositionFactory +{ + /// + /// Get the strategy for the given window + /// + /// The position enum to use + /// The strategy to position the window on the given position + IWindowPositionStrategy? GetWindowPositionStrategy(WindowPositionEnum positionEnum); +} diff --git a/src/ModularToolManager/Strategies/WindowPosition/BottomRightStrategy.cs b/src/ModularToolManager/Strategies/WindowPosition/BottomRightStrategy.cs new file mode 100644 index 00000000..76fd860a --- /dev/null +++ b/src/ModularToolManager/Strategies/WindowPosition/BottomRightStrategy.cs @@ -0,0 +1,24 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Platform; + +namespace ModularToolManager.Strategies.WindowPosition; + +/// +/// Position a Window in the bottom right of a given screen +/// +public class BottomRightStrategy : IWindowPositionStrategy +{ + /// + public void PositionWindow(Window window, Screen? screen) + { + if (screen is null) + { + return; + } + PixelRect workingArea = screen.WorkingArea; + double newXPos = workingArea.X + workingArea.Width - window.Width; + double newYPos = workingArea.Y + workingArea.Height - window.Height; + window.Position = new PixelPoint((int)newXPos, (int)newYPos); + } +} diff --git a/src/ModularToolManager/Strategies/WindowPosition/IWindowPositionStrategy.cs b/src/ModularToolManager/Strategies/WindowPosition/IWindowPositionStrategy.cs new file mode 100644 index 00000000..1c5b688e --- /dev/null +++ b/src/ModularToolManager/Strategies/WindowPosition/IWindowPositionStrategy.cs @@ -0,0 +1,17 @@ +using Avalonia.Controls; +using Avalonia.Platform; + +namespace ModularToolManager.Strategies.WindowPosition; + +/// +/// Strategy to position a window on the screen +/// +public interface IWindowPositionStrategy +{ + /// + /// Position the given window on the screen + /// + /// The window which should be moved + /// The screen to position the window on + void PositionWindow(Window window, Screen? screen); +} diff --git a/src/ModularToolManager/Views/MainWindow.axaml.cs b/src/ModularToolManager/Views/MainWindow.axaml.cs index 9df860e9..68d4f163 100644 --- a/src/ModularToolManager/Views/MainWindow.axaml.cs +++ b/src/ModularToolManager/Views/MainWindow.axaml.cs @@ -3,11 +3,13 @@ using Avalonia.Media; using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging.Messages; +using ModularToolManager.Enums; using ModularToolManager.Models; using ModularToolManager.Models.Messages; using ModularToolManager.Services.Settings; using ModularToolManager.Services.Ui; using System; +using System.Linq; namespace ModularToolManager.Views; @@ -27,19 +29,24 @@ public partial class MainWindow : Window, IDisposable private readonly IWindowManagementService? modalService; /// - /// Is this the first render of the application + /// Is this the first time the window was shown /// - private bool firstRender; + private bool firstTimeShown; /// /// The settings service to use /// private readonly ISettingsService? settingsService; + /// + /// The factory to get the window position strategy to use + /// + private readonly IWindowPositionFactory? windowPositionFactory; + /// /// Create a new empty instance of this class /// - public MainWindow() : this(null, null) + public MainWindow() : this(null, null, null) { } @@ -49,13 +56,13 @@ public MainWindow() : this(null, null) /// /// The modal service to use /// The settings service to use - public MainWindow(IWindowManagementService? modalService, ISettingsService? settingsService) + public MainWindow(IWindowManagementService? modalService, ISettingsService? settingsService, IWindowPositionFactory? windowPositionFactory) { this.modalService = modalService; this.settingsService = settingsService; - - firstRender = true; + this.windowPositionFactory = windowPositionFactory; + firstTimeShown = true; InitializeComponent(); WeakReferenceMessenger.Default.Register(this, (_, _) => @@ -99,7 +106,14 @@ public MainWindow(IWindowManagementService? modalService, ISettingsService? sett public override void Render(DrawingContext context) { base.Render(context); - if (firstRender) + PositionWindow(); + } + + /// + public override void Show() + { + base.Show(); + if (firstTimeShown) { if (settingsService?.GetApplicationSettings().StartMinimized ?? false) { @@ -107,9 +121,7 @@ public override void Render(DrawingContext context) mainWindow?.Hide(); } } - - PositionWindow(); - firstRender = false; + firstTimeShown = false; } /// @@ -117,10 +129,7 @@ public override void Render(DrawingContext context) /// private void PositionWindow() { - PixelRect workingArea = Screens.Primary.WorkingArea; - double newXPos = workingArea.X + workingArea.Width - Width; - double newYPos = workingArea.Y + workingArea.Height - Height; - Position = new PixelPoint((int)newXPos, (int)newYPos); + windowPositionFactory?.GetWindowPositionStrategy(WindowPositionEnum.BottomRight)?.PositionWindow(this, Screens.Primary); } ///