mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +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
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents errors that occur withing the Artemis Core
|
||||
/// Represents errors that occur within the Artemis Core
|
||||
/// </summary>
|
||||
public class ArtemisCoreException : Exception
|
||||
{
|
||||
|
||||
@ -11,7 +11,7 @@ namespace Artemis.Core.Services
|
||||
public DataModelService(IPluginManagementService pluginManagementService)
|
||||
{
|
||||
// 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);
|
||||
foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetFeaturesOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
||||
AddDataModelExpansionDataModel(dataModelExpansion);
|
||||
@ -61,7 +61,8 @@ namespace Artemis.Core.Services
|
||||
private void AddModuleDataModel(Module module)
|
||||
{
|
||||
if (module.InternalDataModel == null)
|
||||
throw new ArtemisCoreException("Cannot add module data model that is not enabled");
|
||||
return;
|
||||
|
||||
if (module.InternalDataModel.DataModelDescription == 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/=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/=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/=propertyinput/@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
|
||||
{
|
||||
/// <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>
|
||||
{
|
||||
private TextBox _textBox;
|
||||
private TextBox? _textBox;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnAttached()
|
||||
{
|
||||
base.OnAttached();
|
||||
@ -18,6 +22,7 @@ namespace Artemis.UI.Shared
|
||||
_textBox.GotFocus += TextBoxGotFocus;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnDetaching()
|
||||
{
|
||||
if (_textBox == null) return;
|
||||
@ -28,6 +33,7 @@ namespace Artemis.UI.Shared
|
||||
|
||||
private void TextBoxGotFocus(object sender, RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
if (_textBox == null) return;
|
||||
_textBox.CaretIndex = _textBox.Text.Length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,21 @@ using Ninject;
|
||||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether or not the shared UI library has been initialized
|
||||
/// </summary>
|
||||
public static bool Initialized { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the shared UI library
|
||||
/// </summary>
|
||||
/// <param name="kernel"></param>
|
||||
public static void Initialize(IKernel kernel)
|
||||
{
|
||||
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:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Shared.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||
|
||||
@ -3,24 +3,37 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
|
||||
namespace Artemis.UI.Shared.Controls
|
||||
namespace Artemis.UI.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ArtemisIcon.xaml
|
||||
/// </summary>
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
new FrameworkPropertyMetadata(IconPropertyChangedCallback));
|
||||
|
||||
private bool _inCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ArtemisIcon"/> class
|
||||
/// </summary>
|
||||
public ArtemisIcon()
|
||||
{
|
||||
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
|
||||
/// to an SVG
|
||||
/// </summary>
|
||||
public object Icon
|
||||
public object? Icon
|
||||
{
|
||||
get => GetValue(IconProperty);
|
||||
set => SetValue(IconProperty, value);
|
||||
@ -73,9 +86,9 @@ namespace Artemis.UI.Shared.Controls
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Artemis.UI.Shared.Services;
|
||||
@ -12,22 +11,34 @@ namespace Artemis.UI.Shared
|
||||
/// <summary>
|
||||
/// Interaction logic for ColorPicker.xaml
|
||||
/// </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),
|
||||
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),
|
||||
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),
|
||||
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, StaysOpenPropertyChangedCallback));
|
||||
|
||||
internal static readonly DependencyProperty ColorOpacityProperty = DependencyProperty.Register(nameof(ColorOpacity), typeof(byte), typeof(ColorPicker),
|
||||
new FrameworkPropertyMetadata((byte) 255, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ColorOpacityPropertyChangedCallback));
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the selected color has changed
|
||||
/// </summary>
|
||||
public static readonly RoutedEvent ColorChangedEvent =
|
||||
EventManager.RegisterRoutedEvent(
|
||||
nameof(Color),
|
||||
@ -35,6 +46,9 @@ namespace Artemis.UI.Shared
|
||||
typeof(RoutedPropertyChangedEventHandler<Color>),
|
||||
typeof(ColorPicker));
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the popup opens or closes
|
||||
/// </summary>
|
||||
public static readonly RoutedEvent PopupOpenChangedEvent =
|
||||
EventManager.RegisterRoutedEvent(
|
||||
nameof(PopupOpen),
|
||||
@ -44,6 +58,9 @@ namespace Artemis.UI.Shared
|
||||
|
||||
private bool _inCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ColorPicker" /> class
|
||||
/// </summary>
|
||||
public ColorPicker()
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -51,6 +68,33 @@ namespace Artemis.UI.Shared
|
||||
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>
|
||||
/// Used by the gradient picker to load saved gradients, do not touch or it'll just throw an exception
|
||||
/// </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
|
||||
{
|
||||
get => (byte) GetValue(ColorOpacityProperty);
|
||||
set => SetValue(ColorOpacityProperty, value);
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="PropertyChanged" /> event
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
@ -105,7 +133,7 @@ namespace Artemis.UI.Shared
|
||||
|
||||
colorPicker.SetCurrentValue(ColorOpacityProperty, ((Color) e.NewValue).A);
|
||||
colorPicker.OnPropertyChanged(nameof(Color));
|
||||
_colorPickerService.UpdateColorDisplay(colorPicker.Color);
|
||||
_colorPickerService?.UpdateColorDisplay(colorPicker.Color);
|
||||
|
||||
colorPicker._inCallback = false;
|
||||
}
|
||||
@ -145,7 +173,7 @@ namespace Artemis.UI.Shared
|
||||
color = Color.FromArgb(opacity, color.R, color.G, color.B);
|
||||
colorPicker.SetCurrentValue(ColorProperty, color);
|
||||
colorPicker.OnPropertyChanged(nameof(ColorOpacity));
|
||||
_colorPickerService.UpdateColorDisplay(colorPicker.Color);
|
||||
_colorPickerService?.UpdateColorDisplay(colorPicker.Color);
|
||||
|
||||
colorPicker._inCallback = false;
|
||||
}
|
||||
@ -163,6 +191,7 @@ namespace Artemis.UI.Shared
|
||||
|
||||
private void Slider_OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (_colorPickerService == null) return;
|
||||
OnDragStarted();
|
||||
|
||||
if (_colorPickerService.PreviewSetting.Value)
|
||||
@ -171,42 +200,63 @@ namespace Artemis.UI.Shared
|
||||
|
||||
private void Slider_OnMouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (_colorPickerService == null) return;
|
||||
OnDragEnded();
|
||||
_colorPickerService.StopColorDisplay();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (_colorPickerService == null) return;
|
||||
PreviewCheckBox.IsChecked = _colorPickerService.PreviewSetting.Value;
|
||||
_colorPickerService.PreviewSetting.SettingChanged += PreviewSettingOnSettingChanged;
|
||||
}
|
||||
|
||||
private void OnUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_colorPickerService == null) return;
|
||||
_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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler DragStarted;
|
||||
public event EventHandler DragEnded;
|
||||
/// <summary>
|
||||
/// 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()
|
||||
{
|
||||
DragStarted?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DragEnded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDragEnded()
|
||||
{
|
||||
DragEnded?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
@ -30,9 +30,8 @@ namespace Artemis.UI.Shared
|
||||
|
||||
public ArtemisLed Led { get; }
|
||||
public Rect LedRect { get; set; }
|
||||
public BitmapImage LedImage { get; set; }
|
||||
|
||||
public Geometry DisplayGeometry { get; private set; }
|
||||
public BitmapImage? LedImage { get; set; }
|
||||
public Geometry? DisplayGeometry { get; private set; }
|
||||
|
||||
public void RenderColor(DrawingContext drawingContext, bool isDimmed)
|
||||
{
|
||||
|
||||
@ -4,7 +4,6 @@ using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
@ -12,15 +11,32 @@ namespace Artemis.UI.Shared
|
||||
/// <summary>
|
||||
/// Interaction logic for DraggableFloat.xaml
|
||||
/// </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),
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum value
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the value has changed
|
||||
/// </summary>
|
||||
public static readonly RoutedEvent ValueChangedEvent =
|
||||
EventManager.RegisterRoutedEvent(
|
||||
nameof(Value),
|
||||
@ -28,42 +44,61 @@ namespace Artemis.UI.Shared
|
||||
typeof(RoutedPropertyChangedEventHandler<float>),
|
||||
typeof(DraggableFloat));
|
||||
|
||||
private readonly Regex _inputRegex = new Regex("^[.][-|0-9]+$|^-?[0-9]*[.]{0,1}[0-9]*$");
|
||||
|
||||
private bool _calledDragStarted;
|
||||
|
||||
private bool _inCallback;
|
||||
private readonly Regex _inputRegex = new Regex("^[.][-|0-9]+$|^-?[0-9]*[.]{0,1}[0-9]*$");
|
||||
private Point _mouseDragStartPoint;
|
||||
private float _startValue;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="DraggableFloat" /> class
|
||||
/// </summary>
|
||||
public DraggableFloat()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current value
|
||||
/// </summary>
|
||||
public float Value
|
||||
{
|
||||
get => (float) GetValue(ValueProperty);
|
||||
set => SetValue(ValueProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current value as a string
|
||||
/// </summary>
|
||||
public string InputValue
|
||||
{
|
||||
get => Value.ToString("N3", CultureInfo.InvariantCulture);
|
||||
set => UpdateValue(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the step size when dragging
|
||||
/// </summary>
|
||||
public float StepSize
|
||||
{
|
||||
get => (float) GetValue(StepSizeProperty);
|
||||
set => SetValue(StepSizeProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum value
|
||||
/// </summary>
|
||||
public float? Min
|
||||
{
|
||||
get => (float?) GetValue(MinProperty);
|
||||
set => SetValue(MinProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum value
|
||||
/// </summary>
|
||||
public float? Max
|
||||
{
|
||||
get => (float?) GetValue(MaxProperty);
|
||||
@ -135,7 +170,9 @@ namespace Artemis.UI.Shared
|
||||
|
||||
Point position = e.GetPosition((IInputElement) sender);
|
||||
if (position == _mouseDragStartPoint)
|
||||
{
|
||||
DisplayInput();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnDragEnded();
|
||||
@ -186,10 +223,12 @@ namespace Artemis.UI.Shared
|
||||
private void InputKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Enter)
|
||||
{
|
||||
DisplayDragHandle();
|
||||
}
|
||||
else if (e.Key == Key.Escape)
|
||||
{
|
||||
DraggableFloatInputTextBox.Text = _startValue.ToString();
|
||||
DraggableFloatInputTextBox.Text = _startValue.ToString(CultureInfo.InvariantCulture);
|
||||
DisplayDragHandle();
|
||||
}
|
||||
}
|
||||
@ -208,32 +247,51 @@ namespace Artemis.UI.Shared
|
||||
{
|
||||
if (e.DataObject.GetDataPresent(typeof(string)))
|
||||
{
|
||||
string text = (string) e.DataObject.GetData(typeof(string));
|
||||
if (!_inputRegex.IsMatch(text))
|
||||
if (e.DataObject.GetData(typeof(string)) is string text && !_inputRegex.IsMatch(text))
|
||||
e.CancelCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
e.CancelCommand();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public event EventHandler DragStarted;
|
||||
public event EventHandler DragEnded;
|
||||
/// <inheritdoc />
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DragStarted" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDragStarted()
|
||||
{
|
||||
DragStarted?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DragEnded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDragEnded()
|
||||
{
|
||||
DragEnded?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Properties;
|
||||
@ -14,16 +13,37 @@ namespace Artemis.UI.Shared
|
||||
/// <summary>
|
||||
/// Interaction logic for GradientPicker.xaml
|
||||
/// </summary>
|
||||
public partial class GradientPicker : UserControl, INotifyPropertyChanged
|
||||
public partial class GradientPicker : INotifyPropertyChanged
|
||||
{
|
||||
private static IColorPickerService _colorPickerService;
|
||||
private static IColorPickerService? _colorPickerService;
|
||||
private bool _inCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="GradientPicker" /> class
|
||||
/// </summary>
|
||||
public GradientPicker()
|
||||
{
|
||||
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>
|
||||
/// Used by the gradient picker to load saved gradients, do not touch or it'll just throw an exception
|
||||
/// </summary>
|
||||
@ -38,39 +58,35 @@ namespace Artemis.UI.Shared
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently selected color gradient
|
||||
/// Occurs when the dialog has opened
|
||||
/// </summary>
|
||||
public ColorGradient ColorGradient
|
||||
{
|
||||
get => (ColorGradient) GetValue(ColorGradientProperty);
|
||||
set => SetValue(ColorGradientProperty, value);
|
||||
}
|
||||
public event EventHandler? DialogOpened;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently selected color gradient
|
||||
/// Occurs when the dialog has closed
|
||||
/// </summary>
|
||||
public string DialogHost
|
||||
{
|
||||
get => (string) GetValue(DialogHostProperty);
|
||||
set => SetValue(DialogHostProperty, value);
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public event EventHandler DialogOpened;
|
||||
public event EventHandler DialogClosed;
|
||||
public event EventHandler? DialogClosed;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="PropertyChanged" /> event
|
||||
/// </summary>
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DialogOpened" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDialogOpened()
|
||||
{
|
||||
DialogOpened?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DialogClosed" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDialogClosed()
|
||||
{
|
||||
DialogClosed?.Invoke(this, EventArgs.Empty);
|
||||
@ -89,6 +105,9 @@ namespace Artemis.UI.Shared
|
||||
|
||||
private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (_colorPickerService == null)
|
||||
return;
|
||||
|
||||
Execute.OnUIThread(async () =>
|
||||
{
|
||||
OnDialogOpened();
|
||||
@ -97,14 +116,26 @@ namespace Artemis.UI.Shared
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
#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),
|
||||
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),
|
||||
new FrameworkPropertyMetadata(default(string)));
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the color gradient has changed
|
||||
/// </summary>
|
||||
public static readonly RoutedEvent ColorGradientChangedEvent =
|
||||
EventManager.RegisterRoutedEvent(nameof(ColorGradient), RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<ColorGradient>), typeof(GradientPicker));
|
||||
|
||||
|
||||
@ -3,24 +3,30 @@ using System.Windows.Controls.Primitives;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a toggle button that can be locked using a property
|
||||
/// </summary>
|
||||
public class LockableToggleButton : ToggleButton
|
||||
{
|
||||
protected override void OnToggle()
|
||||
{
|
||||
if (!IsLocked)
|
||||
{
|
||||
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...
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the toggle button is locked
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsLockedProperty =
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents errors that occur within the Artemis Shared UI library
|
||||
/// </summary>
|
||||
public class ArtemisSharedUIException : Exception
|
||||
{
|
||||
internal ArtemisSharedUIException()
|
||||
|
||||
@ -4,8 +4,18 @@ using Artemis.UI.Shared.Services;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extensions for special data model wrappers used by events and list conditions
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
DataModelPropertiesViewModel viewModel = new DataModelPropertiesViewModel(wrapper, null, new DataModelPath(wrapper));
|
||||
@ -16,6 +26,13 @@ namespace Artemis.UI.Shared
|
||||
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)
|
||||
{
|
||||
DataModelPropertiesViewModel viewModel = new DataModelPropertiesViewModel(wrapper, null, new DataModelPath(wrapper));
|
||||
|
||||
@ -3,15 +3,33 @@ using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
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
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A factory that allows the creation of data model view models
|
||||
/// </summary>
|
||||
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);
|
||||
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using Artemis.UI.Shared.Ninject.Factories;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Ninject.Extensions.Conventions;
|
||||
using Ninject.Modules;
|
||||
|
||||
namespace Artemis.UI.Shared.Ninject
|
||||
namespace Artemis.UI.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a property input registration, registered through <see cref="IProfileEditorService.RegisterPropertyInput"/>
|
||||
/// </summary>
|
||||
public class PropertyInputRegistration
|
||||
{
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
@ -19,8 +22,19 @@ namespace Artemis.UI.Shared
|
||||
Plugin.Disabled += InstanceOnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin that registered the property input
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type supported by the property input
|
||||
/// </summary>
|
||||
public Type SupportedType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the view model type of the property input
|
||||
/// </summary>
|
||||
public Type ViewModelType { get; }
|
||||
|
||||
internal void Unsubscribe()
|
||||
@ -29,7 +43,7 @@ namespace Artemis.UI.Shared
|
||||
Plugin.Disabled -= InstanceOnDisabled;
|
||||
}
|
||||
|
||||
private void InstanceOnDisabled(object sender, EventArgs e)
|
||||
private void InstanceOnDisabled(object? sender, EventArgs e)
|
||||
{
|
||||
// Profile editor service will call Unsubscribe
|
||||
_profileEditorService.RemovePropertyInput(this);
|
||||
|
||||
@ -5,11 +5,20 @@ using Stylet;
|
||||
|
||||
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
|
||||
{
|
||||
private bool _inputDragging;
|
||||
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)
|
||||
{
|
||||
LayerProperty = layerProperty;
|
||||
@ -21,6 +30,12 @@ namespace Artemis.UI.Shared
|
||||
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)
|
||||
{
|
||||
LayerProperty = layerProperty;
|
||||
@ -32,17 +47,32 @@ namespace Artemis.UI.Shared
|
||||
UpdateInputValue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the layer property this view model is editing
|
||||
/// </summary>
|
||||
public LayerProperty<T> LayerProperty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profile editor service
|
||||
/// </summary>
|
||||
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
|
||||
{
|
||||
get => _inputDragging;
|
||||
private set => SetAndNotify(ref _inputDragging, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the input value
|
||||
/// </summary>
|
||||
public T 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;
|
||||
LayerProperty.CurrentValueSet -= LayerPropertyOnUpdated;
|
||||
LayerProperty.DataBindingEnabled -= LayerPropertyOnDataBindingChange;
|
||||
LayerProperty.DataBindingDisabled -= LayerPropertyOnDataBindingChange;
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
if (disposing)
|
||||
{
|
||||
LayerProperty.Updated -= LayerPropertyOnUpdated;
|
||||
LayerProperty.CurrentValueSet -= LayerPropertyOnUpdated;
|
||||
LayerProperty.DataBindingEnabled -= LayerPropertyOnDataBindingChange;
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the input value has changed
|
||||
/// </summary>
|
||||
protected virtual void OnInputValueChanged()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when data bindings have been enabled or disabled on the layer property
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingsChanged()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the input value to the layer property
|
||||
/// </summary>
|
||||
protected void ApplyInputValue()
|
||||
{
|
||||
// Force the validator to run
|
||||
@ -89,9 +140,13 @@ namespace Artemis.UI.Shared
|
||||
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()
|
||||
@ -114,27 +169,35 @@ namespace Artemis.UI.Shared
|
||||
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
InputDragging = false;
|
||||
ProfileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void SetCurrentValue(T value, bool saveChanges)
|
||||
private void LayerPropertyOnUpdated(object? sender, EventArgs e)
|
||||
{
|
||||
LayerProperty.SetCurrentValue(value, ProfileEditorService.CurrentTime);
|
||||
if (saveChanges)
|
||||
ProfileEditorService.UpdateSelectedProfileElement();
|
||||
else
|
||||
ProfileEditorService.UpdateProfilePreview();
|
||||
UpdateInputValue();
|
||||
}
|
||||
|
||||
private void LayerPropertyOnDataBindingChange(object sender, LayerPropertyEventArgs<T> e)
|
||||
private void LayerPropertyOnDataBindingChange(object? sender, LayerPropertyEventArgs<T> e)
|
||||
{
|
||||
OnDataBindingsChanged();
|
||||
}
|
||||
@ -147,10 +210,16 @@ namespace Artemis.UI.Shared
|
||||
/// </summary>
|
||||
public abstract class PropertyInputViewModel : ValidatingModelBase, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// For internal use only, implement <see cref="PropertyInputViewModel{T}" /> instead.
|
||||
/// </summary>
|
||||
protected PropertyInputViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only, implement <see cref="PropertyInputViewModel{T}" /> instead.
|
||||
/// </summary>
|
||||
protected PropertyInputViewModel(IModelValidator validator) : base(validator)
|
||||
{
|
||||
}
|
||||
@ -161,13 +230,29 @@ namespace Artemis.UI.Shared
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
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)
|
||||
{
|
||||
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.UI.Shared.DefaultTypes.DataModel.Display;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Ninject.Factories;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
|
||||
|
||||
@ -3,38 +3,55 @@ using Stylet;
|
||||
|
||||
namespace Artemis.UI.Shared.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the base class for a dialog view model
|
||||
/// </summary>
|
||||
public abstract class DialogViewModelBase : ValidatingModelBase
|
||||
{
|
||||
private DialogViewModelHost _dialogViewModelHost;
|
||||
private DialogSession _session;
|
||||
private DialogViewModelHost? _dialogViewModelHost;
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="DialogViewModelBase" />
|
||||
/// </summary>
|
||||
protected DialogViewModelBase()
|
||||
{
|
||||
}
|
||||
|
||||
public DialogViewModelHost DialogViewModelHost
|
||||
{
|
||||
get => _dialogViewModelHost;
|
||||
set => SetAndNotify(ref _dialogViewModelHost, value);
|
||||
}
|
||||
|
||||
public DialogSession Session
|
||||
/// <summary>
|
||||
/// Gets the dialog session that created this dialog
|
||||
/// <para>Not available until after the dialog has been opened</para>
|
||||
/// </summary>
|
||||
public DialogSession? Session
|
||||
{
|
||||
get => _session;
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
internal void OnDialogOpened(object sender, DialogOpenedEventArgs e)
|
||||
{
|
||||
Session = e.Session;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,7 @@ using Stylet;
|
||||
|
||||
namespace Artemis.UI.Shared.Services
|
||||
{
|
||||
public class DialogViewModelHost : PropertyChangedBase
|
||||
internal class DialogViewModelHost : PropertyChangedBase
|
||||
{
|
||||
private readonly IViewManager _viewManager;
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
namespace Artemis.UI.Shared.Services
|
||||
{
|
||||
// ReSharper disable once InconsistentNaming
|
||||
/// <summary>
|
||||
/// Represents a service provided by the Artemis Shared UI library
|
||||
/// </summary>
|
||||
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.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
void ShowExceptionDialog(string message, Exception exception);
|
||||
}
|
||||
|
||||
@ -3,27 +3,93 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Ninject;
|
||||
|
||||
namespace Artemis.UI.Shared.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access the the profile editor back-end logic
|
||||
/// </summary>
|
||||
public interface IProfileEditorService : IArtemisSharedUIService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the currently selected profile
|
||||
/// </summary>
|
||||
Profile SelectedProfile { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently selected profile element
|
||||
/// </summary>
|
||||
RenderProfileElement SelectedProfileElement { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently selected data binding property
|
||||
/// </summary>
|
||||
ILayerProperty SelectedDataBinding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current time
|
||||
/// </summary>
|
||||
TimeSpan CurrentTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pixels per second (zoom level)
|
||||
/// </summary>
|
||||
int PixelsPerSecond { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a read-only collection of all registered property editors
|
||||
/// </summary>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the selected profile and saves it to persistent storage
|
||||
/// </summary>
|
||||
void UpdateSelectedProfile();
|
||||
|
||||
/// <summary>
|
||||
/// Changes the selected profile element
|
||||
/// </summary>
|
||||
/// <param name="profileElement">The profile element to select</param>
|
||||
void ChangeSelectedProfileElement(RenderProfileElement profileElement);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the selected profile element and saves the profile it is contained in to persistent storage
|
||||
/// </summary>
|
||||
void UpdateSelectedProfileElement();
|
||||
|
||||
/// <summary>
|
||||
/// Changes the selected data binding property
|
||||
/// </summary>
|
||||
/// <param name="layerProperty">The data binding property to select</param>
|
||||
void ChangeSelectedDataBinding(ILayerProperty layerProperty);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the profile preview, forcing UI-elements to re-render
|
||||
/// </summary>
|
||||
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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <summary>
|
||||
@ -85,6 +151,10 @@ namespace Artemis.UI.Shared.Services
|
||||
/// <returns></returns>
|
||||
PropertyInputRegistration RegisterPropertyInput(Type viewModelType, Plugin plugin);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the property input view model
|
||||
/// </summary>
|
||||
/// <param name="registration"></param>
|
||||
void RemovePropertyInput(PropertyInputRegistration registration);
|
||||
|
||||
/// <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="snapTimes">An optional extra list of times to snap to</param>
|
||||
/// <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>
|
||||
/// 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>
|
||||
PropertyInputViewModel<T> CreatePropertyInputViewModel<T>(LayerProperty<T> layerProperty);
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ namespace Artemis.UI.Shared.Services
|
||||
private readonly object _selectedProfileLock = new object();
|
||||
private TimeSpan _currentTime;
|
||||
private int _pixelsPerSecond;
|
||||
private IKernel _kernel;
|
||||
|
||||
public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger, ICoreService coreService)
|
||||
{
|
||||
@ -29,8 +30,8 @@ namespace Artemis.UI.Shared.Services
|
||||
_logger = logger;
|
||||
_coreService = coreService;
|
||||
_registeredPropertyEditors = new List<PropertyInputRegistration>();
|
||||
_kernel = kernel;
|
||||
|
||||
Kernel = kernel;
|
||||
PixelsPerSecond = 100;
|
||||
}
|
||||
|
||||
@ -40,7 +41,6 @@ namespace Artemis.UI.Shared.Services
|
||||
Execute.PostToUIThread(OnProfilePreviewUpdated);
|
||||
}
|
||||
|
||||
public IKernel Kernel { get; }
|
||||
public ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
|
||||
public Profile SelectedProfile { get; private set; }
|
||||
public RenderProfileElement SelectedProfileElement { get; private set; }
|
||||
@ -207,7 +207,7 @@ namespace Artemis.UI.Shared.Services
|
||||
return existing;
|
||||
}
|
||||
|
||||
Kernel.Bind(viewModelType).ToSelf();
|
||||
_kernel.Bind(viewModelType).ToSelf();
|
||||
PropertyInputRegistration registration = new PropertyInputRegistration(this, plugin, supportedType, viewModelType);
|
||||
_registeredPropertyEditors.Add(registration);
|
||||
return registration;
|
||||
@ -223,7 +223,7 @@ namespace Artemis.UI.Shared.Services
|
||||
registration.Unsubscribe();
|
||||
_registeredPropertyEditors.Remove(registration);
|
||||
|
||||
Kernel.Unbind(registration.ViewModelType);
|
||||
_kernel.Unbind(registration.ViewModelType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,7 +282,7 @@ namespace Artemis.UI.Shared.Services
|
||||
return null;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -3,24 +3,47 @@ using System.Windows.Input;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a command that simply calls a delegate when invoked
|
||||
/// </summary>
|
||||
public class DelegateCommand : ICommand
|
||||
{
|
||||
private readonly Predicate<object> _canExecute;
|
||||
private readonly Action<object> _execute;
|
||||
private readonly Predicate<object?>? _canExecute;
|
||||
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;
|
||||
_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)
|
||||
return true;
|
||||
@ -28,14 +51,10 @@ namespace Artemis.UI.Shared
|
||||
return _canExecute(parameter);
|
||||
}
|
||||
|
||||
public void Execute(object parameter)
|
||||
/// <inheritdoc />
|
||||
public void Execute(object? parameter)
|
||||
{
|
||||
_execute(parameter);
|
||||
}
|
||||
|
||||
public void RaiseCanExecuteChanged()
|
||||
{
|
||||
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -20,7 +20,7 @@ namespace Artemis.UI.Shared
|
||||
if (!t.IsEnum)
|
||||
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>
|
||||
@ -34,9 +34,30 @@ namespace Artemis.UI.Shared
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a value and a description for an enum value
|
||||
/// </summary>
|
||||
public class ValueDescription
|
||||
{
|
||||
public object Value { get; set; }
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// 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.IO;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Controls;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media.Animation;
|
||||
|
||||
// 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
|
||||
{
|
||||
#if DEBUG
|
||||
#if DEBUG
|
||||
|
||||
/// <summary>
|
||||
/// Contains attached properties to activate Trigger Tracing on the specified Triggers.
|
||||
@ -65,37 +64,31 @@ namespace Artemis.UI.Shared
|
||||
/// </summary>
|
||||
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);
|
||||
|
||||
if (format.StartsWith("Storyboard has begun;"))
|
||||
{
|
||||
TriggerTraceStoryboard storyboard = args[1] as TriggerTraceStoryboard;
|
||||
if (storyboard != null)
|
||||
if (format.StartsWith("Storyboard has begun;") && args != null)
|
||||
if (args[1] is TriggerTraceStoryboard storyboard)
|
||||
{
|
||||
// add a breakpoint here to see when your trigger has been
|
||||
// entered or exited
|
||||
|
||||
// the element being acted upon
|
||||
object targetElement = args[5];
|
||||
|
||||
// the namescope of the element being acted upon
|
||||
INameScope namescope = (INameScope) args[7];
|
||||
object? targetElement = args[5];
|
||||
|
||||
TriggerBase triggerBase = storyboard.TriggerBase;
|
||||
string triggerName = GetTriggerName(storyboard.TriggerBase);
|
||||
|
||||
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.
|
||||
/// </summary>
|
||||
/// <param name="trigger">The trigger.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns></returns>
|
||||
public static void SetTriggerName(TriggerBase trigger, string value)
|
||||
{
|
||||
trigger.SetValue(TriggerNameProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the trigger name property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty TriggerNameProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"TriggerName",
|
||||
@ -155,6 +152,9 @@ namespace Artemis.UI.Shared
|
||||
trigger.SetValue(TraceEnabledProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the trace is enabled
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty TraceEnabledProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"TraceEnabled",
|
||||
@ -164,9 +164,7 @@ namespace Artemis.UI.Shared
|
||||
|
||||
private static void OnTraceEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
TriggerBase triggerBase = d as TriggerBase;
|
||||
|
||||
if (triggerBase == null)
|
||||
if (!(d is TriggerBase triggerBase))
|
||||
return;
|
||||
|
||||
if (!(e.NewValue is bool))
|
||||
@ -187,22 +185,16 @@ namespace Artemis.UI.Shared
|
||||
// remove the dummy storyboards
|
||||
|
||||
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;
|
||||
|
||||
if (bsb != null && bsb.Storyboard != null && bsb.Storyboard is TriggerTraceStoryboard)
|
||||
{
|
||||
actionCollection.Remove(bsb);
|
||||
break;
|
||||
}
|
||||
actionCollection.Remove(bsb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@ -15,7 +15,7 @@ using Artemis.Core.Services;
|
||||
using Artemis.UI.Ninject;
|
||||
using Artemis.UI.Screens;
|
||||
using Artemis.UI.Screens.Splash;
|
||||
using Artemis.UI.Shared.Ninject;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Stylet;
|
||||
using Ninject;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
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}">
|
||||
<Grid Height="48">
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
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"
|
||||
d:DesignHeight="574.026"
|
||||
d:DesignWidth="1029.87"
|
||||
@ -37,7 +37,7 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
</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">
|
||||
<TextBlock Style="{StaticResource MaterialDesignHeadline4TextBlock}" TextWrapping="Wrap">Welcome to Artemis, RGB on steroids.</TextBlock>
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}"
|
||||
|
||||
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
xmlns:wpf="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:modules="clr-namespace:Artemis.Core.Modules;assembly=Artemis.Core"
|
||||
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"
|
||||
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:DataModelDebugViewModel}">
|
||||
<UserControl.Resources>
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
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:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}"
|
||||
@ -34,7 +33,7 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<controls:ArtemisIcon Icon="{Binding Icon}"
|
||||
<shared:ArtemisIcon Icon="{Binding Icon}"
|
||||
Width="48"
|
||||
Height="48"
|
||||
Margin="0 5 0 0"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user