mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
UI - Refactorings, project builds and runs again :P
This commit is contained in:
parent
c178fc6cf8
commit
41171a5ade
@ -1,9 +1,15 @@
|
||||
namespace Artemis.Core
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a configuration dialog for a <see cref="Plugin" />
|
||||
/// </summary>
|
||||
public interface IPluginConfigurationDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of view model the tab contains
|
||||
/// </summary>
|
||||
Type Type { get; }
|
||||
}
|
||||
}
|
||||
@ -89,6 +89,28 @@ namespace Artemis.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the core has requested an application shutdown
|
||||
/// </summary>
|
||||
public static event EventHandler? ShutdownRequested;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the core has requested an application restart
|
||||
/// </summary>
|
||||
public static event EventHandler<RestartEventArgs>? RestartRequested;
|
||||
|
||||
/// <summary>
|
||||
/// Opens the provided folder in the user's file explorer
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the folder to open</param>
|
||||
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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current application location
|
||||
/// </summary>
|
||||
@ -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
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the core has requested an application shutdown
|
||||
/// </summary>
|
||||
public static event EventHandler? ShutdownRequested;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the core has requested an application restart
|
||||
/// </summary>
|
||||
public static event EventHandler<RestartEventArgs>? RestartRequested;
|
||||
|
||||
private static void OnShutdownRequested()
|
||||
{
|
||||
ShutdownRequested?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,3 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cwindowservice/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
491
src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml
Normal file
491
src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml
Normal file
@ -0,0 +1,491 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>Artemis.UI.Avalonia.Shared</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer">
|
||||
<summary>
|
||||
Visualizes an <see cref="T:Artemis.Core.ArtemisDevice" /> with optional per-LED colors
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.#ctor">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.Render(Avalonia.Media.DrawingContext)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="E:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.LedClicked">
|
||||
<summary>
|
||||
Occurs when a LED of the device has been clicked
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.OnLedClicked(Artemis.UI.Avalonia.Shared.Events.LedClickedEventArgs)">
|
||||
<summary>
|
||||
Invokes the <see cref="E:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.LedClicked" /> event
|
||||
</summary>
|
||||
<param name="e"></param>
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.DeviceProperty">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:Artemis.Core.ArtemisDevice" /> to display
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.Device">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:Artemis.Core.ArtemisDevice" /> to display
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.ShowColorsProperty">
|
||||
<summary>
|
||||
Gets or sets boolean indicating whether or not to show per-LED colors
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.ShowColors">
|
||||
<summary>
|
||||
Gets or sets a boolean indicating whether or not to show per-LED colors
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.HighlightedLedsProperty">
|
||||
<summary>
|
||||
Gets or sets a list of LEDs to highlight
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.HighlightedLeds">
|
||||
<summary>
|
||||
Gets or sets a list of LEDs to highlight
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.OnAttachedToLogicalTree(Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.OnDetachedFromLogicalTree(Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer.MeasureOverride(Avalonia.Size)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.EnumComboBox.ValueProperty">
|
||||
<summary>
|
||||
Gets or sets the currently selected value
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Controls.EnumComboBox.Value">
|
||||
<summary>
|
||||
Gets or sets the currently selected value
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.EnumComboBox.OnAttachedToLogicalTree(Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.EnumComboBox.OnDetachedFromLogicalTree(Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.ProfileConfigurationIcon.ConfigurationIconProperty">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:Artemis.Core.ProfileConfigurationIcon" /> to display
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Controls.ProfileConfigurationIcon.ConfigurationIcon">
|
||||
<summary>
|
||||
Gets or sets the <see cref="T:Artemis.Core.ProfileConfigurationIcon" /> to display
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle">
|
||||
<summary>
|
||||
Visualizes an <see cref="T:Artemis.Core.ArtemisDevice" /> with optional per-LED colors
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.BackgroundProperty">
|
||||
<summary>
|
||||
Defines the <see cref="P:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.Background" /> property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.BorderBrushProperty">
|
||||
<summary>
|
||||
Defines the <see cref="P:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.BorderBrush" /> property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.BorderThicknessProperty">
|
||||
<summary>
|
||||
Defines the <see cref="P:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.BorderBrush" /> property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.InputElementProperty">
|
||||
<summary>
|
||||
Defines the <see cref="M:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.get_InputElement" /> property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.#ctor">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.Background">
|
||||
<summary>
|
||||
Gets or sets a brush used to paint the control's background.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.BorderBrush">
|
||||
<summary>
|
||||
Gets or sets a brush used to paint the control's border
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.BorderThickness">
|
||||
<summary>
|
||||
Gets or sets the width of the control's border
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.OnAttachedToVisualTree(Avalonia.VisualTreeAttachmentEventArgs)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Controls.SelectionRectangle.OnDetachedFromVisualTree(Avalonia.VisualTreeAttachmentEventArgs)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Converters.ColorToSKColorConverter">
|
||||
<summary>
|
||||
Converts <see cref="T:Avalonia.Media.Color" /> into <see cref="T:SkiaSharp.SKColor" />.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Converters.ColorToSKColorConverter.Convert(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Converters.ColorToSKColorConverter.ConvertBack(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Converters.SKColorToColorConverter">
|
||||
<summary>
|
||||
Converts <see cref="T:SkiaSharp.SKColor" /> into <see cref="T:Avalonia.Media.Color" />.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Converters.SKColorToColorConverter.Convert(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Converters.SKColorToColorConverter.ConvertBack(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Events.DataModelInputDynamicEventArgs">
|
||||
<summary>
|
||||
Provides data about selection events raised by <see cref="!:DataModelDynamicViewModel" />
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Events.DataModelInputDynamicEventArgs.DataModelPath">
|
||||
<summary>
|
||||
Gets the data model path that was selected
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Events.DataModelInputStaticEventArgs">
|
||||
<summary>
|
||||
Provides data about submit events raised by <see cref="!:DataModelStaticViewModel" />
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Events.DataModelInputStaticEventArgs.Value">
|
||||
<summary>
|
||||
The value that was submitted
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Events.LedClickedEventArgs">
|
||||
<summary>
|
||||
Provides data on LED click events raised by the device visualizer
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Events.LedClickedEventArgs.Device">
|
||||
<summary>
|
||||
The device that was clicked
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Events.LedClickedEventArgs.Led">
|
||||
<summary>
|
||||
The LED that was clicked
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Events.ProfileConfigurationEventArgs">
|
||||
<summary>
|
||||
Provides data on profile related events raised by the profile editor
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Events.ProfileConfigurationEventArgs.ProfileConfiguration">
|
||||
<summary>
|
||||
Gets the profile the event was raised for
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Events.ProfileConfigurationEventArgs.PreviousProfileConfiguration">
|
||||
<summary>
|
||||
If applicable, the previous active profile before the event was raised
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Events.RenderProfileElementEventArgs">
|
||||
<summary>
|
||||
Provides data on profile element related events raised by the profile editor
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Events.RenderProfileElementEventArgs.RenderProfileElement">
|
||||
<summary>
|
||||
Gets the profile element the event was raised for
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.Events.RenderProfileElementEventArgs.PreviousRenderProfileElement">
|
||||
<summary>
|
||||
If applicable, the previous active profile element before the event was raised
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Exceptions.ArtemisSharedUIException">
|
||||
<summary>
|
||||
Represents errors that occur within the Artemis Shared UI library
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Ninject.SharedUIModule">
|
||||
<summary>
|
||||
The main <see cref="T:Ninject.Modules.NinjectModule" /> of the Artemis Shared UI toolkit that binds all services
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Ninject.SharedUIModule.Load">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.PluginConfigurationDialog`1">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.PluginConfigurationDialog`1.Type">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.PluginConfigurationDialog">
|
||||
<summary>
|
||||
Describes a configuration dialog for a specific plugin
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.PluginConfigurationDialog.Type">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.PluginConfigurationViewModel">
|
||||
<summary>
|
||||
Represents a view model for a plugin configuration window
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.PluginConfigurationViewModel.#ctor(Artemis.Core.Plugin)">
|
||||
<summary>
|
||||
Creates a new instance of the <see cref="T:Artemis.UI.Avalonia.Shared.PluginConfigurationViewModel" /> class
|
||||
</summary>
|
||||
<param name="plugin"></param>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.PluginConfigurationViewModel.Plugin">
|
||||
<summary>
|
||||
Gets the plugin this configuration view model is associated with
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.PluginConfigurationViewModel.Close">
|
||||
<summary>
|
||||
A command that closes the window
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Services.Builders.FileDialogFilterBuilder">
|
||||
<summary>
|
||||
Represents a builder that can create a <see cref="T:Avalonia.Controls.FileDialogFilter" />.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.FileDialogFilterBuilder.WithName(System.String)">
|
||||
<summary>
|
||||
Sets the name of the filter
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.FileDialogFilterBuilder.WithExtension(System.String)">
|
||||
<summary>
|
||||
Adds the provided extension to the filter
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.NotificationBuilder.HavingButton(System.Action{Artemis.UI.Avalonia.Shared.Services.Builders.NotificationButtonBuilder})">
|
||||
<summary>
|
||||
Add a filter to the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Services.Builders.OpenFileDialogBuilder">
|
||||
<summary>
|
||||
Represents a builder that can create a <see cref="T:Avalonia.Controls.OpenFileDialog" />.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.OpenFileDialogBuilder.WithAllowMultiple">
|
||||
<summary>
|
||||
Indicate that the user can select multiple files.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.OpenFileDialogBuilder.WithTitle(System.String)">
|
||||
<summary>
|
||||
Set the title of the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.OpenFileDialogBuilder.WithDirectory(System.String)">
|
||||
<summary>
|
||||
Set the initial directory of the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.OpenFileDialogBuilder.WithInitialFileName(System.String)">
|
||||
<summary>
|
||||
Set the initial file name of the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.OpenFileDialogBuilder.HavingFilter(System.Action{Artemis.UI.Avalonia.Shared.Services.Builders.FileDialogFilterBuilder})">
|
||||
<summary>
|
||||
Add a filter to the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.OpenFileDialogBuilder.ShowAsync">
|
||||
<summary>
|
||||
Shows the file dialog
|
||||
</summary>
|
||||
<returns>
|
||||
A task that on completion returns an array containing the full path to the selected
|
||||
files, or null if the dialog was canceled.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Services.Builders.SaveFileDialogBuilder">
|
||||
<summary>
|
||||
Represents a builder that can create a <see cref="T:Avalonia.Controls.SaveFileDialog" />.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.SaveFileDialogBuilder.WithTitle(System.String)">
|
||||
<summary>
|
||||
Set the title of the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.SaveFileDialogBuilder.WithDirectory(System.String)">
|
||||
<summary>
|
||||
Set the initial directory of the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.SaveFileDialogBuilder.WithInitialFileName(System.String)">
|
||||
<summary>
|
||||
Set the initial file name of the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.SaveFileDialogBuilder.WithDefaultExtension(System.String)">
|
||||
<summary>
|
||||
Set the default extension of the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.SaveFileDialogBuilder.HavingFilter(System.Action{Artemis.UI.Avalonia.Shared.Services.Builders.FileDialogFilterBuilder})">
|
||||
<summary>
|
||||
Add a filter to the dialog
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Builders.SaveFileDialogBuilder.ShowAsync">
|
||||
<summary>
|
||||
Shows the save file dialog.
|
||||
</summary>
|
||||
<returns>
|
||||
A task that on completion contains the full path of the save location, or null if the
|
||||
dialog was canceled.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.Services.Interfaces.IArtemisSharedUIService">
|
||||
<summary>
|
||||
Represents a service provided by the Artemis Shared UI library
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Interfaces.IWindowService.ShowWindow``1(System.ValueTuple{System.String,System.Object}[])">
|
||||
<summary>
|
||||
Creates a view model instance of type <typeparamref name="TViewModel" /> and shows its corresponding View as a window
|
||||
</summary>
|
||||
<typeparam name="TViewModel">The type of view model to create</typeparam>
|
||||
<returns>The created view model</returns>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Interfaces.IWindowService.ShowWindow(System.Object)">
|
||||
<summary>
|
||||
Given a ViewModel, show its corresponding View as a window
|
||||
</summary>
|
||||
<param name="viewModel">ViewModel to show the View for</param>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Interfaces.IWindowService.ShowExceptionDialog(System.String,System.Exception)">
|
||||
<summary>
|
||||
Shows a dialog displaying the given exception
|
||||
</summary>
|
||||
<param name="title">The title of the dialog</param>
|
||||
<param name="exception">The exception to display</param>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Interfaces.IWindowService.ShowDialogAsync``1(Artemis.UI.Avalonia.Shared.DialogViewModelBase{``0})">
|
||||
<summary>
|
||||
Given an existing ViewModel, show its corresponding View as a Dialog
|
||||
</summary>
|
||||
<typeparam name="TResult">The return type</typeparam>
|
||||
<param name="viewModel">ViewModel to show the View for</param>
|
||||
<returns>A task containing the return value of type <typeparamref name="TResult" /></returns>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Interfaces.IWindowService.ShowDialogAsync``2(System.ValueTuple{System.String,System.Object}[])">
|
||||
<summary>
|
||||
Creates a view model instance of type <typeparamref name="TViewModel"/> and shows its corresponding View as a Dialog
|
||||
</summary>
|
||||
<typeparam name="TViewModel">The view model type</typeparam>
|
||||
<typeparam name="TResult">The return type</typeparam>
|
||||
<returns>A task containing the return value of type <typeparamref name="TResult" /></returns>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Interfaces.IWindowService.ShowConfirmContentDialog(System.String,System.String,System.String,System.String)">
|
||||
<summary>
|
||||
Shows a content dialog asking the user to confirm an action
|
||||
</summary>
|
||||
<param name="title">The title of the dialog</param>
|
||||
<param name="message">The message of the dialog</param>
|
||||
<param name="confirm">The text of the confirm button</param>
|
||||
<param name="cancel">The text of the cancel button, if <see langword="null"/> the cancel button will not be shown</param>
|
||||
<returns>A task containing the result of the dialog, <see langword="true"/> if confirmed; otherwise <see langword="false"/></returns>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Interfaces.IWindowService.CreateOpenFileDialog">
|
||||
<summary>
|
||||
Creates an open file dialog, use the fluent API to configure it
|
||||
</summary>
|
||||
<returns>The builder that can be used to configure the dialog</returns>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.Services.Interfaces.IWindowService.CreateSaveFileDialog">
|
||||
<summary>
|
||||
Creates a save file dialog, use the fluent API to configure it
|
||||
</summary>
|
||||
<returns>The builder that can be used to configure the dialog</returns>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.ViewModelBase">
|
||||
<summary>
|
||||
Represents the base class for Artemis view models
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.ViewModelBase.DisplayName">
|
||||
<summary>
|
||||
Gets or sets the display name of the view model
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.ActivatableViewModelBase">
|
||||
<summary>
|
||||
Represents the base class for Artemis view models that are interested in the activated event
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.ActivatableViewModelBase.#ctor">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.ActivatableViewModelBase.Dispose(System.Boolean)">
|
||||
<summary>
|
||||
Releases the unmanaged resources used by the object and optionally releases the managed resources.
|
||||
</summary>
|
||||
<param name="disposing">
|
||||
<see langword="true" /> to release both managed and unmanaged resources;
|
||||
<see langword="false" /> to release only unmanaged resources.
|
||||
</param>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.ActivatableViewModelBase.Activator">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.ActivatableViewModelBase.Dispose">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="T:Artemis.UI.Avalonia.Shared.DialogViewModelBase`1">
|
||||
<summary>
|
||||
Represents the base class for Artemis view models used to drive dialogs
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Artemis.UI.Avalonia.Shared.DialogViewModelBase`1.#ctor">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.DialogViewModelBase`1.Close">
|
||||
<summary>
|
||||
Closes the dialog with a given result
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Artemis.UI.Avalonia.Shared.DialogViewModelBase`1.Cancel">
|
||||
<summary>
|
||||
Closes the dialog without a result
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Shared
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class PluginConfigurationDialog<T> : PluginConfigurationDialog where T : PluginConfigurationViewModel
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override Type Type => typeof(T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a configuration dialog for a specific plugin
|
||||
/// </summary>
|
||||
public abstract class PluginConfigurationDialog : IPluginConfigurationDialog
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public abstract Type Type { get; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
using System.Reactive;
|
||||
using Artemis.Core;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a view model for a plugin configuration window
|
||||
/// </summary>
|
||||
public abstract class PluginConfigurationViewModel : ViewModelBase, IPluginConfigurationViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="PluginConfigurationViewModel" /> class
|
||||
/// </summary>
|
||||
/// <param name="plugin"></param>
|
||||
protected PluginConfigurationViewModel(Plugin plugin)
|
||||
{
|
||||
Plugin = plugin;
|
||||
Close = ReactiveCommand.Create(() => { });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin this configuration view model is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A command that closes the window
|
||||
/// </summary>
|
||||
public ReactiveCommand<Unit, Unit> Close { get; }
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -43,6 +43,16 @@ namespace Artemis.UI.Avalonia.Shared.Services.Interfaces
|
||||
/// <returns>A task containing the return value of type <typeparamref name="TResult" /></returns>
|
||||
Task<TResult> ShowDialogAsync<TViewModel, TResult>(params (string name, object value)[] parameters) where TViewModel : DialogViewModelBase<TResult>;
|
||||
|
||||
/// <summary>
|
||||
/// Shows a content dialog asking the user to confirm an action
|
||||
/// </summary>
|
||||
/// <param name="title">The title of the dialog</param>
|
||||
/// <param name="message">The message of the dialog</param>
|
||||
/// <param name="confirm">The text of the confirm button</param>
|
||||
/// <param name="cancel">The text of the cancel button, if <see langword="null"/> the cancel button will not be shown</param>
|
||||
/// <returns>A task containing the result of the dialog, <see langword="true"/> if confirmed; otherwise <see langword="false"/></returns>
|
||||
Task<bool> ShowConfirmContentDialog(string title, string message, string confirm = "Confirm", string? cancel = "Cancel");
|
||||
|
||||
/// <summary>
|
||||
/// Creates an open file dialog, use the fluent API to configure it
|
||||
/// </summary>
|
||||
@ -57,8 +67,6 @@ namespace Artemis.UI.Avalonia.Shared.Services.Interfaces
|
||||
|
||||
ContentDialogBuilder CreateContentDialog();
|
||||
|
||||
ConfirmDialogBuilder CreateConfirmDialog();
|
||||
|
||||
Window GetCurrentWindow();
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Shared.Services
|
||||
{
|
||||
|
||||
@ -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<bool> 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<TResult> ShowDialogAsync<TResult>(DialogViewModelBase<TResult> viewModel)
|
||||
{
|
||||
if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime classic)
|
||||
|
||||
@ -22,6 +22,13 @@ namespace Artemis.UI.Avalonia.Ninject.Factories
|
||||
InputMappingsTabViewModel InputMappingsTabViewModel(ArtemisDevice device, ObservableCollection<ArtemisLed> 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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using ReactiveUI;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Debugger.Tabs.DataModel
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using ReactiveUI;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Debugger.Tabs.Logs
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using ReactiveUI;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Debugger.Tabs.Performance
|
||||
{
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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<object>
|
||||
{
|
||||
public DevicePropertiesViewModel(ArtemisDevice device, IDeviceVmFactory deviceVmFactory)
|
||||
{
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Avalonia;
|
||||
using RGB.NET.Core;
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using DynamicData.Binding;
|
||||
using ReactiveUI;
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Artemis.UI.Avalonia.Shared.Services.Builders;
|
||||
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||
using ReactiveUI;
|
||||
|
||||
@ -5,6 +5,7 @@ using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Exceptions;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
using RGB.NET.Core;
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using ReactiveUI;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens
|
||||
{
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@ -70,7 +69,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.Combine(Constants.DataFolder, "Logs"));
|
||||
Utilities.OpenFolder(Path.Combine(Constants.DataFolder, "logs"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -80,21 +79,21 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
|
||||
public void ViewLoadException()
|
||||
{
|
||||
if (LoadException != null)
|
||||
if (LoadException != null)
|
||||
_windowService.ShowExceptionDialog("Feature failed to enable", LoadException);
|
||||
}
|
||||
|
||||
public async Task InstallPrerequisites()
|
||||
{
|
||||
if (FeatureInfo.Prerequisites.Any())
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_dialogService, new List<IPrerequisitesSubject> {FeatureInfo});
|
||||
if (FeatureInfo.Prerequisites.Any())
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_windowService, new List<IPrerequisitesSubject> {FeatureInfo});
|
||||
}
|
||||
|
||||
public async Task RemovePrerequisites()
|
||||
{
|
||||
if (FeatureInfo.Prerequisites.Any(p => p.UninstallActions.Any()))
|
||||
{
|
||||
await PluginPrerequisitesUninstallDialogViewModel.Show(_dialogService, new List<IPrerequisitesSubject> {FeatureInfo});
|
||||
await PluginPrerequisitesUninstallDialogViewModel.Show(_windowService, new List<IPrerequisitesSubject> {FeatureInfo});
|
||||
this.RaisePropertyChanged(nameof(IsEnabled));
|
||||
}
|
||||
}
|
||||
@ -142,7 +141,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
{
|
||||
if (FeatureInfo.Plugin.Info.RequiresAdmin && !_coreService.IsElevated)
|
||||
{
|
||||
bool confirmed = await _dialogService.ShowConfirmDialog("Enable feature", "The plugin of this feature requires admin rights, are you sure you want to enable it?");
|
||||
bool confirmed = await _windowService.ShowConfirmContentDialog("Enable feature", "The plugin of this feature requires admin rights, are you sure you want to enable it?");
|
||||
if (!confirmed)
|
||||
{
|
||||
this.RaisePropertyChanged(nameof(IsEnabled));
|
||||
@ -153,7 +152,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
// Check if all prerequisites are met async
|
||||
if (!FeatureInfo.ArePrerequisitesMet())
|
||||
{
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_dialogService, new List<IPrerequisitesSubject> {FeatureInfo});
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_windowService, new List<IPrerequisitesSubject> {FeatureInfo});
|
||||
if (!FeatureInfo.ArePrerequisitesMet())
|
||||
{
|
||||
this.RaisePropertyChanged(nameof(IsEnabled));
|
||||
@ -185,20 +184,14 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
|
||||
private void OnFeatureEnabling(object? sender, PluginFeatureEventArgs e)
|
||||
{
|
||||
if (e.PluginFeature != FeatureInfo.Instance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (e.PluginFeature != FeatureInfo.Instance) return;
|
||||
|
||||
Enabling = true;
|
||||
}
|
||||
|
||||
private void OnFeatureEnableStopped(object? sender, PluginFeatureEventArgs e)
|
||||
{
|
||||
if (e.PluginFeature != FeatureInfo.Instance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (e.PluginFeature != FeatureInfo.Instance) return;
|
||||
|
||||
Enabling = false;
|
||||
|
||||
|
||||
@ -5,8 +5,6 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
{
|
||||
public class PluginPrerequisiteActionViewModel : ViewModelBase
|
||||
{
|
||||
|
||||
|
||||
public PluginPrerequisiteActionViewModel(PluginPrerequisiteAction action)
|
||||
{
|
||||
Action = action;
|
||||
|
||||
@ -5,23 +5,22 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using DynamicData;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
{
|
||||
public class PluginPrerequisiteViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly bool _uninstall;
|
||||
private readonly ObservableAsPropertyHelper<bool> _busy;
|
||||
private readonly ObservableAsPropertyHelper<int> _activeStepNumber;
|
||||
|
||||
private bool _installing;
|
||||
private bool _uninstalling;
|
||||
private bool _isMet;
|
||||
private readonly ObservableAsPropertyHelper<bool> _busy;
|
||||
private readonly bool _uninstall;
|
||||
|
||||
private PluginPrerequisiteActionViewModel? _activeAction;
|
||||
|
||||
private bool _installing;
|
||||
private bool _isMet;
|
||||
private bool _uninstalling;
|
||||
|
||||
public PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall)
|
||||
{
|
||||
_uninstall = uninstall;
|
||||
@ -45,7 +44,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
public PluginPrerequisiteActionViewModel? ActiveAction
|
||||
{
|
||||
get => _activeAction;
|
||||
set => this.RaiseAndSetIfChanged(ref _activeAction , value);
|
||||
set => this.RaiseAndSetIfChanged(ref _activeAction, value);
|
||||
}
|
||||
|
||||
public PluginPrerequisite PluginPrerequisite { get; }
|
||||
@ -106,6 +105,14 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing) PluginPrerequisite.PropertyChanged -= PluginPrerequisiteOnPropertyChanged;
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void PluginPrerequisiteOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(PluginPrerequisite.CurrentAction))
|
||||
@ -120,21 +127,5 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
|
||||
ActiveAction = activeAction;
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
PluginPrerequisite.PropertyChanged -= PluginPrerequisiteOnPropertyChanged;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
{
|
||||
public class PluginPrerequisitesInstallDialogViewModel : DialogViewModelBase<bool>
|
||||
{
|
||||
private PluginPrerequisiteViewModel _activePrerequisite;
|
||||
private PluginPrerequisiteViewModel? _activePrerequisite;
|
||||
private bool _canInstall;
|
||||
private bool _showFailed;
|
||||
private bool _showInstall = true;
|
||||
@ -34,7 +34,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
|
||||
public ObservableCollection<PluginPrerequisiteViewModel> Prerequisites { get; }
|
||||
|
||||
public PluginPrerequisiteViewModel ActivePrerequisite
|
||||
public PluginPrerequisiteViewModel? ActivePrerequisite
|
||||
{
|
||||
get => _activePrerequisite;
|
||||
set => this.RaiseAndSetIfChanged(ref _activePrerequisite, value);
|
||||
|
||||
@ -9,7 +9,6 @@ using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||
using DynamicData;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
@ -19,9 +18,9 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly List<IPrerequisitesSubject> _subjects;
|
||||
private readonly IWindowService _windowService;
|
||||
private PluginPrerequisiteViewModel? _activePrerequisite;
|
||||
private bool _canUninstall;
|
||||
private bool _isFinished;
|
||||
private PluginPrerequisiteViewModel? _activePrerequisite;
|
||||
private CancellationTokenSource? _tokenSource;
|
||||
|
||||
public PluginPrerequisitesUninstallDialogViewModel(List<IPrerequisitesSubject> subjects, string cancelLabel, IPrerequisitesVmFactory prerequisitesVmFactory, IWindowService windowService,
|
||||
@ -61,18 +60,6 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
set => this.RaiseAndSetIfChanged(ref _isFinished, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_tokenSource?.Cancel();
|
||||
_tokenSource?.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
public async Task Uninstall()
|
||||
{
|
||||
CanUninstall = false;
|
||||
@ -80,29 +67,18 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
// Disable all subjects that are plugins, this will disable their features too
|
||||
foreach (IPrerequisitesSubject prerequisitesSubject in _subjects)
|
||||
{
|
||||
if (prerequisitesSubject is PluginInfo pluginInfo)
|
||||
{
|
||||
_pluginManagementService.DisablePlugin(pluginInfo.Plugin, true);
|
||||
}
|
||||
if (prerequisitesSubject is PluginInfo pluginInfo) _pluginManagementService.DisablePlugin(pluginInfo.Plugin, true);
|
||||
}
|
||||
|
||||
// Disable all subjects that are features if still required
|
||||
foreach (IPrerequisitesSubject prerequisitesSubject in _subjects)
|
||||
{
|
||||
if (prerequisitesSubject is not PluginFeatureInfo featureInfo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (prerequisitesSubject is not PluginFeatureInfo featureInfo) continue;
|
||||
|
||||
// Disable the parent plugin if the feature is AlwaysEnabled
|
||||
if (featureInfo.AlwaysEnabled)
|
||||
{
|
||||
_pluginManagementService.DisablePlugin(featureInfo.Plugin, true);
|
||||
}
|
||||
else if (featureInfo.Instance != null)
|
||||
{
|
||||
_pluginManagementService.DisablePluginFeature(featureInfo.Instance, true);
|
||||
}
|
||||
else if (featureInfo.Instance != null) _pluginManagementService.DisablePluginFeature(featureInfo.Instance, true);
|
||||
}
|
||||
|
||||
_tokenSource = new CancellationTokenSource();
|
||||
@ -112,19 +88,13 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
foreach (PluginPrerequisiteViewModel pluginPrerequisiteViewModel in Prerequisites)
|
||||
{
|
||||
pluginPrerequisiteViewModel.IsMet = pluginPrerequisiteViewModel.PluginPrerequisite.IsMet();
|
||||
if (!pluginPrerequisiteViewModel.IsMet)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!pluginPrerequisiteViewModel.IsMet) continue;
|
||||
|
||||
ActivePrerequisite = pluginPrerequisiteViewModel;
|
||||
await ActivePrerequisite.Uninstall(_tokenSource.Token);
|
||||
|
||||
// Wait after the task finished for the user to process what happened
|
||||
if (pluginPrerequisiteViewModel != Prerequisites.Last())
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
if (pluginPrerequisiteViewModel != Prerequisites.Last()) await Task.Delay(1000);
|
||||
}
|
||||
|
||||
if (Prerequisites.All(p => !p.IsMet))
|
||||
@ -163,5 +133,17 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
{
|
||||
return await windowService.ShowDialogAsync<PluginPrerequisitesUninstallDialogViewModel, bool>(("subjects", subjects), ("cancelLabel", cancelLabel));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_tokenSource?.Cancel();
|
||||
_tokenSource?.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Exceptions;
|
||||
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||
using Ninject;
|
||||
using ReactiveUI;
|
||||
|
||||
@ -16,8 +18,10 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
public class PluginSettingsViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly ICoreService _coreService;
|
||||
private readonly INotificationService _notificationService;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly ISettingsVmFactory _settingsVmFactory;
|
||||
private readonly IWindowService _windowService;
|
||||
private bool _canInstallPrerequisites;
|
||||
private bool _canRemovePrerequisites;
|
||||
private bool _enabling;
|
||||
@ -27,13 +31,24 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
public PluginSettingsViewModel(Plugin plugin,
|
||||
ISettingsVmFactory settingsVmFactory,
|
||||
ICoreService coreService,
|
||||
IWindowService windowService,
|
||||
INotificationService notificationService,
|
||||
IPluginManagementService pluginManagementService)
|
||||
{
|
||||
Plugin = plugin;
|
||||
_plugin = plugin;
|
||||
|
||||
_settingsVmFactory = settingsVmFactory;
|
||||
_coreService = coreService;
|
||||
_windowService = windowService;
|
||||
_notificationService = notificationService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
|
||||
PluginFeatures = new ObservableCollection<PluginFeatureViewModel>();
|
||||
foreach (PluginFeatureInfo pluginFeatureInfo in Plugin.Features)
|
||||
PluginFeatures.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeatureInfo, false));
|
||||
|
||||
_pluginManagementService.PluginDisabled += PluginManagementServiceOnPluginToggled;
|
||||
_pluginManagementService.PluginEnabled += PluginManagementServiceOnPluginToggled;
|
||||
}
|
||||
|
||||
public ObservableCollection<PluginFeatureViewModel> PluginFeatures { get; }
|
||||
@ -49,7 +64,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
get => _enabling;
|
||||
set => this.RaiseAndSetIfChanged(ref _enabling, value);
|
||||
}
|
||||
|
||||
|
||||
public string Type => Plugin.GetType().BaseType?.Name ?? Plugin.GetType().Name;
|
||||
public bool CanOpenSettings => IsEnabled && Plugin.ConfigurationDialog != null;
|
||||
|
||||
@ -83,18 +98,20 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
|
||||
public void OpenSettings()
|
||||
{
|
||||
PluginConfigurationDialog configurationViewModel = (PluginConfigurationDialog) Plugin.ConfigurationDialog;
|
||||
if (configurationViewModel == null)
|
||||
if (Plugin.ConfigurationDialog == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
PluginConfigurationViewModel viewModel = (PluginConfigurationViewModel) Plugin.Kernel.Get(configurationViewModel.Type);
|
||||
_windowManager.ShowWindow(new PluginSettingsWindowViewModel(viewModel));
|
||||
PluginConfigurationViewModel? viewModel = Plugin.Kernel!.Get(Plugin.ConfigurationDialog.Type) as PluginConfigurationViewModel;
|
||||
if (viewModel == null)
|
||||
throw new ArtemisUIException($"The type of a plugin configuration dialog must inherit {nameof(PluginConfigurationViewModel)}");
|
||||
|
||||
_windowService.ShowWindow(new PluginSettingsWindowViewModel(viewModel));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_dialogService.ShowExceptionDialog("An exception occured while trying to show the plugin's settings window", e);
|
||||
_windowService.ShowExceptionDialog("An exception occured while trying to show the plugin's settings window", e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@ -103,11 +120,11 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Plugin.Directory.FullName);
|
||||
Utilities.OpenFolder(Plugin.Directory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||
_windowService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,16 +133,16 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
bool wasEnabled = IsEnabled;
|
||||
|
||||
_pluginManagementService.UnloadPlugin(Plugin);
|
||||
Items.Clear();
|
||||
PluginFeatures.Clear();
|
||||
|
||||
Plugin = _pluginManagementService.LoadPlugin(Plugin.Directory);
|
||||
foreach (PluginFeatureInfo pluginFeatureInfo in Plugin.Features)
|
||||
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeatureInfo, false));
|
||||
PluginFeatures.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeatureInfo, false));
|
||||
|
||||
if (wasEnabled)
|
||||
await UpdateEnabled(true);
|
||||
|
||||
_messageService.ShowMessage("Reloaded plugin.");
|
||||
_notificationService.CreateNotification().WithTitle("Reloaded plugin.").Show();
|
||||
}
|
||||
|
||||
public async Task InstallPrerequisites()
|
||||
@ -134,7 +151,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
subjects.AddRange(Plugin.Features.Where(f => f.AlwaysEnabled));
|
||||
|
||||
if (subjects.Any(s => s.Prerequisites.Any()))
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_dialogService, subjects);
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_windowService, subjects);
|
||||
}
|
||||
|
||||
public async Task RemovePrerequisites(bool forPluginRemoval = false)
|
||||
@ -144,15 +161,15 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
|
||||
if (subjects.Any(s => s.Prerequisites.Any(p => p.UninstallActions.Any())))
|
||||
{
|
||||
await PluginPrerequisitesUninstallDialogViewModel.Show(_dialogService, subjects, forPluginRemoval ? "SKIP, REMOVE PLUGIN" : "CANCEL");
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
NotifyOfPropertyChange(nameof(CanOpenSettings));
|
||||
await PluginPrerequisitesUninstallDialogViewModel.Show(_windowService, subjects, forPluginRemoval ? "Skip, remove plugin" : "Cancel");
|
||||
this.RaisePropertyChanged(nameof(IsEnabled));
|
||||
this.RaisePropertyChanged(nameof(CanOpenSettings));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RemoveSettings()
|
||||
{
|
||||
bool confirmed = await _dialogService.ShowConfirmDialog("Clear plugin settings", "Are you sure you want to clear the settings of this plugin?");
|
||||
bool confirmed = await _windowService.ShowConfirmContentDialog("Clear plugin settings", "Are you sure you want to clear the settings of this plugin?");
|
||||
if (!confirmed)
|
||||
return;
|
||||
|
||||
@ -166,12 +183,12 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
if (wasEnabled)
|
||||
await UpdateEnabled(true);
|
||||
|
||||
_messageService.ShowMessage("Cleared plugin settings.");
|
||||
_notificationService.CreateNotification().WithTitle("Cleared plugin settings.").Show();
|
||||
}
|
||||
|
||||
public async Task Remove()
|
||||
{
|
||||
bool confirmed = await _dialogService.ShowConfirmDialog("Remove plugin", "Are you sure you want to remove this plugin?");
|
||||
bool confirmed = await _windowService.ShowConfirmContentDialog("Remove plugin", "Are you sure you want to remove this plugin?");
|
||||
if (!confirmed)
|
||||
return;
|
||||
|
||||
@ -184,45 +201,55 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
try
|
||||
{
|
||||
_pluginManagementService.RemovePlugin(Plugin, false);
|
||||
((PluginSettingsTabViewModel) Parent).GetPluginInstances();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_dialogService.ShowExceptionDialog("Failed to remove plugin", e);
|
||||
_windowService.ShowExceptionDialog("Failed to remove plugin", e);
|
||||
throw;
|
||||
}
|
||||
|
||||
_messageService.ShowMessage("Removed plugin.");
|
||||
_notificationService.CreateNotification().WithTitle("Removed plugin.").Show();
|
||||
}
|
||||
|
||||
public void ShowLogsFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.Combine(Constants.DataFolder, "Logs"));
|
||||
Utilities.OpenFolder(Path.Combine(Constants.DataFolder, "logs"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
|
||||
_windowService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenUri(Uri uri)
|
||||
{
|
||||
Core.Utilities.OpenUrl(uri.ToString());
|
||||
Utilities.OpenUrl(uri.ToString());
|
||||
}
|
||||
|
||||
private void PluginManagementServiceOnPluginToggled(object sender, PluginEventArgs e)
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
NotifyOfPropertyChange(nameof(CanOpenSettings));
|
||||
if (disposing)
|
||||
{
|
||||
_pluginManagementService.PluginDisabled -= PluginManagementServiceOnPluginToggled;
|
||||
_pluginManagementService.PluginEnabled -= PluginManagementServiceOnPluginToggled;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void PluginManagementServiceOnPluginToggled(object? sender, PluginEventArgs e)
|
||||
{
|
||||
this.RaisePropertyChanged(nameof(IsEnabled));
|
||||
this.RaisePropertyChanged(nameof(CanOpenSettings));
|
||||
}
|
||||
|
||||
private async Task UpdateEnabled(bool enable)
|
||||
{
|
||||
if (IsEnabled == enable)
|
||||
{
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
this.RaisePropertyChanged(nameof(IsEnabled));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -232,7 +259,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
|
||||
if (Plugin.Info.RequiresAdmin && !_coreService.IsElevated)
|
||||
{
|
||||
bool confirmed = await _dialogService.ShowConfirmDialog("Enable plugin", "This plugin requires admin rights, are you sure you want to enable it?");
|
||||
bool confirmed = await _windowService.ShowConfirmContentDialog("Enable plugin", "This plugin requires admin rights, are you sure you want to enable it?");
|
||||
if (!confirmed)
|
||||
{
|
||||
CancelEnable();
|
||||
@ -246,7 +273,7 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
|
||||
if (subjects.Any(s => !s.ArePrerequisitesMet()))
|
||||
{
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_dialogService, subjects);
|
||||
await PluginPrerequisitesInstallDialogViewModel.Show(_windowService, subjects);
|
||||
if (!subjects.All(s => s.ArePrerequisitesMet()))
|
||||
{
|
||||
CancelEnable();
|
||||
@ -262,7 +289,10 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_messageService.ShowMessage($"Failed to enable plugin {Plugin.Info.Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder);
|
||||
_notificationService.CreateNotification()
|
||||
.WithMessage($"Failed to enable plugin {Plugin.Info.Name}\r\n{e.Message}")
|
||||
.HavingButton(b => b.WithText("View logs").WithAction(ShowLogsFolder))
|
||||
.Show();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -271,17 +301,19 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_pluginManagementService.DisablePlugin(Plugin, true);
|
||||
}
|
||||
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
NotifyOfPropertyChange(nameof(CanOpenSettings));
|
||||
this.RaisePropertyChanged(nameof(IsEnabled));
|
||||
this.RaisePropertyChanged(nameof(CanOpenSettings));
|
||||
}
|
||||
|
||||
private void CancelEnable()
|
||||
{
|
||||
Enabling = false;
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
NotifyOfPropertyChange(nameof(CanOpenSettings));
|
||||
this.RaisePropertyChanged(nameof(IsEnabled));
|
||||
this.RaisePropertyChanged(nameof(CanOpenSettings));
|
||||
}
|
||||
|
||||
private void CheckPrerequisites()
|
||||
@ -291,26 +323,5 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
CanRemovePrerequisites = Plugin.Info.Prerequisites.Any(p => p.UninstallActions.Any()) ||
|
||||
Plugin.Features.Where(f => f.AlwaysEnabled).Any(f => f.Prerequisites.Any(p => p.UninstallActions.Any()));
|
||||
}
|
||||
|
||||
#region Overrides of Screen
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
foreach (PluginFeatureInfo pluginFeatureInfo in Plugin.Features)
|
||||
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeatureInfo, false));
|
||||
|
||||
_pluginManagementService.PluginDisabled += PluginManagementServiceOnPluginToggled;
|
||||
_pluginManagementService.PluginEnabled += PluginManagementServiceOnPluginToggled;
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
_pluginManagementService.PluginDisabled -= PluginManagementServiceOnPluginToggled;
|
||||
_pluginManagementService.PluginEnabled -= PluginManagementServiceOnPluginToggled;
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,32 +1,20 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||
{
|
||||
public class PluginSettingsWindowViewModel : Conductor<PluginConfigurationViewModel>
|
||||
public class PluginSettingsWindowViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly PluginConfigurationViewModel _configurationViewModel;
|
||||
|
||||
public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel)
|
||||
{
|
||||
_configurationViewModel = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel));
|
||||
ConfigurationViewModel = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel));
|
||||
Plugin = configurationViewModel.Plugin;
|
||||
|
||||
DisplayName = $"{Plugin.Info.Name} | Settings";
|
||||
}
|
||||
|
||||
public PluginConfigurationViewModel ConfigurationViewModel { get; }
|
||||
public Plugin Plugin { get; }
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
ActiveItem = _configurationViewModel;
|
||||
ActiveItem.Closed += ActiveItemOnClosed;
|
||||
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
private void ActiveItemOnClosed(object sender, CloseEventArgs e)
|
||||
{
|
||||
ActiveItem.Closed -= ActiveItemOnClosed;
|
||||
RequestClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,6 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Avalonia.Screens.Plugins.Views.PluginSettingsWindowView"
|
||||
Title="PluginSettingsWindowView">
|
||||
Welcome to Avalonia!
|
||||
Title="{Binding DisplayName}">
|
||||
<ContentControl Content="{Binding ConfigurationViewModel}"></ContentControl>
|
||||
</Window>
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
using System;
|
||||
using Artemis.UI.Avalonia.Screens.Plugins.ViewModels;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Mixins;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Plugins.Views
|
||||
{
|
||||
public partial class PluginSettingsWindowView : Window
|
||||
public class PluginSettingsWindowView : ReactiveWindow<PluginSettingsWindowViewModel>
|
||||
{
|
||||
public PluginSettingsWindowView()
|
||||
{
|
||||
@ -12,6 +16,8 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.Views
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
|
||||
this.WhenActivated(disposables => { ViewModel!.ConfigurationViewModel.Close.Subscribe(_ => Close()).DisposeWith(disposables); });
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
@ -19,4 +25,4 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.Views
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
namespace Artemis.UI.Avalonia.Screens.ProfileEditor.ViewModels
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.ProfileEditor.ViewModels
|
||||
{
|
||||
public class ProfileEditorViewModel : ActivatableViewModelBase
|
||||
{
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Root.ViewModels
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Root.ViewModels
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Root.ViewModels
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Material.Icons;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
|
||||
@ -9,6 +9,7 @@ using Artemis.UI.Avalonia.Screens.Home.ViewModels;
|
||||
using Artemis.UI.Avalonia.Screens.Settings;
|
||||
using Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels;
|
||||
using Artemis.UI.Avalonia.Screens.Workshop.ViewModels;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Material.Icons;
|
||||
using Ninject;
|
||||
using ReactiveUI;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Settings
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Flurl.Http;
|
||||
using ReactiveUI;
|
||||
@ -19,7 +21,7 @@ namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||
public AboutTabViewModel()
|
||||
{
|
||||
DisplayName = "About";
|
||||
this.WhenActivated((Action<IDisposable> _) => Task.Run(Activate));
|
||||
this.WhenActivated((CompositeDisposable _) => Task.Run(Activate));
|
||||
}
|
||||
|
||||
public string? Version
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||
{
|
||||
public class DevicesTabViewModel : ActivatableViewModelBase
|
||||
{
|
||||
|
||||
@ -11,6 +11,7 @@ using Artemis.Core;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Services.Interfaces;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
using Serilog.Events;
|
||||
|
||||
|
||||
@ -1,10 +1,116 @@
|
||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Extensions;
|
||||
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||
using Artemis.UI.Avalonia.Screens.Plugins.ViewModels;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Artemis.UI.Avalonia.Shared.Services.Builders;
|
||||
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||
{
|
||||
public class PluginsTabViewModel : ActivatableViewModelBase
|
||||
{
|
||||
public PluginsTabViewModel()
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly INotificationService _notificationService;
|
||||
private readonly IWindowService _windowService;
|
||||
private readonly ISettingsVmFactory _settingsVmFactory;
|
||||
private string? _searchPluginInput;
|
||||
private List<PluginSettingsViewModel>? _instances;
|
||||
|
||||
public PluginsTabViewModel(IPluginManagementService pluginManagementService, INotificationService notificationService, IWindowService windowService, ISettingsVmFactory settingsVmFactory)
|
||||
{
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_notificationService = notificationService;
|
||||
_windowService = windowService;
|
||||
_settingsVmFactory = settingsVmFactory;
|
||||
|
||||
DisplayName = "Plugins";
|
||||
Plugins = new ObservableCollection<PluginSettingsViewModel>();
|
||||
|
||||
this.WhenAnyValue(x => x.SearchPluginInput).Throttle(TimeSpan.FromMilliseconds(300)).Subscribe(SearchPlugins);
|
||||
this.WhenActivated((CompositeDisposable _) => GetPluginInstances());
|
||||
}
|
||||
|
||||
public ObservableCollection<PluginSettingsViewModel> Plugins { get; }
|
||||
|
||||
public string? SearchPluginInput
|
||||
{
|
||||
get => _searchPluginInput;
|
||||
set => this.RaiseAndSetIfChanged(ref _searchPluginInput, value);
|
||||
}
|
||||
|
||||
public void OpenUrl(string url) => Utilities.OpenUrl(url);
|
||||
|
||||
public async Task ImportPlugin()
|
||||
{
|
||||
string[]? files = await _windowService.CreateOpenFileDialog().WithTitle("Import Artemis plugin").HavingFilter(f => f.WithExtension("zip").WithName("ZIP files")).ShowAsync();
|
||||
if (files == null)
|
||||
return;
|
||||
|
||||
// Take the actual import off of the UI thread
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Plugin plugin = _pluginManagementService.ImportPlugin(files[0]);
|
||||
|
||||
GetPluginInstances();
|
||||
SearchPluginInput = plugin.Info.Name;
|
||||
|
||||
// Enable it via the VM to enable the prerequisite dialog
|
||||
PluginSettingsViewModel pluginViewModel = Plugins.FirstOrDefault(i => i.Plugin == plugin);
|
||||
if (pluginViewModel is { IsEnabled: false })
|
||||
pluginViewModel.IsEnabled = true;
|
||||
|
||||
_notificationService.CreateNotification()
|
||||
.WithTitle("Success")
|
||||
.WithMessage($"Imported plugin: {plugin.Info.Name}")
|
||||
.WithSeverity(NotificationSeverity.Success)
|
||||
.Show();
|
||||
});
|
||||
}
|
||||
|
||||
public void GetPluginInstances()
|
||||
{
|
||||
_instances = _pluginManagementService.GetAllPlugins()
|
||||
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
|
||||
.OrderBy(i => i.Plugin.Info.Name)
|
||||
.ToList();
|
||||
|
||||
SearchPlugins(SearchPluginInput);
|
||||
}
|
||||
|
||||
private void SearchPlugins(string? searchPluginInput)
|
||||
{
|
||||
if (_instances == null)
|
||||
return;
|
||||
|
||||
List<PluginSettingsViewModel> instances = _instances;
|
||||
string? search = searchPluginInput?.ToLower();
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
instances = instances.Where(i => i.Plugin.Info.Name.ToLower().Contains(search) ||
|
||||
i.Plugin.Info.Description != null && i.Plugin.Info.Description.ToLower().Contains(search)).ToList();
|
||||
|
||||
foreach (PluginSettingsViewModel pluginSettingsViewModel in instances)
|
||||
{
|
||||
if (!Plugins.Contains(pluginSettingsViewModel))
|
||||
Plugins.Add(pluginSettingsViewModel);
|
||||
}
|
||||
|
||||
foreach (PluginSettingsViewModel pluginSettingsViewModel in Plugins.ToList())
|
||||
{
|
||||
if (!instances.Contains(pluginSettingsViewModel))
|
||||
Plugins.Remove(pluginSettingsViewModel);
|
||||
}
|
||||
|
||||
Plugins.Sort(i => i.Plugin.Info.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,5 +4,5 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Avalonia.Screens.Settings.Tabs.Views.PluginsTabView">
|
||||
Welcome to Avalonia!
|
||||
<ItemsControl Items="{Binding Plugins}"></ItemsControl>
|
||||
</UserControl>
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
using Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Views
|
||||
{
|
||||
public partial class PluginsTabView : UserControl
|
||||
public partial class PluginsTabView : ReactiveUserControl<PluginsTabViewModel>
|
||||
{
|
||||
public PluginsTabView()
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using ReactiveUI;
|
||||
using SkiaSharp;
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||
using Artemis.UI.Avalonia.Shared;
|
||||
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||
using Avalonia.Input;
|
||||
using ReactiveUI;
|
||||
@ -105,7 +106,7 @@ namespace Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels
|
||||
|
||||
private async Task ExecuteViewProperties(ArtemisDevice device)
|
||||
{
|
||||
await _windowService.ShowDialogAsync<bool>(_deviceVmFactory.DevicePropertiesViewModel(device));
|
||||
await _windowService.ShowDialogAsync(_deviceVmFactory.DevicePropertiesViewModel(device));
|
||||
}
|
||||
|
||||
private bool Fits(float x, float y)
|
||||
|
||||
@ -15,9 +15,7 @@ namespace Artemis.UI.Shared
|
||||
/// </summary>
|
||||
public abstract class PluginConfigurationDialog : IPluginConfigurationDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of view model the tab contains
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public abstract Type Type { get; }
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user