From 4c5c785aa635cf8caec1b53e3dfb85eafa4d2991 Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 27 Nov 2021 23:02:02 +0100 Subject: [PATCH] Meta - Updated Nuget packages Settings - Changed where panels start scrolling Home - Clip cards to bounds Sidebar - Added category creation/renaming Debugger - Fixed existing window focus Tray icon - Implemented all functionality --- src/Artemis.ConsoleUI/packages.lock.json | 8 +- src/Artemis.Core/Artemis.Core.csproj | 2 +- src/Artemis.Core/packages.lock.json | 8 +- src/Artemis.Storage/Artemis.Storage.csproj | 2 +- src/Artemis.Storage/packages.lock.json | 6 +- .../Artemis.UI.Avalonia.Shared.xml | 46 ++ src/Artemis.UI.Shared/packages.lock.json | 8 +- src/Artemis.UI/packages.lock.json | 8 +- .../packages.lock.json | 8 +- .../Artemis.UI.Linux/packages.lock.json | 139 ++-- .../Artemis.UI.MacOS/packages.lock.json | 139 ++-- .../Artemis.UI.Shared.csproj | 11 +- .../DataValidationErrorsExtensions.cs | 25 + .../Services/Builders/ContentDialogBuilder.cs | 30 +- .../Services/WindowService/WindowService.cs | 2 +- .../Artemis.UI.Shared/ViewModelBase.cs | 59 ++ .../Artemis.UI.Shared/packages.lock.json | 180 +++-- .../Artemis.UI.Windows/packages.lock.json | 139 ++-- src/Avalonia/Artemis.UI/Artemis.UI.csproj | 9 +- src/Avalonia/Artemis.UI/ArtemisTrayIcon.axaml | 2 +- src/Avalonia/Artemis.UI/MainWindow.axaml | 5 +- .../Ninject/Factories/IVMFactory.cs | 2 +- .../Screens/Debugger/DebugView.axaml.cs | 29 +- .../Screens/Debugger/DebugViewModel.cs | 18 +- .../Device/DeviceDetectInputViewModel.cs | 2 +- .../Artemis.UI/Screens/Home/HomeView.axaml | 7 +- .../Artemis.UI/Screens/Root/RootViewModel.cs | 52 +- .../Dialogs/SidebarCategoryCreateView.axaml | 13 + .../SidebarCategoryCreateView.axaml.cs | 21 + .../Dialogs/SidebarCategoryCreateViewModel.cs | 60 ++ .../Root/Sidebar/SidebarCategoryView.axaml | 30 +- .../Root/Sidebar/SidebarCategoryViewModel.cs | 23 +- .../Screens/Root/Sidebar/SidebarView.axaml | 5 +- .../Screens/Root/Sidebar/SidebarViewModel.cs | 24 +- .../Screens/Settings/SettingsView.axaml | 7 - .../Settings/Tabs/DevicesTabView.axaml | 40 +- .../Settings/Tabs/GeneralTabView.axaml | 660 +++++++++--------- .../Settings/Tabs/PluginsTabView.axaml | 4 +- .../Artemis.UI/Services/DebugService.cs | 4 +- src/Avalonia/Artemis.UI/ViewLocator.cs | 4 +- src/Avalonia/Artemis.UI/packages.lock.json | 139 ++-- 41 files changed, 1144 insertions(+), 836 deletions(-) create mode 100644 src/Avalonia/Artemis.UI.Shared/Extensions/DataValidationErrorsExtensions.cs create mode 100644 src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateView.axaml create mode 100644 src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateView.axaml.cs create mode 100644 src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateViewModel.cs diff --git a/src/Artemis.ConsoleUI/packages.lock.json b/src/Artemis.ConsoleUI/packages.lock.json index feeaa74a8..2bb2a6632 100644 --- a/src/Artemis.ConsoleUI/packages.lock.json +++ b/src/Artemis.ConsoleUI/packages.lock.json @@ -89,8 +89,8 @@ }, "LiteDB": { "type": "Transitive", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "McMaster.NETCore.Plugins": { "type": "Transitive", @@ -1217,7 +1217,7 @@ "EmbedIO": "3.4.3", "HidSharp": "2.1.0", "Humanizer.Core": "2.11.10", - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "McMaster.NETCore.Plugins": "1.4.0", "Newtonsoft.Json": "13.0.1", "Ninject": "3.3.4", @@ -1238,7 +1238,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } } diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index f73a999ab..b96547b2f 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -41,7 +41,7 @@ - + diff --git a/src/Artemis.Core/packages.lock.json b/src/Artemis.Core/packages.lock.json index ea7b5f80c..85eb5a7b3 100644 --- a/src/Artemis.Core/packages.lock.json +++ b/src/Artemis.Core/packages.lock.json @@ -25,9 +25,9 @@ }, "LiteDB": { "type": "Direct", - "requested": "[5.0.10, )", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "requested": "[5.0.11, )", + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "McMaster.NETCore.Plugins": { "type": "Direct", @@ -1225,7 +1225,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } } diff --git a/src/Artemis.Storage/Artemis.Storage.csproj b/src/Artemis.Storage/Artemis.Storage.csproj index 5b7bf94ff..4819a4a9f 100644 --- a/src/Artemis.Storage/Artemis.Storage.csproj +++ b/src/Artemis.Storage/Artemis.Storage.csproj @@ -9,7 +9,7 @@ - + \ No newline at end of file diff --git a/src/Artemis.Storage/packages.lock.json b/src/Artemis.Storage/packages.lock.json index 80dc5f587..880bfe32f 100644 --- a/src/Artemis.Storage/packages.lock.json +++ b/src/Artemis.Storage/packages.lock.json @@ -4,9 +4,9 @@ ".NETCoreApp,Version=v5.0": { "LiteDB": { "type": "Direct", - "requested": "[5.0.10, )", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "requested": "[5.0.11, )", + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "Serilog": { "type": "Direct", diff --git a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml index 7dec575f1..94a337097 100644 --- a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml +++ b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml @@ -689,6 +689,17 @@ Represents errors that occur within the Artemis Shared UI library + + + Provides extension methods for Avalonia's type + + + + + Clears all data validation errors on the given control and any of it's logical siblings + + The target control + The main of the Artemis Shared UI toolkit that binds all services @@ -1070,6 +1081,41 @@ Occurs when the main window has been closed + + + Represents the base class for Artemis view models + + + + + Gets the content dialog that hosts the view model + + + + + + + + Releases the unmanaged resources used by the object and optionally releases the managed resources. + + + to release both managed and unmanaged resources; + to release only unmanaged resources. + + + + + + + + Represents the base class for Artemis view models + + + + + Gets or sets the display name of the view model + + Represents the base class for Artemis view models diff --git a/src/Artemis.UI.Shared/packages.lock.json b/src/Artemis.UI.Shared/packages.lock.json index 23ece4496..fb3492af0 100644 --- a/src/Artemis.UI.Shared/packages.lock.json +++ b/src/Artemis.UI.Shared/packages.lock.json @@ -136,8 +136,8 @@ }, "LiteDB": { "type": "Transitive", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "MaterialDesignColors": { "type": "Transitive", @@ -1297,7 +1297,7 @@ "EmbedIO": "3.4.3", "HidSharp": "2.1.0", "Humanizer.Core": "2.11.10", - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "McMaster.NETCore.Plugins": "1.4.0", "Newtonsoft.Json": "13.0.1", "Ninject": "3.3.4", @@ -1318,7 +1318,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } } diff --git a/src/Artemis.UI/packages.lock.json b/src/Artemis.UI/packages.lock.json index e71abceb3..0c9eb0d1f 100644 --- a/src/Artemis.UI/packages.lock.json +++ b/src/Artemis.UI/packages.lock.json @@ -254,8 +254,8 @@ }, "LiteDB": { "type": "Transitive", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "MaterialDesignColors": { "type": "Transitive", @@ -1443,7 +1443,7 @@ "EmbedIO": "3.4.3", "HidSharp": "2.1.0", "Humanizer.Core": "2.11.10", - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "McMaster.NETCore.Plugins": "1.4.0", "Newtonsoft.Json": "13.0.1", "Ninject": "3.3.4", @@ -1464,7 +1464,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } }, diff --git a/src/Artemis.VisualScripting/packages.lock.json b/src/Artemis.VisualScripting/packages.lock.json index 6683a82b1..6c867521c 100644 --- a/src/Artemis.VisualScripting/packages.lock.json +++ b/src/Artemis.VisualScripting/packages.lock.json @@ -91,8 +91,8 @@ }, "LiteDB": { "type": "Transitive", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "MaterialDesignColors": { "type": "Transitive", @@ -1303,7 +1303,7 @@ "EmbedIO": "3.4.3", "HidSharp": "2.1.0", "Humanizer.Core": "2.11.10", - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "McMaster.NETCore.Plugins": "1.4.0", "Newtonsoft.Json": "13.0.1", "Ninject": "3.3.4", @@ -1324,7 +1324,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } }, diff --git a/src/Avalonia/Artemis.UI.Linux/packages.lock.json b/src/Avalonia/Artemis.UI.Linux/packages.lock.json index bc92463a3..4571535af 100644 --- a/src/Avalonia/Artemis.UI.Linux/packages.lock.json +++ b/src/Avalonia/Artemis.UI.Linux/packages.lock.json @@ -71,10 +71,10 @@ }, "Avalonia.Controls.PanAndZoom": { "type": "Transitive", - "resolved": "4.2.0", - "contentHash": "zIQhp86CdV7xmFXFkaQBDNDr0WSyumEdJvqvIrywG5SEQK3HzACt0gR85KX19DHTlkJlnUVjmfkTEiPjwvgGtA==", + "resolved": "4.3.0", + "contentHash": "oUpQm2frhjWll5QWLx8Uzc2VWDNXgPqONlNBLu2gFBis1lkce1jjZvu423U7RNfvg1rOMeZoeiodZq7xZ02STA==", "dependencies": { - "Avalonia": "0.10.8" + "Avalonia": "0.10.10" } }, "Avalonia.FreeDesktop": { @@ -113,13 +113,13 @@ }, "Avalonia.Svg.Skia": { "type": "Transitive", - "resolved": "0.10.8.3", - "contentHash": "w7RYf+8+gOI3uVZZJ59S0EP49LVsyr1jpnZQzVFQqKa3y/c/i2jT/EUoKOeaqPMhFIsQZyEF4iluqoo6aZ05Tw==", + "resolved": "0.10.10", + "contentHash": "7xQkg3b/djGjGQe6ODxCY+LxMeZ0MtSFUOeEu8IMMUG89gueptuS84GZMRY27xG8lvjP3Mu8B1p3/YY5u7UiDg==", "dependencies": { - "Avalonia": "0.10.8", - "Avalonia.Skia": "0.10.8", + "Avalonia": "0.10.10", + "Avalonia.Skia": "0.10.10", "SkiaSharp": "2.80.2", - "Svg.Skia": "0.5.8.3" + "Svg.Skia": "0.5.10" } }, "Avalonia.Win32": { @@ -145,27 +145,27 @@ }, "Avalonia.Xaml.Behaviors": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "rHDkieWZDTjG+PVGQzronzknmH24r2VDtzbNfC3O8FLZGqREsBoCRDrqW4R4bmtD6CqpDPBey5soBYnnDE1m3Q==", + "resolved": "0.10.10.4", + "contentHash": "iSVOObfXch8vFzhYFvwGntRt4l4kg+dxXYc4C4RDhnoyPh60BCMUzdk2gYUYySv9UVSGAhqH4dQPWZ0l9USmYA==", "dependencies": { "Avalonia": "0.10.10", - "Avalonia.Xaml.Interactions": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10" + "Avalonia.Xaml.Interactions": "0.10.10.4", + "Avalonia.Xaml.Interactivity": "0.10.10.4" } }, "Avalonia.Xaml.Interactions": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "bOJvciyk6kUjPx+mg6n+bwHQqRqgNiTDzTBkpokfkcWl9pMAlKvqqUe6YXWVCpKIDBjbzvkAbYa29S0ajqwFxw==", + "resolved": "0.10.10.4", + "contentHash": "OAwrl0tzsz+iX2z3T5wdsEG/JkbnlylfXUjCfbgQlQqODUBO0kk02RpCHJMnV86apkVXjeLV+S5+yA1yX+DT6g==", "dependencies": { "Avalonia": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10" + "Avalonia.Xaml.Interactivity": "0.10.10.4" } }, "Avalonia.Xaml.Interactivity": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "xxWrpi0HsySczpU3Zl6c2ugbkTOs9qwqbvClfi/AKncoVbWpXv7W6J3kfQcfRlnKFwkTPjLyTYKVERIkb7kNCQ==", + "resolved": "0.10.10.4", + "contentHash": "RH33/HboQikon64SCfu1qFpuy4+mox2SEGYbXrrw9mnw3Ogw8PeYTJLtZw8/mNYs6dZAU3NusRBaLIG+0PGisw==", "dependencies": { "Avalonia": "0.10.10" } @@ -189,8 +189,8 @@ }, "DynamicData": { "type": "Transitive", - "resolved": "7.1.1", - "contentHash": "Pc6J5bFnSxEa64PV2V67FMcLlDdpv6m+zTBKSnRN3aLon/WtWWy8kuDpHFbJlgXHtqc6Nxloj9ItuvDlvKC/8w==", + "resolved": "7.3.1", + "contentHash": "E9oTvWlAgzct0MuWt6k+0s+nSDA3LkFVvDwkMUTklIZZnva314KZAEF2vG4XX9I98ia+EpMqjte67jWEBJlsRw==", "dependencies": { "System.Reactive": "5.0.0" } @@ -210,12 +210,12 @@ }, "FluentAvaloniaUI": { "type": "Transitive", - "resolved": "1.1.5", - "contentHash": "1W1VZQaCeH4/kzNM2c9yPHAVVs9lW9/09bzz1lqu7Tvu79u9JCOjwkZmR8rGC0KbyOA7twwVr2/VvB84zDZYvA==", + "resolved": "1.1.6", + "contentHash": "EJukyiTmEVhaYlHdntFMyQKI4+u772rSClKYQqJRfkTb1NoJXLqiIVqMjx8ZQ0pxnfih+6CZ7+x82lfrGHIPUw==", "dependencies": { - "Avalonia": "0.10.9", - "Avalonia.Desktop": "0.10.9", - "Avalonia.Diagnostics": "0.10.9" + "Avalonia": "0.10.10", + "Avalonia.Desktop": "0.10.10", + "Avalonia.Diagnostics": "0.10.10" } }, "Flurl": { @@ -269,8 +269,8 @@ }, "LiteDB": { "type": "Transitive", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "Live.Avalonia": { "type": "Transitive", @@ -505,13 +505,19 @@ }, "ReactiveUI": { "type": "Transitive", - "resolved": "13.2.10", - "contentHash": "fOCbEZ+RsO2Jhv6vB8VX+ZEvczYJaC95atcSG7oXohJeL/sEwbbqvv9k+tbj2l4bRSj2j5CQvhwA3HNLaxlCAg==", + "resolved": "16.2.6", + "contentHash": "jf1RvD8HxHuA6CGQtheGHUCHzRrhpvo0z593Npsz7g8KJWXfGR45Dc9bILJHoymBxhdDD1L1WjUfh0fcucIPPg==", "dependencies": { - "DynamicData": "7.1.1", - "Splat": "10.0.1", - "System.Reactive": "5.0.0", - "System.Runtime.Serialization.Primitives": "4.3.0" + "DynamicData": "7.3.1", + "Splat": "13.1.1" + } + }, + "ReactiveUI.Validation": { + "type": "Transitive", + "resolved": "2.2.1", + "contentHash": "rhEphZ4ErbGfNtbBQ/tYMsLJYHyLVyqidU+sgZ3kXKbS7QrNoM4j6PPxCwLMKsJUuvVL8JN45xgmB9tSwm7+lg==", + "dependencies": { + "ReactiveUI": "16.2.6" } }, "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { @@ -652,8 +658,8 @@ }, "ShimSkiaSharp": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "BWwwsIlYUFF0DUc8Pa9xONIXVDvEL9pOYc9YmWilpHrWC37dcK+H4+tfuxztZxtfJx559HGn+6iZmMDjfFoOxA==" + "resolved": "0.5.10", + "contentHash": "G1ltdwS5+eMhMCoMx31hHjFIznGAjdUK7xAg8raFMFbN09p2tuxzvK7cKbveWm8SEAGIW7NgDyEqGGJzrPrMrg==" }, "SkiaSharp": { "type": "Transitive", @@ -682,22 +688,22 @@ }, "Splat": { "type": "Transitive", - "resolved": "13.1.30", - "contentHash": "yaj3r8CvHQwtvhfTi+dp5LpIb3c4svqe/tL6LdAS8wWP+dXAp3fTCLjYx21TrW1QBFTBJcg9lrJqDPbheSzHbA==" + "resolved": "13.1.63", + "contentHash": "7iW45RA7AbSlQPCgdokmysva5PGd6iBUhuNkC0XD73LF9dxfTkKeo3wZkohU7nvspDhJ7PJsYHvDtxIt5bMQ8Q==" }, "Splat.Ninject": { "type": "Transitive", - "resolved": "13.1.30", - "contentHash": "hYgyD12Syt2l8U/KccMzNUj4nmrdULjoRTF4g5Q9XtVWPrcdTYmLEdcX/prZEWaFT7vGNP6x9uFXvOlM7Jc+gg==", + "resolved": "13.1.63", + "contentHash": "rTF0HSa6p8nxrXj2hwVgkutcTDJUXY34sY+zYK4ky65b7a0ROL8kdiYyxVVLE4Lq31N5Rcd4bBbqlPkgwZguww==", "dependencies": { "Ninject": "3.3.4", - "Splat": "13.1.30" + "Splat": "13.1.63" } }, "Svg.Custom": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "6FnbI4T3uCNN7DYJpfPFa4caTTJzp4YbhU3J4c/syX7wQNSeQ/1u7JZZ+dGgrRUauiWP8VsiCLKP8qinc5xI5w==", + "resolved": "0.5.10", + "contentHash": "Ypi/4NxDxjM24vsK+4Uit08aJUFHcZZpB5Ctb7FLMVevMq0hYeDqzKp6OVLFO5UCX/TxUfRiL1u9F7fvUDA0tQ==", "dependencies": { "Fizzler": "1.2.0", "System.Drawing.Common": "5.0.0", @@ -708,22 +714,22 @@ }, "Svg.Model": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "F/rimPwV5KF64P8oofXGMwOZ0T7b3z1A9OiC4mv5OdSpLpMpUxpSwGLAOkJ5DFqQgXqVjKKLhPdjIjQBwy0AjA==", + "resolved": "0.5.10", + "contentHash": "sh5W7VpghtFjDnPOMa+CEiIKpJPmkb7FxNuHnB2sLZwJR2qzyVlZaBWM95VaRAXlOU8c0qbtA5ZNVREOpzLQRw==", "dependencies": { - "ShimSkiaSharp": "0.5.8.3", - "Svg.Custom": "0.5.8.3" + "ShimSkiaSharp": "0.5.10", + "Svg.Custom": "0.5.10" } }, "Svg.Skia": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "ajQ0aINQtEzWkqEXyJjnwqOFNusWNMHJVGrKa1ISbP21nrWJh+tApydLFVFGGjs91d7K3YOUbWDKlEzzdDQaOg==", + "resolved": "0.5.10", + "contentHash": "Xz/nd+5dNJAh7IbfjyduWIJAtpHNqMopX+ORg6ZNnW6l1I7lK20KHlSdMNy9c18vALrA95eU8WFo00nloLVUkQ==", "dependencies": { "SkiaSharp": "2.80.2", "SkiaSharp.HarfBuzz": "2.80.2", - "Svg.Custom": "0.5.8.3", - "Svg.Model": "0.5.8.3" + "Svg.Custom": "0.5.10", + "Svg.Model": "0.5.10" } }, "System.AppContext": { @@ -1335,15 +1341,6 @@ "System.Runtime.Extensions": "4.3.0" } }, - "System.Runtime.Serialization.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==", - "dependencies": { - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "5.0.0", @@ -1658,7 +1655,7 @@ "EmbedIO": "3.4.3", "HidSharp": "2.1.0", "Humanizer.Core": "2.11.10", - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "McMaster.NETCore.Plugins": "1.4.0", "Newtonsoft.Json": "13.0.1", "Ninject": "3.3.4", @@ -1679,7 +1676,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } }, @@ -1689,16 +1686,17 @@ "Artemis.Core": "1.0.0", "Artemis.UI.Shared": "1.0.0", "Avalonia": "0.10.10", - "Avalonia.Controls.PanAndZoom": "4.2.0", + "Avalonia.Controls.PanAndZoom": "4.3.0", "Avalonia.Desktop": "0.10.10", "Avalonia.Diagnostics": "0.10.10", "Avalonia.ReactiveUI": "0.10.10", - "Avalonia.Svg.Skia": "0.10.8.3", - "FluentAvaloniaUI": "1.1.5", + "Avalonia.Svg.Skia": "0.10.10", + "FluentAvaloniaUI": "1.1.6", "Flurl.Http": "3.2.0", "Live.Avalonia": "1.3.1", "Material.Icons.Avalonia": "1.0.2", - "Splat.Ninject": "13.1.30" + "ReactiveUI.Validation": "2.2.1", + "Splat.Ninject": "13.1.63" } }, "artemis.ui.shared": { @@ -1707,12 +1705,13 @@ "Artemis.Core": "1.0.0", "Avalonia": "0.10.10", "Avalonia.ReactiveUI": "0.10.10", - "Avalonia.Svg.Skia": "0.10.8.3", - "Avalonia.Xaml.Behaviors": "0.10.10", - "Avalonia.Xaml.Interactions": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10", - "FluentAvaloniaUI": "1.1.5", - "Material.Icons.Avalonia": "1.0.2" + "Avalonia.Svg.Skia": "0.10.10", + "Avalonia.Xaml.Behaviors": "0.10.10.4", + "Avalonia.Xaml.Interactions": "0.10.10.4", + "Avalonia.Xaml.Interactivity": "0.10.10.4", + "FluentAvaloniaUI": "1.1.6", + "Material.Icons.Avalonia": "1.0.2", + "ReactiveUI.Validation": "2.2.1" } } } diff --git a/src/Avalonia/Artemis.UI.MacOS/packages.lock.json b/src/Avalonia/Artemis.UI.MacOS/packages.lock.json index bc92463a3..4571535af 100644 --- a/src/Avalonia/Artemis.UI.MacOS/packages.lock.json +++ b/src/Avalonia/Artemis.UI.MacOS/packages.lock.json @@ -71,10 +71,10 @@ }, "Avalonia.Controls.PanAndZoom": { "type": "Transitive", - "resolved": "4.2.0", - "contentHash": "zIQhp86CdV7xmFXFkaQBDNDr0WSyumEdJvqvIrywG5SEQK3HzACt0gR85KX19DHTlkJlnUVjmfkTEiPjwvgGtA==", + "resolved": "4.3.0", + "contentHash": "oUpQm2frhjWll5QWLx8Uzc2VWDNXgPqONlNBLu2gFBis1lkce1jjZvu423U7RNfvg1rOMeZoeiodZq7xZ02STA==", "dependencies": { - "Avalonia": "0.10.8" + "Avalonia": "0.10.10" } }, "Avalonia.FreeDesktop": { @@ -113,13 +113,13 @@ }, "Avalonia.Svg.Skia": { "type": "Transitive", - "resolved": "0.10.8.3", - "contentHash": "w7RYf+8+gOI3uVZZJ59S0EP49LVsyr1jpnZQzVFQqKa3y/c/i2jT/EUoKOeaqPMhFIsQZyEF4iluqoo6aZ05Tw==", + "resolved": "0.10.10", + "contentHash": "7xQkg3b/djGjGQe6ODxCY+LxMeZ0MtSFUOeEu8IMMUG89gueptuS84GZMRY27xG8lvjP3Mu8B1p3/YY5u7UiDg==", "dependencies": { - "Avalonia": "0.10.8", - "Avalonia.Skia": "0.10.8", + "Avalonia": "0.10.10", + "Avalonia.Skia": "0.10.10", "SkiaSharp": "2.80.2", - "Svg.Skia": "0.5.8.3" + "Svg.Skia": "0.5.10" } }, "Avalonia.Win32": { @@ -145,27 +145,27 @@ }, "Avalonia.Xaml.Behaviors": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "rHDkieWZDTjG+PVGQzronzknmH24r2VDtzbNfC3O8FLZGqREsBoCRDrqW4R4bmtD6CqpDPBey5soBYnnDE1m3Q==", + "resolved": "0.10.10.4", + "contentHash": "iSVOObfXch8vFzhYFvwGntRt4l4kg+dxXYc4C4RDhnoyPh60BCMUzdk2gYUYySv9UVSGAhqH4dQPWZ0l9USmYA==", "dependencies": { "Avalonia": "0.10.10", - "Avalonia.Xaml.Interactions": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10" + "Avalonia.Xaml.Interactions": "0.10.10.4", + "Avalonia.Xaml.Interactivity": "0.10.10.4" } }, "Avalonia.Xaml.Interactions": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "bOJvciyk6kUjPx+mg6n+bwHQqRqgNiTDzTBkpokfkcWl9pMAlKvqqUe6YXWVCpKIDBjbzvkAbYa29S0ajqwFxw==", + "resolved": "0.10.10.4", + "contentHash": "OAwrl0tzsz+iX2z3T5wdsEG/JkbnlylfXUjCfbgQlQqODUBO0kk02RpCHJMnV86apkVXjeLV+S5+yA1yX+DT6g==", "dependencies": { "Avalonia": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10" + "Avalonia.Xaml.Interactivity": "0.10.10.4" } }, "Avalonia.Xaml.Interactivity": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "xxWrpi0HsySczpU3Zl6c2ugbkTOs9qwqbvClfi/AKncoVbWpXv7W6J3kfQcfRlnKFwkTPjLyTYKVERIkb7kNCQ==", + "resolved": "0.10.10.4", + "contentHash": "RH33/HboQikon64SCfu1qFpuy4+mox2SEGYbXrrw9mnw3Ogw8PeYTJLtZw8/mNYs6dZAU3NusRBaLIG+0PGisw==", "dependencies": { "Avalonia": "0.10.10" } @@ -189,8 +189,8 @@ }, "DynamicData": { "type": "Transitive", - "resolved": "7.1.1", - "contentHash": "Pc6J5bFnSxEa64PV2V67FMcLlDdpv6m+zTBKSnRN3aLon/WtWWy8kuDpHFbJlgXHtqc6Nxloj9ItuvDlvKC/8w==", + "resolved": "7.3.1", + "contentHash": "E9oTvWlAgzct0MuWt6k+0s+nSDA3LkFVvDwkMUTklIZZnva314KZAEF2vG4XX9I98ia+EpMqjte67jWEBJlsRw==", "dependencies": { "System.Reactive": "5.0.0" } @@ -210,12 +210,12 @@ }, "FluentAvaloniaUI": { "type": "Transitive", - "resolved": "1.1.5", - "contentHash": "1W1VZQaCeH4/kzNM2c9yPHAVVs9lW9/09bzz1lqu7Tvu79u9JCOjwkZmR8rGC0KbyOA7twwVr2/VvB84zDZYvA==", + "resolved": "1.1.6", + "contentHash": "EJukyiTmEVhaYlHdntFMyQKI4+u772rSClKYQqJRfkTb1NoJXLqiIVqMjx8ZQ0pxnfih+6CZ7+x82lfrGHIPUw==", "dependencies": { - "Avalonia": "0.10.9", - "Avalonia.Desktop": "0.10.9", - "Avalonia.Diagnostics": "0.10.9" + "Avalonia": "0.10.10", + "Avalonia.Desktop": "0.10.10", + "Avalonia.Diagnostics": "0.10.10" } }, "Flurl": { @@ -269,8 +269,8 @@ }, "LiteDB": { "type": "Transitive", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "Live.Avalonia": { "type": "Transitive", @@ -505,13 +505,19 @@ }, "ReactiveUI": { "type": "Transitive", - "resolved": "13.2.10", - "contentHash": "fOCbEZ+RsO2Jhv6vB8VX+ZEvczYJaC95atcSG7oXohJeL/sEwbbqvv9k+tbj2l4bRSj2j5CQvhwA3HNLaxlCAg==", + "resolved": "16.2.6", + "contentHash": "jf1RvD8HxHuA6CGQtheGHUCHzRrhpvo0z593Npsz7g8KJWXfGR45Dc9bILJHoymBxhdDD1L1WjUfh0fcucIPPg==", "dependencies": { - "DynamicData": "7.1.1", - "Splat": "10.0.1", - "System.Reactive": "5.0.0", - "System.Runtime.Serialization.Primitives": "4.3.0" + "DynamicData": "7.3.1", + "Splat": "13.1.1" + } + }, + "ReactiveUI.Validation": { + "type": "Transitive", + "resolved": "2.2.1", + "contentHash": "rhEphZ4ErbGfNtbBQ/tYMsLJYHyLVyqidU+sgZ3kXKbS7QrNoM4j6PPxCwLMKsJUuvVL8JN45xgmB9tSwm7+lg==", + "dependencies": { + "ReactiveUI": "16.2.6" } }, "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { @@ -652,8 +658,8 @@ }, "ShimSkiaSharp": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "BWwwsIlYUFF0DUc8Pa9xONIXVDvEL9pOYc9YmWilpHrWC37dcK+H4+tfuxztZxtfJx559HGn+6iZmMDjfFoOxA==" + "resolved": "0.5.10", + "contentHash": "G1ltdwS5+eMhMCoMx31hHjFIznGAjdUK7xAg8raFMFbN09p2tuxzvK7cKbveWm8SEAGIW7NgDyEqGGJzrPrMrg==" }, "SkiaSharp": { "type": "Transitive", @@ -682,22 +688,22 @@ }, "Splat": { "type": "Transitive", - "resolved": "13.1.30", - "contentHash": "yaj3r8CvHQwtvhfTi+dp5LpIb3c4svqe/tL6LdAS8wWP+dXAp3fTCLjYx21TrW1QBFTBJcg9lrJqDPbheSzHbA==" + "resolved": "13.1.63", + "contentHash": "7iW45RA7AbSlQPCgdokmysva5PGd6iBUhuNkC0XD73LF9dxfTkKeo3wZkohU7nvspDhJ7PJsYHvDtxIt5bMQ8Q==" }, "Splat.Ninject": { "type": "Transitive", - "resolved": "13.1.30", - "contentHash": "hYgyD12Syt2l8U/KccMzNUj4nmrdULjoRTF4g5Q9XtVWPrcdTYmLEdcX/prZEWaFT7vGNP6x9uFXvOlM7Jc+gg==", + "resolved": "13.1.63", + "contentHash": "rTF0HSa6p8nxrXj2hwVgkutcTDJUXY34sY+zYK4ky65b7a0ROL8kdiYyxVVLE4Lq31N5Rcd4bBbqlPkgwZguww==", "dependencies": { "Ninject": "3.3.4", - "Splat": "13.1.30" + "Splat": "13.1.63" } }, "Svg.Custom": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "6FnbI4T3uCNN7DYJpfPFa4caTTJzp4YbhU3J4c/syX7wQNSeQ/1u7JZZ+dGgrRUauiWP8VsiCLKP8qinc5xI5w==", + "resolved": "0.5.10", + "contentHash": "Ypi/4NxDxjM24vsK+4Uit08aJUFHcZZpB5Ctb7FLMVevMq0hYeDqzKp6OVLFO5UCX/TxUfRiL1u9F7fvUDA0tQ==", "dependencies": { "Fizzler": "1.2.0", "System.Drawing.Common": "5.0.0", @@ -708,22 +714,22 @@ }, "Svg.Model": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "F/rimPwV5KF64P8oofXGMwOZ0T7b3z1A9OiC4mv5OdSpLpMpUxpSwGLAOkJ5DFqQgXqVjKKLhPdjIjQBwy0AjA==", + "resolved": "0.5.10", + "contentHash": "sh5W7VpghtFjDnPOMa+CEiIKpJPmkb7FxNuHnB2sLZwJR2qzyVlZaBWM95VaRAXlOU8c0qbtA5ZNVREOpzLQRw==", "dependencies": { - "ShimSkiaSharp": "0.5.8.3", - "Svg.Custom": "0.5.8.3" + "ShimSkiaSharp": "0.5.10", + "Svg.Custom": "0.5.10" } }, "Svg.Skia": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "ajQ0aINQtEzWkqEXyJjnwqOFNusWNMHJVGrKa1ISbP21nrWJh+tApydLFVFGGjs91d7K3YOUbWDKlEzzdDQaOg==", + "resolved": "0.5.10", + "contentHash": "Xz/nd+5dNJAh7IbfjyduWIJAtpHNqMopX+ORg6ZNnW6l1I7lK20KHlSdMNy9c18vALrA95eU8WFo00nloLVUkQ==", "dependencies": { "SkiaSharp": "2.80.2", "SkiaSharp.HarfBuzz": "2.80.2", - "Svg.Custom": "0.5.8.3", - "Svg.Model": "0.5.8.3" + "Svg.Custom": "0.5.10", + "Svg.Model": "0.5.10" } }, "System.AppContext": { @@ -1335,15 +1341,6 @@ "System.Runtime.Extensions": "4.3.0" } }, - "System.Runtime.Serialization.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==", - "dependencies": { - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "5.0.0", @@ -1658,7 +1655,7 @@ "EmbedIO": "3.4.3", "HidSharp": "2.1.0", "Humanizer.Core": "2.11.10", - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "McMaster.NETCore.Plugins": "1.4.0", "Newtonsoft.Json": "13.0.1", "Ninject": "3.3.4", @@ -1679,7 +1676,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } }, @@ -1689,16 +1686,17 @@ "Artemis.Core": "1.0.0", "Artemis.UI.Shared": "1.0.0", "Avalonia": "0.10.10", - "Avalonia.Controls.PanAndZoom": "4.2.0", + "Avalonia.Controls.PanAndZoom": "4.3.0", "Avalonia.Desktop": "0.10.10", "Avalonia.Diagnostics": "0.10.10", "Avalonia.ReactiveUI": "0.10.10", - "Avalonia.Svg.Skia": "0.10.8.3", - "FluentAvaloniaUI": "1.1.5", + "Avalonia.Svg.Skia": "0.10.10", + "FluentAvaloniaUI": "1.1.6", "Flurl.Http": "3.2.0", "Live.Avalonia": "1.3.1", "Material.Icons.Avalonia": "1.0.2", - "Splat.Ninject": "13.1.30" + "ReactiveUI.Validation": "2.2.1", + "Splat.Ninject": "13.1.63" } }, "artemis.ui.shared": { @@ -1707,12 +1705,13 @@ "Artemis.Core": "1.0.0", "Avalonia": "0.10.10", "Avalonia.ReactiveUI": "0.10.10", - "Avalonia.Svg.Skia": "0.10.8.3", - "Avalonia.Xaml.Behaviors": "0.10.10", - "Avalonia.Xaml.Interactions": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10", - "FluentAvaloniaUI": "1.1.5", - "Material.Icons.Avalonia": "1.0.2" + "Avalonia.Svg.Skia": "0.10.10", + "Avalonia.Xaml.Behaviors": "0.10.10.4", + "Avalonia.Xaml.Interactions": "0.10.10.4", + "Avalonia.Xaml.Interactivity": "0.10.10.4", + "FluentAvaloniaUI": "1.1.6", + "Material.Icons.Avalonia": "1.0.2", + "ReactiveUI.Validation": "2.2.1" } } } diff --git a/src/Avalonia/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Avalonia/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 98ccfc302..7dbbc699f 100644 --- a/src/Avalonia/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Avalonia/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -18,12 +18,13 @@ - - - - - + + + + + + diff --git a/src/Avalonia/Artemis.UI.Shared/Extensions/DataValidationErrorsExtensions.cs b/src/Avalonia/Artemis.UI.Shared/Extensions/DataValidationErrorsExtensions.cs new file mode 100644 index 000000000..52a09e663 --- /dev/null +++ b/src/Avalonia/Artemis.UI.Shared/Extensions/DataValidationErrorsExtensions.cs @@ -0,0 +1,25 @@ +using Avalonia.Controls; +using Avalonia.LogicalTree; + +namespace Artemis.UI.Shared.Extensions +{ + /// + /// Provides extension methods for Avalonia's type + /// + public static class ControlExtensions + { + /// + /// Clears all data validation errors on the given control and any of it's logical siblings + /// + /// The target control + public static void ClearAllDataValidationErrors(this Control target) + { + DataValidationErrors.ClearErrors(target); + foreach (ILogical logicalChild in target.GetLogicalChildren()) + { + if (logicalChild is Control childControl) + childControl.ClearAllDataValidationErrors(); + } + } + } +} \ No newline at end of file diff --git a/src/Avalonia/Artemis.UI.Shared/Services/Builders/ContentDialogBuilder.cs b/src/Avalonia/Artemis.UI.Shared/Services/Builders/ContentDialogBuilder.cs index c2a5d967f..b6c65f276 100644 --- a/src/Avalonia/Artemis.UI.Shared/Services/Builders/ContentDialogBuilder.cs +++ b/src/Avalonia/Artemis.UI.Shared/Services/Builders/ContentDialogBuilder.cs @@ -6,6 +6,7 @@ using Avalonia.Controls; using FluentAvalonia.UI.Controls; using Ninject; using Ninject.Parameters; +using ReactiveUI; namespace Artemis.UI.Shared.Services.Builders { @@ -14,6 +15,7 @@ namespace Artemis.UI.Shared.Services.Builders private readonly ContentDialog _contentDialog; private readonly IKernel _kernel; private readonly Window _parent; + private ContentDialogViewModelBase? _viewModel; internal ContentDialogBuilder(IKernel kernel, Window parent) { @@ -53,6 +55,13 @@ namespace Artemis.UI.Shared.Services.Builders _contentDialog.PrimaryButtonCommand = builder.Command; _contentDialog.PrimaryButtonCommandParameter = builder.CommandParameter; + // I feel like this isn't my responsibility... + if (builder.Command != null) + { + _contentDialog.IsPrimaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter); + builder.Command.CanExecuteChanged += (_, _) => _contentDialog.IsPrimaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter); + } + return this; } @@ -66,6 +75,13 @@ namespace Artemis.UI.Shared.Services.Builders _contentDialog.SecondaryButtonCommand = builder.Command; _contentDialog.SecondaryButtonCommandParameter = builder.CommandParameter; + // I feel like this isn't my responsibility... + if (builder.Command != null) + { + _contentDialog.IsSecondaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter); + builder.Command.CanExecuteChanged += (_, _) => _contentDialog.IsSecondaryButtonEnabled = builder.Command.CanExecute(builder.CommandParameter); + } + return this; } @@ -75,24 +91,32 @@ namespace Artemis.UI.Shared.Services.Builders return this; } - public ContentDialogBuilder WithViewModel(out T viewModel, params (string name, object value)[] parameters) where T : ViewModelBase + public ContentDialogBuilder WithViewModel(out T viewModel, params (string name, object? value)[] parameters) where T : ContentDialogViewModelBase { IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.name, kv.value)).Cast().ToArray(); viewModel = _kernel.Get(paramsArray); + viewModel.ContentDialog = _contentDialog; _contentDialog.Content = viewModel; + _viewModel = viewModel; return this; } public async Task ShowAsync() { if (_parent.Content is not Panel panel) - return ContentDialogResult.None; + throw new ArtemisSharedUIException($"The parent window {_parent.GetType().FullName} should contain a panel at its root"); try { panel.Children.Add(_contentDialog); - return await _contentDialog.ShowAsync(); + ContentDialogResult result = await _contentDialog.ShowAsync(); + + // Take the dialog away from the VM in case it's going to try to hide it again or whatever... + if (_viewModel != null) + _viewModel.ContentDialog = null; + + return result; } finally { diff --git a/src/Avalonia/Artemis.UI.Shared/Services/WindowService/WindowService.cs b/src/Avalonia/Artemis.UI.Shared/Services/WindowService/WindowService.cs index 8ef62b62c..7d6df0d16 100644 --- a/src/Avalonia/Artemis.UI.Shared/Services/WindowService/WindowService.cs +++ b/src/Avalonia/Artemis.UI.Shared/Services/WindowService/WindowService.cs @@ -142,7 +142,7 @@ namespace Artemis.UI.Shared.Services throw new ArtemisSharedUIException("Can't show a dialog when application lifetime is not IClassicDesktopStyleApplicationLifetime."); } - Window? parent = classic.Windows.FirstOrDefault(w => w.IsActive) ?? classic.MainWindow; + Window? parent = classic.Windows.FirstOrDefault(w => w.IsActive && w.ShowInTaskbar) ?? classic.MainWindow; return parent; } } diff --git a/src/Avalonia/Artemis.UI.Shared/ViewModelBase.cs b/src/Avalonia/Artemis.UI.Shared/ViewModelBase.cs index 5ce9ad05a..85926ff55 100644 --- a/src/Avalonia/Artemis.UI.Shared/ViewModelBase.cs +++ b/src/Avalonia/Artemis.UI.Shared/ViewModelBase.cs @@ -1,10 +1,69 @@ using System; using System.Reactive.Disposables; using Artemis.UI.Shared.Events; +using FluentAvalonia.UI.Controls; using ReactiveUI; +using ReactiveUI.Validation.Helpers; namespace Artemis.UI.Shared { + /// + /// Represents the base class for Artemis view models + /// + public abstract class ContentDialogViewModelBase : ReactiveValidationObject, IActivatableViewModel, IDisposable + { + /// + /// Gets the content dialog that hosts the view model + /// + public ContentDialog? ContentDialog { get; internal set; } + + #region Implementation of IActivatableViewModel + + /// + public ViewModelActivator Activator { get; } = new(); + + #endregion + + #region IDisposable + + /// + /// Releases the unmanaged resources used by the object and optionally releases the managed resources. + /// + /// + /// to release both managed and unmanaged resources; + /// to release only unmanaged resources. + /// + protected virtual void Dispose(bool disposing) + { + } + + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + } + + /// + /// Represents the base class for Artemis view models + /// + public abstract class ViewModelValidationBase : ReactiveValidationObject + { + private string? _displayName; + + /// + /// Gets or sets the display name of the view model + /// + public string? DisplayName + { + get => _displayName; + set => this.RaiseAndSetIfChanged(ref _displayName, value); + } + } + /// /// Represents the base class for Artemis view models /// diff --git a/src/Avalonia/Artemis.UI.Shared/packages.lock.json b/src/Avalonia/Artemis.UI.Shared/packages.lock.json index 4e75df400..df39f637e 100644 --- a/src/Avalonia/Artemis.UI.Shared/packages.lock.json +++ b/src/Avalonia/Artemis.UI.Shared/packages.lock.json @@ -30,55 +30,55 @@ }, "Avalonia.Svg.Skia": { "type": "Direct", - "requested": "[0.10.8.3, )", - "resolved": "0.10.8.3", - "contentHash": "w7RYf+8+gOI3uVZZJ59S0EP49LVsyr1jpnZQzVFQqKa3y/c/i2jT/EUoKOeaqPMhFIsQZyEF4iluqoo6aZ05Tw==", + "requested": "[0.10.10, )", + "resolved": "0.10.10", + "contentHash": "7xQkg3b/djGjGQe6ODxCY+LxMeZ0MtSFUOeEu8IMMUG89gueptuS84GZMRY27xG8lvjP3Mu8B1p3/YY5u7UiDg==", "dependencies": { - "Avalonia": "0.10.8", - "Avalonia.Skia": "0.10.8", + "Avalonia": "0.10.10", + "Avalonia.Skia": "0.10.10", "SkiaSharp": "2.80.2", - "Svg.Skia": "0.5.8.3" + "Svg.Skia": "0.5.10" } }, "Avalonia.Xaml.Behaviors": { "type": "Direct", - "requested": "[0.10.10, )", - "resolved": "0.10.10", - "contentHash": "rHDkieWZDTjG+PVGQzronzknmH24r2VDtzbNfC3O8FLZGqREsBoCRDrqW4R4bmtD6CqpDPBey5soBYnnDE1m3Q==", + "requested": "[0.10.10.4, )", + "resolved": "0.10.10.4", + "contentHash": "iSVOObfXch8vFzhYFvwGntRt4l4kg+dxXYc4C4RDhnoyPh60BCMUzdk2gYUYySv9UVSGAhqH4dQPWZ0l9USmYA==", "dependencies": { "Avalonia": "0.10.10", - "Avalonia.Xaml.Interactions": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10" + "Avalonia.Xaml.Interactions": "0.10.10.4", + "Avalonia.Xaml.Interactivity": "0.10.10.4" } }, "Avalonia.Xaml.Interactions": { "type": "Direct", - "requested": "[0.10.10, )", - "resolved": "0.10.10", - "contentHash": "bOJvciyk6kUjPx+mg6n+bwHQqRqgNiTDzTBkpokfkcWl9pMAlKvqqUe6YXWVCpKIDBjbzvkAbYa29S0ajqwFxw==", + "requested": "[0.10.10.4, )", + "resolved": "0.10.10.4", + "contentHash": "OAwrl0tzsz+iX2z3T5wdsEG/JkbnlylfXUjCfbgQlQqODUBO0kk02RpCHJMnV86apkVXjeLV+S5+yA1yX+DT6g==", "dependencies": { "Avalonia": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10" + "Avalonia.Xaml.Interactivity": "0.10.10.4" } }, "Avalonia.Xaml.Interactivity": { "type": "Direct", - "requested": "[0.10.10, )", - "resolved": "0.10.10", - "contentHash": "xxWrpi0HsySczpU3Zl6c2ugbkTOs9qwqbvClfi/AKncoVbWpXv7W6J3kfQcfRlnKFwkTPjLyTYKVERIkb7kNCQ==", + "requested": "[0.10.10.4, )", + "resolved": "0.10.10.4", + "contentHash": "RH33/HboQikon64SCfu1qFpuy4+mox2SEGYbXrrw9mnw3Ogw8PeYTJLtZw8/mNYs6dZAU3NusRBaLIG+0PGisw==", "dependencies": { "Avalonia": "0.10.10" } }, "FluentAvaloniaUI": { "type": "Direct", - "requested": "[1.1.5, )", - "resolved": "1.1.5", - "contentHash": "1W1VZQaCeH4/kzNM2c9yPHAVVs9lW9/09bzz1lqu7Tvu79u9JCOjwkZmR8rGC0KbyOA7twwVr2/VvB84zDZYvA==", + "requested": "[1.1.6, )", + "resolved": "1.1.6", + "contentHash": "EJukyiTmEVhaYlHdntFMyQKI4+u772rSClKYQqJRfkTb1NoJXLqiIVqMjx8ZQ0pxnfih+6CZ7+x82lfrGHIPUw==", "dependencies": { - "Avalonia": "0.10.9", - "Avalonia.Desktop": "0.10.9", - "Avalonia.Diagnostics": "0.10.9" + "Avalonia": "0.10.10", + "Avalonia.Desktop": "0.10.10", + "Avalonia.Diagnostics": "0.10.10" } }, "Material.Icons.Avalonia": { @@ -91,6 +91,15 @@ "Material.Icons": "1.0.2" } }, + "ReactiveUI.Validation": { + "type": "Direct", + "requested": "[2.2.1, )", + "resolved": "2.2.1", + "contentHash": "rhEphZ4ErbGfNtbBQ/tYMsLJYHyLVyqidU+sgZ3kXKbS7QrNoM4j6PPxCwLMKsJUuvVL8JN45xgmB9tSwm7+lg==", + "dependencies": { + "ReactiveUI": "16.2.6" + } + }, "Avalonia.Angle.Windows.Natives": { "type": "Transitive", "resolved": "2.1.0.2020091801", @@ -98,53 +107,53 @@ }, "Avalonia.Controls.DataGrid": { "type": "Transitive", - "resolved": "0.10.9", - "contentHash": "AiBcvRi6Dbu0q45l2rQYa0uh05VsM2NYtjrAi2KKjDlu7c9molsZ2hFAKzhf0ugxgRT5tLMHAUA2urCWCzDzFw==", + "resolved": "0.10.10", + "contentHash": "AsKm4xBJuCnIdUibNnsU5mNd6+kivhO5gEmpzO9+kNvVZCXxJkKZfmqS+9ghqXnF5c4BDYF5BPvPjZ1cP/jn7Q==", "dependencies": { - "Avalonia": "0.10.9", - "Avalonia.Remote.Protocol": "0.10.9", + "Avalonia": "0.10.10", + "Avalonia.Remote.Protocol": "0.10.10", "JetBrains.Annotations": "10.3.0", "System.Reactive": "5.0.0" } }, "Avalonia.Desktop": { "type": "Transitive", - "resolved": "0.10.9", - "contentHash": "RWWfnBpslILJEqrdVySJP4leZfINXNiTIsNVEs/pKM5cBM/rwlCAKnfKASKgkbAfBByknUpmJd4PgLoavabz3w==", + "resolved": "0.10.10", + "contentHash": "K23aC2UxplUqbKvSehgcwLRU0dACRLSQGLs3bXKKW1n6ICXtWhwqSmx8a1Ju0PbbQISRfoc0IjHoAXlGRNZ1dA==", "dependencies": { - "Avalonia": "0.10.9", - "Avalonia.Native": "0.10.9", - "Avalonia.Skia": "0.10.9", - "Avalonia.Win32": "0.10.9", - "Avalonia.X11": "0.10.9" + "Avalonia": "0.10.10", + "Avalonia.Native": "0.10.10", + "Avalonia.Skia": "0.10.10", + "Avalonia.Win32": "0.10.10", + "Avalonia.X11": "0.10.10" } }, "Avalonia.Diagnostics": { "type": "Transitive", - "resolved": "0.10.9", - "contentHash": "Zc6iMO1TLRMvEi7pwRnpq/jlPyHvz0HotrJelyQs3VYzbrLxNy4YvLfiuWeIT9b3DCozD7V8blzgN7NSBU2mPg==", + "resolved": "0.10.10", + "contentHash": "k4VA+uch7Xtd6kqp+A6XEpsVuARseIh6PQtarI3lxcTFFrNbxDZhD1nXUILXrnp44uQ7JPGpKYGlJ0EElfxhbA==", "dependencies": { - "Avalonia": "0.10.9", - "Avalonia.Controls.DataGrid": "0.10.9", + "Avalonia": "0.10.10", + "Avalonia.Controls.DataGrid": "0.10.10", "Microsoft.CodeAnalysis.CSharp.Scripting": "3.4.0", "System.Reactive": "5.0.0" } }, "Avalonia.FreeDesktop": { "type": "Transitive", - "resolved": "0.10.9", - "contentHash": "SG1hwJNktnCrDK4COtL+IArd2CbAlHBDAYP8wnTEVfnmrAsGvSijvICN8jrNRQnomYRNgA5TjsEFq5Vz8Z9PPQ==", + "resolved": "0.10.10", + "contentHash": "pflbsb3CQkZH6T7NCG16Cu/LhA0kJD2ZvRprjzueIWonuS4pxF231Z2T3xv5LGaXpN44ufBjpMvlczCmb6sieQ==", "dependencies": { - "Avalonia": "0.10.9", + "Avalonia": "0.10.10", "Tmds.DBus": "0.9.0" } }, "Avalonia.Native": { "type": "Transitive", - "resolved": "0.10.9", - "contentHash": "IOZ7S7o2F2STZAj2uTve4nnnF008CK4/nGSqvYxXyM0X3jK4yCkhydbBN7jmItDfD7hR0h+CQfRUS7qekTNlEQ==", + "resolved": "0.10.10", + "contentHash": "pJ8mlzjtlhPA7ueHnCN4FjBmXZMXJ+hKG+6uLnz+3A879oGLei6yacYRVel80sVoIML1ir8A5InWL52ra1Qdag==", "dependencies": { - "Avalonia": "0.10.9" + "Avalonia": "0.10.10" } }, "Avalonia.Remote.Protocol": { @@ -154,10 +163,10 @@ }, "Avalonia.Skia": { "type": "Transitive", - "resolved": "0.10.9", - "contentHash": "NMnwpHg98IgBG334GOD/lOiXZhXnKEuwCV3ztFwURg3IDKdL+erSW7VM/2rpKm6d914j627UvRaAkvMWht2K6g==", + "resolved": "0.10.10", + "contentHash": "8KtlObMQ+8pDMch6SMdPNpIWk9J0OaPjA7lbALEsDkRNb+XLDdIZXWbKle5Y6ASUEQhQGIX4DCP/8UYp7Us5zg==", "dependencies": { - "Avalonia": "0.10.9", + "Avalonia": "0.10.10", "HarfBuzzSharp": "2.6.1.7", "HarfBuzzSharp.NativeAssets.Linux": "2.6.1.7", "SkiaSharp": "2.80.2", @@ -166,10 +175,10 @@ }, "Avalonia.Win32": { "type": "Transitive", - "resolved": "0.10.9", - "contentHash": "hZtdaEyqynFCCoYT/NCZxeE4KajJodLZCzUThv9/diZFqxYsasEQjguDVeTvLaNBVjqxsZXt35C3D72fjDzPww==", + "resolved": "0.10.10", + "contentHash": "6AS6yIB+OS8+g96mj+ShJihjxqhVH6v7jfdqLwjQfGAsqqqN7zBNsFdvoVVCnutuVx0g/9FhCnBTIZyZDlwqkA==", "dependencies": { - "Avalonia": "0.10.9", + "Avalonia": "0.10.10", "Avalonia.Angle.Windows.Natives": "2.1.0.2020091801", "System.Drawing.Common": "4.5.0", "System.Numerics.Vectors": "4.5.0" @@ -177,12 +186,12 @@ }, "Avalonia.X11": { "type": "Transitive", - "resolved": "0.10.9", - "contentHash": "+PoPHSmAhIcxQ1qmxc2kfbBr7Dxddaqi8FNrbCk2dqvEdQAeaxBswYupSoIARtpDE0wqtrXXneWeAnHxl/YgMw==", + "resolved": "0.10.10", + "contentHash": "XsWWNYlKy3XJ8HFzCvv/2Ym8Ku72tN+JxbPX8lLBZSYzQEtvfKQ+DcKb8us1AWjXQhQQSrZQylrtVZ043a4SsQ==", "dependencies": { - "Avalonia": "0.10.9", - "Avalonia.FreeDesktop": "0.10.9", - "Avalonia.Skia": "0.10.9" + "Avalonia": "0.10.10", + "Avalonia.FreeDesktop": "0.10.10", + "Avalonia.Skia": "0.10.10" } }, "Castle.Core": { @@ -204,8 +213,8 @@ }, "DynamicData": { "type": "Transitive", - "resolved": "7.1.1", - "contentHash": "Pc6J5bFnSxEa64PV2V67FMcLlDdpv6m+zTBKSnRN3aLon/WtWWy8kuDpHFbJlgXHtqc6Nxloj9ItuvDlvKC/8w==", + "resolved": "7.3.1", + "contentHash": "E9oTvWlAgzct0MuWt6k+0s+nSDA3LkFVvDwkMUTklIZZnva314KZAEF2vG4XX9I98ia+EpMqjte67jWEBJlsRw==", "dependencies": { "System.Reactive": "5.0.0" } @@ -259,8 +268,8 @@ }, "LiteDB": { "type": "Transitive", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "Material.Icons": { "type": "Transitive", @@ -478,13 +487,11 @@ }, "ReactiveUI": { "type": "Transitive", - "resolved": "13.2.10", - "contentHash": "fOCbEZ+RsO2Jhv6vB8VX+ZEvczYJaC95atcSG7oXohJeL/sEwbbqvv9k+tbj2l4bRSj2j5CQvhwA3HNLaxlCAg==", + "resolved": "16.2.6", + "contentHash": "jf1RvD8HxHuA6CGQtheGHUCHzRrhpvo0z593Npsz7g8KJWXfGR45Dc9bILJHoymBxhdDD1L1WjUfh0fcucIPPg==", "dependencies": { - "DynamicData": "7.1.1", - "Splat": "10.0.1", - "System.Reactive": "5.0.0", - "System.Runtime.Serialization.Primitives": "4.3.0" + "DynamicData": "7.3.1", + "Splat": "13.1.1" } }, "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { @@ -625,8 +632,8 @@ }, "ShimSkiaSharp": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "BWwwsIlYUFF0DUc8Pa9xONIXVDvEL9pOYc9YmWilpHrWC37dcK+H4+tfuxztZxtfJx559HGn+6iZmMDjfFoOxA==" + "resolved": "0.5.10", + "contentHash": "G1ltdwS5+eMhMCoMx31hHjFIznGAjdUK7xAg8raFMFbN09p2tuxzvK7cKbveWm8SEAGIW7NgDyEqGGJzrPrMrg==" }, "SkiaSharp": { "type": "Transitive", @@ -655,13 +662,13 @@ }, "Splat": { "type": "Transitive", - "resolved": "10.0.1", - "contentHash": "N8BMGVuUBnVLAHSVbna/st8XiLd8ulF3BfkKUSGCPqYpDCis3ELvM+aFaZQLBUIBEcweCYVLq3HFEBqHkCKFyA==" + "resolved": "13.1.1", + "contentHash": "Hv41NNJwYEoxjpCrUw0BdzN17YLZrduhrnHgJyXatSgT6Dq/N/viVkPLfohCeoXf7MqA6ppB/AxtUGU3vJ7YEA==" }, "Svg.Custom": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "6FnbI4T3uCNN7DYJpfPFa4caTTJzp4YbhU3J4c/syX7wQNSeQ/1u7JZZ+dGgrRUauiWP8VsiCLKP8qinc5xI5w==", + "resolved": "0.5.10", + "contentHash": "Ypi/4NxDxjM24vsK+4Uit08aJUFHcZZpB5Ctb7FLMVevMq0hYeDqzKp6OVLFO5UCX/TxUfRiL1u9F7fvUDA0tQ==", "dependencies": { "Fizzler": "1.2.0", "System.Drawing.Common": "5.0.0", @@ -672,22 +679,22 @@ }, "Svg.Model": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "F/rimPwV5KF64P8oofXGMwOZ0T7b3z1A9OiC4mv5OdSpLpMpUxpSwGLAOkJ5DFqQgXqVjKKLhPdjIjQBwy0AjA==", + "resolved": "0.5.10", + "contentHash": "sh5W7VpghtFjDnPOMa+CEiIKpJPmkb7FxNuHnB2sLZwJR2qzyVlZaBWM95VaRAXlOU8c0qbtA5ZNVREOpzLQRw==", "dependencies": { - "ShimSkiaSharp": "0.5.8.3", - "Svg.Custom": "0.5.8.3" + "ShimSkiaSharp": "0.5.10", + "Svg.Custom": "0.5.10" } }, "Svg.Skia": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "ajQ0aINQtEzWkqEXyJjnwqOFNusWNMHJVGrKa1ISbP21nrWJh+tApydLFVFGGjs91d7K3YOUbWDKlEzzdDQaOg==", + "resolved": "0.5.10", + "contentHash": "Xz/nd+5dNJAh7IbfjyduWIJAtpHNqMopX+ORg6ZNnW6l1I7lK20KHlSdMNy9c18vALrA95eU8WFo00nloLVUkQ==", "dependencies": { "SkiaSharp": "2.80.2", "SkiaSharp.HarfBuzz": "2.80.2", - "Svg.Custom": "0.5.8.3", - "Svg.Model": "0.5.8.3" + "Svg.Custom": "0.5.10", + "Svg.Model": "0.5.10" } }, "System.AppContext": { @@ -1299,15 +1306,6 @@ "System.Runtime.Extensions": "4.3.0" } }, - "System.Runtime.Serialization.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==", - "dependencies": { - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "5.0.0", @@ -1622,7 +1620,7 @@ "EmbedIO": "3.4.3", "HidSharp": "2.1.0", "Humanizer.Core": "2.11.10", - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "McMaster.NETCore.Plugins": "1.4.0", "Newtonsoft.Json": "13.0.1", "Ninject": "3.3.4", @@ -1643,7 +1641,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } } diff --git a/src/Avalonia/Artemis.UI.Windows/packages.lock.json b/src/Avalonia/Artemis.UI.Windows/packages.lock.json index 7cf886e7b..e5f9d627d 100644 --- a/src/Avalonia/Artemis.UI.Windows/packages.lock.json +++ b/src/Avalonia/Artemis.UI.Windows/packages.lock.json @@ -71,10 +71,10 @@ }, "Avalonia.Controls.PanAndZoom": { "type": "Transitive", - "resolved": "4.2.0", - "contentHash": "zIQhp86CdV7xmFXFkaQBDNDr0WSyumEdJvqvIrywG5SEQK3HzACt0gR85KX19DHTlkJlnUVjmfkTEiPjwvgGtA==", + "resolved": "4.3.0", + "contentHash": "oUpQm2frhjWll5QWLx8Uzc2VWDNXgPqONlNBLu2gFBis1lkce1jjZvu423U7RNfvg1rOMeZoeiodZq7xZ02STA==", "dependencies": { - "Avalonia": "0.10.8" + "Avalonia": "0.10.10" } }, "Avalonia.FreeDesktop": { @@ -113,13 +113,13 @@ }, "Avalonia.Svg.Skia": { "type": "Transitive", - "resolved": "0.10.8.3", - "contentHash": "w7RYf+8+gOI3uVZZJ59S0EP49LVsyr1jpnZQzVFQqKa3y/c/i2jT/EUoKOeaqPMhFIsQZyEF4iluqoo6aZ05Tw==", + "resolved": "0.10.10", + "contentHash": "7xQkg3b/djGjGQe6ODxCY+LxMeZ0MtSFUOeEu8IMMUG89gueptuS84GZMRY27xG8lvjP3Mu8B1p3/YY5u7UiDg==", "dependencies": { - "Avalonia": "0.10.8", - "Avalonia.Skia": "0.10.8", + "Avalonia": "0.10.10", + "Avalonia.Skia": "0.10.10", "SkiaSharp": "2.80.2", - "Svg.Skia": "0.5.8.3" + "Svg.Skia": "0.5.10" } }, "Avalonia.Win32": { @@ -145,27 +145,27 @@ }, "Avalonia.Xaml.Behaviors": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "rHDkieWZDTjG+PVGQzronzknmH24r2VDtzbNfC3O8FLZGqREsBoCRDrqW4R4bmtD6CqpDPBey5soBYnnDE1m3Q==", + "resolved": "0.10.10.4", + "contentHash": "iSVOObfXch8vFzhYFvwGntRt4l4kg+dxXYc4C4RDhnoyPh60BCMUzdk2gYUYySv9UVSGAhqH4dQPWZ0l9USmYA==", "dependencies": { "Avalonia": "0.10.10", - "Avalonia.Xaml.Interactions": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10" + "Avalonia.Xaml.Interactions": "0.10.10.4", + "Avalonia.Xaml.Interactivity": "0.10.10.4" } }, "Avalonia.Xaml.Interactions": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "bOJvciyk6kUjPx+mg6n+bwHQqRqgNiTDzTBkpokfkcWl9pMAlKvqqUe6YXWVCpKIDBjbzvkAbYa29S0ajqwFxw==", + "resolved": "0.10.10.4", + "contentHash": "OAwrl0tzsz+iX2z3T5wdsEG/JkbnlylfXUjCfbgQlQqODUBO0kk02RpCHJMnV86apkVXjeLV+S5+yA1yX+DT6g==", "dependencies": { "Avalonia": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10" + "Avalonia.Xaml.Interactivity": "0.10.10.4" } }, "Avalonia.Xaml.Interactivity": { "type": "Transitive", - "resolved": "0.10.10", - "contentHash": "xxWrpi0HsySczpU3Zl6c2ugbkTOs9qwqbvClfi/AKncoVbWpXv7W6J3kfQcfRlnKFwkTPjLyTYKVERIkb7kNCQ==", + "resolved": "0.10.10.4", + "contentHash": "RH33/HboQikon64SCfu1qFpuy4+mox2SEGYbXrrw9mnw3Ogw8PeYTJLtZw8/mNYs6dZAU3NusRBaLIG+0PGisw==", "dependencies": { "Avalonia": "0.10.10" } @@ -189,8 +189,8 @@ }, "DynamicData": { "type": "Transitive", - "resolved": "7.1.1", - "contentHash": "Pc6J5bFnSxEa64PV2V67FMcLlDdpv6m+zTBKSnRN3aLon/WtWWy8kuDpHFbJlgXHtqc6Nxloj9ItuvDlvKC/8w==", + "resolved": "7.3.1", + "contentHash": "E9oTvWlAgzct0MuWt6k+0s+nSDA3LkFVvDwkMUTklIZZnva314KZAEF2vG4XX9I98ia+EpMqjte67jWEBJlsRw==", "dependencies": { "System.Reactive": "5.0.0" } @@ -210,12 +210,12 @@ }, "FluentAvaloniaUI": { "type": "Transitive", - "resolved": "1.1.5", - "contentHash": "1W1VZQaCeH4/kzNM2c9yPHAVVs9lW9/09bzz1lqu7Tvu79u9JCOjwkZmR8rGC0KbyOA7twwVr2/VvB84zDZYvA==", + "resolved": "1.1.6", + "contentHash": "EJukyiTmEVhaYlHdntFMyQKI4+u772rSClKYQqJRfkTb1NoJXLqiIVqMjx8ZQ0pxnfih+6CZ7+x82lfrGHIPUw==", "dependencies": { - "Avalonia": "0.10.9", - "Avalonia.Desktop": "0.10.9", - "Avalonia.Diagnostics": "0.10.9" + "Avalonia": "0.10.10", + "Avalonia.Desktop": "0.10.10", + "Avalonia.Diagnostics": "0.10.10" } }, "Flurl": { @@ -269,8 +269,8 @@ }, "LiteDB": { "type": "Transitive", - "resolved": "5.0.10", - "contentHash": "x70WuqMDuP75dajqSLvO+AnI/BbwS6da+ukTO7rueV7VoXoQ5CRA9FV4r7cOS4OUr2NS1Up7LDIutjCxQycRvg==" + "resolved": "5.0.11", + "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ==" }, "Live.Avalonia": { "type": "Transitive", @@ -505,13 +505,19 @@ }, "ReactiveUI": { "type": "Transitive", - "resolved": "13.2.10", - "contentHash": "fOCbEZ+RsO2Jhv6vB8VX+ZEvczYJaC95atcSG7oXohJeL/sEwbbqvv9k+tbj2l4bRSj2j5CQvhwA3HNLaxlCAg==", + "resolved": "16.2.6", + "contentHash": "jf1RvD8HxHuA6CGQtheGHUCHzRrhpvo0z593Npsz7g8KJWXfGR45Dc9bILJHoymBxhdDD1L1WjUfh0fcucIPPg==", "dependencies": { - "DynamicData": "7.1.1", - "Splat": "10.0.1", - "System.Reactive": "5.0.0", - "System.Runtime.Serialization.Primitives": "4.3.0" + "DynamicData": "7.3.1", + "Splat": "13.1.1" + } + }, + "ReactiveUI.Validation": { + "type": "Transitive", + "resolved": "2.2.1", + "contentHash": "rhEphZ4ErbGfNtbBQ/tYMsLJYHyLVyqidU+sgZ3kXKbS7QrNoM4j6PPxCwLMKsJUuvVL8JN45xgmB9tSwm7+lg==", + "dependencies": { + "ReactiveUI": "16.2.6" } }, "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { @@ -652,8 +658,8 @@ }, "ShimSkiaSharp": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "BWwwsIlYUFF0DUc8Pa9xONIXVDvEL9pOYc9YmWilpHrWC37dcK+H4+tfuxztZxtfJx559HGn+6iZmMDjfFoOxA==" + "resolved": "0.5.10", + "contentHash": "G1ltdwS5+eMhMCoMx31hHjFIznGAjdUK7xAg8raFMFbN09p2tuxzvK7cKbveWm8SEAGIW7NgDyEqGGJzrPrMrg==" }, "SkiaSharp": { "type": "Transitive", @@ -682,22 +688,22 @@ }, "Splat": { "type": "Transitive", - "resolved": "13.1.30", - "contentHash": "yaj3r8CvHQwtvhfTi+dp5LpIb3c4svqe/tL6LdAS8wWP+dXAp3fTCLjYx21TrW1QBFTBJcg9lrJqDPbheSzHbA==" + "resolved": "13.1.63", + "contentHash": "7iW45RA7AbSlQPCgdokmysva5PGd6iBUhuNkC0XD73LF9dxfTkKeo3wZkohU7nvspDhJ7PJsYHvDtxIt5bMQ8Q==" }, "Splat.Ninject": { "type": "Transitive", - "resolved": "13.1.30", - "contentHash": "hYgyD12Syt2l8U/KccMzNUj4nmrdULjoRTF4g5Q9XtVWPrcdTYmLEdcX/prZEWaFT7vGNP6x9uFXvOlM7Jc+gg==", + "resolved": "13.1.63", + "contentHash": "rTF0HSa6p8nxrXj2hwVgkutcTDJUXY34sY+zYK4ky65b7a0ROL8kdiYyxVVLE4Lq31N5Rcd4bBbqlPkgwZguww==", "dependencies": { "Ninject": "3.3.4", - "Splat": "13.1.30" + "Splat": "13.1.63" } }, "Svg.Custom": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "6FnbI4T3uCNN7DYJpfPFa4caTTJzp4YbhU3J4c/syX7wQNSeQ/1u7JZZ+dGgrRUauiWP8VsiCLKP8qinc5xI5w==", + "resolved": "0.5.10", + "contentHash": "Ypi/4NxDxjM24vsK+4Uit08aJUFHcZZpB5Ctb7FLMVevMq0hYeDqzKp6OVLFO5UCX/TxUfRiL1u9F7fvUDA0tQ==", "dependencies": { "Fizzler": "1.2.0", "System.Drawing.Common": "5.0.0", @@ -708,22 +714,22 @@ }, "Svg.Model": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "F/rimPwV5KF64P8oofXGMwOZ0T7b3z1A9OiC4mv5OdSpLpMpUxpSwGLAOkJ5DFqQgXqVjKKLhPdjIjQBwy0AjA==", + "resolved": "0.5.10", + "contentHash": "sh5W7VpghtFjDnPOMa+CEiIKpJPmkb7FxNuHnB2sLZwJR2qzyVlZaBWM95VaRAXlOU8c0qbtA5ZNVREOpzLQRw==", "dependencies": { - "ShimSkiaSharp": "0.5.8.3", - "Svg.Custom": "0.5.8.3" + "ShimSkiaSharp": "0.5.10", + "Svg.Custom": "0.5.10" } }, "Svg.Skia": { "type": "Transitive", - "resolved": "0.5.8.3", - "contentHash": "ajQ0aINQtEzWkqEXyJjnwqOFNusWNMHJVGrKa1ISbP21nrWJh+tApydLFVFGGjs91d7K3YOUbWDKlEzzdDQaOg==", + "resolved": "0.5.10", + "contentHash": "Xz/nd+5dNJAh7IbfjyduWIJAtpHNqMopX+ORg6ZNnW6l1I7lK20KHlSdMNy9c18vALrA95eU8WFo00nloLVUkQ==", "dependencies": { "SkiaSharp": "2.80.2", "SkiaSharp.HarfBuzz": "2.80.2", - "Svg.Custom": "0.5.8.3", - "Svg.Model": "0.5.8.3" + "Svg.Custom": "0.5.10", + "Svg.Model": "0.5.10" } }, "System.AppContext": { @@ -1335,15 +1341,6 @@ "System.Runtime.Extensions": "4.3.0" } }, - "System.Runtime.Serialization.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==", - "dependencies": { - "System.Resources.ResourceManager": "4.3.0", - "System.Runtime": "4.3.0" - } - }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "5.0.0", @@ -1658,7 +1655,7 @@ "EmbedIO": "3.4.3", "HidSharp": "2.1.0", "Humanizer.Core": "2.11.10", - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "McMaster.NETCore.Plugins": "1.4.0", "Newtonsoft.Json": "13.0.1", "Ninject": "3.3.4", @@ -1679,7 +1676,7 @@ "artemis.storage": { "type": "Project", "dependencies": { - "LiteDB": "5.0.10", + "LiteDB": "5.0.11", "Serilog": "2.10.0" } }, @@ -1689,16 +1686,17 @@ "Artemis.Core": "1.0.0", "Artemis.UI.Shared": "1.0.0", "Avalonia": "0.10.10", - "Avalonia.Controls.PanAndZoom": "4.2.0", + "Avalonia.Controls.PanAndZoom": "4.3.0", "Avalonia.Desktop": "0.10.10", "Avalonia.Diagnostics": "0.10.10", "Avalonia.ReactiveUI": "0.10.10", - "Avalonia.Svg.Skia": "0.10.8.3", - "FluentAvaloniaUI": "1.1.5", + "Avalonia.Svg.Skia": "0.10.10", + "FluentAvaloniaUI": "1.1.6", "Flurl.Http": "3.2.0", "Live.Avalonia": "1.3.1", "Material.Icons.Avalonia": "1.0.2", - "Splat.Ninject": "13.1.30" + "ReactiveUI.Validation": "2.2.1", + "Splat.Ninject": "13.1.63" } }, "artemis.ui.shared": { @@ -1707,12 +1705,13 @@ "Artemis.Core": "1.0.0", "Avalonia": "0.10.10", "Avalonia.ReactiveUI": "0.10.10", - "Avalonia.Svg.Skia": "0.10.8.3", - "Avalonia.Xaml.Behaviors": "0.10.10", - "Avalonia.Xaml.Interactions": "0.10.10", - "Avalonia.Xaml.Interactivity": "0.10.10", - "FluentAvaloniaUI": "1.1.5", - "Material.Icons.Avalonia": "1.0.2" + "Avalonia.Svg.Skia": "0.10.10", + "Avalonia.Xaml.Behaviors": "0.10.10.4", + "Avalonia.Xaml.Interactions": "0.10.10.4", + "Avalonia.Xaml.Interactivity": "0.10.10.4", + "FluentAvaloniaUI": "1.1.6", + "Material.Icons.Avalonia": "1.0.2", + "ReactiveUI.Validation": "2.2.1" } } } diff --git a/src/Avalonia/Artemis.UI/Artemis.UI.csproj b/src/Avalonia/Artemis.UI/Artemis.UI.csproj index 994dc780c..3f8dc2dd6 100644 --- a/src/Avalonia/Artemis.UI/Artemis.UI.csproj +++ b/src/Avalonia/Artemis.UI/Artemis.UI.csproj @@ -14,16 +14,17 @@ - + - - + + - + + diff --git a/src/Avalonia/Artemis.UI/ArtemisTrayIcon.axaml b/src/Avalonia/Artemis.UI/ArtemisTrayIcon.axaml index 2e2530293..d9b3e4f4c 100644 --- a/src/Avalonia/Artemis.UI/ArtemisTrayIcon.axaml +++ b/src/Avalonia/Artemis.UI/ArtemisTrayIcon.axaml @@ -3,7 +3,7 @@ - + diff --git a/src/Avalonia/Artemis.UI/MainWindow.axaml b/src/Avalonia/Artemis.UI/MainWindow.axaml index 38ca7cdb6..2a507bddd 100644 --- a/src/Avalonia/Artemis.UI/MainWindow.axaml +++ b/src/Avalonia/Artemis.UI/MainWindow.axaml @@ -6,5 +6,8 @@ x:Class="Artemis.UI.MainWindow" Icon="/Assets/Images/Logo/bow.ico" Title="Artemis 2.0"> - + + + + \ No newline at end of file diff --git a/src/Avalonia/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Avalonia/Artemis.UI/Ninject/Factories/IVMFactory.cs index 878b09a36..7f83f4027 100644 --- a/src/Avalonia/Artemis.UI/Ninject/Factories/IVMFactory.cs +++ b/src/Avalonia/Artemis.UI/Ninject/Factories/IVMFactory.cs @@ -35,7 +35,7 @@ namespace Artemis.UI.Ninject.Factories public interface ISidebarVmFactory : IVmFactory { SidebarViewModel? SidebarViewModel(IScreen hostScreen); - SidebarCategoryViewModel SidebarCategoryViewModel(ProfileCategory profileCategory); + SidebarCategoryViewModel SidebarCategoryViewModel(SidebarViewModel sidebarViewModel, ProfileCategory profileCategory); SidebarProfileConfigurationViewModel SidebarProfileConfigurationViewModel(ProfileConfiguration profileConfiguration); } diff --git a/src/Avalonia/Artemis.UI/Screens/Debugger/DebugView.axaml.cs b/src/Avalonia/Artemis.UI/Screens/Debugger/DebugView.axaml.cs index fc050bc5c..07bc6b909 100644 --- a/src/Avalonia/Artemis.UI/Screens/Debugger/DebugView.axaml.cs +++ b/src/Avalonia/Artemis.UI/Screens/Debugger/DebugView.axaml.cs @@ -1,5 +1,6 @@ using System; using System.Reactive.Disposables; +using System.Reactive.Linq; using Artemis.UI.Shared.Events; using Avalonia.Controls; using Avalonia.Markup.Xaml; @@ -12,19 +13,20 @@ namespace Artemis.UI.Screens.Debugger { public class DebugView : ReactiveWindow { - private readonly NavigationView _navigation; - public DebugView() { - Activated += OnActivated; - Deactivated += OnDeactivated; InitializeComponent(); + NavigationView navigation = this.Get("Navigation"); - _navigation = this.Get("Navigation"); this.WhenActivated(d => { - ViewModel!.WhenAnyValue(vm => vm!.IsActive).Subscribe(_ => Activate()).DisposeWith(d); - ViewModel!.SelectedItem = (NavigationViewItem) _navigation.MenuItems.ElementAt(0); + Observable.FromEventPattern(x => ViewModel!.ActivationRequested += x, x => ViewModel!.ActivationRequested -= x).Subscribe(_ => + { + WindowState = WindowState.Normal; + Activate(); + + }).DisposeWith(d); + ViewModel!.SelectedItem = (NavigationViewItem) navigation.MenuItems.ElementAt(0); }); } @@ -33,21 +35,8 @@ namespace Artemis.UI.Screens.Debugger AvaloniaXamlLoader.Load(this); } - private void OnDeactivated(object? sender, EventArgs e) - { - if (ViewModel != null) - ViewModel.IsActive = false; - } - - private void OnActivated(object? sender, EventArgs e) - { - if (ViewModel != null) - ViewModel.IsActive = true; - } - private void DeviceVisualizer_OnLedClicked(object? sender, LedClickedEventArgs e) { - } } } \ No newline at end of file diff --git a/src/Avalonia/Artemis.UI/Screens/Debugger/DebugViewModel.cs b/src/Avalonia/Artemis.UI/Screens/Debugger/DebugViewModel.cs index 39f75b565..20080c129 100644 --- a/src/Avalonia/Artemis.UI/Screens/Debugger/DebugViewModel.cs +++ b/src/Avalonia/Artemis.UI/Screens/Debugger/DebugViewModel.cs @@ -18,7 +18,6 @@ namespace Artemis.UI.Screens.Debugger { private readonly IKernel _kernel; private readonly IDebugService _debugService; - private bool _isActive; private NavigationViewItem? _selectedItem; public DebugViewModel(IKernel kernel, IDebugService debugService) @@ -35,11 +34,6 @@ namespace Artemis.UI.Screens.Debugger }); } - public bool IsActive - { - get => _isActive; - set => this.RaiseAndSetIfChanged(ref _isActive, value); - } public NavigationViewItem? SelectedItem { @@ -77,5 +71,17 @@ namespace Artemis.UI.Screens.Debugger } public RoutingState Router { get; } = new(); + + public void Activate() + { + OnActivationRequested(); + } + + public event EventHandler? ActivationRequested; + + protected virtual void OnActivationRequested() + { + ActivationRequested?.Invoke(this, EventArgs.Empty); + } } } \ No newline at end of file diff --git a/src/Avalonia/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs b/src/Avalonia/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs index e69616629..b08d51459 100644 --- a/src/Avalonia/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs +++ b/src/Avalonia/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs @@ -12,7 +12,7 @@ using RGB.NET.Core; namespace Artemis.UI.Screens.Device { - public class DeviceDetectInputViewModel : ActivatableViewModelBase + public class DeviceDetectInputViewModel : ContentDialogViewModelBase { private readonly IInputService _inputService; private readonly INotificationService _notificationService; diff --git a/src/Avalonia/Artemis.UI/Screens/Home/HomeView.axaml b/src/Avalonia/Artemis.UI/Screens/Home/HomeView.axaml index c34ba7bca..ca58c2982 100644 --- a/src/Avalonia/Artemis.UI/Screens/Home/HomeView.axaml +++ b/src/Avalonia/Artemis.UI/Screens/Home/HomeView.axaml @@ -2,7 +2,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:svg="clr-namespace:Avalonia.Svg.Skia;assembly=Avalonia.Svg.Skia" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="900" @@ -29,7 +28,7 @@ Text=" Welcome to Artemis, the unified RGB platform." /> - + @@ -55,7 +54,7 @@ - + @@ -95,7 +94,7 @@ - + diff --git a/src/Avalonia/Artemis.UI/Screens/Root/RootViewModel.cs b/src/Avalonia/Artemis.UI/Screens/Root/RootViewModel.cs index a702c091e..177d5496a 100644 --- a/src/Avalonia/Artemis.UI/Screens/Root/RootViewModel.cs +++ b/src/Avalonia/Artemis.UI/Screens/Root/RootViewModel.cs @@ -4,7 +4,11 @@ using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Ninject.Factories; +using Artemis.UI.Screens.Home; using Artemis.UI.Screens.Root.Sidebar; +using Artemis.UI.Screens.Settings; +using Artemis.UI.Screens.SurfaceEditor; +using Artemis.UI.Screens.Workshop; using Artemis.UI.Services.Interfaces; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.Interfaces; @@ -14,6 +18,8 @@ using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Platform; using Avalonia.Threading; +using Ninject; +using Ninject.Parameters; using ReactiveUI; namespace Artemis.UI.Screens.Root @@ -24,6 +30,7 @@ namespace Artemis.UI.Screens.Root private readonly ICoreService _coreService; private readonly ISettingsService _settingsService; private readonly IWindowService _windowService; + private readonly IDebugService _debugService; private readonly IAssetLoader _assetLoader; private readonly ISidebarVmFactory _sidebarVmFactory; private SidebarViewModel? _sidebarViewModel; @@ -35,6 +42,7 @@ namespace Artemis.UI.Screens.Root IRegistrationService registrationService, IWindowService windowService, IMainWindowService mainWindowService, + IDebugService debugService, IAssetLoader assetLoader, ISidebarVmFactory sidebarVmFactory) { @@ -43,6 +51,7 @@ namespace Artemis.UI.Screens.Root _coreService = coreService; _settingsService = settingsService; _windowService = windowService; + _debugService = debugService; _assetLoader = assetLoader; _sidebarVmFactory = sidebarVmFactory; _lifeTime = (IClassicDesktopStyleApplicationLifetime) Application.Current.ApplicationLifetime; @@ -50,7 +59,7 @@ namespace Artemis.UI.Screens.Root coreService.StartupArguments = _lifeTime.Args.ToList(); mainWindowService.ConfigureMainWindowProvider(this); registrationService.RegisterProviders(); - + DisplayAccordingToSettings(); Task.Run(coreService.Initialize); } @@ -64,13 +73,6 @@ namespace Artemis.UI.Screens.Root /// public RoutingState Router { get; } - public async Task Exit() - { - // Don't freeze the UI right after clicking - await Task.Delay(200); - Utilities.Shutdown(); - } - private void CurrentMainWindowOnClosed(object? sender, EventArgs e) { _lifeTime.MainWindow = null; @@ -88,7 +90,7 @@ namespace Artemis.UI.Screens.Root // Always show the tray icon if ShowOnStartup is false or the user has no way to open the main window bool showTrayIcon = !showOnAutoRun || _settingsService.GetSetting("UI.ShowTrayIcon", true).Value; - if (showTrayIcon) + if (showTrayIcon) ShowTrayIcon(); if (autoRunning && !showOnAutoRun || minimized) @@ -109,7 +111,11 @@ namespace Artemis.UI.Screens.Root private void ShowTrayIcon() { - _trayIcon = new TrayIcon {Icon = new WindowIcon(_assetLoader.Open(new Uri("avares://Artemis.UI/Assets/Images/Logo/bow.ico")))}; + _trayIcon = new TrayIcon + { + Icon = new WindowIcon(_assetLoader.Open(new Uri("avares://Artemis.UI/Assets/Images/Logo/bow.ico"))), + Command = ReactiveCommand.Create(OpenMainWindow) + }; _trayIcon.Menu = (NativeMenu?) Application.Current.FindResource("TrayIconMenu"); _trayIcons = new TrayIcons {_trayIcon}; TrayIcon.SetIcons(Application.Current, _trayIcons); @@ -124,6 +130,30 @@ namespace Artemis.UI.Screens.Root _trayIcons = null; } + #region Tray commands + + public void OpenScreen(string displayName) + { + OpenMainWindow(); + + // At this point there is a sidebar VM because the main window was opened + SidebarViewModel!.SelectedSidebarScreen = SidebarViewModel.SidebarScreens.FirstOrDefault(s => s.DisplayName == displayName); + } + + public async Task OpenDebugger() + { + await Dispatcher.UIThread.InvokeAsync(() => _debugService.ShowDebugger()); + } + + public async Task Exit() + { + // Don't freeze the UI right after clicking + await Task.Delay(200); + Utilities.Shutdown(); + } + + #endregion + #region Implementation of IMainWindowProvider /// @@ -140,8 +170,8 @@ namespace Artemis.UI.Screens.Root _lifeTime.MainWindow.Closed += CurrentMainWindowOnClosed; } + _lifeTime.MainWindow.WindowState = WindowState.Normal; _lifeTime.MainWindow.Activate(); - OnMainWindowOpened(); } diff --git a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateView.axaml b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateView.axaml new file mode 100644 index 000000000..b7bafdec8 --- /dev/null +++ b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateView.axaml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateView.axaml.cs b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateView.axaml.cs new file mode 100644 index 000000000..8e344301c --- /dev/null +++ b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateView.axaml.cs @@ -0,0 +1,21 @@ +using Artemis.UI.Shared.Extensions; +using Avalonia.Markup.Xaml; +using Avalonia.ReactiveUI; +using ReactiveUI; + +namespace Artemis.UI.Screens.Root.Sidebar.Dialogs +{ + public class SidebarCategoryCreateView : ReactiveUserControl + { + public SidebarCategoryCreateView() + { + InitializeComponent(); + this.WhenActivated(_ => this.ClearAllDataValidationErrors()); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + } +} \ No newline at end of file diff --git a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateViewModel.cs b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateViewModel.cs new file mode 100644 index 000000000..de76b9457 --- /dev/null +++ b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/Dialogs/SidebarCategoryCreateViewModel.cs @@ -0,0 +1,60 @@ +using System.Reactive; +using Artemis.Core; +using Artemis.Core.Services; +using Artemis.UI.Shared; +using FluentAvalonia.UI.Controls; +using ReactiveUI; +using ReactiveUI.Validation.Extensions; + +namespace Artemis.UI.Screens.Root.Sidebar.Dialogs +{ + public class SidebarCategoryCreateViewModel : ContentDialogViewModelBase + { + private readonly IProfileService _profileService; + private readonly ProfileCategory? _category; + private string? _categoryName; + + public SidebarCategoryCreateViewModel(IProfileService profileService, ProfileCategory? category) + { + _profileService = profileService; + _category = category; + + if (_category != null) + _categoryName = _category.Name; + + Confirm = ReactiveCommand.Create(ExecuteConfirm, ValidationContext.Valid); + Delete = ReactiveCommand.Create(ExecuteDelete); + + this.ValidationRule(vm => vm.CategoryName, categoryName => !string.IsNullOrWhiteSpace(categoryName), "You must specify a valid name"); + } + + public ReactiveCommand Delete { get; set; } + + public string? CategoryName + { + get => _categoryName; + set => this.RaiseAndSetIfChanged(ref _categoryName, value); + } + + public ReactiveCommand Confirm { get; } + + private void ExecuteConfirm() + { + if (_category != null) + { + _category.Name = CategoryName!; + _profileService.SaveProfileCategory(_category); + } + else + _profileService.CreateProfileCategory(CategoryName!); + + ContentDialog?.Hide(ContentDialogResult.Primary); + } + + private void ExecuteDelete() + { + if (_category != null) + _profileService.DeleteProfileCategory(_category); + } + } +} \ No newline at end of file diff --git a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarCategoryView.axaml b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarCategoryView.axaml index 500b30c08..da722c486 100644 --- a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarCategoryView.axaml +++ b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarCategoryView.axaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:local="clr-namespace:Artemis.UI.Screens.Root.Sidebar" + xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.Root.Sidebar.SidebarCategoryView"> @@ -27,19 +28,8 @@ - - - - - - - - - - - - - + + + HorizontalAlignment="Right" + Command="{Binding EditCategory}"> - - - - - - + + diff --git a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarCategoryViewModel.cs b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarCategoryViewModel.cs index 5c20689eb..c8b1ffbbb 100644 --- a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarCategoryViewModel.cs +++ b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarCategoryViewModel.cs @@ -1,22 +1,30 @@ using System.Collections.ObjectModel; using System.Linq; +using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Ninject.Factories; +using Artemis.UI.Screens.Root.Sidebar.Dialogs; using Artemis.UI.Shared; +using Artemis.UI.Shared.Services.Interfaces; +using FluentAvalonia.UI.Controls; using ReactiveUI; namespace Artemis.UI.Screens.Root.Sidebar { public class SidebarCategoryViewModel : ViewModelBase { + private readonly SidebarViewModel _sidebarViewModel; private readonly IProfileService _profileService; + private readonly IWindowService _windowService; private readonly ISidebarVmFactory _vmFactory; private SidebarProfileConfigurationViewModel? _selectedProfileConfiguration; - public SidebarCategoryViewModel(ProfileCategory profileCategory, IProfileService profileService, ISidebarVmFactory vmFactory) + public SidebarCategoryViewModel(SidebarViewModel sidebarViewModel, ProfileCategory profileCategory, IProfileService profileService, IWindowService windowService, ISidebarVmFactory vmFactory) { + _sidebarViewModel = sidebarViewModel; _profileService = profileService; + _windowService = windowService; _vmFactory = vmFactory; ProfileCategory = profileCategory; @@ -62,6 +70,19 @@ namespace Artemis.UI.Screens.Root.Sidebar } } + public async Task EditCategory() + { + await _windowService.CreateContentDialog() + .WithTitle("Edit category") + .WithViewModel(out var vm, ("category", ProfileCategory)) + .HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Confirm)) + .HavingSecondaryButton(b => b.WithText("Delete").WithCommand(vm.Delete)) + .WithDefaultButton(ContentDialogButton.Primary) + .ShowAsync(); + + _sidebarViewModel.UpdateProfileCategories(); + } + private void CreateProfileViewModels() { ProfileConfigurations.Clear(); diff --git a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarView.axaml b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarView.axaml index b159cb66a..e9cc753c5 100644 --- a/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarView.axaml +++ b/src/Avalonia/Artemis.UI/Screens/Root/Sidebar/SidebarView.axaml @@ -48,7 +48,10 @@ -