diff --git a/src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs b/src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs
index 27736b149..5d179d0d7 100644
--- a/src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs
+++ b/src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs
@@ -1,9 +1,15 @@
-namespace Artemis.Core
+using System;
+
+namespace Artemis.Core
{
///
/// Represents a configuration dialog for a
///
public interface IPluginConfigurationDialog
{
+ ///
+ /// The type of view model the tab contains
+ ///
+ Type Type { get; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Utilities/Utilities.cs b/src/Artemis.Core/Utilities/Utilities.cs
index cd9299be2..e036fa39b 100644
--- a/src/Artemis.Core/Utilities/Utilities.cs
+++ b/src/Artemis.Core/Utilities/Utilities.cs
@@ -89,6 +89,28 @@ namespace Artemis.Core
}
}
+ ///
+ /// Occurs when the core has requested an application shutdown
+ ///
+ public static event EventHandler? ShutdownRequested;
+
+ ///
+ /// Occurs when the core has requested an application restart
+ ///
+ public static event EventHandler? RestartRequested;
+
+ ///
+ /// Opens the provided folder in the user's file explorer
+ ///
+ /// The full path of the folder to open
+ public static void OpenFolder(string path)
+ {
+ if (OperatingSystem.IsWindows())
+ Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", path);
+ else
+ throw new PlatformNotSupportedException("Can't open folders yet on non-Windows systems Q.Q");
+ }
+
///
/// Gets the current application location
///
@@ -103,6 +125,11 @@ namespace Artemis.Core
RestartRequested?.Invoke(null, e);
}
+ private static void OnShutdownRequested()
+ {
+ ShutdownRequested?.Invoke(null, EventArgs.Empty);
+ }
+
#region Scaling
internal static int RenderScaleMultiplier { get; set; } = 2;
@@ -118,32 +145,13 @@ namespace Artemis.Core
return SKRectI.Create(roundX, roundY, roundWidth, roundHeight);
return SKRectI.Create(
- roundX - (roundX % RenderScaleMultiplier),
- roundY - (roundY % RenderScaleMultiplier),
- roundWidth - (roundWidth % RenderScaleMultiplier),
- roundHeight - (roundHeight % RenderScaleMultiplier)
+ roundX - roundX % RenderScaleMultiplier,
+ roundY - roundY % RenderScaleMultiplier,
+ roundWidth - roundWidth % RenderScaleMultiplier,
+ roundHeight - roundHeight % RenderScaleMultiplier
);
}
#endregion
-
- #region Events
-
- ///
- /// Occurs when the core has requested an application shutdown
- ///
- public static event EventHandler? ShutdownRequested;
-
- ///
- /// Occurs when the core has requested an application restart
- ///
- public static event EventHandler? RestartRequested;
-
- private static void OnShutdownRequested()
- {
- ShutdownRequested?.Invoke(null, EventArgs.Empty);
- }
-
- #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj.DotSettings b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj.DotSettings
index 1865d232b..5230616f2 100644
--- a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj.DotSettings
+++ b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj.DotSettings
@@ -1,2 +1,3 @@
+ TrueTrue
\ No newline at end of file
diff --git a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml
new file mode 100644
index 000000000..30012341d
--- /dev/null
+++ b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml
@@ -0,0 +1,491 @@
+
+
+
+ Artemis.UI.Avalonia.Shared
+
+
+
+
+ Visualizes an with optional per-LED colors
+
+
+
+
+
+
+
+
+
+
+ Occurs when a LED of the device has been clicked
+
+
+
+
+ Invokes the event
+
+
+
+
+
+ Gets or sets the to display
+
+
+
+
+ Gets or sets the to display
+
+
+
+
+ Gets or sets boolean indicating whether or not to show per-LED colors
+
+
+
+
+ Gets or sets a boolean indicating whether or not to show per-LED colors
+
+
+
+
+ Gets or sets a list of LEDs to highlight
+
+
+
+
+ Gets or sets a list of LEDs to highlight
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets or sets the currently selected value
+
+
+
+
+ Gets or sets the currently selected value
+
+
+
+
+
+
+
+
+
+
+ Gets or sets the to display
+
+
+
+
+ Gets or sets the to display
+
+
+
+
+ Visualizes an with optional per-LED colors
+
+
+
+
+ Defines the property.
+
+
+
+
+ Defines the property.
+
+
+
+
+ Defines the property.
+
+
+
+
+ Defines the property.
+
+
+
+
+
+
+
+ Gets or sets a brush used to paint the control's background.
+
+
+
+
+ Gets or sets a brush used to paint the control's border
+
+
+
+
+ Gets or sets the width of the control's border
+
+
+
+
+
+
+
+
+
+
+ Converts into .
+
+
+
+
+
+
+
+
+
+
+ Converts into .
+
+
+
+
+
+
+
+
+
+
+ Provides data about selection events raised by
+
+
+
+
+ Gets the data model path that was selected
+
+
+
+
+ Provides data about submit events raised by
+
+
+
+
+ The value that was submitted
+
+
+
+
+ Provides data on LED click events raised by the device visualizer
+
+
+
+
+ The device that was clicked
+
+
+
+
+ The LED that was clicked
+
+
+
+
+ Provides data on profile related events raised by the profile editor
+
+
+
+
+ Gets the profile the event was raised for
+
+
+
+
+ If applicable, the previous active profile before the event was raised
+
+
+
+
+ Provides data on profile element related events raised by the profile editor
+
+
+
+
+ Gets the profile element the event was raised for
+
+
+
+
+ If applicable, the previous active profile element before the event was raised
+
+
+
+
+ Represents errors that occur within the Artemis Shared UI library
+
+
+
+
+ The main of the Artemis Shared UI toolkit that binds all services
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Describes a configuration dialog for a specific plugin
+
+
+
+
+
+
+
+ Represents a view model for a plugin configuration window
+
+
+
+
+ Creates a new instance of the class
+
+
+
+
+
+ Gets the plugin this configuration view model is associated with
+
+
+
+
+ A command that closes the window
+
+
+
+
+ Represents a builder that can create a .
+
+
+
+
+ Sets the name of the filter
+
+
+
+
+ Adds the provided extension to the filter
+
+
+
+
+ Add a filter to the dialog
+
+
+
+
+ Represents a builder that can create a .
+
+
+
+
+ Indicate that the user can select multiple files.
+
+
+
+
+ Set the title of the dialog
+
+
+
+
+ Set the initial directory of the dialog
+
+
+
+
+ Set the initial file name of the dialog
+
+
+
+
+ Add a filter to the dialog
+
+
+
+
+ Shows the file dialog
+
+
+ A task that on completion returns an array containing the full path to the selected
+ files, or null if the dialog was canceled.
+
+
+
+
+ Represents a builder that can create a .
+
+
+
+
+ Set the title of the dialog
+
+
+
+
+ Set the initial directory of the dialog
+
+
+
+
+ Set the initial file name of the dialog
+
+
+
+
+ Set the default extension of the dialog
+
+
+
+
+ Add a filter to the dialog
+
+
+
+
+ Shows the save file dialog.
+
+
+ A task that on completion contains the full path of the save location, or null if the
+ dialog was canceled.
+
+
+
+
+ Represents a service provided by the Artemis Shared UI library
+
+
+
+
+ Creates a view model instance of type and shows its corresponding View as a window
+
+ The type of view model to create
+ The created view model
+
+
+
+ Given a ViewModel, show its corresponding View as a window
+
+ ViewModel to show the View for
+
+
+
+ Shows a dialog displaying the given exception
+
+ The title of the dialog
+ The exception to display
+
+
+
+ Given an existing ViewModel, show its corresponding View as a Dialog
+
+ The return type
+ ViewModel to show the View for
+ A task containing the return value of type
+
+
+
+ Creates a view model instance of type and shows its corresponding View as a Dialog
+
+ The view model type
+ The return type
+ A task containing the return value of type
+
+
+
+ Shows a content dialog asking the user to confirm an action
+
+ The title of the dialog
+ The message of the dialog
+ The text of the confirm button
+ The text of the cancel button, if the cancel button will not be shown
+ A task containing the result of the dialog, if confirmed; otherwise
+
+
+
+ Creates an open file dialog, use the fluent API to configure it
+
+ The builder that can be used to configure the dialog
+
+
+
+ Creates a save file dialog, use the fluent API to configure it
+
+ The builder that can be used to configure the dialog
+
+
+
+ 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 that are interested in the activated event
+
+
+
+
+
+
+
+ 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 used to drive dialogs
+
+
+
+
+
+
+
+ Closes the dialog with a given result
+
+
+
+
+ Closes the dialog without a result
+
+
+
+
diff --git a/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationDialog.cs b/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationDialog.cs
new file mode 100644
index 000000000..48736d54e
--- /dev/null
+++ b/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationDialog.cs
@@ -0,0 +1,21 @@
+using System;
+using Artemis.Core;
+
+namespace Artemis.UI.Avalonia.Shared
+{
+ ///
+ public class PluginConfigurationDialog : PluginConfigurationDialog where T : PluginConfigurationViewModel
+ {
+ ///
+ public override Type Type => typeof(T);
+ }
+
+ ///
+ /// Describes a configuration dialog for a specific plugin
+ ///
+ public abstract class PluginConfigurationDialog : IPluginConfigurationDialog
+ {
+ ///
+ public abstract Type Type { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationViewModel.cs b/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationViewModel.cs
new file mode 100644
index 000000000..008d8ccb7
--- /dev/null
+++ b/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationViewModel.cs
@@ -0,0 +1,32 @@
+using System.Reactive;
+using Artemis.Core;
+using ReactiveUI;
+
+namespace Artemis.UI.Avalonia.Shared
+{
+ ///
+ /// Represents a view model for a plugin configuration window
+ ///
+ public abstract class PluginConfigurationViewModel : ViewModelBase, IPluginConfigurationViewModel
+ {
+ ///
+ /// Creates a new instance of the class
+ ///
+ ///
+ protected PluginConfigurationViewModel(Plugin plugin)
+ {
+ Plugin = plugin;
+ Close = ReactiveCommand.Create(() => { });
+ }
+
+ ///
+ /// Gets the plugin this configuration view model is associated with
+ ///
+ public Plugin Plugin { get; }
+
+ ///
+ /// A command that closes the window
+ ///
+ public ReactiveCommand Close { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Avalonia.Shared/Services/Builders/NotificationBuilder.cs b/src/Artemis.UI.Avalonia.Shared/Services/Builders/NotificationBuilder.cs
index 4d4e6d04f..7cd562f7c 100644
--- a/src/Artemis.UI.Avalonia.Shared/Services/Builders/NotificationBuilder.cs
+++ b/src/Artemis.UI.Avalonia.Shared/Services/Builders/NotificationBuilder.cs
@@ -1,6 +1,5 @@
using System;
using System.Threading.Tasks;
-using Artemis.UI.Avalonia.Shared.Utilities;
using Avalonia.Controls;
using Avalonia.Threading;
using FluentAvalonia.UI.Controls;
diff --git a/src/Artemis.UI.Avalonia.Shared/Services/Interfaces/IWindowService.cs b/src/Artemis.UI.Avalonia.Shared/Services/Interfaces/IWindowService.cs
index ea73f0756..8efcda80a 100644
--- a/src/Artemis.UI.Avalonia.Shared/Services/Interfaces/IWindowService.cs
+++ b/src/Artemis.UI.Avalonia.Shared/Services/Interfaces/IWindowService.cs
@@ -43,6 +43,16 @@ namespace Artemis.UI.Avalonia.Shared.Services.Interfaces
/// A task containing the return value of type
Task ShowDialogAsync(params (string name, object value)[] parameters) where TViewModel : DialogViewModelBase;
+ ///
+ /// Shows a content dialog asking the user to confirm an action
+ ///
+ /// The title of the dialog
+ /// The message of the dialog
+ /// The text of the confirm button
+ /// The text of the cancel button, if the cancel button will not be shown
+ /// A task containing the result of the dialog, if confirmed; otherwise
+ Task ShowConfirmContentDialog(string title, string message, string confirm = "Confirm", string? cancel = "Cancel");
+
///
/// Creates an open file dialog, use the fluent API to configure it
///
@@ -57,8 +67,6 @@ namespace Artemis.UI.Avalonia.Shared.Services.Interfaces
ContentDialogBuilder CreateContentDialog();
- ConfirmDialogBuilder CreateConfirmDialog();
-
Window GetCurrentWindow();
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Avalonia.Shared/Services/WindowService/ExceptionDialogView.axaml.cs b/src/Artemis.UI.Avalonia.Shared/Services/WindowService/ExceptionDialogView.axaml.cs
index 8457638c4..773c3f6d7 100644
--- a/src/Artemis.UI.Avalonia.Shared/Services/WindowService/ExceptionDialogView.axaml.cs
+++ b/src/Artemis.UI.Avalonia.Shared/Services/WindowService/ExceptionDialogView.axaml.cs
@@ -1,4 +1,6 @@
+using Avalonia;
using Avalonia.Markup.Xaml;
+using Avalonia.ReactiveUI;
namespace Artemis.UI.Avalonia.Shared.Services
{
diff --git a/src/Artemis.UI.Avalonia.Shared/Services/WindowService/WindowService.cs b/src/Artemis.UI.Avalonia.Shared/Services/WindowService/WindowService.cs
index 8dfe1c199..15959fe96 100644
--- a/src/Artemis.UI.Avalonia.Shared/Services/WindowService/WindowService.cs
+++ b/src/Artemis.UI.Avalonia.Shared/Services/WindowService/WindowService.cs
@@ -7,6 +7,7 @@ using Artemis.UI.Avalonia.Shared.Services.Interfaces;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
+using FluentAvalonia.UI.Controls;
using Ninject;
using Ninject.Parameters;
@@ -57,6 +58,18 @@ namespace Artemis.UI.Avalonia.Shared.Services
return await ShowDialogAsync(viewModel);
}
+ public async Task ShowConfirmContentDialog(string title, string message, string confirm = "Confirm", string? cancel = "Cancel")
+ {
+ ContentDialogResult contentDialogResult = await CreateContentDialog()
+ .WithTitle(title)
+ .WithContent(message)
+ .HavingPrimaryButton(b => b.WithText(confirm))
+ .WithCloseButtonText(cancel)
+ .ShowAsync();
+
+ return contentDialogResult == ContentDialogResult.Primary;
+ }
+
public async Task ShowDialogAsync(DialogViewModelBase viewModel)
{
if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime classic)
diff --git a/src/Artemis.UI.Avalonia/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI.Avalonia/Ninject/Factories/IVMFactory.cs
index 34a52dbc6..735a93e58 100644
--- a/src/Artemis.UI.Avalonia/Ninject/Factories/IVMFactory.cs
+++ b/src/Artemis.UI.Avalonia/Ninject/Factories/IVMFactory.cs
@@ -22,6 +22,13 @@ namespace Artemis.UI.Avalonia.Ninject.Factories
InputMappingsTabViewModel InputMappingsTabViewModel(ArtemisDevice device, ObservableCollection selectedLeds);
}
+ public interface ISettingsVmFactory : IVmFactory
+ {
+ PluginSettingsViewModel CreatePluginSettingsViewModel(Plugin plugin);
+ PluginFeatureViewModel CreatePluginFeatureViewModel(PluginFeatureInfo pluginFeatureInfo, bool showShield);
+ // DeviceSettingsViewModel CreateDeviceSettingsViewModel(ArtemisDevice device);
+ }
+
public interface ISidebarVmFactory : IVmFactory
{
SidebarViewModel SidebarViewModel(IScreen hostScreen);
diff --git a/src/Artemis.UI.Avalonia/Ninject/UIModule.cs b/src/Artemis.UI.Avalonia/Ninject/UIModule.cs
index 61eebd3ae..faf29a400 100644
--- a/src/Artemis.UI.Avalonia/Ninject/UIModule.cs
+++ b/src/Artemis.UI.Avalonia/Ninject/UIModule.cs
@@ -2,6 +2,7 @@
using Artemis.UI.Avalonia.Ninject.Factories;
using Artemis.UI.Avalonia.Screens;
using Artemis.UI.Avalonia.Services.Interfaces;
+using Artemis.UI.Avalonia.Shared;
using Ninject.Extensions.Conventions;
using Ninject.Modules;
using Ninject.Planning.Bindings.Resolvers;
diff --git a/src/Artemis.UI.Avalonia/Screens/Debugger/DebugViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Debugger/DebugViewModel.cs
index 967de423c..04e7fdc2a 100644
--- a/src/Artemis.UI.Avalonia/Screens/Debugger/DebugViewModel.cs
+++ b/src/Artemis.UI.Avalonia/Screens/Debugger/DebugViewModel.cs
@@ -5,6 +5,7 @@ using Artemis.UI.Avalonia.Screens.Debugger.Tabs.Logs;
using Artemis.UI.Avalonia.Screens.Debugger.Tabs.Performance;
using Artemis.UI.Avalonia.Screens.Debugger.Tabs.Render;
using Artemis.UI.Avalonia.Services.Interfaces;
+using Artemis.UI.Avalonia.Shared;
using FluentAvalonia.UI.Controls;
using Ninject;
using Ninject.Parameters;
diff --git a/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
index bbc5f996e..f5da16218 100644
--- a/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
+++ b/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
@@ -1,4 +1,5 @@
-using ReactiveUI;
+using Artemis.UI.Avalonia.Shared;
+using ReactiveUI;
namespace Artemis.UI.Avalonia.Screens.Debugger.Tabs.DataModel
{
diff --git a/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs
index bca2adce5..01eb8348f 100644
--- a/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs
+++ b/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs
@@ -1,4 +1,5 @@
-using ReactiveUI;
+using Artemis.UI.Avalonia.Shared;
+using ReactiveUI;
namespace Artemis.UI.Avalonia.Screens.Debugger.Tabs.Logs
{
diff --git a/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Performance/PerformanceDebugViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Performance/PerformanceDebugViewModel.cs
index 922bb501c..21ade068f 100644
--- a/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Performance/PerformanceDebugViewModel.cs
+++ b/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Performance/PerformanceDebugViewModel.cs
@@ -1,4 +1,5 @@
-using ReactiveUI;
+using Artemis.UI.Avalonia.Shared;
+using ReactiveUI;
namespace Artemis.UI.Avalonia.Screens.Debugger.Tabs.Performance
{
diff --git a/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Render/RenderDebugViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Render/RenderDebugViewModel.cs
index eda43abca..6f58feab8 100644
--- a/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Render/RenderDebugViewModel.cs
+++ b/src/Artemis.UI.Avalonia/Screens/Debugger/Tabs/Render/RenderDebugViewModel.cs
@@ -3,6 +3,7 @@ using System.Reactive.Disposables;
using System.Timers;
using Artemis.Core;
using Artemis.Core.Services;
+using Artemis.UI.Avalonia.Shared;
using ReactiveUI;
using SkiaSharp;
diff --git a/src/Artemis.UI.Avalonia/Screens/Device/DevicePropertiesViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Device/DevicePropertiesViewModel.cs
index 9fe91baf9..1acc67272 100644
--- a/src/Artemis.UI.Avalonia/Screens/Device/DevicePropertiesViewModel.cs
+++ b/src/Artemis.UI.Avalonia/Screens/Device/DevicePropertiesViewModel.cs
@@ -1,12 +1,13 @@
using System.Collections.ObjectModel;
using Artemis.Core;
using Artemis.UI.Avalonia.Ninject.Factories;
+using Artemis.UI.Avalonia.Shared;
using RGB.NET.Core;
using ArtemisLed = Artemis.Core.ArtemisLed;
namespace Artemis.UI.Avalonia.Screens.Device
{
- public class DevicePropertiesViewModel : ActivatableViewModelBase
+ public class DevicePropertiesViewModel : DialogViewModelBase