mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 09:43:46 +00:00
Core - Fixed an error when enabling a module without a datamodel
Shared UI - XML comments
This commit is contained in:
parent
fb3466e102
commit
833a61ecab
@ -3,7 +3,7 @@
|
|||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents errors that occur withing the Artemis Core
|
/// Represents errors that occur within the Artemis Core
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ArtemisCoreException : Exception
|
public class ArtemisCoreException : Exception
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Artemis.Core.Services
|
|||||||
public DataModelService(IPluginManagementService pluginManagementService)
|
public DataModelService(IPluginManagementService pluginManagementService)
|
||||||
{
|
{
|
||||||
// Add data models of already loaded plugins
|
// Add data models of already loaded plugins
|
||||||
foreach (Module module in pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled && p.InternalDataModel != null))
|
foreach (Module module in pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled))
|
||||||
AddModuleDataModel(module);
|
AddModuleDataModel(module);
|
||||||
foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetFeaturesOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetFeaturesOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
||||||
AddDataModelExpansionDataModel(dataModelExpansion);
|
AddDataModelExpansionDataModel(dataModelExpansion);
|
||||||
@ -61,7 +61,8 @@ namespace Artemis.Core.Services
|
|||||||
private void AddModuleDataModel(Module module)
|
private void AddModuleDataModel(Module module)
|
||||||
{
|
{
|
||||||
if (module.InternalDataModel == null)
|
if (module.InternalDataModel == null)
|
||||||
throw new ArtemisCoreException("Cannot add module data model that is not enabled");
|
return;
|
||||||
|
|
||||||
if (module.InternalDataModel.DataModelDescription == null)
|
if (module.InternalDataModel.DataModelDescription == null)
|
||||||
throw new ArtemisPluginFeatureException(module, "Module overrides GetDataModelDescription but returned null");
|
throw new ArtemisPluginFeatureException(module, "Module overrides GetDataModelDescription but returned null");
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=ninject/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=ninject_005Cfactories/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=propertyinput/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=propertyinput/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdatamodelvisualization/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdatamodelvisualization/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
@ -4,10 +4,14 @@ using Microsoft.Xaml.Behaviors;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a behavior that puts the cursor at the end of a text box when it receives focus
|
||||||
|
/// </summary>
|
||||||
public class PutCursorAtEndTextBox : Behavior<UIElement>
|
public class PutCursorAtEndTextBox : Behavior<UIElement>
|
||||||
{
|
{
|
||||||
private TextBox _textBox;
|
private TextBox? _textBox;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void OnAttached()
|
protected override void OnAttached()
|
||||||
{
|
{
|
||||||
base.OnAttached();
|
base.OnAttached();
|
||||||
@ -18,6 +22,7 @@ namespace Artemis.UI.Shared
|
|||||||
_textBox.GotFocus += TextBoxGotFocus;
|
_textBox.GotFocus += TextBoxGotFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void OnDetaching()
|
protected override void OnDetaching()
|
||||||
{
|
{
|
||||||
if (_textBox == null) return;
|
if (_textBox == null) return;
|
||||||
@ -28,6 +33,7 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
private void TextBoxGotFocus(object sender, RoutedEventArgs routedEventArgs)
|
private void TextBoxGotFocus(object sender, RoutedEventArgs routedEventArgs)
|
||||||
{
|
{
|
||||||
|
if (_textBox == null) return;
|
||||||
_textBox.CaretIndex = _textBox.Text.Length;
|
_textBox.CaretIndex = _textBox.Text.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,21 @@ using Ninject;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the main entry point for the shared UI library
|
||||||
|
/// <para>The Artemis UI calls this so there's no need to deal with this in a plugin</para>
|
||||||
|
/// </summary>
|
||||||
public static class Bootstrapper
|
public static class Bootstrapper
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a boolean indicating whether or not the shared UI library has been initialized
|
||||||
|
/// </summary>
|
||||||
public static bool Initialized { get; private set; }
|
public static bool Initialized { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the shared UI library
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="kernel"></param>
|
||||||
public static void Initialize(IKernel kernel)
|
public static void Initialize(IKernel kernel)
|
||||||
{
|
{
|
||||||
if (Initialized)
|
if (Initialized)
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
<UserControl x:Class="Artemis.UI.Shared.Controls.ArtemisIcon"
|
<UserControl x:Class="Artemis.UI.Shared.ArtemisIcon"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:Artemis.UI.Shared.Controls"
|
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||||
|
|||||||
@ -3,24 +3,37 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.Controls
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for ArtemisIcon.xaml
|
/// Interaction logic for ArtemisIcon.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ArtemisIcon : UserControl
|
public partial class ArtemisIcon : UserControl
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the currently displayed icon as either a <see cref="PackIconKind" /> or an <see cref="Uri" /> pointing
|
||||||
|
/// to an SVG
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(object), typeof(ArtemisIcon),
|
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(object), typeof(ArtemisIcon),
|
||||||
new FrameworkPropertyMetadata(IconPropertyChangedCallback));
|
new FrameworkPropertyMetadata(IconPropertyChangedCallback));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the <see cref="PackIconKind" />
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty PackIconProperty = DependencyProperty.Register(nameof(PackIcon), typeof(PackIconKind?), typeof(ArtemisIcon),
|
public static readonly DependencyProperty PackIconProperty = DependencyProperty.Register(nameof(PackIcon), typeof(PackIconKind?), typeof(ArtemisIcon),
|
||||||
new FrameworkPropertyMetadata(IconPropertyChangedCallback));
|
new FrameworkPropertyMetadata(IconPropertyChangedCallback));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the <see cref="Uri" /> pointing to the SVG
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty SvgSourceProperty = DependencyProperty.Register(nameof(SvgSource), typeof(Uri), typeof(ArtemisIcon),
|
public static readonly DependencyProperty SvgSourceProperty = DependencyProperty.Register(nameof(SvgSource), typeof(Uri), typeof(ArtemisIcon),
|
||||||
new FrameworkPropertyMetadata(IconPropertyChangedCallback));
|
new FrameworkPropertyMetadata(IconPropertyChangedCallback));
|
||||||
|
|
||||||
private bool _inCallback;
|
private bool _inCallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="ArtemisIcon"/> class
|
||||||
|
/// </summary>
|
||||||
public ArtemisIcon()
|
public ArtemisIcon()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -30,7 +43,7 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
/// Gets or sets the currently displayed icon as either a <see cref="PackIconKind" /> or an <see cref="Uri" /> pointing
|
/// Gets or sets the currently displayed icon as either a <see cref="PackIconKind" /> or an <see cref="Uri" /> pointing
|
||||||
/// to an SVG
|
/// to an SVG
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Icon
|
public object? Icon
|
||||||
{
|
{
|
||||||
get => GetValue(IconProperty);
|
get => GetValue(IconProperty);
|
||||||
set => SetValue(IconProperty, value);
|
set => SetValue(IconProperty, value);
|
||||||
@ -73,9 +86,9 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
}
|
}
|
||||||
else if (artemisIcon.Icon is string iconString)
|
else if (artemisIcon.Icon is string iconString)
|
||||||
{
|
{
|
||||||
if (Uri.TryCreate(iconString, UriKind.Absolute, out Uri uriResult))
|
if (Uri.TryCreate(iconString, UriKind.Absolute, out Uri? uriResult))
|
||||||
artemisIcon.Icon = uriResult;
|
artemisIcon.Icon = uriResult;
|
||||||
else if (Enum.TryParse(typeof(PackIconKind), iconString, true, out object result))
|
else if (Enum.TryParse(typeof(PackIconKind), iconString, true, out object? result))
|
||||||
artemisIcon.Icon = result;
|
artemisIcon.Icon = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
@ -12,22 +11,34 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for ColorPicker.xaml
|
/// Interaction logic for ColorPicker.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ColorPicker : UserControl, INotifyPropertyChanged
|
public partial class ColorPicker : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private static IColorPickerService _colorPickerService;
|
private static IColorPickerService? _colorPickerService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(nameof(Color), typeof(Color), typeof(ColorPicker),
|
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(nameof(Color), typeof(Color), typeof(ColorPicker),
|
||||||
new FrameworkPropertyMetadata(default(Color), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorPropertyChangedCallback));
|
new FrameworkPropertyMetadata(default(Color), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorPropertyChangedCallback));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating that the popup containing the color picker is open
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty PopupOpenProperty = DependencyProperty.Register(nameof(PopupOpen), typeof(bool), typeof(ColorPicker),
|
public static readonly DependencyProperty PopupOpenProperty = DependencyProperty.Register(nameof(PopupOpen), typeof(bool), typeof(ColorPicker),
|
||||||
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PopupOpenPropertyChangedCallback));
|
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PopupOpenPropertyChangedCallback));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether the popup should stay open when clicked outside of it
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty StaysOpenProperty = DependencyProperty.Register(nameof(StaysOpen), typeof(bool), typeof(ColorPicker),
|
public static readonly DependencyProperty StaysOpenProperty = DependencyProperty.Register(nameof(StaysOpen), typeof(bool), typeof(ColorPicker),
|
||||||
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, StaysOpenPropertyChangedCallback));
|
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, StaysOpenPropertyChangedCallback));
|
||||||
|
|
||||||
internal static readonly DependencyProperty ColorOpacityProperty = DependencyProperty.Register(nameof(ColorOpacity), typeof(byte), typeof(ColorPicker),
|
internal static readonly DependencyProperty ColorOpacityProperty = DependencyProperty.Register(nameof(ColorOpacity), typeof(byte), typeof(ColorPicker),
|
||||||
new FrameworkPropertyMetadata((byte) 255, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorOpacityPropertyChangedCallback));
|
new FrameworkPropertyMetadata((byte) 255, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorOpacityPropertyChangedCallback));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the selected color has changed
|
||||||
|
/// </summary>
|
||||||
public static readonly RoutedEvent ColorChangedEvent =
|
public static readonly RoutedEvent ColorChangedEvent =
|
||||||
EventManager.RegisterRoutedEvent(
|
EventManager.RegisterRoutedEvent(
|
||||||
nameof(Color),
|
nameof(Color),
|
||||||
@ -35,6 +46,9 @@ namespace Artemis.UI.Shared
|
|||||||
typeof(RoutedPropertyChangedEventHandler<Color>),
|
typeof(RoutedPropertyChangedEventHandler<Color>),
|
||||||
typeof(ColorPicker));
|
typeof(ColorPicker));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the popup opens or closes
|
||||||
|
/// </summary>
|
||||||
public static readonly RoutedEvent PopupOpenChangedEvent =
|
public static readonly RoutedEvent PopupOpenChangedEvent =
|
||||||
EventManager.RegisterRoutedEvent(
|
EventManager.RegisterRoutedEvent(
|
||||||
nameof(PopupOpen),
|
nameof(PopupOpen),
|
||||||
@ -44,6 +58,9 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
private bool _inCallback;
|
private bool _inCallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="ColorPicker" /> class
|
||||||
|
/// </summary>
|
||||||
public ColorPicker()
|
public ColorPicker()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -51,6 +68,33 @@ namespace Artemis.UI.Shared
|
|||||||
Unloaded += OnUnloaded;
|
Unloaded += OnUnloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color
|
||||||
|
/// </summary>
|
||||||
|
public Color Color
|
||||||
|
{
|
||||||
|
get => (Color) GetValue(ColorProperty);
|
||||||
|
set => SetValue(ColorProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating that the popup containing the color picker is open
|
||||||
|
/// </summary>
|
||||||
|
public bool PopupOpen
|
||||||
|
{
|
||||||
|
get => (bool) GetValue(PopupOpenProperty);
|
||||||
|
set => SetValue(PopupOpenProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether the popup should stay open when clicked outside of it
|
||||||
|
/// </summary>
|
||||||
|
public bool StaysOpen
|
||||||
|
{
|
||||||
|
get => (bool) GetValue(StaysOpenProperty);
|
||||||
|
set => SetValue(StaysOpenProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used by the gradient picker to load saved gradients, do not touch or it'll just throw an exception
|
/// Used by the gradient picker to load saved gradients, do not touch or it'll just throw an exception
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -64,33 +108,17 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color Color
|
|
||||||
{
|
|
||||||
get => (Color) GetValue(ColorProperty);
|
|
||||||
set => SetValue(ColorProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool PopupOpen
|
|
||||||
{
|
|
||||||
get => (bool) GetValue(PopupOpenProperty);
|
|
||||||
set => SetValue(PopupOpenProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool StaysOpen
|
|
||||||
{
|
|
||||||
get => (bool) GetValue(StaysOpenProperty);
|
|
||||||
set => SetValue(StaysOpenProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal byte ColorOpacity
|
internal byte ColorOpacity
|
||||||
{
|
{
|
||||||
get => (byte) GetValue(ColorOpacityProperty);
|
get => (byte) GetValue(ColorOpacityProperty);
|
||||||
set => SetValue(ColorOpacityProperty, value);
|
set => SetValue(ColorOpacityProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="PropertyChanged" /> event
|
||||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
/// </summary>
|
||||||
|
/// <param name="propertyName"></param>
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
@ -105,7 +133,7 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
colorPicker.SetCurrentValue(ColorOpacityProperty, ((Color) e.NewValue).A);
|
colorPicker.SetCurrentValue(ColorOpacityProperty, ((Color) e.NewValue).A);
|
||||||
colorPicker.OnPropertyChanged(nameof(Color));
|
colorPicker.OnPropertyChanged(nameof(Color));
|
||||||
_colorPickerService.UpdateColorDisplay(colorPicker.Color);
|
_colorPickerService?.UpdateColorDisplay(colorPicker.Color);
|
||||||
|
|
||||||
colorPicker._inCallback = false;
|
colorPicker._inCallback = false;
|
||||||
}
|
}
|
||||||
@ -145,7 +173,7 @@ namespace Artemis.UI.Shared
|
|||||||
color = Color.FromArgb(opacity, color.R, color.G, color.B);
|
color = Color.FromArgb(opacity, color.R, color.G, color.B);
|
||||||
colorPicker.SetCurrentValue(ColorProperty, color);
|
colorPicker.SetCurrentValue(ColorProperty, color);
|
||||||
colorPicker.OnPropertyChanged(nameof(ColorOpacity));
|
colorPicker.OnPropertyChanged(nameof(ColorOpacity));
|
||||||
_colorPickerService.UpdateColorDisplay(colorPicker.Color);
|
_colorPickerService?.UpdateColorDisplay(colorPicker.Color);
|
||||||
|
|
||||||
colorPicker._inCallback = false;
|
colorPicker._inCallback = false;
|
||||||
}
|
}
|
||||||
@ -163,6 +191,7 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
private void Slider_OnMouseDown(object sender, MouseButtonEventArgs e)
|
private void Slider_OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (_colorPickerService == null) return;
|
||||||
OnDragStarted();
|
OnDragStarted();
|
||||||
|
|
||||||
if (_colorPickerService.PreviewSetting.Value)
|
if (_colorPickerService.PreviewSetting.Value)
|
||||||
@ -171,42 +200,63 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
private void Slider_OnMouseUp(object sender, MouseButtonEventArgs e)
|
private void Slider_OnMouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (_colorPickerService == null) return;
|
||||||
OnDragEnded();
|
OnDragEnded();
|
||||||
_colorPickerService.StopColorDisplay();
|
_colorPickerService.StopColorDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreviewCheckBoxClick(object sender, RoutedEventArgs e)
|
private void PreviewCheckBoxClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_colorPickerService.PreviewSetting.Value = PreviewCheckBox.IsChecked.Value;
|
if (_colorPickerService == null) return;
|
||||||
|
_colorPickerService.PreviewSetting.Value = PreviewCheckBox.IsChecked ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (_colorPickerService == null) return;
|
||||||
PreviewCheckBox.IsChecked = _colorPickerService.PreviewSetting.Value;
|
PreviewCheckBox.IsChecked = _colorPickerService.PreviewSetting.Value;
|
||||||
_colorPickerService.PreviewSetting.SettingChanged += PreviewSettingOnSettingChanged;
|
_colorPickerService.PreviewSetting.SettingChanged += PreviewSettingOnSettingChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUnloaded(object sender, RoutedEventArgs e)
|
private void OnUnloaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (_colorPickerService == null) return;
|
||||||
_colorPickerService.PreviewSetting.SettingChanged -= PreviewSettingOnSettingChanged;
|
_colorPickerService.PreviewSetting.SettingChanged -= PreviewSettingOnSettingChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreviewSettingOnSettingChanged(object sender, EventArgs e)
|
private void PreviewSettingOnSettingChanged(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
if (_colorPickerService == null) return;
|
||||||
PreviewCheckBox.IsChecked = _colorPickerService.PreviewSetting.Value;
|
PreviewCheckBox.IsChecked = _colorPickerService.PreviewSetting.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public event EventHandler DragStarted;
|
/// <summary>
|
||||||
public event EventHandler DragEnded;
|
/// Occurs when dragging the color picker has started
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? DragStarted;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when dragging the color picker has ended
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? DragEnded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="DragStarted" /> event
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnDragStarted()
|
protected virtual void OnDragStarted()
|
||||||
{
|
{
|
||||||
DragStarted?.Invoke(this, EventArgs.Empty);
|
DragStarted?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="DragEnded" /> event
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnDragEnded()
|
protected virtual void OnDragEnded()
|
||||||
{
|
{
|
||||||
DragEnded?.Invoke(this, EventArgs.Empty);
|
DragEnded?.Invoke(this, EventArgs.Empty);
|
||||||
|
|||||||
@ -30,9 +30,8 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
public ArtemisLed Led { get; }
|
public ArtemisLed Led { get; }
|
||||||
public Rect LedRect { get; set; }
|
public Rect LedRect { get; set; }
|
||||||
public BitmapImage LedImage { get; set; }
|
public BitmapImage? LedImage { get; set; }
|
||||||
|
public Geometry? DisplayGeometry { get; private set; }
|
||||||
public Geometry DisplayGeometry { get; private set; }
|
|
||||||
|
|
||||||
public void RenderColor(DrawingContext drawingContext, bool isDimmed)
|
public void RenderColor(DrawingContext drawingContext, bool isDimmed)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,7 +4,6 @@ using System.Globalization;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
@ -12,15 +11,32 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for DraggableFloat.xaml
|
/// Interaction logic for DraggableFloat.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class DraggableFloat : UserControl, INotifyPropertyChanged
|
public partial class DraggableFloat : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the current value
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(float), typeof(DraggableFloat),
|
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(float), typeof(DraggableFloat),
|
||||||
new FrameworkPropertyMetadata(default(float), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, FloatPropertyChangedCallback));
|
new FrameworkPropertyMetadata(default(float), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, FloatPropertyChangedCallback));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the step size when dragging
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty StepSizeProperty = DependencyProperty.Register(nameof(StepSize), typeof(float), typeof(DraggableFloat));
|
public static readonly DependencyProperty StepSizeProperty = DependencyProperty.Register(nameof(StepSize), typeof(float), typeof(DraggableFloat));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the minimum value
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty MinProperty = DependencyProperty.Register(nameof(Min), typeof(float?), typeof(DraggableFloat));
|
public static readonly DependencyProperty MinProperty = DependencyProperty.Register(nameof(Min), typeof(float?), typeof(DraggableFloat));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the maximum value
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty MaxProperty = DependencyProperty.Register(nameof(Max), typeof(float?), typeof(DraggableFloat));
|
public static readonly DependencyProperty MaxProperty = DependencyProperty.Register(nameof(Max), typeof(float?), typeof(DraggableFloat));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the value has changed
|
||||||
|
/// </summary>
|
||||||
public static readonly RoutedEvent ValueChangedEvent =
|
public static readonly RoutedEvent ValueChangedEvent =
|
||||||
EventManager.RegisterRoutedEvent(
|
EventManager.RegisterRoutedEvent(
|
||||||
nameof(Value),
|
nameof(Value),
|
||||||
@ -28,42 +44,61 @@ namespace Artemis.UI.Shared
|
|||||||
typeof(RoutedPropertyChangedEventHandler<float>),
|
typeof(RoutedPropertyChangedEventHandler<float>),
|
||||||
typeof(DraggableFloat));
|
typeof(DraggableFloat));
|
||||||
|
|
||||||
|
private readonly Regex _inputRegex = new Regex("^[.][-|0-9]+$|^-?[0-9]*[.]{0,1}[0-9]*$");
|
||||||
|
|
||||||
private bool _calledDragStarted;
|
private bool _calledDragStarted;
|
||||||
|
|
||||||
private bool _inCallback;
|
private bool _inCallback;
|
||||||
private readonly Regex _inputRegex = new Regex("^[.][-|0-9]+$|^-?[0-9]*[.]{0,1}[0-9]*$");
|
|
||||||
private Point _mouseDragStartPoint;
|
private Point _mouseDragStartPoint;
|
||||||
private float _startValue;
|
private float _startValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DraggableFloat" /> class
|
||||||
|
/// </summary>
|
||||||
public DraggableFloat()
|
public DraggableFloat()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the current value
|
||||||
|
/// </summary>
|
||||||
public float Value
|
public float Value
|
||||||
{
|
{
|
||||||
get => (float) GetValue(ValueProperty);
|
get => (float) GetValue(ValueProperty);
|
||||||
set => SetValue(ValueProperty, value);
|
set => SetValue(ValueProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the current value as a string
|
||||||
|
/// </summary>
|
||||||
public string InputValue
|
public string InputValue
|
||||||
{
|
{
|
||||||
get => Value.ToString("N3", CultureInfo.InvariantCulture);
|
get => Value.ToString("N3", CultureInfo.InvariantCulture);
|
||||||
set => UpdateValue(value);
|
set => UpdateValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the step size when dragging
|
||||||
|
/// </summary>
|
||||||
public float StepSize
|
public float StepSize
|
||||||
{
|
{
|
||||||
get => (float) GetValue(StepSizeProperty);
|
get => (float) GetValue(StepSizeProperty);
|
||||||
set => SetValue(StepSizeProperty, value);
|
set => SetValue(StepSizeProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the minimum value
|
||||||
|
/// </summary>
|
||||||
public float? Min
|
public float? Min
|
||||||
{
|
{
|
||||||
get => (float?) GetValue(MinProperty);
|
get => (float?) GetValue(MinProperty);
|
||||||
set => SetValue(MinProperty, value);
|
set => SetValue(MinProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the maximum value
|
||||||
|
/// </summary>
|
||||||
public float? Max
|
public float? Max
|
||||||
{
|
{
|
||||||
get => (float?) GetValue(MaxProperty);
|
get => (float?) GetValue(MaxProperty);
|
||||||
@ -135,7 +170,9 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
Point position = e.GetPosition((IInputElement) sender);
|
Point position = e.GetPosition((IInputElement) sender);
|
||||||
if (position == _mouseDragStartPoint)
|
if (position == _mouseDragStartPoint)
|
||||||
|
{
|
||||||
DisplayInput();
|
DisplayInput();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OnDragEnded();
|
OnDragEnded();
|
||||||
@ -186,10 +223,12 @@ namespace Artemis.UI.Shared
|
|||||||
private void InputKeyDown(object sender, KeyEventArgs e)
|
private void InputKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Key == Key.Enter)
|
if (e.Key == Key.Enter)
|
||||||
|
{
|
||||||
DisplayDragHandle();
|
DisplayDragHandle();
|
||||||
|
}
|
||||||
else if (e.Key == Key.Escape)
|
else if (e.Key == Key.Escape)
|
||||||
{
|
{
|
||||||
DraggableFloatInputTextBox.Text = _startValue.ToString();
|
DraggableFloatInputTextBox.Text = _startValue.ToString(CultureInfo.InvariantCulture);
|
||||||
DisplayDragHandle();
|
DisplayDragHandle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,32 +247,51 @@ namespace Artemis.UI.Shared
|
|||||||
{
|
{
|
||||||
if (e.DataObject.GetDataPresent(typeof(string)))
|
if (e.DataObject.GetDataPresent(typeof(string)))
|
||||||
{
|
{
|
||||||
string text = (string) e.DataObject.GetData(typeof(string));
|
if (e.DataObject.GetData(typeof(string)) is string text && !_inputRegex.IsMatch(text))
|
||||||
if (!_inputRegex.IsMatch(text))
|
|
||||||
e.CancelCommand();
|
e.CancelCommand();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
e.CancelCommand();
|
e.CancelCommand();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
/// <inheritdoc />
|
||||||
public event EventHandler DragStarted;
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
public event EventHandler DragEnded;
|
|
||||||
|
|
||||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
/// <summary>
|
||||||
|
/// Occurs when dragging has started
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? DragStarted;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when dragging has ended
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? DragEnded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="PropertyChanged" /> event
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="DragStarted" /> event
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnDragStarted()
|
protected virtual void OnDragStarted()
|
||||||
{
|
{
|
||||||
DragStarted?.Invoke(this, EventArgs.Empty);
|
DragStarted?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="DragEnded" /> event
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnDragEnded()
|
protected virtual void OnDragEnded()
|
||||||
{
|
{
|
||||||
DragEnded?.Invoke(this, EventArgs.Empty);
|
DragEnded?.Invoke(this, EventArgs.Empty);
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.Properties;
|
using Artemis.UI.Shared.Properties;
|
||||||
@ -14,16 +13,37 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for GradientPicker.xaml
|
/// Interaction logic for GradientPicker.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class GradientPicker : UserControl, INotifyPropertyChanged
|
public partial class GradientPicker : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private static IColorPickerService _colorPickerService;
|
private static IColorPickerService? _colorPickerService;
|
||||||
private bool _inCallback;
|
private bool _inCallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="GradientPicker" /> class
|
||||||
|
/// </summary>
|
||||||
public GradientPicker()
|
public GradientPicker()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color gradient
|
||||||
|
/// </summary>
|
||||||
|
public ColorGradient ColorGradient
|
||||||
|
{
|
||||||
|
get => (ColorGradient) GetValue(ColorGradientProperty);
|
||||||
|
set => SetValue(ColorGradientProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the dialog host in which to show the gradient dialog
|
||||||
|
/// </summary>
|
||||||
|
public string DialogHost
|
||||||
|
{
|
||||||
|
get => (string) GetValue(DialogHostProperty);
|
||||||
|
set => SetValue(DialogHostProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used by the gradient picker to load saved gradients, do not touch or it'll just throw an exception
|
/// Used by the gradient picker to load saved gradients, do not touch or it'll just throw an exception
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -38,39 +58,35 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the currently selected color gradient
|
/// Occurs when the dialog has opened
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ColorGradient ColorGradient
|
public event EventHandler? DialogOpened;
|
||||||
{
|
|
||||||
get => (ColorGradient) GetValue(ColorGradientProperty);
|
|
||||||
set => SetValue(ColorGradientProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the currently selected color gradient
|
/// Occurs when the dialog has closed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DialogHost
|
public event EventHandler? DialogClosed;
|
||||||
{
|
|
||||||
get => (string) GetValue(DialogHostProperty);
|
|
||||||
set => SetValue(DialogHostProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
public event EventHandler DialogOpened;
|
|
||||||
public event EventHandler DialogClosed;
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="PropertyChanged" /> event
|
||||||
|
/// </summary>
|
||||||
[NotifyPropertyChangedInvocator]
|
[NotifyPropertyChangedInvocator]
|
||||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="DialogOpened" /> event
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnDialogOpened()
|
protected virtual void OnDialogOpened()
|
||||||
{
|
{
|
||||||
DialogOpened?.Invoke(this, EventArgs.Empty);
|
DialogOpened?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="DialogClosed" /> event
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnDialogClosed()
|
protected virtual void OnDialogClosed()
|
||||||
{
|
{
|
||||||
DialogClosed?.Invoke(this, EventArgs.Empty);
|
DialogClosed?.Invoke(this, EventArgs.Empty);
|
||||||
@ -89,6 +105,9 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
|
private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (_colorPickerService == null)
|
||||||
|
return;
|
||||||
|
|
||||||
Execute.OnUIThread(async () =>
|
Execute.OnUIThread(async () =>
|
||||||
{
|
{
|
||||||
OnDialogOpened();
|
OnDialogOpened();
|
||||||
@ -97,14 +116,26 @@ namespace Artemis.UI.Shared
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
#region Static WPF fields
|
#region Static WPF fields
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color gradient
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty ColorGradientProperty = DependencyProperty.Register(nameof(ColorGradient), typeof(ColorGradient), typeof(GradientPicker),
|
public static readonly DependencyProperty ColorGradientProperty = DependencyProperty.Register(nameof(ColorGradient), typeof(ColorGradient), typeof(GradientPicker),
|
||||||
new FrameworkPropertyMetadata(default(ColorGradient), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorGradientPropertyChangedCallback));
|
new FrameworkPropertyMetadata(default(ColorGradient), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorGradientPropertyChangedCallback));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the dialog host in which to show the gradient dialog
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty DialogHostProperty = DependencyProperty.Register(nameof(DialogHost), typeof(string), typeof(GradientPicker),
|
public static readonly DependencyProperty DialogHostProperty = DependencyProperty.Register(nameof(DialogHost), typeof(string), typeof(GradientPicker),
|
||||||
new FrameworkPropertyMetadata(default(string)));
|
new FrameworkPropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the color gradient has changed
|
||||||
|
/// </summary>
|
||||||
public static readonly RoutedEvent ColorGradientChangedEvent =
|
public static readonly RoutedEvent ColorGradientChangedEvent =
|
||||||
EventManager.RegisterRoutedEvent(nameof(ColorGradient), RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<ColorGradient>), typeof(GradientPicker));
|
EventManager.RegisterRoutedEvent(nameof(ColorGradient), RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<ColorGradient>), typeof(GradientPicker));
|
||||||
|
|
||||||
|
|||||||
@ -3,24 +3,30 @@ using System.Windows.Controls.Primitives;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a toggle button that can be locked using a property
|
||||||
|
/// </summary>
|
||||||
public class LockableToggleButton : ToggleButton
|
public class LockableToggleButton : ToggleButton
|
||||||
{
|
{
|
||||||
protected override void OnToggle()
|
/// <summary>
|
||||||
{
|
/// Gets or sets a boolean indicating whether the toggle button is locked
|
||||||
if (!IsLocked)
|
/// </summary>
|
||||||
{
|
|
||||||
base.OnToggle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsLocked
|
|
||||||
{
|
|
||||||
get { return (bool)GetValue(IsLockedProperty); }
|
|
||||||
set { SetValue(IsLockedProperty, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Using a DependencyProperty as the backing store for LockToggle. This enables animation, styling, binding, etc...
|
|
||||||
public static readonly DependencyProperty IsLockedProperty =
|
public static readonly DependencyProperty IsLockedProperty =
|
||||||
DependencyProperty.Register("IsLocked", typeof(bool), typeof(LockableToggleButton), new UIPropertyMetadata(false));
|
DependencyProperty.Register("IsLocked", typeof(bool), typeof(LockableToggleButton), new UIPropertyMetadata(false));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether the toggle button is locked
|
||||||
|
/// </summary>
|
||||||
|
public bool IsLocked
|
||||||
|
{
|
||||||
|
get => (bool) GetValue(IsLockedProperty);
|
||||||
|
set => SetValue(IsLockedProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnToggle()
|
||||||
|
{
|
||||||
|
if (!IsLocked) base.OnToggle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents errors that occur within the Artemis Shared UI library
|
||||||
|
/// </summary>
|
||||||
public class ArtemisSharedUIException : Exception
|
public class ArtemisSharedUIException : Exception
|
||||||
{
|
{
|
||||||
internal ArtemisSharedUIException()
|
internal ArtemisSharedUIException()
|
||||||
|
|||||||
@ -4,8 +4,18 @@ using Artemis.UI.Shared.Services;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extensions for special data model wrappers used by events and list conditions
|
||||||
|
/// </summary>
|
||||||
public static class DataModelWrapperExtensions
|
public static class DataModelWrapperExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a view model for a <see cref="EventPredicateWrapperDataModel" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wrapper">The wrapper to create the view model for</param>
|
||||||
|
/// <param name="dataModelUIService">The data model UI service to be used by the view model</param>
|
||||||
|
/// <param name="configuration">The update configuration to be used by the view model</param>
|
||||||
|
/// <returns>The created view model</returns>
|
||||||
public static DataModelPropertiesViewModel CreateViewModel(this EventPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
public static DataModelPropertiesViewModel CreateViewModel(this EventPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
||||||
{
|
{
|
||||||
DataModelPropertiesViewModel viewModel = new DataModelPropertiesViewModel(wrapper, null, new DataModelPath(wrapper));
|
DataModelPropertiesViewModel viewModel = new DataModelPropertiesViewModel(wrapper, null, new DataModelPath(wrapper));
|
||||||
@ -16,6 +26,13 @@ namespace Artemis.UI.Shared
|
|||||||
return viewModel;
|
return viewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a view model for a <see cref="ListPredicateWrapperDataModel" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wrapper">The wrapper to create the view model for</param>
|
||||||
|
/// <param name="dataModelUIService">The data model UI service to be used by the view model</param>
|
||||||
|
/// <param name="configuration">The update configuration to be used by the view model</param>
|
||||||
|
/// <returns>The created view model</returns>
|
||||||
public static DataModelPropertiesViewModel CreateViewModel(this ListPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
public static DataModelPropertiesViewModel CreateViewModel(this ListPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
||||||
{
|
{
|
||||||
DataModelPropertiesViewModel viewModel = new DataModelPropertiesViewModel(wrapper, null, new DataModelPath(wrapper));
|
DataModelPropertiesViewModel viewModel = new DataModelPropertiesViewModel(wrapper, null, new DataModelPath(wrapper));
|
||||||
|
|||||||
@ -3,15 +3,33 @@ using Artemis.Core.DataModelExpansions;
|
|||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Artemis.UI.Shared.Input;
|
using Artemis.UI.Shared.Input;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.Ninject.Factories
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a factory for view models provided by the Artemis Shared UI library
|
||||||
|
/// </summary>
|
||||||
public interface ISharedVmFactory
|
public interface ISharedVmFactory
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A factory that allows the creation of data model view models
|
||||||
|
/// </summary>
|
||||||
public interface IDataModelVmFactory : ISharedVmFactory
|
public interface IDataModelVmFactory : ISharedVmFactory
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DataModelDynamicViewModel" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="module">The module to associate the dynamic view model with</param>
|
||||||
|
/// <returns>A new instance of the <see cref="DataModelDynamicViewModel" /> class</returns>
|
||||||
DataModelDynamicViewModel DataModelDynamicViewModel(Module module);
|
DataModelDynamicViewModel DataModelDynamicViewModel(Module module);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DataModelStaticViewModel" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="targetType">The type of property that is expected in this input</param>
|
||||||
|
/// <param name="targetDescription">The description of the property that this input is for</param>
|
||||||
|
/// <returns>A new instance of the <see cref="DataModelStaticViewModel" /> class</returns>
|
||||||
DataModelStaticViewModel DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription);
|
DataModelStaticViewModel DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,11 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.UI.Shared.Ninject.Factories;
|
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
using Ninject.Extensions.Conventions;
|
using Ninject.Extensions.Conventions;
|
||||||
using Ninject.Modules;
|
using Ninject.Modules;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.Ninject
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main <see cref="NinjectModule" /> of the Artemis Shared UI toolkit that binds all services
|
/// The main <see cref="NinjectModule" /> of the Artemis Shared UI toolkit that binds all services
|
||||||
|
|||||||
@ -4,6 +4,9 @@ using Artemis.UI.Shared.Services;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a property input registration, registered through <see cref="IProfileEditorService.RegisterPropertyInput"/>
|
||||||
|
/// </summary>
|
||||||
public class PropertyInputRegistration
|
public class PropertyInputRegistration
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
@ -19,8 +22,19 @@ namespace Artemis.UI.Shared
|
|||||||
Plugin.Disabled += InstanceOnDisabled;
|
Plugin.Disabled += InstanceOnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the plugin that registered the property input
|
||||||
|
/// </summary>
|
||||||
public Plugin Plugin { get; }
|
public Plugin Plugin { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type supported by the property input
|
||||||
|
/// </summary>
|
||||||
public Type SupportedType { get; }
|
public Type SupportedType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the view model type of the property input
|
||||||
|
/// </summary>
|
||||||
public Type ViewModelType { get; }
|
public Type ViewModelType { get; }
|
||||||
|
|
||||||
internal void Unsubscribe()
|
internal void Unsubscribe()
|
||||||
@ -29,7 +43,7 @@ namespace Artemis.UI.Shared
|
|||||||
Plugin.Disabled -= InstanceOnDisabled;
|
Plugin.Disabled -= InstanceOnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InstanceOnDisabled(object sender, EventArgs e)
|
private void InstanceOnDisabled(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
// Profile editor service will call Unsubscribe
|
// Profile editor service will call Unsubscribe
|
||||||
_profileEditorService.RemovePropertyInput(this);
|
_profileEditorService.RemovePropertyInput(this);
|
||||||
|
|||||||
@ -5,11 +5,20 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the base class for a property input view model that is used to edit layer properties
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of property this input view model supports</typeparam>
|
||||||
public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
|
public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
|
||||||
{
|
{
|
||||||
private bool _inputDragging;
|
private bool _inputDragging;
|
||||||
private T _inputValue;
|
private T _inputValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="PropertyInputViewModel" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="layerProperty">The layer property this view model will edit</param>
|
||||||
|
/// <param name="profileEditorService">The profile editor service</param>
|
||||||
protected PropertyInputViewModel(LayerProperty<T> layerProperty, IProfileEditorService profileEditorService)
|
protected PropertyInputViewModel(LayerProperty<T> layerProperty, IProfileEditorService profileEditorService)
|
||||||
{
|
{
|
||||||
LayerProperty = layerProperty;
|
LayerProperty = layerProperty;
|
||||||
@ -21,6 +30,12 @@ namespace Artemis.UI.Shared
|
|||||||
UpdateInputValue();
|
UpdateInputValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="PropertyInputViewModel" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="layerProperty">The layer property this view model will edit</param>
|
||||||
|
/// <param name="profileEditorService">The profile editor service</param>
|
||||||
|
/// <param name="validator">The validator used to validate the input</param>
|
||||||
protected PropertyInputViewModel(LayerProperty<T> layerProperty, IProfileEditorService profileEditorService, IModelValidator validator) : base(validator)
|
protected PropertyInputViewModel(LayerProperty<T> layerProperty, IProfileEditorService profileEditorService, IModelValidator validator) : base(validator)
|
||||||
{
|
{
|
||||||
LayerProperty = layerProperty;
|
LayerProperty = layerProperty;
|
||||||
@ -32,17 +47,32 @@ namespace Artemis.UI.Shared
|
|||||||
UpdateInputValue();
|
UpdateInputValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the layer property this view model is editing
|
||||||
|
/// </summary>
|
||||||
public LayerProperty<T> LayerProperty { get; }
|
public LayerProperty<T> LayerProperty { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the profile editor service
|
||||||
|
/// </summary>
|
||||||
public IProfileEditorService ProfileEditorService { get; }
|
public IProfileEditorService ProfileEditorService { get; }
|
||||||
|
|
||||||
internal override object InternalGuard { get; } = null;
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether the input is currently being dragged
|
||||||
|
/// <para>
|
||||||
|
/// Only applicable when using something like a <see cref="DraggableFloat" />, see
|
||||||
|
/// <see cref="InputDragStarted" /> and <see cref="InputDragEnded" />
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
public bool InputDragging
|
public bool InputDragging
|
||||||
{
|
{
|
||||||
get => _inputDragging;
|
get => _inputDragging;
|
||||||
private set => SetAndNotify(ref _inputDragging, value);
|
private set => SetAndNotify(ref _inputDragging, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the input value
|
||||||
|
/// </summary>
|
||||||
public T InputValue
|
public T InputValue
|
||||||
{
|
{
|
||||||
get => _inputValue;
|
get => _inputValue;
|
||||||
@ -53,29 +83,50 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
internal override object InternalGuard { get; } = new object();
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
LayerProperty.Updated -= LayerPropertyOnUpdated;
|
if (disposing)
|
||||||
LayerProperty.CurrentValueSet -= LayerPropertyOnUpdated;
|
{
|
||||||
LayerProperty.DataBindingEnabled -= LayerPropertyOnDataBindingChange;
|
LayerProperty.Updated -= LayerPropertyOnUpdated;
|
||||||
LayerProperty.DataBindingDisabled -= LayerPropertyOnDataBindingChange;
|
LayerProperty.CurrentValueSet -= LayerPropertyOnUpdated;
|
||||||
Dispose(true);
|
LayerProperty.DataBindingEnabled -= LayerPropertyOnDataBindingChange;
|
||||||
GC.SuppressFinalize(this);
|
LayerProperty.DataBindingDisabled -= LayerPropertyOnDataBindingChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the input value has been applied to the layer property
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnInputValueApplied()
|
protected virtual void OnInputValueApplied()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the input value has changed
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnInputValueChanged()
|
protected virtual void OnInputValueChanged()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when data bindings have been enabled or disabled on the layer property
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnDataBindingsChanged()
|
protected virtual void OnDataBindingsChanged()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies the input value to the layer property
|
||||||
|
/// </summary>
|
||||||
protected void ApplyInputValue()
|
protected void ApplyInputValue()
|
||||||
{
|
{
|
||||||
// Force the validator to run
|
// Force the validator to run
|
||||||
@ -89,9 +140,13 @@ namespace Artemis.UI.Shared
|
|||||||
OnInputValueApplied();
|
OnInputValueApplied();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerPropertyOnUpdated(object sender, EventArgs e)
|
private void SetCurrentValue(T value, bool saveChanges)
|
||||||
{
|
{
|
||||||
UpdateInputValue();
|
LayerProperty.SetCurrentValue(value, ProfileEditorService.CurrentTime);
|
||||||
|
if (saveChanges)
|
||||||
|
ProfileEditorService.UpdateSelectedProfileElement();
|
||||||
|
else
|
||||||
|
ProfileEditorService.UpdateProfilePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateInputValue()
|
private void UpdateInputValue()
|
||||||
@ -114,27 +169,35 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called by the view input drag has started
|
||||||
|
/// <para>
|
||||||
|
/// To use, add the following to DraggableFloat in your xaml: <c>DragStarted="{s:Action InputDragStarted}"</c>
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
public void InputDragStarted(object sender, EventArgs e)
|
public void InputDragStarted(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
InputDragging = true;
|
InputDragging = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called by the view when input drag has ended
|
||||||
|
/// <para>
|
||||||
|
/// To use, add the following to DraggableFloat in your xaml: <c>DragEnded="{s:Action InputDragEnded}"</c>
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
public void InputDragEnded(object sender, EventArgs e)
|
public void InputDragEnded(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
InputDragging = false;
|
InputDragging = false;
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
ProfileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetCurrentValue(T value, bool saveChanges)
|
private void LayerPropertyOnUpdated(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
LayerProperty.SetCurrentValue(value, ProfileEditorService.CurrentTime);
|
UpdateInputValue();
|
||||||
if (saveChanges)
|
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
|
||||||
else
|
|
||||||
ProfileEditorService.UpdateProfilePreview();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerPropertyOnDataBindingChange(object sender, LayerPropertyEventArgs<T> e)
|
private void LayerPropertyOnDataBindingChange(object? sender, LayerPropertyEventArgs<T> e)
|
||||||
{
|
{
|
||||||
OnDataBindingsChanged();
|
OnDataBindingsChanged();
|
||||||
}
|
}
|
||||||
@ -147,10 +210,16 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PropertyInputViewModel : ValidatingModelBase, IDisposable
|
public abstract class PropertyInputViewModel : ValidatingModelBase, IDisposable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// For internal use only, implement <see cref="PropertyInputViewModel{T}" /> instead.
|
||||||
|
/// </summary>
|
||||||
protected PropertyInputViewModel()
|
protected PropertyInputViewModel()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For internal use only, implement <see cref="PropertyInputViewModel{T}" /> instead.
|
||||||
|
/// </summary>
|
||||||
protected PropertyInputViewModel(IModelValidator validator) : base(validator)
|
protected PropertyInputViewModel(IModelValidator validator) : base(validator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -161,13 +230,29 @@ namespace Artemis.UI.Shared
|
|||||||
// ReSharper disable once UnusedMember.Global
|
// ReSharper disable once UnusedMember.Global
|
||||||
internal abstract object InternalGuard { get; }
|
internal abstract object InternalGuard { get; }
|
||||||
|
|
||||||
public abstract void Dispose();
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <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>
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.Services
|
|
||||||
{
|
|
||||||
internal class DataBindingUIService : IDataBindingUIService
|
|
||||||
{
|
|
||||||
public object GetDataBindingViewModel(Type propertyType)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -7,7 +7,6 @@ using Artemis.Core.Modules;
|
|||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Shared.DefaultTypes.DataModel.Display;
|
using Artemis.UI.Shared.DefaultTypes.DataModel.Display;
|
||||||
using Artemis.UI.Shared.Input;
|
using Artemis.UI.Shared.Input;
|
||||||
using Artemis.UI.Shared.Ninject.Factories;
|
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using Ninject.Parameters;
|
using Ninject.Parameters;
|
||||||
|
|
||||||
|
|||||||
@ -3,38 +3,55 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared.Services
|
namespace Artemis.UI.Shared.Services
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the base class for a dialog view model
|
||||||
|
/// </summary>
|
||||||
public abstract class DialogViewModelBase : ValidatingModelBase
|
public abstract class DialogViewModelBase : ValidatingModelBase
|
||||||
{
|
{
|
||||||
private DialogViewModelHost _dialogViewModelHost;
|
private DialogViewModelHost? _dialogViewModelHost;
|
||||||
private DialogSession _session;
|
private DialogSession? _session;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DialogViewModelBase" /> class with a model validator
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="validator">A validator to apply to the model</param>
|
||||||
protected DialogViewModelBase(IModelValidator validator) : base(validator)
|
protected DialogViewModelBase(IModelValidator validator) : base(validator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DialogViewModelBase" />
|
||||||
|
/// </summary>
|
||||||
protected DialogViewModelBase()
|
protected DialogViewModelBase()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public DialogViewModelHost DialogViewModelHost
|
/// <summary>
|
||||||
{
|
/// Gets the dialog session that created this dialog
|
||||||
get => _dialogViewModelHost;
|
/// <para>Not available until after the dialog has been opened</para>
|
||||||
set => SetAndNotify(ref _dialogViewModelHost, value);
|
/// </summary>
|
||||||
}
|
public DialogSession? Session
|
||||||
|
|
||||||
public DialogSession Session
|
|
||||||
{
|
{
|
||||||
get => _session;
|
get => _session;
|
||||||
private set => SetAndNotify(ref _session, value);
|
private set => SetAndNotify(ref _session, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDialogOpened(object sender, DialogOpenedEventArgs e)
|
internal DialogViewModelHost? DialogViewModelHost
|
||||||
{
|
{
|
||||||
Session = e.Session;
|
get => _dialogViewModelHost;
|
||||||
|
set => SetAndNotify(ref _dialogViewModelHost, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the dialog has closed
|
||||||
|
/// </summary>
|
||||||
public virtual void OnDialogClosed(object sender, DialogClosingEventArgs e)
|
public virtual void OnDialogClosed(object sender, DialogClosingEventArgs e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void OnDialogOpened(object sender, DialogOpenedEventArgs e)
|
||||||
|
{
|
||||||
|
Session = e.Session;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,7 +4,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared.Services
|
namespace Artemis.UI.Shared.Services
|
||||||
{
|
{
|
||||||
public class DialogViewModelHost : PropertyChangedBase
|
internal class DialogViewModelHost : PropertyChangedBase
|
||||||
{
|
{
|
||||||
private readonly IViewManager _viewManager;
|
private readonly IViewManager _viewManager;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
namespace Artemis.UI.Shared.Services
|
namespace Artemis.UI.Shared.Services
|
||||||
{
|
{
|
||||||
// ReSharper disable once InconsistentNaming
|
/// <summary>
|
||||||
|
/// Represents a service provided by the Artemis Shared UI library
|
||||||
|
/// </summary>
|
||||||
public interface IArtemisSharedUIService
|
public interface IArtemisSharedUIService
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.Services
|
|
||||||
{
|
|
||||||
public interface IDataBindingUIService : IArtemisSharedUIService
|
|
||||||
{
|
|
||||||
object GetDataBindingViewModel(Type propertyType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -79,6 +79,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// Shows a dialog displaying the provided message and exception. Does not handle, log or throw the exception.
|
/// Shows a dialog displaying the provided message and exception. Does not handle, log or throw the exception.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message to display in the dialog title</param>
|
/// <param name="message">The message to display in the dialog title</param>
|
||||||
|
/// <param name="exception">The exception to display</param>
|
||||||
/// <returns>A task resolving when the dialog is closed</returns>
|
/// <returns>A task resolving when the dialog is closed</returns>
|
||||||
void ShowExceptionDialog(string message, Exception exception);
|
void ShowExceptionDialog(string message, Exception exception);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,27 +3,93 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Ninject;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.Services
|
namespace Artemis.UI.Shared.Services
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides access the the profile editor back-end logic
|
||||||
|
/// </summary>
|
||||||
public interface IProfileEditorService : IArtemisSharedUIService
|
public interface IProfileEditorService : IArtemisSharedUIService
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the currently selected profile
|
||||||
|
/// </summary>
|
||||||
Profile SelectedProfile { get; }
|
Profile SelectedProfile { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the currently selected profile element
|
||||||
|
/// </summary>
|
||||||
RenderProfileElement SelectedProfileElement { get; }
|
RenderProfileElement SelectedProfileElement { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the currently selected data binding property
|
||||||
|
/// </summary>
|
||||||
ILayerProperty SelectedDataBinding { get; }
|
ILayerProperty SelectedDataBinding { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the current time
|
||||||
|
/// </summary>
|
||||||
TimeSpan CurrentTime { get; set; }
|
TimeSpan CurrentTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the pixels per second (zoom level)
|
||||||
|
/// </summary>
|
||||||
int PixelsPerSecond { get; set; }
|
int PixelsPerSecond { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a read-only collection of all registered property editors
|
||||||
|
/// </summary>
|
||||||
ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors { get; }
|
ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors { get; }
|
||||||
IKernel Kernel { get; }
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the selected profile
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="profile">The profile to select</param>
|
||||||
void ChangeSelectedProfile(Profile profile);
|
void ChangeSelectedProfile(Profile profile);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the selected profile and saves it to persistent storage
|
||||||
|
/// </summary>
|
||||||
void UpdateSelectedProfile();
|
void UpdateSelectedProfile();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the selected profile element
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="profileElement">The profile element to select</param>
|
||||||
void ChangeSelectedProfileElement(RenderProfileElement profileElement);
|
void ChangeSelectedProfileElement(RenderProfileElement profileElement);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the selected profile element and saves the profile it is contained in to persistent storage
|
||||||
|
/// </summary>
|
||||||
void UpdateSelectedProfileElement();
|
void UpdateSelectedProfileElement();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the selected data binding property
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="layerProperty">The data binding property to select</param>
|
||||||
void ChangeSelectedDataBinding(ILayerProperty layerProperty);
|
void ChangeSelectedDataBinding(ILayerProperty layerProperty);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the profile preview, forcing UI-elements to re-render
|
||||||
|
/// </summary>
|
||||||
void UpdateProfilePreview();
|
void UpdateProfilePreview();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restores the profile to the last <see cref="UpdateSelectedProfile" /> call
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see langword="true" /> if undo was successful, otherwise <see langword="false" /></returns>
|
||||||
bool UndoUpdateProfile();
|
bool UndoUpdateProfile();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restores the profile to the last <see cref="UndoUpdateProfile" /> call
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see langword="true" /> if redo was successful, otherwise <see langword="false" /></returns>
|
||||||
bool RedoUpdateProfile();
|
bool RedoUpdateProfile();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current module the profile editor is initialized for
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The current module the profile editor is initialized for</returns>
|
||||||
ProfileModule GetCurrentModule();
|
ProfileModule GetCurrentModule();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -85,6 +151,10 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
PropertyInputRegistration RegisterPropertyInput(Type viewModelType, Plugin plugin);
|
PropertyInputRegistration RegisterPropertyInput(Type viewModelType, Plugin plugin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the property input view model
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="registration"></param>
|
||||||
void RemovePropertyInput(PropertyInputRegistration registration);
|
void RemovePropertyInput(PropertyInputRegistration registration);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -97,10 +167,11 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// <param name="snapToCurrentTime">Enable snapping to the current time of the editor</param>
|
/// <param name="snapToCurrentTime">Enable snapping to the current time of the editor</param>
|
||||||
/// <param name="snapTimes">An optional extra list of times to snap to</param>
|
/// <param name="snapTimes">An optional extra list of times to snap to</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, List<TimeSpan> snapTimes = null);
|
TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, List<TimeSpan>? snapTimes = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If a matching registration is found, creates a new <see cref="PropertyInputViewModel{T}"/> supporting <typeparamref name="T"/>
|
/// If a matching registration is found, creates a new <see cref="PropertyInputViewModel{T}" /> supporting
|
||||||
|
/// <typeparamref name="T" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
PropertyInputViewModel<T> CreatePropertyInputViewModel<T>(LayerProperty<T> layerProperty);
|
PropertyInputViewModel<T> CreatePropertyInputViewModel<T>(LayerProperty<T> layerProperty);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
private readonly object _selectedProfileLock = new object();
|
private readonly object _selectedProfileLock = new object();
|
||||||
private TimeSpan _currentTime;
|
private TimeSpan _currentTime;
|
||||||
private int _pixelsPerSecond;
|
private int _pixelsPerSecond;
|
||||||
|
private IKernel _kernel;
|
||||||
|
|
||||||
public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger, ICoreService coreService)
|
public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger, ICoreService coreService)
|
||||||
{
|
{
|
||||||
@ -29,8 +30,8 @@ namespace Artemis.UI.Shared.Services
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
_coreService = coreService;
|
_coreService = coreService;
|
||||||
_registeredPropertyEditors = new List<PropertyInputRegistration>();
|
_registeredPropertyEditors = new List<PropertyInputRegistration>();
|
||||||
|
_kernel = kernel;
|
||||||
|
|
||||||
Kernel = kernel;
|
|
||||||
PixelsPerSecond = 100;
|
PixelsPerSecond = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +41,6 @@ namespace Artemis.UI.Shared.Services
|
|||||||
Execute.PostToUIThread(OnProfilePreviewUpdated);
|
Execute.PostToUIThread(OnProfilePreviewUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IKernel Kernel { get; }
|
|
||||||
public ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
|
public ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
|
||||||
public Profile SelectedProfile { get; private set; }
|
public Profile SelectedProfile { get; private set; }
|
||||||
public RenderProfileElement SelectedProfileElement { get; private set; }
|
public RenderProfileElement SelectedProfileElement { get; private set; }
|
||||||
@ -207,7 +207,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel.Bind(viewModelType).ToSelf();
|
_kernel.Bind(viewModelType).ToSelf();
|
||||||
PropertyInputRegistration registration = new PropertyInputRegistration(this, plugin, supportedType, viewModelType);
|
PropertyInputRegistration registration = new PropertyInputRegistration(this, plugin, supportedType, viewModelType);
|
||||||
_registeredPropertyEditors.Add(registration);
|
_registeredPropertyEditors.Add(registration);
|
||||||
return registration;
|
return registration;
|
||||||
@ -223,7 +223,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
registration.Unsubscribe();
|
registration.Unsubscribe();
|
||||||
_registeredPropertyEditors.Remove(registration);
|
_registeredPropertyEditors.Remove(registration);
|
||||||
|
|
||||||
Kernel.Unbind(registration.ViewModelType);
|
_kernel.Unbind(registration.ViewModelType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,7 +282,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
ConstructorArgument parameter = new ConstructorArgument("layerProperty", layerProperty);
|
ConstructorArgument parameter = new ConstructorArgument("layerProperty", layerProperty);
|
||||||
IKernel kernel = registration != null ? registration.Plugin.Kernel : Kernel;
|
IKernel kernel = registration != null ? registration.Plugin.Kernel : _kernel;
|
||||||
return (PropertyInputViewModel<T>) kernel.Get(viewModelType, parameter);
|
return (PropertyInputViewModel<T>) kernel.Get(viewModelType, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,24 +3,47 @@ using System.Windows.Input;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a command that simply calls a delegate when invoked
|
||||||
|
/// </summary>
|
||||||
public class DelegateCommand : ICommand
|
public class DelegateCommand : ICommand
|
||||||
{
|
{
|
||||||
private readonly Predicate<object> _canExecute;
|
private readonly Predicate<object?>? _canExecute;
|
||||||
private readonly Action<object> _execute;
|
private readonly Action<object?> _execute;
|
||||||
|
|
||||||
public DelegateCommand(Action<object> execute) : this(execute, null)
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DelegateCommand" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="execute">The delegate to execute</param>
|
||||||
|
public DelegateCommand(Action<object?> execute) : this(execute, null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DelegateCommand" /> class with a predicate indicating whether the command
|
||||||
|
/// can be executed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="execute">The delegate to execute</param>
|
||||||
|
/// <param name="canExecute">The predicate that determines whether the command can execute</param>
|
||||||
|
public DelegateCommand(Action<object?> execute, Predicate<object?>? canExecute)
|
||||||
{
|
{
|
||||||
_execute = execute;
|
_execute = execute;
|
||||||
_canExecute = canExecute;
|
_canExecute = canExecute;
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler CanExecuteChanged;
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="CanExecuteChanged" /> event
|
||||||
|
/// </summary>
|
||||||
|
public void RaiseCanExecuteChanged()
|
||||||
|
{
|
||||||
|
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
public bool CanExecute(object parameter)
|
/// <inheritdoc />
|
||||||
|
public event EventHandler? CanExecuteChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool CanExecute(object? parameter)
|
||||||
{
|
{
|
||||||
if (_canExecute == null)
|
if (_canExecute == null)
|
||||||
return true;
|
return true;
|
||||||
@ -28,14 +51,10 @@ namespace Artemis.UI.Shared
|
|||||||
return _canExecute(parameter);
|
return _canExecute(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(object parameter)
|
/// <inheritdoc />
|
||||||
|
public void Execute(object? parameter)
|
||||||
{
|
{
|
||||||
_execute(parameter);
|
_execute(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RaiseCanExecuteChanged()
|
|
||||||
{
|
|
||||||
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ namespace Artemis.UI.Shared
|
|||||||
if (!t.IsEnum)
|
if (!t.IsEnum)
|
||||||
throw new ArgumentException($"{nameof(t)} must be an enum type");
|
throw new ArgumentException($"{nameof(t)} must be an enum type");
|
||||||
|
|
||||||
return Enum.GetValues(t).Cast<Enum>().Select(e => new ValueDescription {Value = e, Description = e.Humanize()}).ToList();
|
return Enum.GetValues(t).Cast<Enum>().Select(e => new ValueDescription(e, e.Humanize())).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -34,9 +34,30 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a value and a description for an enum value
|
||||||
|
/// </summary>
|
||||||
public class ValueDescription
|
public class ValueDescription
|
||||||
{
|
{
|
||||||
public object Value { get; set; }
|
/// <summary>
|
||||||
public string Description { get; set; }
|
/// Creates a new instance of the <see cref="ValueDescription"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The enum value</param>
|
||||||
|
/// <param name="description">The description of the value</param>
|
||||||
|
public ValueDescription(object value, string description)
|
||||||
|
{
|
||||||
|
Value = value ?? throw new ArgumentNullException(nameof(value));
|
||||||
|
Description = description ?? throw new ArgumentNullException(nameof(description));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The enum value
|
||||||
|
/// </summary>
|
||||||
|
public object Value { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The description of the value
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.Controls;
|
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Markup;
|
|
||||||
using System.Windows.Media.Animation;
|
using System.Windows.Media.Animation;
|
||||||
|
|
||||||
// Code from http://www.wpfmentor.com/2009/01/how-to-debug-triggers-using-trigger.html
|
// Code from http://www.wpfmentor.com/2009/01/how-to-debug-triggers-using-trigger.html
|
||||||
@ -22,7 +21,7 @@ using System.Windows.Media.Animation;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains attached properties to activate Trigger Tracing on the specified Triggers.
|
/// Contains attached properties to activate Trigger Tracing on the specified Triggers.
|
||||||
@ -65,37 +64,31 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private class TriggerTraceListener : TraceListener
|
private class TriggerTraceListener : TraceListener
|
||||||
{
|
{
|
||||||
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
|
public override void TraceEvent(TraceEventCache? eventCache, string source, TraceEventType eventType, int id, string format, params object?[]? args)
|
||||||
{
|
{
|
||||||
base.TraceEvent(eventCache, source, eventType, id, format, args);
|
base.TraceEvent(eventCache, source, eventType, id, format, args);
|
||||||
|
|
||||||
if (format.StartsWith("Storyboard has begun;"))
|
if (format.StartsWith("Storyboard has begun;") && args != null)
|
||||||
{
|
if (args[1] is TriggerTraceStoryboard storyboard)
|
||||||
TriggerTraceStoryboard storyboard = args[1] as TriggerTraceStoryboard;
|
|
||||||
if (storyboard != null)
|
|
||||||
{
|
{
|
||||||
// add a breakpoint here to see when your trigger has been
|
// add a breakpoint here to see when your trigger has been
|
||||||
// entered or exited
|
// entered or exited
|
||||||
|
|
||||||
// the element being acted upon
|
// the element being acted upon
|
||||||
object targetElement = args[5];
|
object? targetElement = args[5];
|
||||||
|
|
||||||
// the namescope of the element being acted upon
|
|
||||||
INameScope namescope = (INameScope) args[7];
|
|
||||||
|
|
||||||
TriggerBase triggerBase = storyboard.TriggerBase;
|
TriggerBase triggerBase = storyboard.TriggerBase;
|
||||||
string triggerName = GetTriggerName(storyboard.TriggerBase);
|
string triggerName = GetTriggerName(storyboard.TriggerBase);
|
||||||
|
|
||||||
Debug.WriteLine("Element: {0}, {1}: {2}: {3}", targetElement, triggerBase.GetType().Name, triggerName, storyboard.StoryboardType);
|
Debug.WriteLine("Element: {0}, {1}: {2}: {3}", targetElement, triggerBase.GetType().Name, triggerName, storyboard.StoryboardType);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(string message)
|
public override void Write(string? message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteLine(string message)
|
public override void WriteLine(string? message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,12 +111,16 @@ namespace Artemis.UI.Shared
|
|||||||
/// to identify the trigger in the debug output.
|
/// to identify the trigger in the debug output.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="trigger">The trigger.</param>
|
/// <param name="trigger">The trigger.</param>
|
||||||
|
/// <param name="value">The value.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static void SetTriggerName(TriggerBase trigger, string value)
|
public static void SetTriggerName(TriggerBase trigger, string value)
|
||||||
{
|
{
|
||||||
trigger.SetValue(TriggerNameProperty, value);
|
trigger.SetValue(TriggerNameProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the trigger name property
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty TriggerNameProperty =
|
public static readonly DependencyProperty TriggerNameProperty =
|
||||||
DependencyProperty.RegisterAttached(
|
DependencyProperty.RegisterAttached(
|
||||||
"TriggerName",
|
"TriggerName",
|
||||||
@ -155,6 +152,9 @@ namespace Artemis.UI.Shared
|
|||||||
trigger.SetValue(TraceEnabledProperty, value);
|
trigger.SetValue(TraceEnabledProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether the trace is enabled
|
||||||
|
/// </summary>
|
||||||
public static readonly DependencyProperty TraceEnabledProperty =
|
public static readonly DependencyProperty TraceEnabledProperty =
|
||||||
DependencyProperty.RegisterAttached(
|
DependencyProperty.RegisterAttached(
|
||||||
"TraceEnabled",
|
"TraceEnabled",
|
||||||
@ -164,9 +164,7 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
private static void OnTraceEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void OnTraceEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
TriggerBase triggerBase = d as TriggerBase;
|
if (!(d is TriggerBase triggerBase))
|
||||||
|
|
||||||
if (triggerBase == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(e.NewValue is bool))
|
if (!(e.NewValue is bool))
|
||||||
@ -187,22 +185,16 @@ namespace Artemis.UI.Shared
|
|||||||
// remove the dummy storyboards
|
// remove the dummy storyboards
|
||||||
|
|
||||||
foreach (TriggerActionCollection actionCollection in new[] {triggerBase.EnterActions, triggerBase.ExitActions})
|
foreach (TriggerActionCollection actionCollection in new[] {triggerBase.EnterActions, triggerBase.ExitActions})
|
||||||
{
|
foreach (TriggerAction triggerAction in actionCollection)
|
||||||
foreach (TriggerAction triggerAction in actionCollection)
|
if (triggerAction is BeginStoryboard bsb && bsb.Storyboard is TriggerTraceStoryboard)
|
||||||
{
|
{
|
||||||
BeginStoryboard bsb = triggerAction as BeginStoryboard;
|
actionCollection.Remove(bsb);
|
||||||
|
break;
|
||||||
if (bsb != null && bsb.Storyboard != null && bsb.Storyboard is TriggerTraceStoryboard)
|
|
||||||
{
|
|
||||||
actionCollection.Remove(bsb);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@ using Artemis.Core.Services;
|
|||||||
using Artemis.UI.Ninject;
|
using Artemis.UI.Ninject;
|
||||||
using Artemis.UI.Screens;
|
using Artemis.UI.Screens;
|
||||||
using Artemis.UI.Screens.Splash;
|
using Artemis.UI.Screens.Splash;
|
||||||
using Artemis.UI.Shared.Ninject;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Artemis.UI.Stylet;
|
using Artemis.UI.Stylet;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:model="clr-namespace:MaterialDesignExtensions.Model;assembly=MaterialDesignExtensions"
|
xmlns:model="clr-namespace:MaterialDesignExtensions.Model;assembly=MaterialDesignExtensions"
|
||||||
xmlns:shared="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
xmlns:controls="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
|
||||||
xmlns:controls="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions">
|
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared">
|
||||||
|
|
||||||
<DataTemplate DataType="{x:Type model:FirstLevelNavigationItem}">
|
<DataTemplate DataType="{x:Type model:FirstLevelNavigationItem}">
|
||||||
<Grid Height="48">
|
<Grid Height="48">
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:home="clr-namespace:Artemis.UI.Screens.Home"
|
xmlns:home="clr-namespace:Artemis.UI.Screens.Home"
|
||||||
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="574.026"
|
d:DesignHeight="574.026"
|
||||||
d:DesignWidth="1029.87"
|
d:DesignWidth="1029.87"
|
||||||
@ -37,7 +37,7 @@
|
|||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<controls:ArtemisIcon SvgSource="/Resources/Images/Logo/bow.svg" Width="100" Height="100"/>
|
<shared:ArtemisIcon SvgSource="/Resources/Images/Logo/bow.svg" Width="100" Height="100"/>
|
||||||
<StackPanel Grid.Column="1" Margin="24 0 0 0" VerticalAlignment="Center">
|
<StackPanel Grid.Column="1" Margin="24 0 0 0" VerticalAlignment="Center">
|
||||||
<TextBlock Style="{StaticResource MaterialDesignHeadline4TextBlock}" TextWrapping="Wrap">Welcome to Artemis, RGB on steroids.</TextBlock>
|
<TextBlock Style="{StaticResource MaterialDesignHeadline4TextBlock}" TextWrapping="Wrap">Welcome to Artemis, RGB on steroids.</TextBlock>
|
||||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Extensions;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Extensions;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
xmlns:wpf="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:wpf="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:modules="clr-namespace:Artemis.Core.Modules;assembly=Artemis.Core"
|
xmlns:modules="clr-namespace:Artemis.Core.Modules;assembly=Artemis.Core"
|
||||||
xmlns:dataModel="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
xmlns:dataModel="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||||
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:DataModelDebugViewModel}">
|
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:DataModelDebugViewModel}">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:s="https://github.com/canton7/Stylet"
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
xmlns:devices="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Plugins"
|
xmlns:devices="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Plugins"
|
||||||
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
|
||||||
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
|
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||||
d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}"
|
d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}"
|
||||||
@ -34,7 +33,7 @@
|
|||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<controls:ArtemisIcon Icon="{Binding Icon}"
|
<shared:ArtemisIcon Icon="{Binding Icon}"
|
||||||
Width="48"
|
Width="48"
|
||||||
Height="48"
|
Height="48"
|
||||||
Margin="0 5 0 0"
|
Margin="0 5 0 0"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user