diff --git a/src/ModularToolManager/Models/ApplicationSettings.cs b/src/ModularToolManager/Models/ApplicationSettings.cs index f6456d5..e39b27b 100644 --- a/src/ModularToolManager/Models/ApplicationSettings.cs +++ b/src/ModularToolManager/Models/ApplicationSettings.cs @@ -19,6 +19,12 @@ public class ApplicationSettings [JsonPropertyName("always_on_top")] public bool AlwaysOnTop { get; set; } + /// + /// Should the application be closed if a function is getting pressed + /// + [JsonPropertyName("close_on_function_execute")] + public bool CloseOnFunctionExecute { get; set; } + /// /// Should the application be started minimized /// diff --git a/src/ModularToolManager/Properties/Resources.Designer.cs b/src/ModularToolManager/Properties/Resources.Designer.cs index 2e2c864..3fdb242 100644 --- a/src/ModularToolManager/Properties/Resources.Designer.cs +++ b/src/ModularToolManager/Properties/Resources.Designer.cs @@ -123,6 +123,24 @@ public static string AllPlugins_Header_Settings { } } + /// + /// Looks up a localized string similar to Blue Theme. + /// + public static string App_Blue_Theme { + get { + return ResourceManager.GetString("App_Blue_Theme", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A Theme which mainly uses the color blue as a background. + /// + public static string App_Blue_Theme_Description { + get { + return ResourceManager.GetString("App_Blue_Theme_Description", resourceCulture); + } + } + /// /// Looks up a localized string similar to Dark mode. /// @@ -141,6 +159,24 @@ public static string App_Dark_Theme_Description { } } + /// + /// Looks up a localized string similar to Green Theme. + /// + public static string App_Green_Theme { + get { + return ResourceManager.GetString("App_Green_Theme", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A Theme which mainly uses the color green as a background. + /// + public static string App_Green_Theme_Description { + get { + return ResourceManager.GetString("App_Green_Theme_Description", resourceCulture); + } + } + /// /// Looks up a localized string similar to Light mode. /// @@ -159,6 +195,42 @@ public static string App_Light_Theme_Description { } } + /// + /// Looks up a localized string similar to Orange Theme. + /// + public static string App_Orange_Theme { + get { + return ResourceManager.GetString("App_Orange_Theme", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A Theme which mainly uses the color orange as a background. + /// + public static string App_Orange_Theme_Description { + get { + return ResourceManager.GetString("App_Orange_Theme_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Red Theme. + /// + public static string App_Red_Theme { + get { + return ResourceManager.GetString("App_Red_Theme", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A Theme which mainly uses the color red as a background. + /// + public static string App_Red_Theme_Description { + get { + return ResourceManager.GetString("App_Red_Theme_Description", resourceCulture); + } + } + /// /// Looks up a localized string similar to Modular Tool Manager. /// @@ -249,6 +321,15 @@ public static string Dependency_Project { } } + /// + /// Looks up a localized string similar to Either the path saved on this function is missing, the extension is wrong or the plugin for execution was removed. Please edit the function to fix the error.. + /// + public static string FunctionButton_Method_Error { + get { + return ResourceManager.GetString("FunctionButton_Method_Error", resourceCulture); + } + } + /// /// Looks up a localized string similar to Search for function. /// @@ -555,6 +636,15 @@ public static string RunningWith { } } + /// + /// Looks up a localized string similar to Close if a function was executed. + /// + public static string Settings_CloseOnFunctionExecute { + get { + return ResourceManager.GetString("Settings_CloseOnFunctionExecute", resourceCulture); + } + } + /// /// Looks up a localized string similar to Keep on Top. /// diff --git a/src/ModularToolManager/Properties/Resources.de.resx b/src/ModularToolManager/Properties/Resources.de.resx index 8ea38e0..1e3398e 100644 --- a/src/ModularToolManager/Properties/Resources.de.resx +++ b/src/ModularToolManager/Properties/Resources.de.resx @@ -138,18 +138,42 @@ Einstellungen + + Blaues Thema + + + Ein Theme welches um die Farbe Blau aufgebaut ist. Diese wirkt sich hauptsächlich auf den Hintergrund aus. + Dunkler Modus Dunkler Modus für die Applikation + + Grünes Thema + + + Ein Theme welches um die Farbe Grün aufgebaut ist. Diese wirkt sich hauptsächlich auf den Hintergrund aus. + Heller Modus Heller Modus für die Applikation + + Orangenes Thema + + + Ein Theme welches um die Farbe Orange aufgebaut ist. Diese wirkt sich hauptsächlich auf den Hintergrund aus. + + + Rotes Thema + + + Ein Theme welches um die Farbe Rot aufgebaut ist. Diese wirkt sich hauptsächlich auf den Hintergrund aus. + Projekt Website im Browser öffnen @@ -168,6 +192,9 @@ Editieren + + Entweder der Dateipfad ist falsch, die Dateiendung entspricht nicht der erwarteten oder das entsprechend Plugin wurde entfernt. Bitte editieren Sie die Funktion um den Fehler zu beheben. + Nach Funktion suchen @@ -249,6 +276,9 @@ Läuft mit Avalonia UI + + Applikation schließen nachdem Funktion ausgeführt wurde + Immer über anderen Fenstern diff --git a/src/ModularToolManager/Properties/Resources.resx b/src/ModularToolManager/Properties/Resources.resx index d062396..cc2eb6e 100644 --- a/src/ModularToolManager/Properties/Resources.resx +++ b/src/ModularToolManager/Properties/Resources.resx @@ -141,18 +141,42 @@ Modular Tool Manager + + Blue Theme + + + A Theme which mainly uses the color blue as a background + Dark mode Dark theme for the application + + Green Theme + + + A Theme which mainly uses the color green as a background + Light mode Light theme for the application + + Orange Theme + + + A Theme which mainly uses the color orange as a background + + + Red Theme + + + A Theme which mainly uses the color red as a background + Open project website @@ -180,6 +204,9 @@ Project + + Either the path saved on this function is missing, the extension is wrong or the plugin for execution was removed. Please edit the function to fix the error. + Search for function @@ -282,6 +309,9 @@ Running with Avalonia UI + + Close if a function was executed + Keep on Top diff --git a/src/ModularToolManager/Resources/Icons.axaml b/src/ModularToolManager/Resources/Icons.axaml index 4200ae0..347ae9c 100644 --- a/src/ModularToolManager/Resources/Icons.axaml +++ b/src/ModularToolManager/Resources/Icons.axaml @@ -19,6 +19,7 @@ M24,7.25 C27.1017853,7.25 29.629937,9.70601719 29.7458479,12.7794443 L29.75,13 L37,13 C37.6903559,13 38.25,13.5596441 38.25,14.25 C38.25,14.8972087 37.7581253,15.4295339 37.1278052,15.4935464 L37,15.5 L35.909,15.5 L34.2058308,38.0698451 C34.0385226,40.2866784 32.1910211,42 29.9678833,42 L18.0321167,42 C15.8089789,42 13.9614774,40.2866784 13.7941692,38.0698451 L12.09,15.5 L11,15.5 C10.3527913,15.5 9.8204661,15.0081253 9.75645361,14.3778052 L9.75,14.25 C9.75,13.6027913 10.2418747,13.0704661 10.8721948,13.0064536 L11,13 L18.25,13 C18.25,9.82436269 20.8243627,7.25 24,7.25 Z M33.4021054,15.5 L14.5978946,15.5 L16.2870795,37.8817009 C16.3559711,38.7945146 17.116707,39.5 18.0321167,39.5 L29.9678833,39.5 C30.883293,39.5 31.6440289,38.7945146 31.7129205,37.8817009 L33.4021054,15.5 Z M27.25,20.75 C27.8972087,20.75 28.4295339,21.2418747 28.4935464,21.8721948 L28.5,22 L28.5,33 C28.5,33.6903559 27.9403559,34.25 27.25,34.25 C26.6027913,34.25 26.0704661,33.7581253 26.0064536,33.1278052 L26,33 L26,22 C26,21.3096441 26.5596441,20.75 27.25,20.75 Z M20.75,20.75 C21.3972087,20.75 21.9295339,21.2418747 21.9935464,21.8721948 L22,22 L22,33 C22,33.6903559 21.4403559,34.25 20.75,34.25 C20.1027913,34.25 19.5704661,33.7581253 19.5064536,33.1278052 L19.5,33 L19.5,22 C19.5,21.3096441 20.0596441,20.75 20.75,20.75 Z M24,9.75 C22.2669685,9.75 20.8507541,11.1064548 20.7551448,12.8155761 L20.75,13 L27.25,13 C27.25,11.2050746 25.7949254,9.75 24,9.75 Z M24 4C35.0457 4 44 12.9543 44 24C44 35.0457 35.0457 44 24 44C12.9543 44 4 35.0457 4 24C4 12.9543 12.9543 4 24 4ZM24 6.5C14.335 6.5 6.5 14.335 6.5 24C6.5 33.665 14.335 41.5 24 41.5C33.665 41.5 41.5 33.665 41.5 24C41.5 14.335 33.665 6.5 24 6.5ZM24.25 32C25.0784 32 25.75 32.6716 25.75 33.5C25.75 34.3284 25.0784 35 24.25 35C23.4216 35 22.75 34.3284 22.75 33.5C22.75 32.6716 23.4216 32 24.25 32ZM24.25 13C27.6147 13 30.5 15.8821 30.5 19.2488C30.502 21.3691 29.7314 22.7192 27.8216 24.7772L26.8066 25.8638C25.7842 27.0028 25.3794 27.7252 25.3409 28.5793L25.3379 28.7411L25.3323 28.8689L25.3143 28.9932C25.2018 29.5636 24.7009 29.9957 24.0968 30.0001C23.4065 30.0049 22.8428 29.4493 22.8379 28.7589C22.8251 26.9703 23.5147 25.7467 25.1461 23.9739L26.1734 22.8762C27.5312 21.3837 28.0012 20.503 28 19.25C28 17.2634 26.2346 15.5 24.25 15.5C22.3307 15.5 20.6142 17.1536 20.5055 19.0587L20.4935 19.3778C20.4295 20.0081 19.8972 20.5 19.25 20.5C18.5596 20.5 18 19.9404 18 19.25C18 15.8846 20.8864 13 24.25 13Z M19.7453641,5 C20.9880048,5 21.9953641,6.00735931 21.9953641,7.25 L21.9953641,16.754591 C21.9953641,17.9972317 20.9880048,19.004591 19.7453641,19.004591 L4.25,19.004591 C3.00735931,19.004591 2,17.9972317 2,16.754591 L2,7.25 C2,6.00735931 3.00735931,5 4.25,5 L19.7453641,5 Z M19.7453641,6.5 L4.25,6.5 C3.83578644,6.5 3.5,6.83578644 3.5,7.25 L3.5,16.754591 C3.5,17.1688046 3.83578644,17.504591 4.25,17.504591 L19.7453641,17.504591 C20.1595777,17.504591 20.4953641,17.1688046 20.4953641,16.754591 L20.4953641,7.25 C20.4953641,6.83578644 20.1595777,6.5 19.7453641,6.5 Z M6.75,14.5 L17.25,14.5 C17.6642136,14.5 18,14.8357864 18,15.25 C18,15.6296958 17.7178461,15.943491 17.3517706,15.9931534 L17.25,16 L6.75,16 C6.33578644,16 6,15.6642136 6,15.25 C6,14.8703042 6.28215388,14.556509 6.64822944,14.5068466 L6.75,14.5 L17.25,14.5 L6.75,14.5 Z M16.5,11 C17.0522847,11 17.5,11.4477153 17.5,12 C17.5,12.5522847 17.0522847,13 16.5,13 C15.9477153,13 15.5,12.5522847 15.5,12 C15.5,11.4477153 15.9477153,11 16.5,11 Z M10.5048752,11 C11.05716,11 11.5048752,11.4477153 11.5048752,12 C11.5048752,12.5522847 11.05716,13 10.5048752,13 C9.95259045,13 9.5048752,12.5522847 9.5048752,12 C9.5048752,11.4477153 9.95259045,11 10.5048752,11 Z M7.5048752,11 C8.05715995,11 8.5048752,11.4477153 8.5048752,12 C8.5048752,12.5522847 8.05715995,13 7.5048752,13 C6.95259045,13 6.5048752,12.5522847 6.5048752,12 C6.5048752,11.4477153 6.95259045,11 7.5048752,11 Z M13.5048752,11 C14.05716,11 14.5048752,11.4477153 14.5048752,12 C14.5048752,12.5522847 14.05716,13 13.5048752,13 C12.9525905,13 12.5048752,12.5522847 12.5048752,12 C12.5048752,11.4477153 12.9525905,11 13.5048752,11 Z M6,8 C6.55228475,8 7,8.44771525 7,9 C7,9.55228475 6.55228475,10 6,10 C5.44771525,10 5,9.55228475 5,9 C5,8.44771525 5.44771525,8 6,8 Z M8.9951248,8 C9.54740955,8 9.9951248,8.44771525 9.9951248,9 C9.9951248,9.55228475 9.54740955,10 8.9951248,10 C8.44284005,10 7.9951248,9.55228475 7.9951248,9 C7.9951248,8.44771525 8.44284005,8 8.9951248,8 Z M11.9951248,8 C12.5474095,8 12.9951248,8.44771525 12.9951248,9 C12.9951248,9.55228475 12.5474095,10 11.9951248,10 C11.44284,10 10.9951248,9.55228475 10.9951248,9 C10.9951248,8.44771525 11.44284,8 11.9951248,8 Z M14.9951248,8 C15.5474095,8 15.9951248,8.44771525 15.9951248,9 C15.9951248,9.55228475 15.5474095,10 14.9951248,10 C14.44284,10 13.9951248,9.55228475 13.9951248,9 C13.9951248,8.44771525 14.44284,8 14.9951248,8 Z M17.9951248,8 C18.5474095,8 18.9951248,8.44771525 18.9951248,9 C18.9951248,9.55228475 18.5474095,10 17.9951248,10 C17.44284,10 16.9951248,9.55228475 16.9951248,9 C16.9951248,8.44771525 17.44284,8 17.9951248,8 Z + M10.9093922,2.78216375 C11.9491636,2.20625071 13.2471955,2.54089334 13.8850247,3.52240345 L13.9678229,3.66023048 L21.7267791,17.6684928 C21.9115773,18.0021332 22.0085303,18.3772743 22.0085303,18.7586748 C22.0085303,19.9495388 21.0833687,20.9243197 19.9125791,21.003484 L19.7585303,21.0086748 L4.24277801,21.0086748 C3.86146742,21.0086748 3.48641186,20.9117674 3.15282824,20.7270522 C2.11298886,20.1512618 1.7079483,18.8734454 2.20150311,17.8120352 L2.27440063,17.668725 L10.0311968,3.66046274 C10.2357246,3.291099 10.5400526,2.98673515 10.9093922,2.78216375 Z M20.4146132,18.3952808 L12.6556571,4.3870185 C12.4549601,4.02467391 11.9985248,3.89363262 11.6361802,4.09432959 C11.5438453,4.14547244 11.4637001,4.21532637 11.4006367,4.29899869 L11.3434484,4.38709592 L3.58665221,18.3953582 C3.385998,18.7577265 3.51709315,19.2141464 3.87946142,19.4148006 C3.96285732,19.4609794 4.05402922,19.4906942 4.14802472,19.5026655 L4.24277801,19.5086748 L19.7585303,19.5086748 C20.1727439,19.5086748 20.5085303,19.1728883 20.5085303,18.7586748 C20.5085303,18.6633247 20.4903516,18.5691482 20.455275,18.4811011 L20.4146132,18.3952808 L12.6556571,4.3870185 L20.4146132,18.3952808 Z M12.0004478,16.0017852 C12.5519939,16.0017852 12.9991104,16.4489016 12.9991104,17.0004478 C12.9991104,17.5519939 12.5519939,17.9991104 12.0004478,17.9991104 C11.4489016,17.9991104 11.0017852,17.5519939 11.0017852,17.0004478 C11.0017852,16.4489016 11.4489016,16.0017852 12.0004478,16.0017852 Z M11.9962476,8.49954934 C12.3759432,8.49924613 12.689964,8.78114897 12.7399193,9.14718469 L12.7468472,9.24894974 L12.750448,13.7505438 C12.7507788,14.1647572 12.4152611,14.5008121 12.0010476,14.5011439 C11.621352,14.5014471 11.3073312,14.2195442 11.257376,13.8535085 L11.250448,13.7517435 L11.2468472,9.25014944 C11.2465164,8.83593601 11.5820341,8.49988112 11.9962476,8.49954934 Z diff --git a/src/ModularToolManager/Resources/buildInStyles.json b/src/ModularToolManager/Resources/buildInStyles.json index 7acbf0b..7bc79aa 100644 --- a/src/ModularToolManager/Resources/buildInStyles.json +++ b/src/ModularToolManager/Resources/buildInStyles.json @@ -26,5 +26,61 @@ }, "material_opacity": 0.65, "tint_opacity": 1 + }, + { + "id": 2, + "mode": 0, + "name_translation_key": "App_Blue_Theme", + "description_translation_key": "App_Blue_Theme_Description", + "tint_color": { + "A": 255, + "R": 0, + "G": 0, + "B": 255 + }, + "material_opacity": 0.8, + "tint_opacity": 1 + }, + { + "id": 3, + "mode": 0, + "name_translation_key": "App_Green_Theme", + "description_translation_key": "App_Green_Theme_Description", + "tint_color": { + "A": 255, + "R": 0, + "G": 255, + "B": 0 + }, + "material_opacity": 0.8, + "tint_opacity": 1 + }, + { + "id": 4, + "mode": 0, + "name_translation_key": "App_Red_Theme", + "description_translation_key": "App_Red_Theme_Description", + "tint_color": { + "A": 255, + "R": 255, + "G": 0, + "B": 0 + }, + "material_opacity": 0.8, + "tint_opacity": 1 + }, + { + "id": 5, + "mode": 0, + "name_translation_key": "App_Orange_Theme", + "description_translation_key": "App_Orange_Theme_Description", + "tint_color": { + "A": 255, + "R": 255, + "G": 165, + "B": 0 + }, + "material_opacity": 0.8, + "tint_opacity": 1 } ] \ No newline at end of file diff --git a/src/ModularToolManager/ViewModels/ApplicationStyleViewModel.cs b/src/ModularToolManager/ViewModels/ApplicationStyleViewModel.cs index 690da1c..79582e0 100644 --- a/src/ModularToolManager/ViewModels/ApplicationStyleViewModel.cs +++ b/src/ModularToolManager/ViewModels/ApplicationStyleViewModel.cs @@ -1,4 +1,5 @@ -using CommunityToolkit.Mvvm.ComponentModel; +using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using ModularToolManager.Models; namespace ModularToolManager.ViewModels; @@ -18,6 +19,22 @@ internal partial class ApplicationStyleViewModel : ObservableObject /// public int Id => applicationStyle.Id; + /// + /// The main color of the selected style + /// + [ObservableProperty] + private Brush? styleColor; + + /// + /// The opacity for the loaded style + /// + public float StyleOpacity => applicationStyle.TintOpacity; + + /// + /// The opacity for the material + /// + public float MaterialOpacity => applicationStyle.MaterialOpacity; + /// /// The displayname of the style /// @@ -44,6 +61,8 @@ public ApplicationStyleViewModel(ApplicationStyle applicationStyle) { this.applicationStyle = applicationStyle; DisplayName = applicationStyle.Name ?? string.Empty; - description = applicationStyle.Description ?? string.Empty; + Description = applicationStyle.Description ?? string.Empty; + StyleColor = new SolidColorBrush(applicationStyle.TintColor ?? Colors.Transparent); + } } diff --git a/src/ModularToolManager/ViewModels/FunctionButtonViewModel.cs b/src/ModularToolManager/ViewModels/FunctionButtonViewModel.cs index 9869594..e504ca2 100644 --- a/src/ModularToolManager/ViewModels/FunctionButtonViewModel.cs +++ b/src/ModularToolManager/ViewModels/FunctionButtonViewModel.cs @@ -10,6 +10,7 @@ using ModularToolManagerPlugin.Plugin; using ModularToolManagerPlugin.Services; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; @@ -33,6 +34,12 @@ public partial class FunctionButtonViewModel : ObservableObject [NotifyPropertyChangedFor(nameof(Identifier), nameof(DisplayName), nameof(SortId), nameof(Description))] private FunctionModel? functionModel; + /// + /// Can the function be executed + /// + [ObservableProperty] + private bool canExecute; + /// /// The identifier for this function button /// @@ -51,7 +58,9 @@ public partial class FunctionButtonViewModel : ObservableObject /// /// The description of the function /// - public string? Description => functionModel?.Description; + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(ToolTipDelay))] + private string description; /// /// The logger to use @@ -83,7 +92,10 @@ public partial class FunctionButtonViewModel : ObservableObject /// Create a new instance of this class /// /// The function model to use - public FunctionButtonViewModel(ILogger logger, ISettingsService settingsService, IFunctionSettingsService functionSettingsService) + public FunctionButtonViewModel( + ILogger logger, + ISettingsService settingsService, + IFunctionSettingsService functionSettingsService) { IsActive = true; this.logger = logger; @@ -98,6 +110,9 @@ public FunctionButtonViewModel(ILogger logger, ISetting public void SetFunctionModel(FunctionModel functionModel) { this.functionModel = functionModel; + Description = functionModel?.Description ?? string.Empty; + + CheckIfCanExecute(); } /// @@ -109,6 +124,7 @@ private async Task ExecuteFunction() { try { + bool shouldMinimizeAfter = settingsService.GetApplicationSettings().CloseOnFunctionExecute; var plugin = functionModel?.Plugin; if (plugin is null) { @@ -116,12 +132,41 @@ private async Task ExecuteFunction() } ApplyPluginSettings(plugin); await Task.Run(() => functionModel?.Plugin?.Execute(functionModel.Parameters, functionModel.Path)); + + if (shouldMinimizeAfter) + { + WeakReferenceMessenger.Default.Send(new ToggleApplicationVisibilityMessage(true)); + } } catch (System.Exception e) { logger.LogError(FUNCTION_EXECUTION_FAILED_MESSAGE, Identifier, DisplayName); logger.LogError(e, null); } + CheckIfCanExecute(); + } + + /// + /// Check if this function can be executed and mark it correctly + /// + private void CheckIfCanExecute() + { + if (FunctionModel is null) + { + CanExecute = false; + } + bool pathIsAvailable = File.Exists(FunctionModel.Path); + bool pluginAvailable = FunctionModel?.Plugin is not null; + bool extensionMatching = false; + if (pathIsAvailable) + { + var info = new FileInfo(FunctionModel.Path); + extensionMatching = FunctionModel.Plugin.GetAllowedFileEndings().Any(ending => ending.Extension == info.Extension.Replace(".", string.Empty)); + } + + + CanExecute = pathIsAvailable && extensionMatching && pluginAvailable; + Description = CanExecute ? FunctionModel.Description : Properties.Resources.FunctionButton_Method_Error; } /// diff --git a/src/ModularToolManager/ViewModels/SettingsViewModel.cs b/src/ModularToolManager/ViewModels/SettingsViewModel.cs index b4888fd..afd707b 100644 --- a/src/ModularToolManager/ViewModels/SettingsViewModel.cs +++ b/src/ModularToolManager/ViewModels/SettingsViewModel.cs @@ -17,96 +17,104 @@ namespace ModularToolManager.ViewModels; /// internal partial class SettingsViewModel : ObservableObject { - /// - /// The settings service to use - /// - private readonly ISettingsService settingsService; + /// + /// The settings service to use + /// + private readonly ISettingsService settingsService; - /// - /// Baking field for the top most checkbox - /// - [ObservableProperty] - private bool topMost; + /// + /// Baking field for the top most checkbox + /// + [ObservableProperty] + private bool topMost; - /// - /// Baking field if should be started minimitzed - /// - [ObservableProperty] - private bool startMinimized; + /// + /// Baking field if the app should minimize if a function was pressed + /// + [ObservableProperty] + private bool closeOnFunctionExecute; - /// - /// Baking field if should be shown in taskbar - /// - [ObservableProperty] - private bool showInTaskbar; + /// + /// Baking field if should be started minimitzed + /// + [ObservableProperty] + private bool startMinimized; - /// - /// All the available themes for the application - /// - [ObservableProperty] - private List availableThemes; + /// + /// Baking field if should be shown in taskbar + /// + [ObservableProperty] + private bool showInTaskbar; - /// - /// The currently selected theme - /// - [ObservableProperty] - private ApplicationStyleViewModel? selectedTheme; + /// + /// All the available themes for the application + /// + [ObservableProperty] + private List availableThemes; - /// - /// Create a new instance of this class - /// - /// The settings service to use - public SettingsViewModel(ISettingsService settingsService, IThemeService themeService) - { - this.settingsService = settingsService; - ApplicationSettings appSettings = settingsService.GetApplicationSettings(); - TopMost = appSettings.AlwaysOnTop; - StartMinimized = appSettings.StartMinimized; - ShowInTaskbar = appSettings.ShowInTaskbar; - AvailableThemes = themeService.GetAllStyles() - .OrderBy(style => style.Name) - .Where(style => !string.IsNullOrEmpty(style.Name)) - .Select(style => new ApplicationStyleViewModel(style)) - .ToList(); - SelectedTheme = AvailableThemes.Where(theme => theme.Id == appSettings.SelectedThemeId).FirstOrDefault() ?? AvailableThemes.FirstOrDefault(); + /// + /// The currently selected theme + /// + [ObservableProperty] + private ApplicationStyleViewModel? selectedTheme; - PropertyChanged += (_, e) => - { - if (e.PropertyName == nameof(SelectedTheme) && selectedTheme is not null) - { - WeakReferenceMessenger.Default.Send(new ApplicationThemeUpdated(selectedTheme.Id)); - } - }; - } + /// + /// Create a new instance of this class + /// + /// The settings service to use + public SettingsViewModel(ISettingsService settingsService, IThemeService themeService) + { + this.settingsService = settingsService; + ApplicationSettings appSettings = settingsService.GetApplicationSettings(); + TopMost = appSettings.AlwaysOnTop; + CloseOnFunctionExecute = appSettings.CloseOnFunctionExecute; + StartMinimized = appSettings.StartMinimized; + ShowInTaskbar = appSettings.ShowInTaskbar; + AvailableThemes = themeService.GetAllStyles() + .OrderBy(style => style.Name) + .Where(style => !string.IsNullOrEmpty(style.Name)) + .Select(style => new ApplicationStyleViewModel(style)) + .ToList(); + SelectedTheme = AvailableThemes.Where(theme => theme.Id == appSettings.SelectedThemeId).FirstOrDefault() ?? AvailableThemes.FirstOrDefault(); - /// - /// The ok button to save and confirm the changes - /// - [RelayCommand] - private void Ok() - { - var changeResult = settingsService.ChangeSettings(settings => - { - settings.StartMinimized = StartMinimized; - settings.ShowInTaskbar = ShowInTaskbar; - settings.AlwaysOnTop = topMost; - settings.SelectedThemeId = selectedTheme?.Id ?? 0; - }); - if (changeResult) - { - WeakReferenceMessenger.Default.Send(new ValueChangedMessage(settingsService.GetApplicationSettings())); - Abort(); - } - } + PropertyChanged += (_, e) => + { + if (e.PropertyName == nameof(SelectedTheme) && selectedTheme is not null) + { + WeakReferenceMessenger.Default.Send(new ApplicationThemeUpdated(selectedTheme.Id)); + } + }; + } - /// - /// The abort button to discard the changes and close the modal - /// - [RelayCommand] - private void Abort() - { - WeakReferenceMessenger.Default.Send(new CloseModalMessage(this)); - AvailableThemes.Clear(); - SelectedTheme = null; - } + /// + /// The ok button to save and confirm the changes + /// + [RelayCommand] + private void Ok() + { + var changeResult = settingsService.ChangeSettings(settings => + { + settings.StartMinimized = StartMinimized; + settings.ShowInTaskbar = ShowInTaskbar; + settings.AlwaysOnTop = TopMost; + settings.CloseOnFunctionExecute = CloseOnFunctionExecute; + settings.SelectedThemeId = SelectedTheme?.Id ?? 0; + }); + if (changeResult) + { + WeakReferenceMessenger.Default.Send(new ValueChangedMessage(settingsService.GetApplicationSettings())); + Abort(); + } + } + + /// + /// The abort button to discard the changes and close the modal + /// + [RelayCommand] + private void Abort() + { + WeakReferenceMessenger.Default.Send(new CloseModalMessage(this)); + AvailableThemes.Clear(); + SelectedTheme = null; + } } diff --git a/src/ModularToolManager/Views/ApplicationStyleView.axaml b/src/ModularToolManager/Views/ApplicationStyleView.axaml index b75dbf9..153dd56 100644 --- a/src/ModularToolManager/Views/ApplicationStyleView.axaml +++ b/src/ModularToolManager/Views/ApplicationStyleView.axaml @@ -4,5 +4,9 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="ModularToolManager.Views.ApplicationStyleView"> - + + + + + diff --git a/src/ModularToolManager/Views/FunctionButtonView.axaml b/src/ModularToolManager/Views/FunctionButtonView.axaml index 272dd7b..f5f7992 100644 --- a/src/ModularToolManager/Views/FunctionButtonView.axaml +++ b/src/ModularToolManager/Views/FunctionButtonView.axaml @@ -5,27 +5,35 @@ xmlns:p="clr-namespace:ModularToolManager.Properties" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="ModularToolManager.Views.FunctionButtonView"> - + + + + diff --git a/src/ModularToolManager/Views/MainWindow.axaml.cs b/src/ModularToolManager/Views/MainWindow.axaml.cs index e096f8f..6f45a49 100644 --- a/src/ModularToolManager/Views/MainWindow.axaml.cs +++ b/src/ModularToolManager/Views/MainWindow.axaml.cs @@ -8,14 +8,20 @@ using ModularToolManager.Models.Messages; using ModularToolManager.Services.Settings; using ModularToolManager.Services.Ui; +using System; namespace ModularToolManager.Views; /// /// The main window of the application /// -public partial class MainWindow : Window +public partial class MainWindow : Window, IDisposable { + /// + /// Was the class already disposed + /// + private bool isDisposed; + /// /// The modal service to use /// @@ -75,7 +81,13 @@ public MainWindow(IWindowManagementService? modalService, ISettingsService? sett Topmost = false; } }); - WeakReferenceMessenger.Default.Register(this, (_, e) => e.Reply(IsVisible)); + WeakReferenceMessenger.Default.Register(this, (_, e) => + { + if (!e.HasReceivedResponse) + { + e.Reply(IsVisible); + } + }); WeakReferenceMessenger.Default.Register>(this, (_, settings) => { Topmost = settings.Value.AlwaysOnTop; @@ -120,4 +132,23 @@ private void InitializeComponent() { AvaloniaXamlLoader.Load(this); } + + /// + public void Dispose() + { + if (isDisposed) + { + return; + } + WeakReferenceMessenger.Default.UnregisterAll(this); + isDisposed = true; + } + + /// + /// Deconstructor to ensure disposal on object desctruction + /// + ~MainWindow() + { + Dispose(); + } } diff --git a/src/ModularToolManager/Views/SettingsView.axaml b/src/ModularToolManager/Views/SettingsView.axaml index b77a350..285df84 100644 --- a/src/ModularToolManager/Views/SettingsView.axaml +++ b/src/ModularToolManager/Views/SettingsView.axaml @@ -11,6 +11,10 @@ Content="{x:Static p:Resources.Settings_KeepOnTop}" IsChecked="{Binding TopMost}" /> +