mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 17:53:32 +00:00
Shared UI - Resolved all remaining warnings
UI - Resolved all remaining warnings Layer properties - Fixed DisableKeyframes layer property attribute not being applied
This commit is contained in:
parent
931b43aa66
commit
8d901027ee
@ -491,6 +491,9 @@ namespace Artemis.Core
|
|||||||
Entity = entity ?? throw new ArgumentNullException(nameof(entity));
|
Entity = entity ?? throw new ArgumentNullException(nameof(entity));
|
||||||
PropertyDescription = description ?? throw new ArgumentNullException(nameof(description));
|
PropertyDescription = description ?? throw new ArgumentNullException(nameof(description));
|
||||||
IsLoadedFromStorage = fromStorage;
|
IsLoadedFromStorage = fromStorage;
|
||||||
|
|
||||||
|
if (PropertyDescription.DisableKeyframes)
|
||||||
|
KeyframesSupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@ -184,7 +184,7 @@ namespace Artemis.UI.Shared
|
|||||||
return rotationRect.Size;
|
return rotationRect.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUnloaded(object sender, RoutedEventArgs e)
|
private void OnUnloaded(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_timer.Stop();
|
_timer.Stop();
|
||||||
|
|
||||||
@ -196,12 +196,12 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
private void OnLoaded(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_timer.Start();
|
_timer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TimerOnTick(object sender, EventArgs e)
|
private void TimerOnTick(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (ShowColors && Visibility == Visibility.Visible)
|
if (ShowColors && Visibility == Visibility.Visible)
|
||||||
Render();
|
Render();
|
||||||
|
|||||||
@ -13,20 +13,20 @@ namespace Artemis.UI.Shared
|
|||||||
public class ColorToStringConverter : IValueConverter
|
public class ColorToStringConverter : IValueConverter
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
public object? Convert(object? value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
return value?.ToString()?.ToUpper();
|
return value?.ToString()?.ToUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object? ConvertBack(object? value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace((string) value))
|
if (string.IsNullOrWhiteSpace(value as string))
|
||||||
return default(Color);
|
return default(Color);
|
||||||
|
|
||||||
object color = ColorConverter.ConvertFromString((string) value);
|
object? color = ColorConverter.ConvertFromString((string) value!);
|
||||||
if (color is Color c)
|
if (color is Color c)
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
|
|||||||
@ -14,18 +14,18 @@ namespace Artemis.UI.Shared
|
|||||||
public class SKColorToStringConverter : IValueConverter
|
public class SKColorToStringConverter : IValueConverter
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
public object? Convert(object? value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
return value?.ToString();
|
return value?.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object? value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace((string) value))
|
if (string.IsNullOrWhiteSpace(value as string))
|
||||||
return SKColor.Empty;
|
return SKColor.Empty;
|
||||||
|
|
||||||
return SKColor.TryParse((string) value, out SKColor color) ? color : SKColor.Empty;
|
return SKColor.TryParse((string) value!, out SKColor color) ? color : SKColor.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11,7 +11,7 @@ namespace Artemis.UI.Shared
|
|||||||
public class TypeToStringConverter : IValueConverter
|
public class TypeToStringConverter : IValueConverter
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
public object? Convert(object value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
bool humanizeProvided = bool.TryParse(parameter?.ToString(), out bool humanize);
|
bool humanizeProvided = bool.TryParse(parameter?.ToString(), out bool humanize);
|
||||||
if (value is Type type)
|
if (value is Type type)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Artemis.Core.DataModelExpansions;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Artemis.Core.DataModelExpansions;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
@ -9,11 +10,13 @@ namespace Artemis.UI.Shared
|
|||||||
/// <typeparam name="T">The type of the data model</typeparam>
|
/// <typeparam name="T">The type of the data model</typeparam>
|
||||||
public abstract class DataModelDisplayViewModel<T> : DataModelDisplayViewModel
|
public abstract class DataModelDisplayViewModel<T> : DataModelDisplayViewModel
|
||||||
{
|
{
|
||||||
private T _displayValue;
|
[AllowNull]
|
||||||
|
private T _displayValue = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets value that the view model must display
|
/// Gets or sets value that the view model must display
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[AllowNull]
|
||||||
public T DisplayValue
|
public T DisplayValue
|
||||||
{
|
{
|
||||||
get => _displayValue;
|
get => _displayValue;
|
||||||
@ -24,10 +27,10 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override object InternalGuard => null;
|
internal override object InternalGuard => new object();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void UpdateValue(object model)
|
public override void UpdateValue(object? model)
|
||||||
{
|
{
|
||||||
DisplayValue = model is T value ? value : default;
|
DisplayValue = model is T value ? value : default;
|
||||||
}
|
}
|
||||||
@ -45,12 +48,12 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class DataModelDisplayViewModel : PropertyChangedBase
|
public abstract class DataModelDisplayViewModel : PropertyChangedBase
|
||||||
{
|
{
|
||||||
private DataModelPropertyAttribute _propertyDescription;
|
private DataModelPropertyAttribute? _propertyDescription;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the property description of this value
|
/// Gets the property description of this value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelPropertyAttribute PropertyDescription
|
public DataModelPropertyAttribute? PropertyDescription
|
||||||
{
|
{
|
||||||
get => _propertyDescription;
|
get => _propertyDescription;
|
||||||
internal set => SetAndNotify(ref _propertyDescription, value);
|
internal set => SetAndNotify(ref _propertyDescription, value);
|
||||||
@ -65,6 +68,6 @@ namespace Artemis.UI.Shared
|
|||||||
/// Updates the display value
|
/// Updates the display value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="model">The value to set</param>
|
/// <param name="model">The value to set</param>
|
||||||
public abstract void UpdateValue(object model);
|
public abstract void UpdateValue(object? model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
@ -16,7 +17,7 @@ namespace Artemis.UI.Shared
|
|||||||
public abstract class DataModelInputViewModel<T> : DataModelInputViewModel
|
public abstract class DataModelInputViewModel<T> : DataModelInputViewModel
|
||||||
{
|
{
|
||||||
private bool _closed;
|
private bool _closed;
|
||||||
private T _inputValue;
|
[AllowNull] private T _inputValue = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the <see cref="DataModelInputViewModel{T}" /> class
|
/// Creates a new instance of the <see cref="DataModelInputViewModel{T}" /> class
|
||||||
@ -32,6 +33,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the value shown in the input
|
/// Gets or sets the value shown in the input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[AllowNull]
|
||||||
public T InputValue
|
public T InputValue
|
||||||
{
|
{
|
||||||
get => _inputValue;
|
get => _inputValue;
|
||||||
@ -82,13 +84,13 @@ namespace Artemis.UI.Shared
|
|||||||
// ReSharper disable once UnusedMember.Global
|
// ReSharper disable once UnusedMember.Global
|
||||||
internal abstract object InternalGuard { get; }
|
internal abstract object InternalGuard { get; }
|
||||||
|
|
||||||
internal Action<object, bool> UpdateCallback { get; set; }
|
internal Action<object?, bool> UpdateCallback { get; set; } = null!; // Set right after construction
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the types this input view model can support through type conversion. This list is defined when registering the
|
/// Gets the types this input view model can support through type conversion. This list is defined when registering the
|
||||||
/// view model.
|
/// view model.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal IReadOnlyCollection<Type> CompatibleConversionTypes { get; set; }
|
internal IReadOnlyCollection<Type>? CompatibleConversionTypes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Submits the input value and removes this view model.
|
/// Submits the input value and removes this view model.
|
||||||
@ -133,6 +135,6 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public UIElement View { get; set; }
|
public UIElement? View { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,21 +12,25 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared.Input
|
namespace Artemis.UI.Shared.Input
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a view model that allows selecting a data model property used by boolean operations on a certain data
|
||||||
|
/// model property
|
||||||
|
/// </summary>
|
||||||
public class DataModelDynamicViewModel : PropertyChangedBase, IDisposable
|
public class DataModelDynamicViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
private readonly Module _module;
|
private readonly Module _module;
|
||||||
private readonly Timer _updateTimer;
|
private readonly Timer _updateTimer;
|
||||||
private SolidColorBrush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
|
private SolidColorBrush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
|
||||||
private DataModelPath _dataModelPath;
|
private DataModelPath? _dataModelPath;
|
||||||
private DataModelPropertiesViewModel _dataModelViewModel;
|
private DataModelPropertiesViewModel? _dataModelViewModel;
|
||||||
private bool _displaySwitchButton;
|
private bool _displaySwitchButton;
|
||||||
private Type[] _filterTypes;
|
private Type[] _filterTypes = new Type[0];
|
||||||
private bool _isDataModelViewModelOpen;
|
private bool _isDataModelViewModelOpen;
|
||||||
private bool _isEnabled = true;
|
private bool _isEnabled = true;
|
||||||
private string _placeholder = "Select a property";
|
private string _placeholder = "Select a property";
|
||||||
|
|
||||||
public DataModelDynamicViewModel(Module module, ISettingsService settingsService, IDataModelUIService dataModelUIService)
|
internal DataModelDynamicViewModel(Module module, ISettingsService settingsService, IDataModelUIService dataModelUIService)
|
||||||
{
|
{
|
||||||
_module = module;
|
_module = module;
|
||||||
_dataModelUIService = dataModelUIService;
|
_dataModelUIService = dataModelUIService;
|
||||||
@ -39,6 +43,9 @@ namespace Artemis.UI.Shared.Input
|
|||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the brush to use for the input button
|
||||||
|
/// </summary>
|
||||||
public SolidColorBrush ButtonBrush
|
public SolidColorBrush ButtonBrush
|
||||||
{
|
{
|
||||||
get => _buttonBrush;
|
get => _buttonBrush;
|
||||||
@ -49,26 +56,41 @@ namespace Artemis.UI.Shared.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the brush to use for the switch button
|
||||||
|
/// </summary>
|
||||||
public SolidColorBrush SwitchButtonBrush => new SolidColorBrush(ButtonBrush.Color.Darken());
|
public SolidColorBrush SwitchButtonBrush => new SolidColorBrush(ButtonBrush.Color.Darken());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the placeholder text when no value is entered
|
||||||
|
/// </summary>
|
||||||
public string Placeholder
|
public string Placeholder
|
||||||
{
|
{
|
||||||
get => _placeholder;
|
get => _placeholder;
|
||||||
set => SetAndNotify(ref _placeholder, value);
|
set => SetAndNotify(ref _placeholder, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the enabled state of the input
|
||||||
|
/// </summary>
|
||||||
public bool IsEnabled
|
public bool IsEnabled
|
||||||
{
|
{
|
||||||
get => _isEnabled;
|
get => _isEnabled;
|
||||||
set => SetAndNotify(ref _isEnabled, value);
|
set => SetAndNotify(ref _isEnabled, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether the switch button should be displayed
|
||||||
|
/// </summary>
|
||||||
public bool DisplaySwitchButton
|
public bool DisplaySwitchButton
|
||||||
{
|
{
|
||||||
get => _displaySwitchButton;
|
get => _displaySwitchButton;
|
||||||
set => SetAndNotify(ref _displaySwitchButton, value);
|
set => SetAndNotify(ref _displaySwitchButton, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the types of properties this view model will allow to be selected
|
||||||
|
/// </summary>
|
||||||
public Type[] FilterTypes
|
public Type[] FilterTypes
|
||||||
{
|
{
|
||||||
get => _filterTypes;
|
get => _filterTypes;
|
||||||
@ -79,18 +101,38 @@ namespace Artemis.UI.Shared.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a bindable collection of extra data model view models to show
|
||||||
|
/// </summary>
|
||||||
public BindableCollection<DataModelPropertiesViewModel> ExtraDataModelViewModels { get; }
|
public BindableCollection<DataModelPropertiesViewModel> ExtraDataModelViewModels { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a boolean indicating whether there are any extra data models
|
||||||
|
/// </summary>
|
||||||
public bool HasExtraDataModels => ExtraDataModelViewModels.Any();
|
public bool HasExtraDataModels => ExtraDataModelViewModels.Any();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Command used by view
|
||||||
|
/// </summary>
|
||||||
public DelegateCommand SelectPropertyCommand { get; }
|
public DelegateCommand SelectPropertyCommand { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setting used by view
|
||||||
|
/// </summary>
|
||||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||||
|
|
||||||
public DataModelPropertiesViewModel DataModelViewModel
|
/// <summary>
|
||||||
|
/// Gets or sets root the data model view model
|
||||||
|
/// </summary>
|
||||||
|
public DataModelPropertiesViewModel? DataModelViewModel
|
||||||
{
|
{
|
||||||
get => _dataModelViewModel;
|
get => _dataModelViewModel;
|
||||||
private set => SetAndNotify(ref _dataModelViewModel, value);
|
private set => SetAndNotify(ref _dataModelViewModel, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether the data model is open
|
||||||
|
/// </summary>
|
||||||
public bool IsDataModelViewModelOpen
|
public bool IsDataModelViewModelOpen
|
||||||
{
|
{
|
||||||
get => _isDataModelViewModelOpen;
|
get => _isDataModelViewModelOpen;
|
||||||
@ -101,7 +143,10 @@ namespace Artemis.UI.Shared.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModelPath DataModelPath
|
/// <summary>
|
||||||
|
/// Gets or sets the data model path of the currently selected data model property
|
||||||
|
/// </summary>
|
||||||
|
public DataModelPath? DataModelPath
|
||||||
{
|
{
|
||||||
get => _dataModelPath;
|
get => _dataModelPath;
|
||||||
private set
|
private set
|
||||||
@ -113,9 +158,19 @@ namespace Artemis.UI.Shared.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a boolean indicating whether the current selection is valid
|
||||||
|
/// </summary>
|
||||||
public bool IsValid => DataModelPath?.IsValid ?? true;
|
public bool IsValid => DataModelPath?.IsValid ?? true;
|
||||||
public string DisplayValue => DataModelPath?.GetPropertyDescription()?.Name ?? DataModelPath?.Segments.LastOrDefault()?.Identifier;
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the display name of the currently selected property
|
||||||
|
/// </summary>
|
||||||
|
public string? DisplayValue => DataModelPath?.GetPropertyDescription()?.Name ?? DataModelPath?.Segments.LastOrDefault()?.Identifier;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the human readable path of the currently selected property
|
||||||
|
/// </summary>
|
||||||
public string DisplayPath
|
public string DisplayPath
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -128,8 +183,16 @@ namespace Artemis.UI.Shared.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether event child VMs should be loaded, defaults to <see langword="true" />
|
||||||
|
/// </summary>
|
||||||
public bool LoadEventChildren { get; set; } = true;
|
public bool LoadEventChildren { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the root data model VM stored in <see cref="DataModelViewModel" /> to the provided
|
||||||
|
/// <paramref name="dataModel" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataModel">The data model VM to set the new root data model to</param>
|
||||||
public void ChangeDataModel(DataModelPropertiesViewModel dataModel)
|
public void ChangeDataModel(DataModelPropertiesViewModel dataModel)
|
||||||
{
|
{
|
||||||
if (DataModelViewModel != null)
|
if (DataModelViewModel != null)
|
||||||
@ -141,12 +204,19 @@ namespace Artemis.UI.Shared.Input
|
|||||||
DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested;
|
DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeDataModelPath(DataModelPath dataModelPath)
|
/// <summary>
|
||||||
|
/// Changes the currently selected property by its path
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataModelPath">The path of the property to set the selection to</param>
|
||||||
|
public void ChangeDataModelPath(DataModelPath? dataModelPath)
|
||||||
{
|
{
|
||||||
DataModelPath?.Dispose();
|
DataModelPath?.Dispose();
|
||||||
DataModelPath = dataModelPath != null ? new DataModelPath(dataModelPath) : null;
|
DataModelPath = dataModelPath != null ? new DataModelPath(dataModelPath) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Requests switching the input type to static using a <see cref="DataModelStaticViewModel" />
|
||||||
|
/// </summary>
|
||||||
public void SwitchToStatic()
|
public void SwitchToStatic()
|
||||||
{
|
{
|
||||||
ChangeDataModelPath(null);
|
ChangeDataModelPath(null);
|
||||||
@ -158,13 +228,14 @@ namespace Artemis.UI.Shared.Input
|
|||||||
{
|
{
|
||||||
// Get the data models
|
// Get the data models
|
||||||
DataModelViewModel = _dataModelUIService.GetPluginDataModelVisualization(_module, true);
|
DataModelViewModel = _dataModelUIService.GetPluginDataModelVisualization(_module, true);
|
||||||
DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested;
|
if (DataModelViewModel != null)
|
||||||
|
DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested;
|
||||||
ExtraDataModelViewModels.CollectionChanged += ExtraDataModelViewModelsOnCollectionChanged;
|
ExtraDataModelViewModels.CollectionChanged += ExtraDataModelViewModelsOnCollectionChanged;
|
||||||
_updateTimer.Start();
|
_updateTimer.Start();
|
||||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExecuteSelectPropertyCommand(object context)
|
private void ExecuteSelectPropertyCommand(object? context)
|
||||||
{
|
{
|
||||||
if (!(context is DataModelVisualizationViewModel selected))
|
if (!(context is DataModelVisualizationViewModel selected))
|
||||||
return;
|
return;
|
||||||
@ -173,40 +244,61 @@ namespace Artemis.UI.Shared.Input
|
|||||||
OnPropertySelected(new DataModelInputDynamicEventArgs(DataModelPath));
|
OnPropertySelected(new DataModelInputDynamicEventArgs(DataModelPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
_updateTimer.Stop();
|
||||||
|
_updateTimer.Dispose();
|
||||||
|
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||||
|
|
||||||
|
DataModelPath?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_updateTimer.Stop();
|
Dispose(true);
|
||||||
_updateTimer.Dispose();
|
GC.SuppressFinalize(this);
|
||||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
|
||||||
|
|
||||||
DataModelPath?.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void DataModelOnUpdateRequested(object sender, EventArgs e)
|
private void DataModelOnUpdateRequested(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DataModelViewModel.ApplyTypeFilter(true, FilterTypes);
|
DataModelViewModel?.ApplyTypeFilter(true, FilterTypes);
|
||||||
foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels)
|
foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels)
|
||||||
extraDataModelViewModel.ApplyTypeFilter(true, FilterTypes);
|
extraDataModelViewModel.ApplyTypeFilter(true, FilterTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExtraDataModelViewModelsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
private void ExtraDataModelViewModelsOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
NotifyOfPropertyChange(nameof(HasExtraDataModels));
|
NotifyOfPropertyChange(nameof(HasExtraDataModels));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
private void OnUpdateTimerOnElapsed(object? sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!IsDataModelViewModelOpen)
|
if (!IsDataModelViewModelOpen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UpdateDataModelVisualization();
|
UpdateDataModelVisualization();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateDataModelVisualization()
|
private void UpdateDataModelVisualization()
|
||||||
{
|
{
|
||||||
DataModelViewModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren));
|
DataModelViewModel?.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren));
|
||||||
foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels)
|
foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels)
|
||||||
extraDataModelViewModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren));
|
extraDataModelViewModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren));
|
||||||
}
|
}
|
||||||
@ -215,14 +307,28 @@ namespace Artemis.UI.Shared.Input
|
|||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public event EventHandler<DataModelInputDynamicEventArgs> PropertySelected;
|
/// <summary>
|
||||||
public event EventHandler SwitchToStaticRequested;
|
/// Occurs when anew property has been selected
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<DataModelInputDynamicEventArgs>? PropertySelected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a switch to static input has been requested
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? SwitchToStaticRequested;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="PropertySelected" /> event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
protected virtual void OnPropertySelected(DataModelInputDynamicEventArgs e)
|
protected virtual void OnPropertySelected(DataModelInputDynamicEventArgs e)
|
||||||
{
|
{
|
||||||
PropertySelected?.Invoke(this, e);
|
PropertySelected?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the <see cref="SwitchToStaticRequested" /> event
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnSwitchToStaticRequested()
|
protected virtual void OnSwitchToStaticRequested()
|
||||||
{
|
{
|
||||||
SwitchToStaticRequested?.Invoke(this, EventArgs.Empty);
|
SwitchToStaticRequested?.Invoke(this, EventArgs.Empty);
|
||||||
|
|||||||
@ -11,29 +11,33 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared.Input
|
namespace Artemis.UI.Shared.Input
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a view model that allows inputting a static value used by boolean operations on a certain data model
|
||||||
|
/// property
|
||||||
|
/// </summary>
|
||||||
public class DataModelStaticViewModel : PropertyChangedBase, IDisposable
|
public class DataModelStaticViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
private readonly Window _rootView;
|
private readonly Window? _rootView;
|
||||||
private SolidColorBrush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
|
private SolidColorBrush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
|
||||||
private bool _displaySwitchButton;
|
private bool _displaySwitchButton;
|
||||||
private DataModelDisplayViewModel _displayViewModel;
|
private DataModelDisplayViewModel? _displayViewModel;
|
||||||
private DataModelInputViewModel _inputViewModel;
|
private DataModelInputViewModel? _inputViewModel;
|
||||||
private bool _isEnabled;
|
private bool _isEnabled;
|
||||||
private string _placeholder = "Enter a value";
|
private string _placeholder = "Enter a value";
|
||||||
private DataModelPropertyAttribute _targetDescription;
|
private DataModelPropertyAttribute _targetDescription;
|
||||||
private Type _targetType;
|
private Type _targetType;
|
||||||
private object _value;
|
private object? _value;
|
||||||
|
|
||||||
public DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription, IDataModelUIService dataModelUIService)
|
internal DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription, IDataModelUIService dataModelUIService)
|
||||||
{
|
{
|
||||||
_dataModelUIService = dataModelUIService;
|
_dataModelUIService = dataModelUIService;
|
||||||
_rootView = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
|
_rootView = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
|
||||||
|
|
||||||
TargetType = targetType;
|
_targetType = targetType;
|
||||||
TargetDescription = targetDescription;
|
_targetDescription = targetDescription;
|
||||||
IsEnabled = TargetType != null;
|
_isEnabled = TargetType != null;
|
||||||
DisplayViewModel = _dataModelUIService.GetDataModelDisplayViewModel(TargetType ?? typeof(object), TargetDescription, true);
|
_displayViewModel = _dataModelUIService.GetDataModelDisplayViewModel(TargetType ?? typeof(object), TargetDescription, true);
|
||||||
|
|
||||||
if (_rootView != null)
|
if (_rootView != null)
|
||||||
{
|
{
|
||||||
@ -63,7 +67,7 @@ namespace Artemis.UI.Shared.Input
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the view model used to display the value
|
/// Gets the view model used to display the value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelDisplayViewModel DisplayViewModel
|
public DataModelDisplayViewModel? DisplayViewModel
|
||||||
{
|
{
|
||||||
get => _displayViewModel;
|
get => _displayViewModel;
|
||||||
private set => SetAndNotify(ref _displayViewModel, value);
|
private set => SetAndNotify(ref _displayViewModel, value);
|
||||||
@ -72,7 +76,7 @@ namespace Artemis.UI.Shared.Input
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the view model used to edit the value
|
/// Gets the view model used to edit the value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelInputViewModel InputViewModel
|
public DataModelInputViewModel? InputViewModel
|
||||||
{
|
{
|
||||||
get => _inputViewModel;
|
get => _inputViewModel;
|
||||||
private set => SetAndNotify(ref _inputViewModel, value);
|
private set => SetAndNotify(ref _inputViewModel, value);
|
||||||
@ -99,7 +103,7 @@ namespace Artemis.UI.Shared.Input
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the value of the target
|
/// Gets or sets the value of the target
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Value
|
public object? Value
|
||||||
{
|
{
|
||||||
get => _value;
|
get => _value;
|
||||||
set
|
set
|
||||||
@ -173,7 +177,7 @@ namespace Artemis.UI.Shared.Input
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Requests switching the input type to dynamic
|
/// Requests switching the input type to dynamic using a <see cref="DataModelDynamicViewModel"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SwitchToDynamic()
|
public void SwitchToDynamic()
|
||||||
{
|
{
|
||||||
@ -183,7 +187,7 @@ namespace Artemis.UI.Shared.Input
|
|||||||
OnSwitchToDynamicRequested();
|
OnSwitchToDynamicRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyFreeInput(object value, bool submitted)
|
private void ApplyFreeInput(object? value, bool submitted)
|
||||||
{
|
{
|
||||||
if (submitted)
|
if (submitted)
|
||||||
OnValueUpdated(new DataModelInputStaticEventArgs(value));
|
OnValueUpdated(new DataModelInputStaticEventArgs(value));
|
||||||
@ -204,11 +208,13 @@ namespace Artemis.UI.Shared.Input
|
|||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
|
{
|
||||||
if (_rootView != null)
|
if (_rootView != null)
|
||||||
{
|
{
|
||||||
_rootView.MouseUp -= RootViewOnMouseUp;
|
_rootView.MouseUp -= RootViewOnMouseUp;
|
||||||
_rootView.KeyUp -= RootViewOnKeyUp;
|
_rootView.KeyUp -= RootViewOnKeyUp;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@ -6,21 +6,28 @@ using Artemis.UI.Shared.Services;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a view model that visualizes an event data model property
|
||||||
|
/// </summary>
|
||||||
public class DataModelEventViewModel : DataModelVisualizationViewModel
|
public class DataModelEventViewModel : DataModelVisualizationViewModel
|
||||||
{
|
{
|
||||||
private Type _displayValueType;
|
private Type? _displayValueType;
|
||||||
|
|
||||||
internal DataModelEventViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath) : base(dataModel, parent, dataModelPath)
|
internal DataModelEventViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath) : base(dataModel, parent, dataModelPath)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type DisplayValueType
|
/// <summary>
|
||||||
|
/// Gets the type of event arguments this event triggers and that must be displayed as children
|
||||||
|
/// </summary>
|
||||||
|
public Type? DisplayValueType
|
||||||
{
|
{
|
||||||
get => _displayValueType;
|
get => _displayValueType;
|
||||||
set => SetAndNotify(ref _displayValueType, value);
|
set => SetAndNotify(ref _displayValueType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
/// <inheritdoc />
|
||||||
|
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? configuration)
|
||||||
{
|
{
|
||||||
DisplayValueType = DataModelPath?.GetPropertyType();
|
DisplayValueType = DataModelPath?.GetPropertyType();
|
||||||
|
|
||||||
@ -40,13 +47,16 @@ namespace Artemis.UI.Shared
|
|||||||
dataModelVisualizationViewModel.Update(dataModelUIService, configuration);
|
dataModelVisualizationViewModel.Update(dataModelUIService, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object GetCurrentValue()
|
/// <summary>
|
||||||
|
/// Always returns <see langword="null"/> for data model events
|
||||||
|
/// </summary>
|
||||||
|
public override object? GetCurrentValue()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string? ToString()
|
||||||
{
|
{
|
||||||
return DisplayPath ?? Path;
|
return DisplayPath ?? Path;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,43 +5,63 @@ using Artemis.UI.Shared.Services;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared
|
namespace Artemis.UI.Shared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a view model that wraps a regular <see cref="DataModelPropertiesViewModel" /> but contained in
|
||||||
|
/// a <see cref="DataModelListViewModel" />
|
||||||
|
/// </summary>
|
||||||
public class DataModelListPropertiesViewModel : DataModelPropertiesViewModel
|
public class DataModelListPropertiesViewModel : DataModelPropertiesViewModel
|
||||||
{
|
{
|
||||||
private object _displayValue;
|
private readonly ListPredicateWrapperDataModel _listPredicateWrapper;
|
||||||
|
private object? _displayValue;
|
||||||
private int _index;
|
private int _index;
|
||||||
private Type _listType;
|
private Type? _listType;
|
||||||
|
|
||||||
public DataModelListPropertiesViewModel(Type listType) : base(null, null, null)
|
internal DataModelListPropertiesViewModel(Type listType) : base(null, null, null)
|
||||||
{
|
{
|
||||||
DataModel = ListPredicateWrapperDataModel.Create(listType);
|
_listPredicateWrapper = ListPredicateWrapperDataModel.Create(listType);
|
||||||
|
DataModel = _listPredicateWrapper;
|
||||||
ListType = listType;
|
ListType = listType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the index of the element within the list
|
||||||
|
/// </summary>
|
||||||
public int Index
|
public int Index
|
||||||
{
|
{
|
||||||
get => _index;
|
get => _index;
|
||||||
set => SetAndNotify(ref _index, value);
|
set => SetAndNotify(ref _index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type ListType
|
/// <summary>
|
||||||
|
/// Gets the type of elements contained in the list
|
||||||
|
/// </summary>
|
||||||
|
public Type? ListType
|
||||||
{
|
{
|
||||||
get => _listType;
|
get => _listType;
|
||||||
set => SetAndNotify(ref _listType, value);
|
set => SetAndNotify(ref _listType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public new object DisplayValue
|
/// <summary>
|
||||||
|
/// Gets the value of the property that is being visualized
|
||||||
|
/// </summary>
|
||||||
|
public new object? DisplayValue
|
||||||
{
|
{
|
||||||
get => _displayValue;
|
get => _displayValue;
|
||||||
set => SetAndNotify(ref _displayValue, value);
|
set => SetAndNotify(ref _displayValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModelVisualizationViewModel DisplayViewModel => Children.FirstOrDefault();
|
/// <summary>
|
||||||
|
/// Gets the view model that handles displaying the property
|
||||||
|
/// </summary>
|
||||||
|
public DataModelVisualizationViewModel? DisplayViewModel => Children.FirstOrDefault();
|
||||||
|
|
||||||
public override string DisplayPath => null;
|
/// <inheritdoc />
|
||||||
|
public override string? DisplayPath => null;
|
||||||
|
|
||||||
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
/// <inheritdoc />
|
||||||
|
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? configuration)
|
||||||
{
|
{
|
||||||
((ListPredicateWrapperDataModel) DataModel).UntypedValue = DisplayValue;
|
_listPredicateWrapper.UntypedValue = DisplayValue;
|
||||||
|
|
||||||
PopulateProperties(dataModelUIService, configuration);
|
PopulateProperties(dataModelUIService, configuration);
|
||||||
if (DisplayViewModel == null)
|
if (DisplayViewModel == null)
|
||||||
@ -52,7 +72,8 @@ namespace Artemis.UI.Shared
|
|||||||
DisplayViewModel.Update(dataModelUIService, null);
|
DisplayViewModel.Update(dataModelUIService, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object GetCurrentValue()
|
/// <inheritdoc />
|
||||||
|
public override object? GetCurrentValue()
|
||||||
{
|
{
|
||||||
return DisplayValue;
|
return DisplayValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,19 +10,22 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataModelListPropertyViewModel : DataModelPropertyViewModel
|
public class DataModelListPropertyViewModel : DataModelPropertyViewModel
|
||||||
{
|
{
|
||||||
|
private readonly ListPredicateWrapperDataModel _listPredicateWrapper;
|
||||||
private int _index;
|
private int _index;
|
||||||
private Type _listType;
|
private Type? _listType;
|
||||||
|
|
||||||
internal DataModelListPropertyViewModel(Type listType, DataModelDisplayViewModel displayViewModel) : base(null, null, null)
|
internal DataModelListPropertyViewModel(Type listType, DataModelDisplayViewModel displayViewModel) : base(null, null, null)
|
||||||
{
|
{
|
||||||
DataModel = ListPredicateWrapperDataModel.Create(listType);
|
_listPredicateWrapper = ListPredicateWrapperDataModel.Create(listType);
|
||||||
|
DataModel = _listPredicateWrapper;
|
||||||
ListType = listType;
|
ListType = listType;
|
||||||
DisplayViewModel = displayViewModel;
|
DisplayViewModel = displayViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal DataModelListPropertyViewModel(Type listType) : base(null, null, null)
|
internal DataModelListPropertyViewModel(Type listType) : base(null, null, null)
|
||||||
{
|
{
|
||||||
DataModel = ListPredicateWrapperDataModel.Create(listType);
|
_listPredicateWrapper = ListPredicateWrapperDataModel.Create(listType);
|
||||||
|
DataModel = _listPredicateWrapper;
|
||||||
ListType = listType;
|
ListType = listType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,26 +41,26 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type of elements contained in the list
|
/// Gets the type of elements contained in the list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Type ListType
|
public Type? ListType
|
||||||
{
|
{
|
||||||
get => _listType;
|
get => _listType;
|
||||||
private set => SetAndNotify(ref _listType, value);
|
private set => SetAndNotify(ref _listType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object GetCurrentValue()
|
public override object? GetCurrentValue()
|
||||||
{
|
{
|
||||||
return DisplayValue;
|
return DisplayValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? configuration)
|
||||||
{
|
{
|
||||||
// Display value gets updated by parent, don't do anything if it is null
|
// Display value gets updated by parent, don't do anything if it is null
|
||||||
if (DisplayValue == null)
|
if (DisplayValue == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
((ListPredicateWrapperDataModel) DataModel).UntypedValue = DisplayValue;
|
_listPredicateWrapper.UntypedValue = DisplayValue;
|
||||||
|
|
||||||
if (DisplayViewModel == null)
|
if (DisplayViewModel == null)
|
||||||
DisplayViewModel = dataModelUIService.GetDataModelDisplayViewModel(DisplayValue.GetType(), PropertyDescription, true);
|
DisplayViewModel = dataModelUIService.GetDataModelDisplayViewModel(DisplayValue.GetType(), PropertyDescription, true);
|
||||||
|
|||||||
@ -13,21 +13,22 @@ namespace Artemis.UI.Shared
|
|||||||
public class DataModelListViewModel : DataModelVisualizationViewModel
|
public class DataModelListViewModel : DataModelVisualizationViewModel
|
||||||
{
|
{
|
||||||
private string _countDisplay;
|
private string _countDisplay;
|
||||||
private Type _displayValueType;
|
private Type? _displayValueType;
|
||||||
private IEnumerable _list;
|
private IEnumerable? _list;
|
||||||
private BindableCollection<DataModelVisualizationViewModel> _listChildren;
|
private BindableCollection<DataModelVisualizationViewModel> _listChildren;
|
||||||
private int _listCount;
|
private int _listCount;
|
||||||
|
|
||||||
internal DataModelListViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath)
|
internal DataModelListViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath)
|
||||||
: base(dataModel, parent, dataModelPath)
|
: base(dataModel, parent, dataModelPath)
|
||||||
{
|
{
|
||||||
ListChildren = new BindableCollection<DataModelVisualizationViewModel>();
|
_countDisplay = "0 items";
|
||||||
|
_listChildren = new BindableCollection<DataModelVisualizationViewModel>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the instance of the list that is being visualized
|
/// Gets the instance of the list that is being visualized
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable List
|
public IEnumerable? List
|
||||||
{
|
{
|
||||||
get => _list;
|
get => _list;
|
||||||
private set => SetAndNotify(ref _list, value);
|
private set => SetAndNotify(ref _list, value);
|
||||||
@ -45,7 +46,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type of elements this list contains and that must be displayed as children
|
/// Gets the type of elements this list contains and that must be displayed as children
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Type DisplayValueType
|
public Type? DisplayValueType
|
||||||
{
|
{
|
||||||
get => _displayValueType;
|
get => _displayValueType;
|
||||||
set => SetAndNotify(ref _displayValueType, value);
|
set => SetAndNotify(ref _displayValueType, value);
|
||||||
@ -70,7 +71,7 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? configuration)
|
||||||
{
|
{
|
||||||
if (Parent != null && !Parent.IsVisualizationExpanded)
|
if (Parent != null && !Parent.IsVisualizationExpanded)
|
||||||
return;
|
return;
|
||||||
@ -86,10 +87,12 @@ namespace Artemis.UI.Shared
|
|||||||
if (item == null)
|
if (item == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DataModelVisualizationViewModel child;
|
DataModelVisualizationViewModel? child;
|
||||||
if (ListChildren.Count <= index)
|
if (ListChildren.Count <= index)
|
||||||
{
|
{
|
||||||
child = CreateListChild(dataModelUIService, item.GetType());
|
child = CreateListChild(dataModelUIService, item.GetType());
|
||||||
|
if (child == null)
|
||||||
|
continue;
|
||||||
ListChildren.Add(child);
|
ListChildren.Add(child);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -126,10 +129,10 @@ namespace Artemis.UI.Shared
|
|||||||
return $"[List] {DisplayPath ?? Path} - {ListCount} item(s)";
|
return $"[List] {DisplayPath ?? Path} - {ListCount} item(s)";
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataModelVisualizationViewModel CreateListChild(IDataModelUIService dataModelUIService, Type listType)
|
private DataModelVisualizationViewModel? CreateListChild(IDataModelUIService dataModelUIService, Type listType)
|
||||||
{
|
{
|
||||||
// If a display VM was found, prefer to use that in any case
|
// If a display VM was found, prefer to use that in any case
|
||||||
DataModelDisplayViewModel typeViewModel = dataModelUIService.GetDataModelDisplayViewModel(listType, PropertyDescription);
|
DataModelDisplayViewModel? typeViewModel = dataModelUIService.GetDataModelDisplayViewModel(listType, PropertyDescription);
|
||||||
if (typeViewModel != null)
|
if (typeViewModel != null)
|
||||||
return new DataModelListPropertyViewModel(listType, typeViewModel);
|
return new DataModelListPropertyViewModel(listType, typeViewModel);
|
||||||
// For primitives, create a property view model, it may be null that is fine
|
// For primitives, create a property view model, it may be null that is fine
|
||||||
|
|||||||
@ -10,10 +10,10 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataModelPropertiesViewModel : DataModelVisualizationViewModel
|
public class DataModelPropertiesViewModel : DataModelVisualizationViewModel
|
||||||
{
|
{
|
||||||
private object _displayValue;
|
private object? _displayValue;
|
||||||
private Type _displayValueType;
|
private Type? _displayValueType;
|
||||||
|
|
||||||
internal DataModelPropertiesViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath)
|
internal DataModelPropertiesViewModel(DataModel? dataModel, DataModelVisualizationViewModel? parent, DataModelPath? dataModelPath)
|
||||||
: base(dataModel, parent, dataModelPath)
|
: base(dataModel, parent, dataModelPath)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type of the property that is being visualized
|
/// Gets the type of the property that is being visualized
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Type DisplayValueType
|
public Type? DisplayValueType
|
||||||
{
|
{
|
||||||
get => _displayValueType;
|
get => _displayValueType;
|
||||||
private set => SetAndNotify(ref _displayValueType, value);
|
private set => SetAndNotify(ref _displayValueType, value);
|
||||||
@ -30,19 +30,19 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the value of the property that is being visualized
|
/// Gets the value of the property that is being visualized
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object DisplayValue
|
public object? DisplayValue
|
||||||
{
|
{
|
||||||
get => _displayValue;
|
get => _displayValue;
|
||||||
private set => SetAndNotify(ref _displayValue, value);
|
private set => SetAndNotify(ref _displayValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? configuration)
|
||||||
{
|
{
|
||||||
DisplayValueType = DataModelPath?.GetPropertyType();
|
DisplayValueType = DataModelPath?.GetPropertyType();
|
||||||
|
|
||||||
// Only set a display value if ToString returns useful information and not just the type name
|
// Only set a display value if ToString returns useful information and not just the type name
|
||||||
object currentValue = GetCurrentValue();
|
object? currentValue = GetCurrentValue();
|
||||||
if (currentValue != null && currentValue.ToString() != currentValue.GetType().ToString())
|
if (currentValue != null && currentValue.ToString() != currentValue.GetType().ToString())
|
||||||
DisplayValue = currentValue.ToString();
|
DisplayValue = currentValue.ToString();
|
||||||
else
|
else
|
||||||
@ -60,7 +60,7 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object GetCurrentValue()
|
public override object? GetCurrentValue()
|
||||||
{
|
{
|
||||||
if (Parent == null || Parent.IsRootViewModel || IsRootViewModel)
|
if (Parent == null || Parent.IsRootViewModel || IsRootViewModel)
|
||||||
return DataModel;
|
return DataModel;
|
||||||
@ -68,7 +68,7 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string? ToString()
|
||||||
{
|
{
|
||||||
return DisplayPath ?? Path;
|
return DisplayPath ?? Path;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,11 +11,11 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataModelPropertyViewModel : DataModelVisualizationViewModel
|
public class DataModelPropertyViewModel : DataModelVisualizationViewModel
|
||||||
{
|
{
|
||||||
private object _displayValue;
|
private object? _displayValue;
|
||||||
private Type _displayValueType;
|
private Type? _displayValueType;
|
||||||
private DataModelDisplayViewModel _displayViewModel;
|
private DataModelDisplayViewModel? _displayViewModel;
|
||||||
|
|
||||||
internal DataModelPropertyViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath)
|
internal DataModelPropertyViewModel(DataModel? dataModel, DataModelVisualizationViewModel? parent, DataModelPath? dataModelPath)
|
||||||
: base(dataModel, parent, dataModelPath)
|
: base(dataModel, parent, dataModelPath)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the value of the property that is being visualized
|
/// Gets the value of the property that is being visualized
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object DisplayValue
|
public object? DisplayValue
|
||||||
{
|
{
|
||||||
get => _displayValue;
|
get => _displayValue;
|
||||||
internal set => SetAndNotify(ref _displayValue, value);
|
internal set => SetAndNotify(ref _displayValue, value);
|
||||||
@ -32,7 +32,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type of the property that is being visualized
|
/// Gets the type of the property that is being visualized
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Type DisplayValueType
|
public Type? DisplayValueType
|
||||||
{
|
{
|
||||||
get => _displayValueType;
|
get => _displayValueType;
|
||||||
protected set => SetAndNotify(ref _displayValueType, value);
|
protected set => SetAndNotify(ref _displayValueType, value);
|
||||||
@ -41,26 +41,31 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the view model used to display the display value
|
/// Gets the view model used to display the display value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelDisplayViewModel DisplayViewModel
|
public DataModelDisplayViewModel? DisplayViewModel
|
||||||
{
|
{
|
||||||
get => _displayViewModel;
|
get => _displayViewModel;
|
||||||
internal set => SetAndNotify(ref _displayViewModel, value);
|
internal set => SetAndNotify(ref _displayViewModel, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration)
|
public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? configuration)
|
||||||
{
|
{
|
||||||
if (Parent != null && !Parent.IsVisualizationExpanded && !Parent.IsRootViewModel)
|
if (Parent != null && !Parent.IsVisualizationExpanded && !Parent.IsRootViewModel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (DisplayViewModel == null)
|
if (DisplayViewModel == null)
|
||||||
{
|
{
|
||||||
DisplayViewModel = dataModelUIService.GetDataModelDisplayViewModel(DataModelPath.GetPropertyType(), PropertyDescription, true);
|
Type? propertyType = DataModelPath?.GetPropertyType();
|
||||||
DisplayViewModel.PropertyDescription = DataModelPath.GetPropertyDescription();
|
if (propertyType != null)
|
||||||
|
{
|
||||||
|
DisplayViewModel = dataModelUIService.GetDataModelDisplayViewModel(propertyType, PropertyDescription, true);
|
||||||
|
if (DisplayViewModel != null)
|
||||||
|
DisplayViewModel.PropertyDescription = DataModelPath?.GetPropertyDescription();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayValue = GetCurrentValue();
|
DisplayValue = GetCurrentValue();
|
||||||
DisplayValueType = DisplayValue != null ? DisplayValue.GetType() : DataModelPath.GetPropertyType();
|
DisplayValueType = DisplayValue != null ? DisplayValue.GetType() : DataModelPath?.GetPropertyType();
|
||||||
|
|
||||||
DisplayViewModel?.UpdateValue(DisplayValue);
|
DisplayViewModel?.UpdateValue(DisplayValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,24 +17,24 @@ namespace Artemis.UI.Shared
|
|||||||
{
|
{
|
||||||
private const int MaxDepth = 4;
|
private const int MaxDepth = 4;
|
||||||
private BindableCollection<DataModelVisualizationViewModel> _children;
|
private BindableCollection<DataModelVisualizationViewModel> _children;
|
||||||
private DataModel _dataModel;
|
private DataModel? _dataModel;
|
||||||
private bool _isMatchingFilteredTypes;
|
private bool _isMatchingFilteredTypes;
|
||||||
private bool _isVisualizationExpanded;
|
private bool _isVisualizationExpanded;
|
||||||
private DataModelVisualizationViewModel _parent;
|
private DataModelVisualizationViewModel? _parent;
|
||||||
private DataModelPropertyAttribute _propertyDescription;
|
private DataModelPropertyAttribute? _propertyDescription;
|
||||||
|
|
||||||
internal DataModelVisualizationViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath)
|
internal DataModelVisualizationViewModel(DataModel? dataModel, DataModelVisualizationViewModel? parent, DataModelPath? dataModelPath)
|
||||||
{
|
{
|
||||||
DataModel = dataModel;
|
_dataModel = dataModel;
|
||||||
Parent = parent;
|
_children = new BindableCollection<DataModelVisualizationViewModel>();
|
||||||
|
_parent = parent;
|
||||||
DataModelPath = dataModelPath;
|
DataModelPath = dataModelPath;
|
||||||
Children = new BindableCollection<DataModelVisualizationViewModel>();
|
|
||||||
IsMatchingFilteredTypes = true;
|
IsMatchingFilteredTypes = true;
|
||||||
|
|
||||||
if (parent == null)
|
if (parent == null)
|
||||||
IsRootViewModel = true;
|
IsRootViewModel = true;
|
||||||
else
|
else
|
||||||
PropertyDescription = DataModelPath?.GetPropertyDescription() ?? DataModel.DataModelDescription;
|
PropertyDescription = DataModelPath?.GetPropertyDescription() ?? DataModel?.DataModelDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -45,12 +45,12 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data model path to the property this view model is visualizing
|
/// Gets the data model path to the property this view model is visualizing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelPath DataModelPath { get; }
|
public DataModelPath? DataModelPath { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a string representation of the path backing this model
|
/// Gets a string representation of the path backing this model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Path => DataModelPath?.Path;
|
public string? Path => DataModelPath?.Path;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the property depth of the view model
|
/// Gets the property depth of the view model
|
||||||
@ -60,7 +60,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data model backing this view model
|
/// Gets the data model backing this view model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModel DataModel
|
public DataModel? DataModel
|
||||||
{
|
{
|
||||||
get => _dataModel;
|
get => _dataModel;
|
||||||
protected set => SetAndNotify(ref _dataModel, value);
|
protected set => SetAndNotify(ref _dataModel, value);
|
||||||
@ -69,7 +69,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the property description of the property this view model is visualizing
|
/// Gets the property description of the property this view model is visualizing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelPropertyAttribute PropertyDescription
|
public DataModelPropertyAttribute? PropertyDescription
|
||||||
{
|
{
|
||||||
get => _propertyDescription;
|
get => _propertyDescription;
|
||||||
protected set => SetAndNotify(ref _propertyDescription, value);
|
protected set => SetAndNotify(ref _propertyDescription, value);
|
||||||
@ -78,7 +78,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the parent of this view model
|
/// Gets the parent of this view model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelVisualizationViewModel Parent
|
public DataModelVisualizationViewModel? Parent
|
||||||
{
|
{
|
||||||
get => _parent;
|
get => _parent;
|
||||||
protected set => SetAndNotify(ref _parent, value);
|
protected set => SetAndNotify(ref _parent, value);
|
||||||
@ -119,7 +119,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a user-friendly representation of the <see cref="DataModelPath" />
|
/// Gets a user-friendly representation of the <see cref="DataModelPath" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual string DisplayPath => DataModelPath != null
|
public virtual string? DisplayPath => DataModelPath != null
|
||||||
? string.Join(" › ", DataModelPath.Segments.Select(s => s.GetPropertyDescription()?.Name ?? s.Identifier))
|
? string.Join(" › ", DataModelPath.Segments.Select(s => s.GetPropertyDescription()?.Name ?? s.Identifier))
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
@ -128,18 +128,18 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataModelUIService">The data model UI service used during update</param>
|
/// <param name="dataModelUIService">The data model UI service used during update</param>
|
||||||
/// <param name="configuration">The configuration to apply while updating</param>
|
/// <param name="configuration">The configuration to apply while updating</param>
|
||||||
public abstract void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration);
|
public abstract void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? configuration);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current value of the property being visualized
|
/// Gets the current value of the property being visualized
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The current value of the property being visualized</returns>
|
/// <returns>The current value of the property being visualized</returns>
|
||||||
public virtual object GetCurrentValue()
|
public virtual object? GetCurrentValue()
|
||||||
{
|
{
|
||||||
if (IsRootViewModel)
|
if (IsRootViewModel)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return DataModelPath.GetValue();
|
return DataModelPath?.GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -148,7 +148,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="looseMatch">Whether the type may be a loose match, meaning it can be cast or converted</param>
|
/// <param name="looseMatch">Whether the type may be a loose match, meaning it can be cast or converted</param>
|
||||||
/// <param name="filteredTypes">The types to filter</param>
|
/// <param name="filteredTypes">The types to filter</param>
|
||||||
public void ApplyTypeFilter(bool looseMatch, params Type[] filteredTypes)
|
public void ApplyTypeFilter(bool looseMatch, params Type[]? filteredTypes)
|
||||||
{
|
{
|
||||||
if (filteredTypes != null)
|
if (filteredTypes != null)
|
||||||
{
|
{
|
||||||
@ -176,7 +176,7 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the type couldn't be retrieved either way, assume false
|
// If the type couldn't be retrieved either way, assume false
|
||||||
Type type = DataModelPath?.GetPropertyType();
|
Type? type = DataModelPath?.GetPropertyType();
|
||||||
if (type == null)
|
if (type == null)
|
||||||
{
|
{
|
||||||
IsMatchingFilteredTypes = false;
|
IsMatchingFilteredTypes = false;
|
||||||
@ -197,12 +197,14 @@ namespace Artemis.UI.Shared
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void PopulateProperties(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration dataModelUpdateConfiguration)
|
internal void PopulateProperties(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? dataModelUpdateConfiguration)
|
||||||
{
|
{
|
||||||
if (IsRootViewModel && DataModel == null)
|
if (IsRootViewModel && DataModel == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Type modelType = IsRootViewModel ? DataModel.GetType() : DataModelPath.GetPropertyType();
|
Type? modelType = IsRootViewModel ? DataModel?.GetType() : DataModelPath?.GetPropertyType();
|
||||||
|
if (modelType == null)
|
||||||
|
throw new ArtemisSharedUIException("Failed to populate data model visualization properties, couldn't get a property type");
|
||||||
|
|
||||||
// Add missing static children
|
// Add missing static children
|
||||||
foreach (PropertyInfo propertyInfo in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(t => t.MetadataToken))
|
foreach (PropertyInfo propertyInfo in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(t => t.MetadataToken))
|
||||||
@ -212,27 +214,30 @@ namespace Artemis.UI.Shared
|
|||||||
continue;
|
continue;
|
||||||
if (propertyInfo.GetCustomAttribute<DataModelIgnoreAttribute>() != null)
|
if (propertyInfo.GetCustomAttribute<DataModelIgnoreAttribute>() != null)
|
||||||
continue;
|
continue;
|
||||||
MethodInfo getMethod = propertyInfo.GetGetMethod();
|
MethodInfo? getMethod = propertyInfo.GetGetMethod();
|
||||||
if (getMethod == null || getMethod.GetParameters().Any())
|
if (getMethod == null || getMethod.GetParameters().Any())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DataModelVisualizationViewModel child = CreateChild(dataModelUIService, childPath, GetChildDepth());
|
DataModelVisualizationViewModel? child = CreateChild(dataModelUIService, childPath, GetChildDepth());
|
||||||
if (child != null)
|
if (child != null)
|
||||||
Children.Add(child);
|
Children.Add(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove static children that should be hidden
|
// Remove static children that should be hidden
|
||||||
ReadOnlyCollection<PropertyInfo> hiddenProperties = DataModel.GetHiddenProperties();
|
if (DataModel != null)
|
||||||
foreach (PropertyInfo hiddenProperty in hiddenProperties)
|
|
||||||
{
|
{
|
||||||
string childPath = AppendToPath(hiddenProperty.Name);
|
ReadOnlyCollection<PropertyInfo> hiddenProperties = DataModel.GetHiddenProperties();
|
||||||
DataModelVisualizationViewModel toRemove = Children.FirstOrDefault(c => c.Path != null && c.Path == childPath);
|
foreach (PropertyInfo hiddenProperty in hiddenProperties)
|
||||||
if (toRemove != null)
|
{
|
||||||
Children.Remove(toRemove);
|
string childPath = AppendToPath(hiddenProperty.Name);
|
||||||
|
DataModelVisualizationViewModel? toRemove = Children.FirstOrDefault(c => c.Path != null && c.Path == childPath);
|
||||||
|
if (toRemove != null)
|
||||||
|
Children.Remove(toRemove);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add missing dynamic children
|
// Add missing dynamic children
|
||||||
object value = Parent == null || Parent.IsRootViewModel ? DataModel : DataModelPath.GetValue();
|
object? value = Parent == null || Parent.IsRootViewModel ? DataModel : DataModelPath?.GetValue();
|
||||||
if (value is DataModel dataModel)
|
if (value is DataModel dataModel)
|
||||||
foreach (KeyValuePair<string, DataModel> kvp in dataModel.DynamicDataModels)
|
foreach (KeyValuePair<string, DataModel> kvp in dataModel.DynamicDataModels)
|
||||||
{
|
{
|
||||||
@ -240,19 +245,21 @@ namespace Artemis.UI.Shared
|
|||||||
if (Children.Any(c => c.Path != null && c.Path.Equals(childPath)))
|
if (Children.Any(c => c.Path != null && c.Path.Equals(childPath)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DataModelVisualizationViewModel child = CreateChild(dataModelUIService, childPath, GetChildDepth());
|
DataModelVisualizationViewModel? child = CreateChild(dataModelUIService, childPath, GetChildDepth());
|
||||||
if (child != null)
|
if (child != null)
|
||||||
Children.Add(child);
|
Children.Add(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove dynamic children that have been removed from the data model
|
// Remove dynamic children that have been removed from the data model
|
||||||
List<DataModelVisualizationViewModel> toRemoveDynamic = Children.Where(c => !c.DataModelPath.IsValid).ToList();
|
List<DataModelVisualizationViewModel> toRemoveDynamic = Children.Where(c => c.DataModelPath != null && !c.DataModelPath.IsValid).ToList();
|
||||||
if (toRemoveDynamic.Any())
|
if (toRemoveDynamic.Any())
|
||||||
Children.RemoveRange(toRemoveDynamic);
|
Children.RemoveRange(toRemoveDynamic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataModelVisualizationViewModel CreateChild(IDataModelUIService dataModelUIService, string path, int depth)
|
private DataModelVisualizationViewModel? CreateChild(IDataModelUIService dataModelUIService, string path, int depth)
|
||||||
{
|
{
|
||||||
|
if (DataModel == null)
|
||||||
|
throw new ArtemisSharedUIException("Cannot create a data model visualization child VM for a parent without a data model");
|
||||||
if (depth > MaxDepth)
|
if (depth > MaxDepth)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -260,8 +267,8 @@ namespace Artemis.UI.Shared
|
|||||||
if (!dataModelPath.IsValid)
|
if (!dataModelPath.IsValid)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
PropertyInfo propertyInfo = dataModelPath.GetPropertyInfo();
|
PropertyInfo? propertyInfo = dataModelPath.GetPropertyInfo();
|
||||||
Type propertyType = dataModelPath.GetPropertyType();
|
Type? propertyType = dataModelPath.GetPropertyType();
|
||||||
|
|
||||||
// Skip properties decorated with DataModelIgnore
|
// Skip properties decorated with DataModelIgnore
|
||||||
if (propertyInfo != null && Attribute.IsDefined(propertyInfo, typeof(DataModelIgnoreAttribute)))
|
if (propertyInfo != null && Attribute.IsDefined(propertyInfo, typeof(DataModelIgnoreAttribute)))
|
||||||
@ -270,8 +277,11 @@ namespace Artemis.UI.Shared
|
|||||||
if (DataModel.GetHiddenProperties().Any(p => p.Equals(propertyInfo)))
|
if (DataModel.GetHiddenProperties().Any(p => p.Equals(propertyInfo)))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if (propertyType == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
// If a display VM was found, prefer to use that in any case
|
// If a display VM was found, prefer to use that in any case
|
||||||
DataModelDisplayViewModel typeViewModel = dataModelUIService.GetDataModelDisplayViewModel(propertyType, PropertyDescription);
|
DataModelDisplayViewModel? typeViewModel = dataModelUIService.GetDataModelDisplayViewModel(propertyType, PropertyDescription);
|
||||||
if (typeViewModel != null)
|
if (typeViewModel != null)
|
||||||
return new DataModelPropertyViewModel(DataModel, this, dataModelPath) {DisplayViewModel = typeViewModel, Depth = depth};
|
return new DataModelPropertyViewModel(DataModel, this, dataModelPath) {DisplayViewModel = typeViewModel, Depth = depth};
|
||||||
// For primitives, create a property view model, it may be null that is fine
|
// For primitives, create a property view model, it may be null that is fine
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataModelInputDynamicEventArgs : EventArgs
|
public class DataModelInputDynamicEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
internal DataModelInputDynamicEventArgs(DataModelPath dataModelPath)
|
internal DataModelInputDynamicEventArgs(DataModelPath? dataModelPath)
|
||||||
{
|
{
|
||||||
DataModelPath = dataModelPath;
|
DataModelPath = dataModelPath;
|
||||||
}
|
}
|
||||||
@ -17,6 +17,6 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data model path that was selected
|
/// Gets the data model path that was selected
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelPath DataModelPath { get; }
|
public DataModelPath? DataModelPath { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,7 +8,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataModelInputStaticEventArgs : EventArgs
|
public class DataModelInputStaticEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
internal DataModelInputStaticEventArgs(object value)
|
internal DataModelInputStaticEventArgs(object? value)
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = value;
|
||||||
}
|
}
|
||||||
@ -16,6 +16,6 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value that was submitted
|
/// The value that was submitted
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Value { get; }
|
public object? Value { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,12 +8,12 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ProfileEventArgs : EventArgs
|
public class ProfileEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
internal ProfileEventArgs(Profile profile)
|
internal ProfileEventArgs(Profile? profile)
|
||||||
{
|
{
|
||||||
Profile = profile;
|
Profile = profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ProfileEventArgs(Profile profile, Profile previousProfile)
|
internal ProfileEventArgs(Profile? profile, Profile? previousProfile)
|
||||||
{
|
{
|
||||||
Profile = profile;
|
Profile = profile;
|
||||||
PreviousProfile = previousProfile;
|
PreviousProfile = previousProfile;
|
||||||
@ -22,7 +22,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the profile the event was raised for
|
/// Gets the profile the event was raised for
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Profile Profile { get; }
|
public Profile? Profile { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If applicable, the previous active profile before the event was raised
|
/// If applicable, the previous active profile before the event was raised
|
||||||
|
|||||||
@ -8,12 +8,12 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RenderProfileElementEventArgs : EventArgs
|
public class RenderProfileElementEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
internal RenderProfileElementEventArgs(RenderProfileElement renderProfileElement)
|
internal RenderProfileElementEventArgs(RenderProfileElement? renderProfileElement)
|
||||||
{
|
{
|
||||||
RenderProfileElement = renderProfileElement;
|
RenderProfileElement = renderProfileElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal RenderProfileElementEventArgs(RenderProfileElement renderProfileElement, RenderProfileElement previousRenderProfileElement)
|
internal RenderProfileElementEventArgs(RenderProfileElement? renderProfileElement, RenderProfileElement? previousRenderProfileElement)
|
||||||
{
|
{
|
||||||
RenderProfileElement = renderProfileElement;
|
RenderProfileElement = renderProfileElement;
|
||||||
PreviousRenderProfileElement = previousRenderProfileElement;
|
PreviousRenderProfileElement = previousRenderProfileElement;
|
||||||
@ -22,7 +22,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the profile element the event was raised for
|
/// Gets the profile element the event was raised for
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RenderProfileElement RenderProfileElement { get; }
|
public RenderProfileElement? RenderProfileElement { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If applicable, the previous active profile element before the event was raised
|
/// If applicable, the previous active profile element before the event was raised
|
||||||
|
|||||||
@ -15,11 +15,6 @@ namespace Artemis.UI.Shared.LayerBrushes
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class LayerBrushConfigurationDialog : ILayerBrushConfigurationDialog
|
public abstract class LayerBrushConfigurationDialog : ILayerBrushConfigurationDialog
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The layer brush this dialog belongs to
|
|
||||||
/// </summary>
|
|
||||||
internal BaseLayerBrush LayerBrush { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of view model the tab contains
|
/// The type of view model the tab contains
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -15,10 +15,11 @@ namespace Artemis.UI.Shared.LayerEffects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class LayerEffectConfigurationDialog : ILayerEffectConfigurationDialog
|
public abstract class LayerEffectConfigurationDialog : ILayerEffectConfigurationDialog
|
||||||
{
|
{
|
||||||
|
// TODO: See if this is still in use
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layer effect this dialog belongs to
|
/// The layer effect this dialog belongs to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal BaseLayerEffect LayerEffect { get; set; }
|
public BaseLayerEffect? LayerEffect { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of view model the tab contains
|
/// The type of view model the tab contains
|
||||||
|
|||||||
@ -15,11 +15,6 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PluginConfigurationDialog : IPluginConfigurationDialog
|
public abstract class PluginConfigurationDialog : IPluginConfigurationDialog
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The layer brush this dialog belongs to
|
|
||||||
/// </summary>
|
|
||||||
internal PluginFeature PluginFeature { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of view model the tab contains
|
/// The type of view model the tab contains
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -22,9 +22,10 @@ SOFTWARE. */
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
// ReSharper disable InheritdocConsiderUsage
|
#pragma warning disable 8618
|
||||||
|
|
||||||
#pragma warning disable 1591
|
#pragma warning disable 1591
|
||||||
|
|
||||||
|
// ReSharper disable InheritdocConsiderUsage
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable MemberCanBePrivate.Global
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
@ -12,7 +13,7 @@ namespace Artemis.UI.Shared
|
|||||||
public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
|
public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
|
||||||
{
|
{
|
||||||
private bool _inputDragging;
|
private bool _inputDragging;
|
||||||
private T _inputValue;
|
[AllowNull] private T _inputValue = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the <see cref="PropertyInputViewModel" /> class
|
/// Creates a new instance of the <see cref="PropertyInputViewModel" /> class
|
||||||
@ -73,6 +74,7 @@ namespace Artemis.UI.Shared
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the input value
|
/// Gets or sets the input value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[AllowNull]
|
||||||
public T InputValue
|
public T InputValue
|
||||||
{
|
{
|
||||||
get => _inputValue;
|
get => _inputValue;
|
||||||
|
|||||||
@ -19,13 +19,13 @@ namespace Artemis.UI.Shared.Screens.Dialogs
|
|||||||
|
|
||||||
public void Confirm()
|
public void Confirm()
|
||||||
{
|
{
|
||||||
if (!Session.IsEnded)
|
if (Session != null && !Session.IsEnded)
|
||||||
Session.Close(true);
|
Session.Close(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel()
|
public void Cancel()
|
||||||
{
|
{
|
||||||
if (!Session.IsEnded)
|
if (Session != null && !Session.IsEnded)
|
||||||
Session.Close(false);
|
Session.Close(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,12 +9,12 @@ namespace Artemis.UI.Shared.Screens.Exceptions
|
|||||||
{
|
{
|
||||||
private List<DialogException> _exceptions;
|
private List<DialogException> _exceptions;
|
||||||
|
|
||||||
public ExceptionViewModel(string message, Exception exception)
|
public ExceptionViewModel(string message, Exception? exception)
|
||||||
{
|
{
|
||||||
Header = message;
|
Header = message;
|
||||||
Exceptions = new List<DialogException>();
|
_exceptions = new List<DialogException>();
|
||||||
|
|
||||||
Exception currentException = exception;
|
Exception? currentException = exception;
|
||||||
while (currentException != null)
|
while (currentException != null)
|
||||||
{
|
{
|
||||||
Exceptions.Add(new DialogException(currentException));
|
Exceptions.Add(new DialogException(currentException));
|
||||||
|
|||||||
@ -59,7 +59,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
set => SetAndNotify(ref _willRemoveColorStop, value);
|
set => SetAndNotify(ref _willRemoveColorStop, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ColorStopOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
private void ColorStopOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
_gradientEditorViewModel.ColorGradient.OnColorValuesUpdated();
|
_gradientEditorViewModel.ColorGradient.OnColorValuesUpdated();
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
if (!((IInputElement) sender).IsMouseCaptured)
|
if (!((IInputElement) sender).IsMouseCaptured)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Canvas parent = VisualTreeUtilities.FindParent<Canvas>((DependencyObject) sender, null);
|
Canvas? parent = VisualTreeUtilities.FindParent<Canvas>((DependencyObject) sender, null);
|
||||||
Point position = e.GetPosition(parent);
|
Point position = e.GetPosition(parent);
|
||||||
if (position.Y > 50)
|
if (position.Y > 50)
|
||||||
{
|
{
|
||||||
@ -103,8 +103,8 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
double minValue = 0.0;
|
double minValue = 0.0;
|
||||||
double maxValue = _gradientEditorViewModel.PreviewWidth;
|
double maxValue = _gradientEditorViewModel.PreviewWidth;
|
||||||
List<ColorGradientStop> stops = _gradientEditorViewModel.ColorGradient.Stops.OrderBy(s => s.Position).ToList();
|
List<ColorGradientStop> stops = _gradientEditorViewModel.ColorGradient.Stops.OrderBy(s => s.Position).ToList();
|
||||||
ColorGradientStop previous = stops.IndexOf(ColorStop) >= 1 ? stops[stops.IndexOf(ColorStop) - 1] : null;
|
ColorGradientStop? previous = stops.IndexOf(ColorStop) >= 1 ? stops[stops.IndexOf(ColorStop) - 1] : null;
|
||||||
ColorGradientStop next = stops.IndexOf(ColorStop) + 1 < stops.Count ? stops[stops.IndexOf(ColorStop) + 1] : null;
|
ColorGradientStop? next = stops.IndexOf(ColorStop) + 1 < stops.Count ? stops[stops.IndexOf(ColorStop) + 1] : null;
|
||||||
if (previous != null)
|
if (previous != null)
|
||||||
minValue = previous.Position * _gradientEditorViewModel.PreviewWidth;
|
minValue = previous.Position * _gradientEditorViewModel.PreviewWidth;
|
||||||
if (next != null)
|
if (next != null)
|
||||||
|
|||||||
@ -14,7 +14,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
{
|
{
|
||||||
private readonly List<ColorGradientStop> _originalStops;
|
private readonly List<ColorGradientStop> _originalStops;
|
||||||
private double _previewWidth;
|
private double _previewWidth;
|
||||||
private ColorStopViewModel _selectedColorStopViewModel;
|
private ColorStopViewModel? _selectedColorStopViewModel;
|
||||||
|
|
||||||
public GradientEditorViewModel(ColorGradient colorGradient)
|
public GradientEditorViewModel(ColorGradient colorGradient)
|
||||||
{
|
{
|
||||||
@ -28,7 +28,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
|
|
||||||
public BindableCollection<ColorStopViewModel> ColorStopViewModels { get; set; }
|
public BindableCollection<ColorStopViewModel> ColorStopViewModels { get; set; }
|
||||||
|
|
||||||
public ColorStopViewModel SelectedColorStopViewModel
|
public ColorStopViewModel? SelectedColorStopViewModel
|
||||||
{
|
{
|
||||||
get => _selectedColorStopViewModel;
|
get => _selectedColorStopViewModel;
|
||||||
set
|
set
|
||||||
@ -50,7 +50,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
|
|
||||||
public void AddColorStop(object sender, MouseEventArgs e)
|
public void AddColorStop(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
Canvas child = VisualTreeUtilities.FindChild<Canvas>((DependencyObject) sender, null);
|
Canvas? child = VisualTreeUtilities.FindChild<Canvas>((DependencyObject) sender, null);
|
||||||
float position = (float) (e.GetPosition(child).X / PreviewWidth);
|
float position = (float) (e.GetPosition(child).X / PreviewWidth);
|
||||||
ColorGradientStop stop = new ColorGradientStop(ColorGradient.GetColor(position), position);
|
ColorGradientStop stop = new ColorGradientStop(ColorGradient.GetColor(position), position);
|
||||||
ColorGradient.Stops.Add(stop);
|
ColorGradient.Stops.Add(stop);
|
||||||
@ -74,11 +74,11 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
|
|
||||||
public Point GetPositionInPreview(object sender, MouseEventArgs e)
|
public Point GetPositionInPreview(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
Canvas parent = VisualTreeUtilities.FindParent<Canvas>((DependencyObject) sender, null);
|
Canvas? parent = VisualTreeUtilities.FindParent<Canvas>((DependencyObject) sender, null);
|
||||||
return e.GetPosition(parent);
|
return e.GetPosition(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectColorStop(ColorStopViewModel colorStopViewModel)
|
public void SelectColorStop(ColorStopViewModel? colorStopViewModel)
|
||||||
{
|
{
|
||||||
SelectedColorStopViewModel = colorStopViewModel;
|
SelectedColorStopViewModel = colorStopViewModel;
|
||||||
foreach (ColorStopViewModel stopViewModel in ColorStopViewModels)
|
foreach (ColorStopViewModel stopViewModel in ColorStopViewModels)
|
||||||
@ -87,7 +87,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
|
|
||||||
public void Confirm()
|
public void Confirm()
|
||||||
{
|
{
|
||||||
if (!Session.IsEnded)
|
if (Session != null && !Session.IsEnded)
|
||||||
Session.Close(true);
|
Session.Close(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,11 +98,11 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
|
|||||||
ColorGradient.Stops.AddRange(_originalStops);
|
ColorGradient.Stops.AddRange(_originalStops);
|
||||||
ColorGradient.OnColorValuesUpdated();
|
ColorGradient.OnColorValuesUpdated();
|
||||||
|
|
||||||
if (!Session.IsEnded)
|
if (Session != null && !Session.IsEnded)
|
||||||
Session.Close(false);
|
Session.Close(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateColorStopViewModels(object sender, PropertyChangedEventArgs e)
|
private void UpdateColorStopViewModels(object? sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PropertyName != nameof(PreviewWidth)) return;
|
if (e.PropertyName != nameof(PreviewWidth)) return;
|
||||||
foreach (ColorGradientStop colorStop in ColorGradient.Stops.OrderBy(s => s.Position))
|
foreach (ColorGradientStop colorStop in ColorGradient.Stops.OrderBy(s => s.Position))
|
||||||
|
|||||||
@ -56,7 +56,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
_overlayColor = new SKColor(color.R, color.G, color.B, color.A);
|
_overlayColor = new SKColor(color.R, color.G, color.B, color.A);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderColorPickerOverlay(object sender, FrameRenderingEventArgs e)
|
private void RenderColorPickerOverlay(object? sender, FrameRenderingEventArgs e)
|
||||||
{
|
{
|
||||||
if (_mustRenderOverlay)
|
if (_mustRenderOverlay)
|
||||||
_overlayOpacity += 0.2f;
|
_overlayOpacity += 0.2f;
|
||||||
|
|||||||
@ -46,7 +46,9 @@ namespace Artemis.UI.Shared.Services
|
|||||||
|
|
||||||
public void UpdateModules(DataModelPropertiesViewModel mainDataModelVisualization)
|
public void UpdateModules(DataModelPropertiesViewModel mainDataModelVisualization)
|
||||||
{
|
{
|
||||||
List<DataModelVisualizationViewModel> disabledChildren = mainDataModelVisualization.Children.Where(d => !d.DataModel.Feature.IsEnabled).ToList();
|
List<DataModelVisualizationViewModel> disabledChildren = mainDataModelVisualization.Children
|
||||||
|
.Where(d => d.DataModel != null && !d.DataModel.Feature.IsEnabled)
|
||||||
|
.ToList();
|
||||||
foreach (DataModelVisualizationViewModel child in disabledChildren)
|
foreach (DataModelVisualizationViewModel child in disabledChildren)
|
||||||
mainDataModelVisualization.Children.Remove(child);
|
mainDataModelVisualization.Children.Remove(child);
|
||||||
|
|
||||||
@ -63,24 +65,24 @@ namespace Artemis.UI.Shared.Services
|
|||||||
mainDataModelVisualization.Update(this, null);
|
mainDataModelVisualization.Update(this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginFeature pluginFeature, bool includeMainDataModel)
|
public DataModelPropertiesViewModel? GetPluginDataModelVisualization(PluginFeature pluginFeature, bool includeMainDataModel)
|
||||||
{
|
{
|
||||||
if (includeMainDataModel)
|
if (includeMainDataModel)
|
||||||
{
|
{
|
||||||
DataModelPropertiesViewModel mainDataModel = GetMainDataModelVisualization();
|
DataModelPropertiesViewModel mainDataModel = GetMainDataModelVisualization();
|
||||||
|
|
||||||
// If the main data model already includes the plugin data model we're done
|
// If the main data model already includes the plugin data model we're done
|
||||||
if (mainDataModel.Children.Any(c => c.DataModel.Feature == pluginFeature))
|
if (mainDataModel.Children.Any(c => c.DataModel?.Feature == pluginFeature))
|
||||||
return mainDataModel;
|
return mainDataModel;
|
||||||
// Otherwise get just the plugin data model and add it
|
// Otherwise get just the plugin data model and add it
|
||||||
DataModelPropertiesViewModel pluginDataModel = GetPluginDataModelVisualization(pluginFeature, false);
|
DataModelPropertiesViewModel? pluginDataModel = GetPluginDataModelVisualization(pluginFeature, false);
|
||||||
if (pluginDataModel != null)
|
if (pluginDataModel != null)
|
||||||
mainDataModel.Children.Add(pluginDataModel);
|
mainDataModel.Children.Add(pluginDataModel);
|
||||||
|
|
||||||
return mainDataModel;
|
return mainDataModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataModel dataModel = _dataModelService.GetPluginDataModel(pluginFeature);
|
DataModel? dataModel = _dataModelService.GetPluginDataModel(pluginFeature);
|
||||||
if (dataModel == null)
|
if (dataModel == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -93,15 +95,14 @@ namespace Artemis.UI.Shared.Services
|
|||||||
return viewModel;
|
return viewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModelVisualizationRegistration RegisterDataModelInput<T>(Plugin plugin, IReadOnlyCollection<Type> compatibleConversionTypes = null) where T : DataModelInputViewModel
|
public DataModelVisualizationRegistration RegisterDataModelInput<T>(Plugin plugin, IReadOnlyCollection<Type>? compatibleConversionTypes = null) where T : DataModelInputViewModel
|
||||||
{
|
{
|
||||||
if (compatibleConversionTypes == null)
|
compatibleConversionTypes ??= new List<Type>();
|
||||||
compatibleConversionTypes = new List<Type>();
|
|
||||||
Type viewModelType = typeof(T);
|
Type viewModelType = typeof(T);
|
||||||
lock (_registeredDataModelEditors)
|
lock (_registeredDataModelEditors)
|
||||||
{
|
{
|
||||||
Type supportedType = viewModelType.BaseType.GetGenericArguments()[0];
|
Type supportedType = viewModelType.BaseType!.GetGenericArguments()[0];
|
||||||
DataModelVisualizationRegistration existing = _registeredDataModelEditors.FirstOrDefault(r => r.SupportedType == supportedType);
|
DataModelVisualizationRegistration? existing = _registeredDataModelEditors.FirstOrDefault(r => r.SupportedType == supportedType);
|
||||||
if (existing != null)
|
if (existing != null)
|
||||||
{
|
{
|
||||||
if (existing.Plugin != plugin)
|
if (existing.Plugin != plugin)
|
||||||
@ -129,8 +130,8 @@ namespace Artemis.UI.Shared.Services
|
|||||||
Type viewModelType = typeof(T);
|
Type viewModelType = typeof(T);
|
||||||
lock (_registeredDataModelDisplays)
|
lock (_registeredDataModelDisplays)
|
||||||
{
|
{
|
||||||
Type supportedType = viewModelType.BaseType.GetGenericArguments()[0];
|
Type supportedType = viewModelType.BaseType!.GetGenericArguments()[0];
|
||||||
DataModelVisualizationRegistration existing = _registeredDataModelDisplays.FirstOrDefault(r => r.SupportedType == supportedType);
|
DataModelVisualizationRegistration? existing = _registeredDataModelDisplays.FirstOrDefault(r => r.SupportedType == supportedType);
|
||||||
if (existing != null)
|
if (existing != null)
|
||||||
{
|
{
|
||||||
if (existing.Plugin != plugin)
|
if (existing.Plugin != plugin)
|
||||||
@ -174,15 +175,21 @@ namespace Artemis.UI.Shared.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModelDisplayViewModel GetDataModelDisplayViewModel(Type propertyType, DataModelPropertyAttribute description, bool fallBackToDefault)
|
public DataModelDisplayViewModel? GetDataModelDisplayViewModel(Type propertyType, DataModelPropertyAttribute? description, bool fallBackToDefault)
|
||||||
{
|
{
|
||||||
lock (_registeredDataModelDisplays)
|
lock (_registeredDataModelDisplays)
|
||||||
{
|
{
|
||||||
DataModelDisplayViewModel result;
|
DataModelDisplayViewModel? result;
|
||||||
|
|
||||||
DataModelVisualizationRegistration match = _registeredDataModelDisplays.FirstOrDefault(d => d.SupportedType == propertyType);
|
DataModelVisualizationRegistration? match = _registeredDataModelDisplays.FirstOrDefault(d => d.SupportedType == propertyType);
|
||||||
if (match != null)
|
if (match != null)
|
||||||
|
{
|
||||||
|
// If this ever happens something is likely wrong with the plugin unload detection
|
||||||
|
if (match.Plugin.Kernel == null)
|
||||||
|
throw new ArtemisSharedUIException("Cannot GetDataModelDisplayViewModel for a registration by an uninitialized plugin");
|
||||||
|
|
||||||
result = (DataModelDisplayViewModel) match.Plugin.Kernel.Get(match.ViewModelType);
|
result = (DataModelDisplayViewModel) match.Plugin.Kernel.Get(match.ViewModelType);
|
||||||
|
}
|
||||||
else if (!fallBackToDefault)
|
else if (!fallBackToDefault)
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
@ -195,15 +202,15 @@ namespace Artemis.UI.Shared.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModelInputViewModel GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute description, object initialValue, Action<object, bool> updateCallback)
|
public DataModelInputViewModel? GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute? description, object? initialValue, Action<object?, bool> updateCallback)
|
||||||
{
|
{
|
||||||
lock (_registeredDataModelEditors)
|
lock (_registeredDataModelEditors)
|
||||||
{
|
{
|
||||||
// Prefer a VM that natively supports the type
|
// Prefer a VM that natively supports the type
|
||||||
DataModelVisualizationRegistration match = _registeredDataModelEditors.FirstOrDefault(d => d.SupportedType == propertyType);
|
DataModelVisualizationRegistration? match = _registeredDataModelEditors.FirstOrDefault(d => d.SupportedType == propertyType);
|
||||||
// Fall back on a VM that supports the type through conversion
|
// Fall back on a VM that supports the type through conversion
|
||||||
if (match == null)
|
if (match == null)
|
||||||
match = _registeredDataModelEditors.FirstOrDefault(d => d.CompatibleConversionTypes.Contains(propertyType));
|
match = _registeredDataModelEditors.FirstOrDefault(d => d.CompatibleConversionTypes != null && d.CompatibleConversionTypes.Contains(propertyType));
|
||||||
// Lastly try getting an enum VM if the provided type is an enum
|
// Lastly try getting an enum VM if the provided type is an enum
|
||||||
if (match == null && propertyType.IsEnum)
|
if (match == null && propertyType.IsEnum)
|
||||||
match = _registeredDataModelEditors.FirstOrDefault(d => d.SupportedType == typeof(Enum));
|
match = _registeredDataModelEditors.FirstOrDefault(d => d.SupportedType == typeof(Enum));
|
||||||
@ -229,7 +236,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
return _dataModelVmFactory.DataModelStaticViewModel(targetType, targetDescription);
|
return _dataModelVmFactory.DataModelStaticViewModel(targetType, targetDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute description, object initialValue)
|
private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute? description, object? initialValue)
|
||||||
{
|
{
|
||||||
// This assumes the type can be converted, that has been checked when the VM was created
|
// This assumes the type can be converted, that has been checked when the VM was created
|
||||||
if (initialValue != null && initialValue.GetType() != registration.SupportedType)
|
if (initialValue != null && initialValue.GetType() != registration.SupportedType)
|
||||||
@ -240,6 +247,11 @@ namespace Artemis.UI.Shared.Services
|
|||||||
new ConstructorArgument("targetDescription", description),
|
new ConstructorArgument("targetDescription", description),
|
||||||
new ConstructorArgument("initialValue", initialValue)
|
new ConstructorArgument("initialValue", initialValue)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If this ever happens something is likely wrong with the plugin unload detection
|
||||||
|
if (registration.Plugin.Kernel == null)
|
||||||
|
throw new ArtemisSharedUIException("Cannot InstantiateDataModelInputViewModel for a registration by an uninitialized plugin");
|
||||||
|
|
||||||
DataModelInputViewModel viewModel = (DataModelInputViewModel) registration.Plugin.Kernel.Get(registration.ViewModelType, parameters);
|
DataModelInputViewModel viewModel = (DataModelInputViewModel) registration.Plugin.Kernel.Get(registration.ViewModelType, parameters);
|
||||||
viewModel.CompatibleConversionTypes = registration.CompatibleConversionTypes;
|
viewModel.CompatibleConversionTypes = registration.CompatibleConversionTypes;
|
||||||
return viewModel;
|
return viewModel;
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
@ -16,13 +14,12 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Shared.Services
|
namespace Artemis.UI.Shared.Services
|
||||||
{
|
{
|
||||||
// TODO: Become plugin-aware and use plugin kernel if injected into a plugin
|
|
||||||
internal class DialogService : IDialogService
|
internal class DialogService : IDialogService
|
||||||
{
|
{
|
||||||
private readonly IKernel _kernel;
|
private readonly IKernel _kernel;
|
||||||
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
private readonly IViewManager _viewManager;
|
private readonly IViewManager _viewManager;
|
||||||
private readonly IWindowManager _windowManager;
|
private readonly IWindowManager _windowManager;
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
|
||||||
|
|
||||||
public DialogService(IKernel kernel, IViewManager viewManager, IWindowManager windowManager, IPluginManagementService pluginManagementService)
|
public DialogService(IKernel kernel, IViewManager viewManager, IWindowManager windowManager, IPluginManagementService pluginManagementService)
|
||||||
{
|
{
|
||||||
@ -35,12 +32,12 @@ namespace Artemis.UI.Shared.Services
|
|||||||
private async Task<object> ShowDialog<T>(IParameter[] parameters) where T : DialogViewModelBase
|
private async Task<object> ShowDialog<T>(IParameter[] parameters) where T : DialogViewModelBase
|
||||||
{
|
{
|
||||||
if (parameters == null) throw new ArgumentNullException(nameof(parameters));
|
if (parameters == null) throw new ArgumentNullException(nameof(parameters));
|
||||||
return await ShowDialog("RootDialog", _kernel.Get<T>(parameters));
|
return await ShowDialog("RootDialog", GetBestKernel().Get<T>(parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<object> ShowDialog(string identifier, DialogViewModelBase viewModel)
|
private async Task<object> ShowDialog(string? identifier, DialogViewModelBase viewModel)
|
||||||
{
|
{
|
||||||
Task<object> result = null;
|
Task<object>? result = null;
|
||||||
await Execute.OnUIThreadAsync(() =>
|
await Execute.OnUIThreadAsync(() =>
|
||||||
{
|
{
|
||||||
UIElement view = _viewManager.CreateViewForModel(viewModel);
|
UIElement view = _viewManager.CreateViewForModel(viewModel);
|
||||||
@ -52,12 +49,22 @@ namespace Artemis.UI.Shared.Services
|
|||||||
result = DialogHost.Show(view, identifier, viewModel.OnDialogOpened, viewModel.OnDialogClosed);
|
result = DialogHost.Show(view, identifier, viewModel.OnDialogOpened, viewModel.OnDialogClosed);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
throw new ArtemisSharedUIException("Failed to show dialog host");
|
||||||
return await result;
|
return await result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<object> ShowDialogAt<T>(string identifier, IParameter[] parameters) where T : DialogViewModelBase
|
||||||
|
{
|
||||||
|
if (parameters == null)
|
||||||
|
throw new ArgumentNullException(nameof(parameters));
|
||||||
|
return await ShowDialog(identifier, GetBestKernel().Get<T>(parameters));
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<bool> ShowConfirmDialog(string header, string text, string confirmText = "Confirm", string cancelText = "Cancel")
|
public async Task<bool> ShowConfirmDialog(string header, string text, string confirmText = "Confirm", string cancelText = "Cancel")
|
||||||
{
|
{
|
||||||
IParameter[] arguments = {
|
IParameter[] arguments =
|
||||||
|
{
|
||||||
new ConstructorArgument("header", header),
|
new ConstructorArgument("header", header),
|
||||||
new ConstructorArgument("text", text),
|
new ConstructorArgument("text", text),
|
||||||
new ConstructorArgument("confirmText", confirmText.ToUpper()),
|
new ConstructorArgument("confirmText", confirmText.ToUpper()),
|
||||||
@ -69,7 +76,9 @@ namespace Artemis.UI.Shared.Services
|
|||||||
|
|
||||||
public async Task<bool> ShowConfirmDialogAt(string identifier, string header, string text, string confirmText = "Confirm", string cancelText = "Cancel")
|
public async Task<bool> ShowConfirmDialogAt(string identifier, string header, string text, string confirmText = "Confirm", string cancelText = "Cancel")
|
||||||
{
|
{
|
||||||
IParameter[] arguments = {
|
if (identifier == null) throw new ArgumentNullException(nameof(identifier));
|
||||||
|
IParameter[] arguments =
|
||||||
|
{
|
||||||
new ConstructorArgument("header", header),
|
new ConstructorArgument("header", header),
|
||||||
new ConstructorArgument("text", text),
|
new ConstructorArgument("text", text),
|
||||||
new ConstructorArgument("confirmText", confirmText.ToUpper()),
|
new ConstructorArgument("confirmText", confirmText.ToUpper()),
|
||||||
@ -81,7 +90,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
|
|
||||||
public async Task<object> ShowDialog<T>() where T : DialogViewModelBase
|
public async Task<object> ShowDialog<T>() where T : DialogViewModelBase
|
||||||
{
|
{
|
||||||
return await ShowDialog("RootDialog", _kernel.Get<T>());
|
return await ShowDialog("RootDialog", GetBestKernel().Get<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<object> ShowDialog<T>(Dictionary<string, object> parameters) where T : DialogViewModelBase
|
public Task<object> ShowDialog<T>(Dictionary<string, object> parameters) where T : DialogViewModelBase
|
||||||
@ -95,32 +104,28 @@ namespace Artemis.UI.Shared.Services
|
|||||||
|
|
||||||
public async Task<object> ShowDialogAt<T>(string identifier) where T : DialogViewModelBase
|
public async Task<object> ShowDialogAt<T>(string identifier) where T : DialogViewModelBase
|
||||||
{
|
{
|
||||||
return await ShowDialog(identifier, _kernel.Get<T>());
|
if (identifier == null) throw new ArgumentNullException(nameof(identifier));
|
||||||
|
return await ShowDialog(identifier, GetBestKernel().Get<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<object> ShowDialogAt<T>(string identifier, Dictionary<string, object> parameters) where T : DialogViewModelBase
|
public async Task<object> ShowDialogAt<T>(string identifier, Dictionary<string, object> parameters) where T : DialogViewModelBase
|
||||||
{
|
{
|
||||||
if (parameters == null)
|
if (identifier == null) throw new ArgumentNullException(nameof(identifier));
|
||||||
throw new ArgumentNullException(nameof(parameters));
|
if (parameters == null) throw new ArgumentNullException(nameof(parameters));
|
||||||
|
|
||||||
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.Key, kv.Value)).Cast<IParameter>().ToArray();
|
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.Key, kv.Value)).Cast<IParameter>().ToArray();
|
||||||
return await ShowDialogAt<T>(identifier, paramsArray);
|
return await ShowDialogAt<T>(identifier, paramsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<object> ShowDialogAt<T>(string identifier, IParameter[] parameters) where T : DialogViewModelBase
|
|
||||||
{
|
|
||||||
Plugin callingPlugin = _pluginManagementService.GetCallingPlugin();
|
|
||||||
if (parameters == null)
|
|
||||||
throw new ArgumentNullException(nameof(parameters));
|
|
||||||
|
|
||||||
if (callingPlugin != null)
|
|
||||||
return await ShowDialog(identifier, callingPlugin.Kernel.Get<T>(parameters));
|
|
||||||
return await ShowDialog(identifier, _kernel.Get<T>(parameters));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowExceptionDialog(string message, Exception exception)
|
public void ShowExceptionDialog(string message, Exception exception)
|
||||||
{
|
{
|
||||||
_windowManager.ShowDialog(new ExceptionViewModel(message, exception));
|
_windowManager.ShowDialog(new ExceptionViewModel(message, exception));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IKernel GetBestKernel()
|
||||||
|
{
|
||||||
|
Plugin? callingPlugin = _pluginManagementService.GetCallingPlugin();
|
||||||
|
return callingPlugin?.Kernel ?? _kernel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
_viewManager = viewManager;
|
_viewManager = viewManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DialogViewModelBase ActiveDialogViewModel { get; set; }
|
public DialogViewModelBase? ActiveDialogViewModel { get; set; }
|
||||||
public bool IsOpen { get; set; }
|
public bool IsOpen { get; set; }
|
||||||
|
|
||||||
public void OpenDialog(DialogViewModelBase viewModel, string dialogIdentifier)
|
public void OpenDialog(DialogViewModelBase viewModel, string dialogIdentifier)
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// <param name="pluginFeature">The plugin feature to create hte data model visualization view model for</param>
|
/// <param name="pluginFeature">The plugin feature to create hte data model visualization view model for</param>
|
||||||
/// <param name="includeMainDataModel">Whether or not also to include the main data model</param>
|
/// <param name="includeMainDataModel">Whether or not also to include the main data model</param>
|
||||||
/// <returns>A data model visualization view model containing the data model of the provided feature</returns>
|
/// <returns>A data model visualization view model containing the data model of the provided feature</returns>
|
||||||
DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginFeature pluginFeature, bool includeMainDataModel);
|
DataModelPropertiesViewModel? GetPluginDataModelVisualization(PluginFeature pluginFeature, bool includeMainDataModel);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the children of the provided main data model visualization, removing disabled children and adding newly
|
/// Updates the children of the provided main data model visualization, removing disabled children and adding newly
|
||||||
@ -89,7 +89,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// returned if nothing else is found
|
/// returned if nothing else is found
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>The most appropriate display view model for the provided <paramref name="propertyType"></paramref></returns>
|
/// <returns>The most appropriate display view model for the provided <paramref name="propertyType"></paramref></returns>
|
||||||
DataModelDisplayViewModel GetDataModelDisplayViewModel(Type propertyType, DataModelPropertyAttribute description, bool fallBackToDefault = false);
|
DataModelDisplayViewModel? GetDataModelDisplayViewModel(Type propertyType, DataModelPropertyAttribute? description, bool fallBackToDefault = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the most appropriate input view model for the provided <paramref name="propertyType" /> that allows
|
/// Creates the most appropriate input view model for the provided <paramref name="propertyType" /> that allows
|
||||||
@ -100,7 +100,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// <param name="initialValue">The initial value to show in the input</param>
|
/// <param name="initialValue">The initial value to show in the input</param>
|
||||||
/// <param name="updateCallback">A function to call whenever the input was updated (submitted or not)</param>
|
/// <param name="updateCallback">A function to call whenever the input was updated (submitted or not)</param>
|
||||||
/// <returns>The most appropriate input view model for the provided <paramref name="propertyType" /></returns>
|
/// <returns>The most appropriate input view model for the provided <paramref name="propertyType" /></returns>
|
||||||
DataModelInputViewModel GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute description, object initialValue, Action<object, bool> updateCallback);
|
DataModelInputViewModel? GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute? description, object? initialValue, Action<object?, bool> updateCallback);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a view model that allows selecting a value from the data model
|
/// Creates a view model that allows selecting a value from the data model
|
||||||
|
|||||||
@ -14,17 +14,17 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the currently selected profile
|
/// Gets the currently selected profile
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Profile SelectedProfile { get; }
|
Profile? SelectedProfile { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the currently selected profile element
|
/// Gets the currently selected profile element
|
||||||
/// </summary>
|
/// </summary>
|
||||||
RenderProfileElement SelectedProfileElement { get; }
|
RenderProfileElement? SelectedProfileElement { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the currently selected data binding property
|
/// Gets the currently selected data binding property
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ILayerProperty SelectedDataBinding { get; }
|
ILayerProperty? SelectedDataBinding { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the current time
|
/// Gets or sets the current time
|
||||||
@ -45,7 +45,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// Changes the selected profile
|
/// Changes the selected profile
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="profile">The profile to select</param>
|
/// <param name="profile">The profile to select</param>
|
||||||
void ChangeSelectedProfile(Profile profile);
|
void ChangeSelectedProfile(Profile? profile);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the selected profile and saves it to persistent storage
|
/// Updates the selected profile and saves it to persistent storage
|
||||||
@ -56,7 +56,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// Changes the selected profile element
|
/// Changes the selected profile element
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="profileElement">The profile element to select</param>
|
/// <param name="profileElement">The profile element to select</param>
|
||||||
void ChangeSelectedProfileElement(RenderProfileElement profileElement);
|
void ChangeSelectedProfileElement(RenderProfileElement? profileElement);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the selected profile element and saves the profile it is contained in to persistent storage
|
/// Updates the selected profile element and saves the profile it is contained in to persistent storage
|
||||||
@ -67,7 +67,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// Changes the selected data binding property
|
/// Changes the selected data binding property
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="layerProperty">The data binding property to select</param>
|
/// <param name="layerProperty">The data binding property to select</param>
|
||||||
void ChangeSelectedDataBinding(ILayerProperty layerProperty);
|
void ChangeSelectedDataBinding(ILayerProperty? layerProperty);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the profile preview, forcing UI-elements to re-render
|
/// Updates the profile preview, forcing UI-elements to re-render
|
||||||
@ -90,7 +90,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// Gets the current module the profile editor is initialized for
|
/// Gets the current module the profile editor is initialized for
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The current module the profile editor is initialized for</returns>
|
/// <returns>The current module the profile editor is initialized for</returns>
|
||||||
ProfileModule GetCurrentModule();
|
ProfileModule? GetCurrentModule();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a new profile is selected
|
/// Occurs when a new profile is selected
|
||||||
@ -173,6 +173,6 @@ namespace Artemis.UI.Shared.Services
|
|||||||
/// If a matching registration is found, creates a new <see cref="PropertyInputViewModel{T}" /> supporting
|
/// If a matching registration is found, creates a new <see cref="PropertyInputViewModel{T}" /> supporting
|
||||||
/// <typeparamref name="T" />
|
/// <typeparamref name="T" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
PropertyInputViewModel<T> CreatePropertyInputViewModel<T>(LayerProperty<T> layerProperty);
|
PropertyInputViewModel<T>? CreatePropertyInputViewModel<T>(LayerProperty<T> layerProperty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +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;
|
private readonly IKernel _kernel;
|
||||||
|
|
||||||
public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger, ICoreService coreService)
|
public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger, ICoreService coreService)
|
||||||
{
|
{
|
||||||
@ -42,9 +42,9 @@ namespace Artemis.UI.Shared.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
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; }
|
||||||
public ILayerProperty SelectedDataBinding { get; private set; }
|
public ILayerProperty? SelectedDataBinding { get; private set; }
|
||||||
|
|
||||||
public TimeSpan CurrentTime
|
public TimeSpan CurrentTime
|
||||||
{
|
{
|
||||||
@ -71,7 +71,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeSelectedProfile(Profile profile)
|
public void ChangeSelectedProfile(Profile? profile)
|
||||||
{
|
{
|
||||||
lock (_selectedProfileLock)
|
lock (_selectedProfileLock)
|
||||||
{
|
{
|
||||||
@ -103,14 +103,16 @@ namespace Artemis.UI.Shared.Services
|
|||||||
lock (_selectedProfileLock)
|
lock (_selectedProfileLock)
|
||||||
{
|
{
|
||||||
_logger.Verbose("UpdateSelectedProfile {profile}", SelectedProfile);
|
_logger.Verbose("UpdateSelectedProfile {profile}", SelectedProfile);
|
||||||
_profileService.UpdateProfile(SelectedProfile, true);
|
if (SelectedProfile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_profileService.UpdateProfile(SelectedProfile, true);
|
||||||
OnSelectedProfileChanged(new ProfileEventArgs(SelectedProfile));
|
OnSelectedProfileChanged(new ProfileEventArgs(SelectedProfile));
|
||||||
UpdateProfilePreview();
|
UpdateProfilePreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeSelectedProfileElement(RenderProfileElement profileElement)
|
public void ChangeSelectedProfileElement(RenderProfileElement? profileElement)
|
||||||
{
|
{
|
||||||
lock (_selectedProfileElementLock)
|
lock (_selectedProfileElementLock)
|
||||||
{
|
{
|
||||||
@ -131,13 +133,16 @@ namespace Artemis.UI.Shared.Services
|
|||||||
lock (_selectedProfileElementLock)
|
lock (_selectedProfileElementLock)
|
||||||
{
|
{
|
||||||
_logger.Verbose("UpdateSelectedProfileElement {profile}", SelectedProfileElement);
|
_logger.Verbose("UpdateSelectedProfileElement {profile}", SelectedProfileElement);
|
||||||
|
if (SelectedProfile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
_profileService.UpdateProfile(SelectedProfile, true);
|
_profileService.UpdateProfile(SelectedProfile, true);
|
||||||
UpdateProfilePreview();
|
|
||||||
OnSelectedProfileElementUpdated(new RenderProfileElementEventArgs(SelectedProfileElement));
|
OnSelectedProfileElementUpdated(new RenderProfileElementEventArgs(SelectedProfileElement));
|
||||||
|
UpdateProfilePreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeSelectedDataBinding(ILayerProperty layerProperty)
|
public void ChangeSelectedDataBinding(ILayerProperty? layerProperty)
|
||||||
{
|
{
|
||||||
SelectedDataBinding = layerProperty;
|
SelectedDataBinding = layerProperty;
|
||||||
OnSelectedDataBindingChanged();
|
OnSelectedDataBindingChanged();
|
||||||
@ -159,6 +164,9 @@ namespace Artemis.UI.Shared.Services
|
|||||||
|
|
||||||
public bool UndoUpdateProfile()
|
public bool UndoUpdateProfile()
|
||||||
{
|
{
|
||||||
|
if (SelectedProfile == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
bool undid = _profileService.UndoUpdateProfile(SelectedProfile);
|
bool undid = _profileService.UndoUpdateProfile(SelectedProfile);
|
||||||
if (!undid)
|
if (!undid)
|
||||||
return false;
|
return false;
|
||||||
@ -169,6 +177,9 @@ namespace Artemis.UI.Shared.Services
|
|||||||
|
|
||||||
public bool RedoUpdateProfile()
|
public bool RedoUpdateProfile()
|
||||||
{
|
{
|
||||||
|
if (SelectedProfile == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
bool redid = _profileService.RedoUpdateProfile(SelectedProfile);
|
bool redid = _profileService.RedoUpdateProfile(SelectedProfile);
|
||||||
if (!redid)
|
if (!redid)
|
||||||
return false;
|
return false;
|
||||||
@ -189,7 +200,8 @@ namespace Artemis.UI.Shared.Services
|
|||||||
|
|
||||||
lock (_registeredPropertyEditors)
|
lock (_registeredPropertyEditors)
|
||||||
{
|
{
|
||||||
Type supportedType = viewModelType.BaseType.GetGenericArguments()[0];
|
// Indirectly checked if there's a BaseType above
|
||||||
|
Type supportedType = viewModelType.BaseType!.GetGenericArguments()[0];
|
||||||
// If the supported type is a generic, assume there is a base type
|
// If the supported type is a generic, assume there is a base type
|
||||||
if (supportedType.IsGenericParameter)
|
if (supportedType.IsGenericParameter)
|
||||||
{
|
{
|
||||||
@ -198,7 +210,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
supportedType = supportedType.BaseType;
|
supportedType = supportedType.BaseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyInputRegistration existing = _registeredPropertyEditors.FirstOrDefault(r => r.SupportedType == supportedType);
|
PropertyInputRegistration? existing = _registeredPropertyEditors.FirstOrDefault(r => r.SupportedType == supportedType);
|
||||||
if (existing != null)
|
if (existing != null)
|
||||||
{
|
{
|
||||||
if (existing.Plugin != plugin)
|
if (existing.Plugin != plugin)
|
||||||
@ -228,9 +240,9 @@ namespace Artemis.UI.Shared.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, List<TimeSpan> snapTimes = null)
|
public TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, List<TimeSpan>? snapTimes = null)
|
||||||
{
|
{
|
||||||
if (snapToSegments)
|
if (snapToSegments && SelectedProfileElement != null)
|
||||||
{
|
{
|
||||||
// Snap to the end of the start segment
|
// Snap to the end of the start segment
|
||||||
if (Math.Abs(time.TotalMilliseconds - SelectedProfileElement.Timeline.StartSegmentEndPosition.TotalMilliseconds) < tolerance.TotalMilliseconds)
|
if (Math.Abs(time.TotalMilliseconds - SelectedProfileElement.Timeline.StartSegmentEndPosition.TotalMilliseconds) < tolerance.TotalMilliseconds)
|
||||||
@ -255,7 +267,7 @@ namespace Artemis.UI.Shared.Services
|
|||||||
if (snapTimes != null)
|
if (snapTimes != null)
|
||||||
{
|
{
|
||||||
// Find the closest keyframe
|
// Find the closest keyframe
|
||||||
TimeSpan closeSnapTime = snapTimes.FirstOrDefault(s => Math.Abs(time.TotalMilliseconds - s.TotalMilliseconds) < tolerance.TotalMilliseconds);
|
TimeSpan closeSnapTime = snapTimes.FirstOrDefault(s => Math.Abs(time.TotalMilliseconds - s.TotalMilliseconds) < tolerance.TotalMilliseconds)!;
|
||||||
if (closeSnapTime != TimeSpan.Zero)
|
if (closeSnapTime != TimeSpan.Zero)
|
||||||
return closeSnapTime;
|
return closeSnapTime;
|
||||||
}
|
}
|
||||||
@ -263,10 +275,10 @@ namespace Artemis.UI.Shared.Services
|
|||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyInputViewModel<T> CreatePropertyInputViewModel<T>(LayerProperty<T> layerProperty)
|
public PropertyInputViewModel<T>? CreatePropertyInputViewModel<T>(LayerProperty<T> layerProperty)
|
||||||
{
|
{
|
||||||
Type viewModelType = null;
|
Type? viewModelType = null;
|
||||||
PropertyInputRegistration registration = RegisteredPropertyEditors.FirstOrDefault(r => r.SupportedType == typeof(T));
|
PropertyInputRegistration? registration = RegisteredPropertyEditors.FirstOrDefault(r => r.SupportedType == typeof(T));
|
||||||
|
|
||||||
// Check for enums if no supported type was found
|
// Check for enums if no supported type was found
|
||||||
if (registration == null && typeof(T).IsEnum)
|
if (registration == null && typeof(T).IsEnum)
|
||||||
@ -281,22 +293,30 @@ namespace Artemis.UI.Shared.Services
|
|||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if (viewModelType == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
ConstructorArgument parameter = new ConstructorArgument("layerProperty", layerProperty);
|
ConstructorArgument parameter = new ConstructorArgument("layerProperty", layerProperty);
|
||||||
IKernel kernel = registration != null ? registration.Plugin.Kernel : _kernel;
|
// ReSharper disable once InconsistentlySynchronizedField
|
||||||
|
// When you've just spent the last 2 hours trying to figure out a deadlock and reach this line, I'm so, so sorry. I thought this would be fine.
|
||||||
|
IKernel kernel = registration?.Plugin.Kernel ?? _kernel;
|
||||||
return (PropertyInputViewModel<T>) kernel.Get(viewModelType, parameter);
|
return (PropertyInputViewModel<T>) kernel.Get(viewModelType, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileModule GetCurrentModule()
|
public ProfileModule? GetCurrentModule()
|
||||||
{
|
{
|
||||||
return SelectedProfile?.Module;
|
return SelectedProfile?.Module;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReloadProfile()
|
private void ReloadProfile()
|
||||||
{
|
{
|
||||||
|
if (SelectedProfile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
// Trigger a profile change
|
// Trigger a profile change
|
||||||
OnSelectedProfileChanged(new ProfileEventArgs(SelectedProfile, SelectedProfile));
|
OnSelectedProfileChanged(new ProfileEventArgs(SelectedProfile, SelectedProfile));
|
||||||
// Trigger a selected element change
|
// Trigger a selected element change
|
||||||
RenderProfileElement previousSelectedProfileElement = SelectedProfileElement;
|
RenderProfileElement? previousSelectedProfileElement = SelectedProfileElement;
|
||||||
if (SelectedProfileElement is Folder folder)
|
if (SelectedProfileElement is Folder folder)
|
||||||
SelectedProfileElement = SelectedProfile.GetAllFolders().FirstOrDefault(f => f.EntityId == folder.EntityId);
|
SelectedProfileElement = SelectedProfile.GetAllFolders().FirstOrDefault(f => f.EntityId == folder.EntityId);
|
||||||
else if (SelectedProfileElement is Layer layer)
|
else if (SelectedProfileElement is Layer layer)
|
||||||
@ -305,22 +325,24 @@ namespace Artemis.UI.Shared.Services
|
|||||||
// Trigger selected data binding change
|
// Trigger selected data binding change
|
||||||
if (SelectedDataBinding != null)
|
if (SelectedDataBinding != null)
|
||||||
{
|
{
|
||||||
SelectedDataBinding = SelectedProfileElement?.GetAllLayerProperties()?.FirstOrDefault(p => p.Path == SelectedDataBinding.Path);
|
SelectedDataBinding = SelectedProfileElement?.GetAllLayerProperties().FirstOrDefault(p => p.Path == SelectedDataBinding.Path);
|
||||||
OnSelectedDataBindingChanged();
|
OnSelectedDataBindingChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateProfilePreview();
|
UpdateProfilePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<ProfileEventArgs> ProfileSelected;
|
#region Events
|
||||||
public event EventHandler<ProfileEventArgs> SelectedProfileUpdated;
|
|
||||||
public event EventHandler<RenderProfileElementEventArgs> ProfileElementSelected;
|
public event EventHandler<ProfileEventArgs>? ProfileSelected;
|
||||||
public event EventHandler<RenderProfileElementEventArgs> SelectedProfileElementUpdated;
|
public event EventHandler<ProfileEventArgs>? SelectedProfileUpdated;
|
||||||
public event EventHandler SelectedDataBindingChanged;
|
public event EventHandler<RenderProfileElementEventArgs>? ProfileElementSelected;
|
||||||
public event EventHandler CurrentTimeChanged;
|
public event EventHandler<RenderProfileElementEventArgs>? SelectedProfileElementUpdated;
|
||||||
public event EventHandler PixelsPerSecondChanged;
|
public event EventHandler? SelectedDataBindingChanged;
|
||||||
public event EventHandler ProfilePreviewUpdated;
|
public event EventHandler? CurrentTimeChanged;
|
||||||
public event EventHandler CurrentTimelineChanged;
|
public event EventHandler? PixelsPerSecondChanged;
|
||||||
|
public event EventHandler? ProfilePreviewUpdated;
|
||||||
|
public event EventHandler? CurrentTimelineChanged;
|
||||||
|
|
||||||
protected virtual void OnSelectedProfileChanged(ProfileEventArgs e)
|
protected virtual void OnSelectedProfileChanged(ProfileEventArgs e)
|
||||||
{
|
{
|
||||||
@ -367,10 +389,13 @@ namespace Artemis.UI.Shared.Services
|
|||||||
SelectedDataBindingChanged?.Invoke(this, EventArgs.Empty);
|
SelectedDataBindingChanged?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SelectedProfileOnDeactivated(object sender, EventArgs e)
|
private void SelectedProfileOnDeactivated(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
// Execute.PostToUIThread(() => ChangeSelectedProfile(null));
|
// Execute.PostToUIThread(() => ChangeSelectedProfile(null));
|
||||||
ChangeSelectedProfile(null);
|
ChangeSelectedProfile(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,8 +9,8 @@ namespace Artemis.UI.Shared
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ShortcutUtilities
|
public class ShortcutUtilities
|
||||||
{
|
{
|
||||||
private static readonly Type m_type = Type.GetTypeFromProgID("WScript.Shell");
|
private static readonly Type MType = Type.GetTypeFromProgID("WScript.Shell")!;
|
||||||
private static readonly object m_shell = Activator.CreateInstance(m_type);
|
private static readonly object MShell = Activator.CreateInstance(MType)!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a shortcut
|
/// Creates a shortcut
|
||||||
@ -24,7 +24,10 @@ namespace Artemis.UI.Shared
|
|||||||
/// <param name="iconPath">The icon path of the shortcut</param>
|
/// <param name="iconPath">The icon path of the shortcut</param>
|
||||||
public static void Create(string fileName, string targetPath, string arguments, string workingDirectory, string description, string hotkey, string iconPath)
|
public static void Create(string fileName, string targetPath, string arguments, string workingDirectory, string description, string hotkey, string iconPath)
|
||||||
{
|
{
|
||||||
IWshShortcut shortcut = (IWshShortcut) m_type.InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, m_shell, new object[] {fileName});
|
IWshShortcut? shortcut = (IWshShortcut?) MType.InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, MShell, new object[] {fileName});
|
||||||
|
if (shortcut == null)
|
||||||
|
throw new ArtemisSharedUIException("InvokeMember CreateShortcut returned null");
|
||||||
|
|
||||||
shortcut.Description = description;
|
shortcut.Description = description;
|
||||||
shortcut.Hotkey = hotkey;
|
shortcut.Hotkey = hotkey;
|
||||||
shortcut.TargetPath = targetPath;
|
shortcut.TargetPath = targetPath;
|
||||||
@ -34,7 +37,7 @@ namespace Artemis.UI.Shared
|
|||||||
shortcut.IconLocation = iconPath;
|
shortcut.IconLocation = iconPath;
|
||||||
shortcut.Save();
|
shortcut.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComImport]
|
[ComImport]
|
||||||
[TypeLibType(0x1040)]
|
[TypeLibType(0x1040)]
|
||||||
[Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")]
|
[Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")]
|
||||||
@ -118,14 +121,7 @@ namespace Artemis.UI.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
[DispId(0x3ee)]
|
[DispId(0x3ee)]
|
||||||
int WindowStyle
|
int WindowStyle { [DispId(0x3ee)] get; [param: In] [DispId(0x3ee)] set; }
|
||||||
{
|
|
||||||
[DispId(0x3ee)]
|
|
||||||
get;
|
|
||||||
[param: In]
|
|
||||||
[DispId(0x3ee)]
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DispId(0x3ef)]
|
[DispId(0x3ef)]
|
||||||
string WorkingDirectory
|
string WorkingDirectory
|
||||||
@ -141,6 +137,7 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
[TypeLibFunc(0x40)]
|
[TypeLibFunc(0x40)]
|
||||||
[DispId(0x7d0)]
|
[DispId(0x7d0)]
|
||||||
|
// ReSharper disable once InconsistentNaming - No idea if that breaks it and cba to test
|
||||||
void Load([In] [MarshalAs(UnmanagedType.BStr)] string PathLink);
|
void Load([In] [MarshalAs(UnmanagedType.BStr)] string PathLink);
|
||||||
|
|
||||||
[DispId(0x7d1)]
|
[DispId(0x7d1)]
|
||||||
|
|||||||
@ -20,12 +20,12 @@ namespace Artemis.UI.Shared
|
|||||||
/// If not matching item can be found,
|
/// If not matching item can be found,
|
||||||
/// a null parent is being returned.
|
/// a null parent is being returned.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
|
public static T? FindChild<T>(DependencyObject? parent, string? childName) where T : DependencyObject
|
||||||
{
|
{
|
||||||
// Confirm parent and childName are valid.
|
// Confirm parent and childName are valid.
|
||||||
if (parent == null) return null;
|
if (parent == null) return null;
|
||||||
|
|
||||||
T foundChild = null;
|
T? foundChild = null;
|
||||||
|
|
||||||
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
|
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
|
||||||
for (int i = 0; i < childrenCount; i++)
|
for (int i = 0; i < childrenCount; i++)
|
||||||
@ -72,10 +72,10 @@ namespace Artemis.UI.Shared
|
|||||||
/// If not matching item can be found,
|
/// If not matching item can be found,
|
||||||
/// a null parent is being returned.
|
/// a null parent is being returned.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public static T FindParent<T>(DependencyObject child, string parentName) where T : DependencyObject
|
public static T? FindParent<T>(DependencyObject child, string? parentName) where T : DependencyObject
|
||||||
{
|
{
|
||||||
// Get parent item
|
// Get parent item
|
||||||
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
|
DependencyObject? parentObject = VisualTreeHelper.GetParent(child);
|
||||||
|
|
||||||
// We've reached the end of the tree
|
// We've reached the end of the tree
|
||||||
if (parentObject == null)
|
if (parentObject == null)
|
||||||
|
|||||||
@ -14,7 +14,6 @@ using Artemis.Core.Ninject;
|
|||||||
using Artemis.Core.Services;
|
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.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Artemis.UI.Stylet;
|
using Artemis.UI.Stylet;
|
||||||
@ -88,7 +87,8 @@ namespace Artemis.UI
|
|||||||
|
|
||||||
protected override void ConfigureIoC(IKernel kernel)
|
protected override void ConfigureIoC(IKernel kernel)
|
||||||
{
|
{
|
||||||
// kernel.Settings.InjectNonPublic = true;
|
// This is kinda needed for the VM factories in the Shared UI but perhaps there's a less global solution
|
||||||
|
kernel.Settings.InjectNonPublic = true;
|
||||||
|
|
||||||
// Load the UI modules
|
// Load the UI modules
|
||||||
kernel.Load<UIModule>();
|
kernel.Load<UIModule>();
|
||||||
@ -123,7 +123,7 @@ namespace Artemis.UI
|
|||||||
Execute.OnUIThread(() => Application.Current.Shutdown());
|
Execute.OnUIThread(() => Application.Current.Shutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateDataDirectory(ILogger logger)
|
private static void CreateDataDirectory(ILogger logger)
|
||||||
{
|
{
|
||||||
// Ensure the data folder exists
|
// Ensure the data folder exists
|
||||||
if (Directory.Exists(Constants.DataFolder))
|
if (Directory.Exists(Constants.DataFolder))
|
||||||
@ -161,14 +161,5 @@ namespace Artemis.UI
|
|||||||
Environment.Exit(1);
|
Environment.Exit(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowMainWindow(IWindowManager windowManager, SplashViewModel splashViewModel)
|
|
||||||
{
|
|
||||||
Execute.OnUIThread(() =>
|
|
||||||
{
|
|
||||||
windowManager.ShowWindow(RootViewModel);
|
|
||||||
splashViewModel.RequestClose();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,11 +1,12 @@
|
|||||||
using System.Timers;
|
using System;
|
||||||
|
using System.Timers;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Modules.Tabs
|
namespace Artemis.UI.Screens.Modules.Tabs
|
||||||
{
|
{
|
||||||
public class ActivationRequirementViewModel : Screen
|
public sealed class ActivationRequirementViewModel : Screen, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IModuleActivationRequirement _activationRequirement;
|
private readonly IModuleActivationRequirement _activationRequirement;
|
||||||
private readonly Timer _updateTimer;
|
private readonly Timer _updateTimer;
|
||||||
@ -60,5 +61,15 @@ namespace Artemis.UI.Screens.Modules.Tabs
|
|||||||
RequirementDescription = _activationRequirement.GetUserFriendlyDescription();
|
RequirementDescription = _activationRequirement.GetUserFriendlyDescription();
|
||||||
RequirementMet = _activationRequirement.Evaluate();
|
RequirementMet = _activationRequirement.Evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_updateTimer?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,27 +5,25 @@ using System.Windows;
|
|||||||
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.Screens.ProfileEditor.Conditions.Abstract;
|
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Input;
|
using Artemis.UI.Shared.Input;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract
|
||||||
{
|
{
|
||||||
public abstract class DataModelConditionPredicateViewModel : DataModelConditionViewModel, IDisposable
|
public abstract class DataModelConditionPredicateViewModel : DataModelConditionViewModel, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IConditionOperatorService _conditionOperatorService;
|
private readonly IConditionOperatorService _conditionOperatorService;
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private BindableCollection<BaseConditionOperator> _operators;
|
|
||||||
private DataModelStaticViewModel _rightSideInputViewModel;
|
private DataModelStaticViewModel _rightSideInputViewModel;
|
||||||
private DataModelDynamicViewModel _rightSideSelectionViewModel;
|
private DataModelDynamicViewModel _rightSideSelectionViewModel;
|
||||||
private BaseConditionOperator _selectedOperator;
|
private BaseConditionOperator _selectedOperator;
|
||||||
|
|
||||||
private List<Type> _supportedInputTypes;
|
private List<Type> _supportedInputTypes;
|
||||||
|
|
||||||
public DataModelConditionPredicateViewModel(
|
protected DataModelConditionPredicateViewModel(
|
||||||
DataModelConditionPredicate dataModelConditionPredicate,
|
DataModelConditionPredicate dataModelConditionPredicate,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
IDataModelUIService dataModelUIService,
|
IDataModelUIService dataModelUIService,
|
||||||
@ -199,17 +197,27 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
|
|
||||||
#region IDisposable
|
#region IDisposable
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
if (LeftSideSelectionViewModel != null)
|
||||||
|
{
|
||||||
|
LeftSideSelectionViewModel.PropertySelected -= LeftSideOnPropertySelected;
|
||||||
|
LeftSideSelectionViewModel.Dispose();
|
||||||
|
LeftSideSelectionViewModel = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisposeRightSideStaticViewModel();
|
||||||
|
DisposeRightSideDynamicViewModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (LeftSideSelectionViewModel != null)
|
Dispose(true);
|
||||||
{
|
GC.SuppressFinalize(this);
|
||||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideOnPropertySelected;
|
|
||||||
LeftSideSelectionViewModel.Dispose();
|
|
||||||
LeftSideSelectionViewModel = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisposeRightSideStaticViewModel();
|
|
||||||
DisposeRightSideDynamicViewModel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -284,7 +292,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RightSideInputViewModelOnSwitchToDynamicRequested(object? sender, EventArgs e)
|
private void RightSideInputViewModelOnSwitchToDynamicRequested(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DataModelConditionPredicate.PredicateType = ProfileRightSideType.Dynamic;
|
DataModelConditionPredicate.PredicateType = ProfileRightSideType.Dynamic;
|
||||||
Update();
|
Update();
|
||||||
|
|||||||
@ -10,7 +10,7 @@ using Artemis.UI.Shared.Services;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||||
{
|
{
|
||||||
public class DataModelConditionEventViewModel : DataModelConditionViewModel, IDisposable
|
public sealed class DataModelConditionEventViewModel : DataModelConditionViewModel, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
@ -90,7 +90,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void LeftSideSelectionViewModelOnPropertySelected(object? sender, DataModelInputDynamicEventArgs e)
|
private void LeftSideSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||||
{
|
{
|
||||||
ApplyEvent();
|
ApplyEvent();
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
LeftSideSelectionViewModel.Dispose();
|
LeftSideSelectionViewModel.Dispose();
|
||||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected;
|
LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11,7 +11,7 @@ using Humanizer;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||||
{
|
{
|
||||||
public class DataModelConditionListViewModel : DataModelConditionViewModel, IDisposable
|
public sealed class DataModelConditionListViewModel : DataModelConditionViewModel, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
@ -92,7 +92,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
|
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionList.ListPath);
|
LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionList.ListPath);
|
||||||
@ -130,15 +130,19 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
base.OnInitialActivate();
|
base.OnInitialActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LeftSideSelectionViewModelOnPropertySelected(object? sender, DataModelInputDynamicEventArgs e)
|
private void LeftSideSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||||
{
|
{
|
||||||
ApplyList();
|
ApplyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
LeftSideSelectionViewModel.Dispose();
|
LeftSideSelectionViewModel.Dispose();
|
||||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected;
|
LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@ 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.Extensions;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ 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.Extensions;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
|
||||||
|
|||||||
@ -114,7 +114,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
RenderProfileElement.DisplayCondition.ChildRemoved += DisplayConditionOnChildrenModified;
|
RenderProfileElement.DisplayCondition.ChildRemoved += DisplayConditionOnChildrenModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisplayConditionOnChildrenModified(object? sender, EventArgs e)
|
private void DisplayConditionOnChildrenModified(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DisplayStartHint = !RenderProfileElement.DisplayCondition.Children.Any();
|
DisplayStartHint = !RenderProfileElement.DisplayCondition.Children.Any();
|
||||||
IsEventCondition = RenderProfileElement.DisplayCondition.Children.Any(c => c is DataModelConditionEvent);
|
IsEventCondition = RenderProfileElement.DisplayCondition.Children.Any(c => c is DataModelConditionEvent);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
|
||||||
{
|
{
|
||||||
public class ConditionalDataBindingModeViewModel<TLayerProperty, TProperty> : Conductor<DataBindingConditionViewModel<TLayerProperty, TProperty>>.Collection.AllActive, IDataBindingModeViewModel
|
public sealed class ConditionalDataBindingModeViewModel<TLayerProperty, TProperty> : Conductor<DataBindingConditionViewModel<TLayerProperty, TProperty>>.Collection.AllActive, IDataBindingModeViewModel
|
||||||
{
|
{
|
||||||
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
@ -109,7 +109,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.Conditio
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region IDisposable
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
ConditionalDataBinding.ConditionsUpdated -= ConditionalDataBindingOnConditionsUpdated;
|
ConditionalDataBinding.ConditionsUpdated -= ConditionalDataBindingOnConditionsUpdated;
|
||||||
|
|||||||
@ -10,11 +10,11 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
|
||||||
{
|
{
|
||||||
public class DataBindingConditionViewModel<TLayerProperty, TProperty> : Conductor<DataModelConditionGroupViewModel>, IDisposable
|
public sealed class DataBindingConditionViewModel<TLayerProperty, TProperty> : Conductor<DataModelConditionGroupViewModel>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
|
||||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
|
||||||
public DataBindingConditionViewModel(DataBindingCondition<TLayerProperty, TProperty> dataBindingCondition,
|
public DataBindingConditionViewModel(DataBindingCondition<TLayerProperty, TProperty> dataBindingCondition,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
@ -44,11 +44,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.Conditio
|
|||||||
ValueViewModel.Value = DataBindingCondition.Value;
|
ValueViewModel.Value = DataBindingCondition.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
ValueViewModel.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ActiveItemOnUpdated(object sender, EventArgs e)
|
private void ActiveItemOnUpdated(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (!ActiveItem.GetChildren().Any())
|
if (!ActiveItem.GetChildren().Any())
|
||||||
@ -60,5 +55,15 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.Conditio
|
|||||||
DataBindingCondition.Value = (TProperty) Convert.ChangeType(e.Value, typeof(TProperty));
|
DataBindingCondition.Value = (TProperty) Convert.ChangeType(e.Value, typeof(TProperty));
|
||||||
_profileEditorService.UpdateSelectedProfileElement();
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
ValueViewModel?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,17 +10,17 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||||
{
|
{
|
||||||
public class DataBindingViewModel<TLayerProperty, TProperty> : Conductor<IDataBindingModeViewModel>, IDataBindingViewModel
|
public sealed class DataBindingViewModel<TLayerProperty, TProperty> : Conductor<IDataBindingModeViewModel>, IDataBindingViewModel
|
||||||
{
|
{
|
||||||
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private readonly Timer _updateTimer;
|
private readonly Timer _updateTimer;
|
||||||
|
private bool _applyTestResultToLayer;
|
||||||
private int _easingTime;
|
private int _easingTime;
|
||||||
private bool _isDataBindingEnabled;
|
private bool _isDataBindingEnabled;
|
||||||
private bool _isEasingTimeEnabled;
|
private bool _isEasingTimeEnabled;
|
||||||
private DataBindingModeType _selectedDataBindingMode;
|
private DataBindingModeType _selectedDataBindingMode;
|
||||||
private TimelineEasingViewModel _selectedEasingViewModel;
|
private TimelineEasingViewModel _selectedEasingViewModel;
|
||||||
private bool _applyTestResultToLayer;
|
|
||||||
|
|
||||||
private bool _updating;
|
private bool _updating;
|
||||||
private bool _updatingTestResult;
|
private bool _updatingTestResult;
|
||||||
@ -46,12 +46,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
TestResultValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
|
TestResultValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnInitialActivate()
|
|
||||||
{
|
|
||||||
base.OnInitialActivate();
|
|
||||||
Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataBindingRegistration<TLayerProperty, TProperty> Registration { get; }
|
public DataBindingRegistration<TLayerProperty, TProperty> Registration { get; }
|
||||||
|
|
||||||
public BindableCollection<ValueDescription> DataBindingModes { get; }
|
public BindableCollection<ValueDescription> DataBindingModes { get; }
|
||||||
@ -115,12 +109,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
protected override void OnInitialActivate()
|
||||||
{
|
{
|
||||||
_updateTimer.Dispose();
|
base.OnInitialActivate();
|
||||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
Initialize();
|
||||||
|
|
||||||
Registration.LayerProperty.Updated -= LayerPropertyOnUpdated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
@ -171,18 +163,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
EasingTime = (int) Registration.DataBinding.EasingTime.TotalMilliseconds;
|
EasingTime = (int) Registration.DataBinding.EasingTime.TotalMilliseconds;
|
||||||
SelectedEasingViewModel = EasingViewModels.First(vm => vm.EasingFunction == Registration.DataBinding.EasingFunction);
|
SelectedEasingViewModel = EasingViewModels.First(vm => vm.EasingFunction == Registration.DataBinding.EasingFunction);
|
||||||
IsEasingTimeEnabled = EasingTime > 0;
|
IsEasingTimeEnabled = EasingTime > 0;
|
||||||
switch (Registration.DataBinding.DataBindingMode)
|
SelectedDataBindingMode = Registration.DataBinding.DataBindingMode switch
|
||||||
{
|
{
|
||||||
case DirectDataBinding<TLayerProperty, TProperty> _:
|
DirectDataBinding<TLayerProperty, TProperty> _ => DataBindingModeType.Direct,
|
||||||
SelectedDataBindingMode = DataBindingModeType.Direct;
|
ConditionalDataBinding<TLayerProperty, TProperty> _ => DataBindingModeType.Conditional,
|
||||||
break;
|
_ => DataBindingModeType.None
|
||||||
case ConditionalDataBinding<TLayerProperty, TProperty> _:
|
};
|
||||||
SelectedDataBindingMode = DataBindingModeType.Conditional;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SelectedDataBindingMode = DataBindingModeType.None;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActiveItem?.Update();
|
ActiveItem?.Update();
|
||||||
|
|
||||||
@ -250,7 +236,9 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(currentValue) : default);
|
TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(currentValue) : default);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(default) : default);
|
TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(default) : default);
|
||||||
|
}
|
||||||
|
|
||||||
if (ApplyTestResultToLayer)
|
if (ApplyTestResultToLayer)
|
||||||
{
|
{
|
||||||
@ -288,11 +276,24 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
UpdateTestResult();
|
UpdateTestResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerPropertyOnUpdated(object? sender, LayerPropertyEventArgs<TLayerProperty> e)
|
private void LayerPropertyOnUpdated(object sender, LayerPropertyEventArgs<TLayerProperty> e)
|
||||||
{
|
{
|
||||||
if (ApplyTestResultToLayer)
|
if (ApplyTestResultToLayer)
|
||||||
Registration.DataBinding?.Apply();
|
Registration.DataBinding?.Apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_updateTimer.Dispose();
|
||||||
|
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||||
|
|
||||||
|
Registration.LayerProperty.Updated -= LayerPropertyOnUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IDataBindingViewModel : IScreen, IDisposable
|
public interface IDataBindingViewModel : IScreen, IDisposable
|
||||||
|
|||||||
@ -52,7 +52,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
SelectedItemIndex = 0;
|
SelectedItemIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileEditorServiceOnSelectedDataBindingChanged(object? sender, EventArgs e)
|
private void ProfileEditorServiceOnSelectedDataBindingChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
CreateDataBindingViewModels();
|
CreateDataBindingViewModels();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
|
||||||
{
|
{
|
||||||
public class DataBindingModifierViewModel<TLayerProperty, TProperty> : PropertyChangedBase, IDisposable
|
public sealed class DataBindingModifierViewModel<TLayerProperty, TProperty> : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDataBindingService _dataBindingService;
|
private readonly IDataBindingService _dataBindingService;
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
@ -161,6 +161,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
|
|
||||||
#region IDisposable
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
DisposeDynamicSelectionViewModel();
|
DisposeDynamicSelectionViewModel();
|
||||||
@ -193,13 +194,13 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void DynamicSelectionViewModelOnSwitchToStaticRequested(object? sender, EventArgs e)
|
private void DynamicSelectionViewModelOnSwitchToStaticRequested(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Modifier.ParameterType = ProfileRightSideType.Static;
|
Modifier.ParameterType = ProfileRightSideType.Static;
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StaticInputViewModelOnSwitchToDynamicRequested(object? sender, EventArgs e)
|
private void StaticInputViewModelOnSwitchToDynamicRequested(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Modifier.ParameterType = ProfileRightSideType.Dynamic;
|
Modifier.ParameterType = ProfileRightSideType.Dynamic;
|
||||||
Update();
|
Update();
|
||||||
|
|||||||
@ -12,7 +12,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
|
||||||
{
|
{
|
||||||
public class DirectDataBindingModeViewModel<TLayerProperty, TProperty> : Screen, IDataBindingModeViewModel
|
public sealed class DirectDataBindingModeViewModel<TLayerProperty, TProperty> : Screen, IDataBindingModeViewModel
|
||||||
{
|
{
|
||||||
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
@ -70,6 +70,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
|
|
||||||
#region IDisposable
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
|
TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
|
||||||
|
|||||||
@ -9,7 +9,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
||||||
{
|
{
|
||||||
public class LayerPropertyGroupViewModel : PropertyChangedBase, IDisposable
|
public sealed class LayerPropertyGroupViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
|
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
|
||||||
private bool _isVisible;
|
private bool _isVisible;
|
||||||
@ -40,9 +40,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
|||||||
get => _isVisible;
|
get => _isVisible;
|
||||||
set => SetAndNotify(ref _isVisible, value);
|
set => SetAndNotify(ref _isVisible, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsHighlighted => false;
|
|
||||||
|
|
||||||
public bool IsExpanded
|
public bool IsExpanded
|
||||||
{
|
{
|
||||||
get => LayerPropertyGroup.ProfileElement.IsPropertyGroupExpanded(LayerPropertyGroup);
|
get => LayerPropertyGroup.ProfileElement.IsPropertyGroupExpanded(LayerPropertyGroup);
|
||||||
@ -53,6 +51,9 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
TimelineGroupViewModel.Dispose();
|
TimelineGroupViewModel.Dispose();
|
||||||
@ -64,6 +65,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public void UpdateOrder(int order)
|
public void UpdateOrder(int order)
|
||||||
{
|
{
|
||||||
LayerPropertyGroup.LayerEffect.Order = order;
|
LayerPropertyGroup.LayerEffect.Order = order;
|
||||||
@ -93,7 +96,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="start">The position at which to start removing keyframes, if null this will start at the first keyframe</param>
|
/// <param name="start">The position at which to start removing keyframes, if null this will start at the first keyframe</param>
|
||||||
/// <param name="end">The position at which to start removing keyframes, if null this will end at the last keyframe</param>
|
/// <param name="end">The position at which to start removing keyframes, if null this will end at the last keyframe</param>
|
||||||
public virtual void WipeKeyframes(TimeSpan? start, TimeSpan? end)
|
public void WipeKeyframes(TimeSpan? start, TimeSpan? end)
|
||||||
{
|
{
|
||||||
foreach (PropertyChangedBase child in Children)
|
foreach (PropertyChangedBase child in Children)
|
||||||
{
|
{
|
||||||
@ -139,7 +142,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
|||||||
{
|
{
|
||||||
PropertyDescriptionAttribute propertyAttribute = (PropertyDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyDescriptionAttribute));
|
PropertyDescriptionAttribute propertyAttribute = (PropertyDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyDescriptionAttribute));
|
||||||
PropertyGroupDescriptionAttribute groupAttribute = (PropertyGroupDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyGroupDescriptionAttribute));
|
PropertyGroupDescriptionAttribute groupAttribute = (PropertyGroupDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyGroupDescriptionAttribute));
|
||||||
object? value = propertyInfo.GetValue(LayerPropertyGroup);
|
object value = propertyInfo.GetValue(LayerPropertyGroup);
|
||||||
|
|
||||||
// Create VMs for properties on the group
|
// Create VMs for properties on the group
|
||||||
if (propertyAttribute != null && value is ILayerProperty layerProperty)
|
if (propertyAttribute != null && value is ILayerProperty layerProperty)
|
||||||
|
|||||||
@ -7,7 +7,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
||||||
{
|
{
|
||||||
public class LayerPropertyViewModel : PropertyChangedBase, IDisposable
|
public sealed class LayerPropertyViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
private bool _isVisible;
|
private bool _isVisible;
|
||||||
private bool _isHighlighted;
|
private bool _isHighlighted;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
||||||
{
|
{
|
||||||
public class TimelineGroupViewModel : PropertyChangedBase, IDisposable
|
public sealed class TimelineGroupViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
|
||||||
|
|||||||
@ -7,11 +7,10 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
||||||
{
|
{
|
||||||
public class TimelineKeyframeViewModel<T> : Screen, ITimelineKeyframeViewModel
|
public sealed class TimelineKeyframeViewModel<T> : Screen, ITimelineKeyframeViewModel
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
|
||||||
private BindableCollection<TimelineEasingViewModel> _easingViewModels;
|
|
||||||
private bool _isSelected;
|
private bool _isSelected;
|
||||||
private string _timestamp;
|
private string _timestamp;
|
||||||
private double _x;
|
private double _x;
|
||||||
@ -65,7 +64,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
Timestamp = $"{Math.Floor(LayerPropertyKeyframe.Position.TotalSeconds):00}.{LayerPropertyKeyframe.Position.Milliseconds:000}";
|
Timestamp = $"{Math.Floor(LayerPropertyKeyframe.Position.TotalSeconds):00}.{LayerPropertyKeyframe.Position.Milliseconds:000}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileEditorServiceOnPixelsPerSecondChanged(object? sender, EventArgs e)
|
private void ProfileEditorServiceOnPixelsPerSecondChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
||||||
{
|
{
|
||||||
public class TimelinePropertyViewModel<T> : Conductor<TimelineKeyframeViewModel<T>>.Collection.AllActive, ITimelinePropertyViewModel
|
public sealed class TimelinePropertyViewModel<T> : Conductor<TimelineKeyframeViewModel<T>>.Collection.AllActive, ITimelinePropertyViewModel
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private double _width;
|
private double _width;
|
||||||
|
|||||||
@ -7,7 +7,6 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Screens.ProfileEditor.Dialogs;
|
|
||||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline.Dialogs;
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline.Dialogs;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
@ -15,19 +14,19 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
||||||
{
|
{
|
||||||
public class TimelineSegmentViewModel : Screen, IDisposable
|
public sealed class TimelineSegmentViewModel : Screen, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
private bool _draggingSegment;
|
private bool _draggingSegment;
|
||||||
|
private bool _segmentEnabled;
|
||||||
|
private TimeSpan _segmentEnd;
|
||||||
|
private TimeSpan _segmentLength;
|
||||||
|
private TimeSpan _segmentStart;
|
||||||
|
private double _segmentStartPosition;
|
||||||
|
private double _segmentWidth;
|
||||||
private bool _showDisableButton;
|
private bool _showDisableButton;
|
||||||
private bool _showRepeatButton;
|
private bool _showRepeatButton;
|
||||||
private bool _showSegmentName;
|
private bool _showSegmentName;
|
||||||
private TimeSpan _segmentLength;
|
|
||||||
private TimeSpan _segmentStart;
|
|
||||||
private TimeSpan _segmentEnd;
|
|
||||||
private double _segmentWidth;
|
|
||||||
private bool _segmentEnabled;
|
|
||||||
private double _segmentStartPosition;
|
|
||||||
|
|
||||||
public TimelineSegmentViewModel(SegmentViewModelType segment, BindableCollection<LayerPropertyGroupViewModel> layerPropertyGroups,
|
public TimelineSegmentViewModel(SegmentViewModelType segment, BindableCollection<LayerPropertyGroupViewModel> layerPropertyGroups,
|
||||||
IProfileEditorService profileEditorService, IDialogService dialogService)
|
IProfileEditorService profileEditorService, IDialogService dialogService)
|
||||||
@ -139,6 +138,40 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
await _dialogService.ShowDialog<TimelineSegmentDialogViewModel>(new Dictionary<string, object> {{"segment", this}});
|
await _dialogService.ShowDialog<TimelineSegmentDialogViewModel>(new Dictionary<string, object> {{"segment", this}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ShiftNextSegment(TimeSpan amount)
|
||||||
|
{
|
||||||
|
if (Segment == SegmentViewModelType.Start)
|
||||||
|
ShiftKeyframes(SelectedProfileElement.Timeline.StartSegmentEndPosition, null, amount);
|
||||||
|
else if (Segment == SegmentViewModelType.Main)
|
||||||
|
ShiftKeyframes(SelectedProfileElement.Timeline.MainSegmentEndPosition, null, amount);
|
||||||
|
else if (Segment == SegmentViewModelType.End)
|
||||||
|
ShiftKeyframes(SelectedProfileElement.Timeline.EndSegmentEndPosition, null, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WipeKeyframes(TimeSpan? start, TimeSpan? end)
|
||||||
|
{
|
||||||
|
foreach (LayerPropertyGroupViewModel layerPropertyGroupViewModel in LayerPropertyGroups)
|
||||||
|
layerPropertyGroupViewModel.WipeKeyframes(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShiftKeyframes(TimeSpan? start, TimeSpan? end, TimeSpan amount)
|
||||||
|
{
|
||||||
|
foreach (LayerPropertyGroupViewModel layerPropertyGroupViewModel in LayerPropertyGroups)
|
||||||
|
layerPropertyGroupViewModel.ShiftKeyframes(start, end, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IDIsposable
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
ProfileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
|
||||||
|
ProfileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
|
||||||
|
if (SelectedProfileElement != null)
|
||||||
|
SelectedProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Updating
|
#region Updating
|
||||||
|
|
||||||
private void UpdateHeader()
|
private void UpdateHeader()
|
||||||
@ -283,7 +316,9 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
}
|
}
|
||||||
// If holding down control, round to the closest 50ms
|
// If holding down control, round to the closest 50ms
|
||||||
else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
||||||
|
{
|
||||||
newTime = TimeSpan.FromMilliseconds(Math.Round(newTime.TotalMilliseconds / 50.0) * 50.0);
|
newTime = TimeSpan.FromMilliseconds(Math.Round(newTime.TotalMilliseconds / 50.0) * 50.0);
|
||||||
|
}
|
||||||
|
|
||||||
UpdateLength(newTime);
|
UpdateLength(newTime);
|
||||||
}
|
}
|
||||||
@ -304,7 +339,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
SelectedProfileElement.Timeline.MainSegmentEndPosition = newTime;
|
SelectedProfileElement.Timeline.MainSegmentEndPosition = newTime;
|
||||||
else if (Segment == SegmentViewModelType.End)
|
else if (Segment == SegmentViewModelType.End)
|
||||||
SelectedProfileElement.Timeline.EndSegmentEndPosition = newTime;
|
SelectedProfileElement.Timeline.EndSegmentEndPosition = newTime;
|
||||||
|
|
||||||
if (difference < TimeSpan.Zero)
|
if (difference < TimeSpan.Zero)
|
||||||
ShiftNextSegment(difference);
|
ShiftNextSegment(difference);
|
||||||
|
|
||||||
@ -313,21 +348,9 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IDIsposable
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
ProfileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
|
|
||||||
ProfileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
|
|
||||||
if (SelectedProfileElement != null)
|
|
||||||
SelectedProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void ProfileEditorServiceOnProfileElementSelected(object? sender, RenderProfileElementEventArgs e)
|
private void ProfileEditorServiceOnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PreviousRenderProfileElement != null)
|
if (e.PreviousRenderProfileElement != null)
|
||||||
e.PreviousRenderProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
e.PreviousRenderProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
||||||
@ -347,34 +370,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
NotifyOfPropertyChange(nameof(RepeatSegment));
|
NotifyOfPropertyChange(nameof(RepeatSegment));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileEditorServiceOnPixelsPerSecondChanged(object? sender, EventArgs e)
|
private void ProfileEditorServiceOnPixelsPerSecondChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public void ShiftNextSegment(TimeSpan amount)
|
|
||||||
{
|
|
||||||
if (Segment == SegmentViewModelType.Start)
|
|
||||||
ShiftKeyframes(SelectedProfileElement.Timeline.StartSegmentEndPosition, null, amount);
|
|
||||||
else if (Segment == SegmentViewModelType.Main)
|
|
||||||
ShiftKeyframes(SelectedProfileElement.Timeline.MainSegmentEndPosition, null, amount);
|
|
||||||
else if (Segment == SegmentViewModelType.End)
|
|
||||||
ShiftKeyframes(SelectedProfileElement.Timeline.EndSegmentEndPosition, null, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WipeKeyframes(TimeSpan? start, TimeSpan? end)
|
|
||||||
{
|
|
||||||
foreach (LayerPropertyGroupViewModel layerPropertyGroupViewModel in LayerPropertyGroups)
|
|
||||||
layerPropertyGroupViewModel.WipeKeyframes(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShiftKeyframes(TimeSpan? start, TimeSpan? end, TimeSpan amount)
|
|
||||||
{
|
|
||||||
foreach (LayerPropertyGroupViewModel layerPropertyGroupViewModel in LayerPropertyGroups)
|
|
||||||
layerPropertyGroupViewModel.ShiftKeyframes(start, end, amount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SegmentViewModelType
|
public enum SegmentViewModelType
|
||||||
|
|||||||
@ -6,14 +6,13 @@ using System.Windows;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
using Artemis.Core;
|
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
||||||
{
|
{
|
||||||
public class TimelineViewModel : Screen, IDisposable
|
public sealed class TimelineViewModel : Screen, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private RectangleGeometry _selectionRectangle;
|
private RectangleGeometry _selectionRectangle;
|
||||||
@ -88,7 +87,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileEditorServiceOnProfileElementSelected(object? sender, RenderProfileElementEventArgs e)
|
private void ProfileEditorServiceOnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PreviousRenderProfileElement != null)
|
if (e.PreviousRenderProfileElement != null)
|
||||||
e.PreviousRenderProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
e.PreviousRenderProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
||||||
@ -98,6 +97,18 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_profileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
|
||||||
|
_profileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
|
||||||
|
if (_profileEditorService.SelectedProfileElement != null)
|
||||||
|
_profileEditorService.SelectedProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Command handlers
|
#region Command handlers
|
||||||
|
|
||||||
public void KeyframeMouseDown(object sender, MouseButtonEventArgs e)
|
public void KeyframeMouseDown(object sender, MouseButtonEventArgs e)
|
||||||
@ -105,8 +116,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
// if (e.LeftButton == MouseButtonState.Released)
|
// if (e.LeftButton == MouseButtonState.Released)
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
ITimelineKeyframeViewModel viewModel = (sender as Ellipse)?.DataContext as ITimelineKeyframeViewModel;
|
if (!((sender as Ellipse)?.DataContext is ITimelineKeyframeViewModel viewModel))
|
||||||
if (viewModel == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
((IInputElement) sender).CaptureMouse();
|
((IInputElement) sender).CaptureMouse();
|
||||||
@ -206,7 +216,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
keyframeViewModel.SaveOffsetToKeyframe(sourceKeyframeViewModel);
|
keyframeViewModel.SaveOffsetToKeyframe(sourceKeyframeViewModel);
|
||||||
|
|
||||||
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
|
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
|
||||||
{
|
|
||||||
cursorTime = _profileEditorService.SnapToTimeline(
|
cursorTime = _profileEditorService.SnapToTimeline(
|
||||||
cursorTime,
|
cursorTime,
|
||||||
TimeSpan.FromMilliseconds(1000f / _profileEditorService.PixelsPerSecond * 5),
|
TimeSpan.FromMilliseconds(1000f / _profileEditorService.PixelsPerSecond * 5),
|
||||||
@ -214,7 +223,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
false,
|
false,
|
||||||
keyframeViewModels.Where(k => k != sourceKeyframeViewModel).Select(k => k.Position).ToList()
|
keyframeViewModels.Where(k => k != sourceKeyframeViewModel).Select(k => k.Position).ToList()
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
sourceKeyframeViewModel.UpdatePosition(cursorTime);
|
sourceKeyframeViewModel.UpdatePosition(cursorTime);
|
||||||
|
|
||||||
@ -306,15 +314,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
|
|
||||||
int clickedIndex = keyframeViewModels.IndexOf(clicked);
|
int clickedIndex = keyframeViewModels.IndexOf(clicked);
|
||||||
if (clickedIndex < selectedIndex)
|
if (clickedIndex < selectedIndex)
|
||||||
{
|
|
||||||
foreach (ITimelineKeyframeViewModel keyframeViewModel in keyframeViewModels.Skip(clickedIndex).Take(selectedIndex - clickedIndex + 1))
|
foreach (ITimelineKeyframeViewModel keyframeViewModel in keyframeViewModels.Skip(clickedIndex).Take(selectedIndex - clickedIndex + 1))
|
||||||
keyframeViewModel.IsSelected = true;
|
keyframeViewModel.IsSelected = true;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
foreach (ITimelineKeyframeViewModel keyframeViewModel in keyframeViewModels.Skip(selectedIndex).Take(clickedIndex - selectedIndex + 1))
|
foreach (ITimelineKeyframeViewModel keyframeViewModel in keyframeViewModels.Skip(selectedIndex).Take(clickedIndex - selectedIndex + 1))
|
||||||
keyframeViewModel.IsSelected = true;
|
keyframeViewModel.IsSelected = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (toggle)
|
else if (toggle)
|
||||||
{
|
{
|
||||||
@ -340,17 +344,5 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IDisposable
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_profileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
|
|
||||||
_profileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
|
|
||||||
if (_profileEditorService.SelectedProfileElement != null)
|
|
||||||
_profileEditorService.SelectedProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
@ -8,7 +7,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
|
||||||
{
|
{
|
||||||
public class TreePropertyViewModel<T> : Screen, ITreePropertyViewModel
|
public sealed class TreePropertyViewModel<T> : Screen, ITreePropertyViewModel
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private PropertyInputViewModel<T> _propertyInputViewModel;
|
private PropertyInputViewModel<T> _propertyInputViewModel;
|
||||||
@ -26,7 +25,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
|
|||||||
LayerProperty.DataBindingDisabled += LayerPropertyOnDataBindingChange;
|
LayerProperty.DataBindingDisabled += LayerPropertyOnDataBindingChange;
|
||||||
LayerPropertyViewModel.IsVisible = !LayerProperty.IsHidden;
|
LayerPropertyViewModel.IsVisible = !LayerProperty.IsHidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LayerProperty<T> LayerProperty { get; }
|
public LayerProperty<T> LayerProperty { get; }
|
||||||
public LayerPropertyViewModel LayerPropertyViewModel { get; }
|
public LayerPropertyViewModel LayerPropertyViewModel { get; }
|
||||||
|
|
||||||
@ -36,22 +35,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
|
|||||||
set => SetAndNotify(ref _propertyInputViewModel, value);
|
set => SetAndNotify(ref _propertyInputViewModel, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasDataBinding => LayerProperty.HasDataBinding;
|
|
||||||
public double GetDepth()
|
|
||||||
{
|
|
||||||
int depth = 0;
|
|
||||||
LayerPropertyGroup current = LayerProperty.LayerPropertyGroup;
|
|
||||||
while (current != null)
|
|
||||||
{
|
|
||||||
depth++;
|
|
||||||
current = current.Parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasPropertyInputViewModel => PropertyInputViewModel != null;
|
|
||||||
|
|
||||||
public bool KeyframesEnabled
|
public bool KeyframesEnabled
|
||||||
{
|
{
|
||||||
get => LayerProperty.KeyframesEnabled;
|
get => LayerProperty.KeyframesEnabled;
|
||||||
@ -66,6 +49,42 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
|
|||||||
_profileEditorService.ChangeSelectedDataBinding(LayerProperty);
|
_profileEditorService.ChangeSelectedDataBinding(LayerProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ApplyKeyframesEnabled(bool enable)
|
||||||
|
{
|
||||||
|
// If enabling keyframes for the first time, add a keyframe with the current value at the current position
|
||||||
|
if (enable && !LayerProperty.Keyframes.Any())
|
||||||
|
LayerProperty.AddKeyframe(new LayerPropertyKeyframe<T>(
|
||||||
|
LayerProperty.CurrentValue,
|
||||||
|
_profileEditorService.CurrentTime,
|
||||||
|
Easings.Functions.Linear,
|
||||||
|
LayerProperty
|
||||||
|
));
|
||||||
|
// If disabling keyframes, set the base value to the current value
|
||||||
|
else if (!enable && LayerProperty.Keyframes.Any())
|
||||||
|
LayerProperty.BaseValue = LayerProperty.CurrentValue;
|
||||||
|
|
||||||
|
LayerProperty.KeyframesEnabled = enable;
|
||||||
|
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasDataBinding => LayerProperty.HasDataBinding;
|
||||||
|
|
||||||
|
public double GetDepth()
|
||||||
|
{
|
||||||
|
int depth = 0;
|
||||||
|
LayerPropertyGroup current = LayerProperty.LayerPropertyGroup;
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
depth++;
|
||||||
|
current = current.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasPropertyInputViewModel => PropertyInputViewModel != null;
|
||||||
|
|
||||||
#region IDisposable
|
#region IDisposable
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@ -79,27 +98,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void ApplyKeyframesEnabled(bool enable)
|
|
||||||
{
|
|
||||||
// If enabling keyframes for the first time, add a keyframe with the current value at the current position
|
|
||||||
if (enable && !LayerProperty.Keyframes.Any())
|
|
||||||
{
|
|
||||||
LayerProperty.AddKeyframe(new LayerPropertyKeyframe<T>(
|
|
||||||
LayerProperty.CurrentValue,
|
|
||||||
_profileEditorService.CurrentTime,
|
|
||||||
Easings.Functions.Linear,
|
|
||||||
LayerProperty
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// If disabling keyframes, set the base value to the current value
|
|
||||||
else if (!enable && LayerProperty.Keyframes.Any())
|
|
||||||
LayerProperty.BaseValue = LayerProperty.CurrentValue;
|
|
||||||
|
|
||||||
LayerProperty.KeyframesEnabled = enable;
|
|
||||||
|
|
||||||
_profileEditorService.UpdateSelectedProfileElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void ProfileEditorServiceOnSelectedDataBindingChanged(object sender, EventArgs e)
|
private void ProfileEditorServiceOnSelectedDataBindingChanged(object sender, EventArgs e)
|
||||||
@ -107,12 +105,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
|
|||||||
LayerPropertyViewModel.IsHighlighted = _profileEditorService.SelectedDataBinding == LayerProperty;
|
LayerPropertyViewModel.IsHighlighted = _profileEditorService.SelectedDataBinding == LayerProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerPropertyOnVisibilityChanged(object? sender, LayerPropertyEventArgs<T> e)
|
private void LayerPropertyOnVisibilityChanged(object sender, LayerPropertyEventArgs<T> e)
|
||||||
{
|
{
|
||||||
LayerPropertyViewModel.IsVisible = !LayerProperty.IsHidden;
|
LayerPropertyViewModel.IsVisible = !LayerProperty.IsHidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerPropertyOnDataBindingChange(object? sender, LayerPropertyEventArgs<T> e)
|
private void LayerPropertyOnDataBindingChange(object sender, LayerPropertyEventArgs<T> e)
|
||||||
{
|
{
|
||||||
NotifyOfPropertyChange(nameof(HasDataBinding));
|
NotifyOfPropertyChange(nameof(HasDataBinding));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,12 +21,11 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
|||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void CopyElement()
|
public void CopyElement()
|
||||||
{
|
{
|
||||||
Layer layer = Layer.CreateCopy();
|
Layer layer = Layer.CreateCopy();
|
||||||
|
|
||||||
_profileEditorService.UpdateSelectedProfile();
|
_profileEditorService.UpdateSelectedProfile();
|
||||||
// await Task.Delay(200);
|
|
||||||
_profileEditorService.ChangeSelectedProfileElement(layer);
|
_profileEditorService.ChangeSelectedProfileElement(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,9 +16,9 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
|||||||
public abstract class TreeItemViewModel : Conductor<TreeItemViewModel>.Collection.AllActive, IDisposable
|
public abstract class TreeItemViewModel : Conductor<TreeItemViewModel>.Collection.AllActive, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
|
private readonly ILayerBrushService _layerBrushService;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private readonly IProfileTreeVmFactory _profileTreeVmFactory;
|
private readonly IProfileTreeVmFactory _profileTreeVmFactory;
|
||||||
private readonly ILayerBrushService _layerBrushService;
|
|
||||||
private readonly ISurfaceService _surfaceService;
|
private readonly ISurfaceService _surfaceService;
|
||||||
private ProfileElement _profileElement;
|
private ProfileElement _profileElement;
|
||||||
|
|
||||||
@ -49,11 +49,6 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
|||||||
|
|
||||||
public abstract bool SupportsChildren { get; }
|
public abstract bool SupportsChildren { get; }
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TreeItemViewModel> GetAllChildren()
|
public List<TreeItemViewModel> GetAllChildren()
|
||||||
{
|
{
|
||||||
List<TreeItemViewModel> children = new List<TreeItemViewModel>();
|
List<TreeItemViewModel> children = new List<TreeItemViewModel>();
|
||||||
@ -142,7 +137,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
|||||||
Layer layer = new Layer(ProfileElement, "New layer");
|
Layer layer = new Layer(ProfileElement, "New layer");
|
||||||
|
|
||||||
// Could be null if the default brush got disabled
|
// Could be null if the default brush got disabled
|
||||||
LayerBrushDescriptor? brush = _layerBrushService.GetDefaultLayerBrush();
|
LayerBrushDescriptor brush = _layerBrushService.GetDefaultLayerBrush();
|
||||||
if (brush != null)
|
if (brush != null)
|
||||||
layer.ChangeLayerBrush(brush);
|
layer.ChangeLayerBrush(brush);
|
||||||
|
|
||||||
@ -212,7 +207,6 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
|||||||
|
|
||||||
List<TreeItemViewModel> newChildren = new List<TreeItemViewModel>();
|
List<TreeItemViewModel> newChildren = new List<TreeItemViewModel>();
|
||||||
foreach (ProfileElement profileElement in ProfileElement.Children.OrderBy(c => c.Order))
|
foreach (ProfileElement profileElement in ProfileElement.Children.OrderBy(c => c.Order))
|
||||||
{
|
|
||||||
if (profileElement is Folder folder)
|
if (profileElement is Folder folder)
|
||||||
{
|
{
|
||||||
if (Items.FirstOrDefault(p => p is FolderViewModel vm && vm.ProfileElement == folder) == null)
|
if (Items.FirstOrDefault(p => p is FolderViewModel vm && vm.ProfileElement == folder) == null)
|
||||||
@ -223,7 +217,6 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
|||||||
if (Items.FirstOrDefault(p => p is LayerViewModel vm && vm.ProfileElement == layer) == null)
|
if (Items.FirstOrDefault(p => p is LayerViewModel vm && vm.ProfileElement == layer) == null)
|
||||||
newChildren.Add(_profileTreeVmFactory.LayerViewModel(layer));
|
newChildren.Add(_profileTreeVmFactory.LayerViewModel(layer));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!newChildren.Any())
|
if (!newChildren.Any())
|
||||||
return;
|
return;
|
||||||
@ -262,5 +255,21 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
|||||||
{
|
{
|
||||||
UpdateProfileElements();
|
UpdateProfileElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing) Unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,7 +391,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
|
|||||||
UpdateCanSelectEditTool();
|
UpdateCanSelectEditTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TransformValueChanged(object? sender, LayerPropertyEventArgs e)
|
private void TransformValueChanged(object sender, LayerPropertyEventArgs e)
|
||||||
{
|
{
|
||||||
if (ActiveToolIndex != 1)
|
if (ActiveToolIndex != 1)
|
||||||
ActivateToolByIndex(1);
|
ActivateToolByIndex(1);
|
||||||
|
|||||||
@ -192,7 +192,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization.Tools
|
|||||||
height = layer.Transform.Scale.CurrentValue.Height;
|
height = layer.Transform.Scale.CurrentValue.Height;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException(nameof(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the sides even if shift is held down
|
// Make the sides even if shift is held down
|
||||||
@ -326,10 +326,14 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization.Tools
|
|||||||
{
|
{
|
||||||
// Keep the X position static if dragging vertically
|
// Keep the X position static if dragging vertically
|
||||||
if (_draggingVertically)
|
if (_draggingVertically)
|
||||||
|
{
|
||||||
position.X = _dragStart.X;
|
position.X = _dragStart.X;
|
||||||
|
}
|
||||||
// Keep the Y position static if dragging horizontally
|
// Keep the Y position static if dragging horizontally
|
||||||
else if (_draggingHorizontally)
|
else if (_draggingHorizontally)
|
||||||
|
{
|
||||||
position.Y = _dragStart.Y;
|
position.Y = _dragStart.Y;
|
||||||
|
}
|
||||||
// Snap into place only if the mouse moved atleast a full pixel
|
// Snap into place only if the mouse moved atleast a full pixel
|
||||||
else if (Math.Abs(position.X - _dragStart.X) > 1 || Math.Abs(position.Y - _dragStart.Y) > 1)
|
else if (Math.Abs(position.X - _dragStart.X) > 1 || Math.Abs(position.Y - _dragStart.Y) > 1)
|
||||||
{
|
{
|
||||||
@ -386,23 +390,23 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
#region Private methods
|
#region Private methods
|
||||||
|
|
||||||
private SKPoint RoundPoint(SKPoint point, int decimals)
|
private static SKPoint RoundPoint(SKPoint point, int decimals)
|
||||||
{
|
{
|
||||||
return new SKPoint((float) Math.Round(point.X, decimals, MidpointRounding.AwayFromZero), (float) Math.Round(point.Y, decimals, MidpointRounding.AwayFromZero));
|
return new SKPoint((float) Math.Round(point.X, decimals, MidpointRounding.AwayFromZero), (float) Math.Round(point.Y, decimals, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SKPoint[] UnTransformPoints(SKPoint[] skPoints, Layer layer, SKPoint pivot, bool includeScale)
|
private static SKPoint[] UnTransformPoints(SKPoint[] skPoints, Layer layer, SKPoint pivot, bool includeScale)
|
||||||
{
|
{
|
||||||
using SKPath counterRotatePath = new SKPath();
|
using SKPath counterRotatePath = new SKPath();
|
||||||
counterRotatePath.AddPoly(skPoints, false);
|
counterRotatePath.AddPoly(skPoints, false);
|
||||||
counterRotatePath.Transform(SKMatrix.MakeRotationDegrees(layer.Transform.Rotation.CurrentValue * -1, pivot.X, pivot.Y));
|
counterRotatePath.Transform(SKMatrix.CreateRotationDegrees(layer.Transform.Rotation.CurrentValue * -1, pivot.X, pivot.Y));
|
||||||
if (includeScale)
|
if (includeScale)
|
||||||
counterRotatePath.Transform(SKMatrix.MakeScale(1f / (layer.Transform.Scale.CurrentValue.Width / 100f), 1f / (layer.Transform.Scale.CurrentValue.Height / 100f)));
|
counterRotatePath.Transform(SKMatrix.CreateScale(1f / (layer.Transform.Scale.CurrentValue.Width / 100f), 1f / (layer.Transform.Scale.CurrentValue.Height / 100f)));
|
||||||
|
|
||||||
return counterRotatePath.Points;
|
return counterRotatePath.Points;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Point GetRelativePosition(object sender, MouseEventArgs mouseEventArgs)
|
private static Point GetRelativePosition(object sender, MouseEventArgs mouseEventArgs)
|
||||||
{
|
{
|
||||||
DependencyObject parent = VisualTreeHelper.GetParent((DependencyObject) sender);
|
DependencyObject parent = VisualTreeHelper.GetParent((DependencyObject) sender);
|
||||||
return mouseEventArgs.GetPosition((IInputElement) parent);
|
return mouseEventArgs.GetPosition((IInputElement) parent);
|
||||||
@ -410,7 +414,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
private float CalculateAngle(Layer layer, object mouseEventSender, MouseEventArgs mouseEvent)
|
private float CalculateAngle(Layer layer, object mouseEventSender, MouseEventArgs mouseEvent)
|
||||||
{
|
{
|
||||||
Rect layerBounds = _layerEditorService.GetLayerBounds(layer);
|
|
||||||
Point start = _layerEditorService.GetLayerAnchorPosition(layer);
|
Point start = _layerEditorService.GetLayerAnchorPosition(layer);
|
||||||
Point arrival = GetRelativePosition(mouseEventSender, mouseEvent);
|
Point arrival = GetRelativePosition(mouseEventSender, mouseEvent);
|
||||||
|
|
||||||
|
|||||||
@ -20,22 +20,22 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens
|
namespace Artemis.UI.Screens
|
||||||
{
|
{
|
||||||
public class RootViewModel : Conductor<IScreen>
|
public sealed class RootViewModel : Conductor<IScreen>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IRegistrationService _builtInRegistrationService;
|
private readonly IRegistrationService _builtInRegistrationService;
|
||||||
private readonly PluginSetting<ApplicationColorScheme> _colorScheme;
|
private readonly PluginSetting<ApplicationColorScheme> _colorScheme;
|
||||||
private readonly ICoreService _coreService;
|
private readonly ICoreService _coreService;
|
||||||
private readonly IDebugService _debugService;
|
private readonly IDebugService _debugService;
|
||||||
private readonly IEventAggregator _eventAggregator;
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private readonly Timer _frameTimeUpdateTimer;
|
||||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
||||||
private readonly ThemeWatcher _themeWatcher;
|
private readonly ThemeWatcher _themeWatcher;
|
||||||
private readonly Timer _frameTimeUpdateTimer;
|
|
||||||
private readonly PluginSetting<WindowSize> _windowSize;
|
private readonly PluginSetting<WindowSize> _windowSize;
|
||||||
private bool _activeItemReady;
|
private bool _activeItemReady;
|
||||||
|
private string _frameTime;
|
||||||
private bool _lostFocus;
|
private bool _lostFocus;
|
||||||
private ISnackbarMessageQueue _mainMessageQueue;
|
private ISnackbarMessageQueue _mainMessageQueue;
|
||||||
private string _windowTitle;
|
private string _windowTitle;
|
||||||
private string _frameTime;
|
|
||||||
|
|
||||||
public RootViewModel(
|
public RootViewModel(
|
||||||
IEventAggregator eventAggregator,
|
IEventAggregator eventAggregator,
|
||||||
@ -64,7 +64,7 @@ namespace Artemis.UI.Screens
|
|||||||
ActiveItem = SidebarViewModel.SelectedItem;
|
ActiveItem = SidebarViewModel.SelectedItem;
|
||||||
ActiveItemReady = true;
|
ActiveItemReady = true;
|
||||||
|
|
||||||
AssemblyInformationalVersionAttribute? versionAttribute = typeof(RootViewModel).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
|
AssemblyInformationalVersionAttribute versionAttribute = typeof(RootViewModel).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
|
||||||
WindowTitle = $"Artemis {versionAttribute?.InformationalVersion}";
|
WindowTitle = $"Artemis {versionAttribute?.InformationalVersion}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,19 +141,18 @@ namespace Artemis.UI.Screens
|
|||||||
|
|
||||||
private void UpdateFrameTime()
|
private void UpdateFrameTime()
|
||||||
{
|
{
|
||||||
|
|
||||||
FrameTime = $"Frame time: {_coreService.FrameTime.TotalMilliseconds:F2} ms";
|
FrameTime = $"Frame time: {_coreService.FrameTime.TotalMilliseconds:F2} ms";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SidebarViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
private void SidebarViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PropertyName == nameof(SidebarViewModel.SelectedItem) && ActiveItem != SidebarViewModel.SelectedItem)
|
if (e.PropertyName == nameof(SidebarViewModel.SelectedItem) && ActiveItem != SidebarViewModel.SelectedItem)
|
||||||
{
|
{
|
||||||
SidebarViewModel.IsSidebarOpen = false;
|
SidebarViewModel.IsSidebarOpen = false;
|
||||||
// Don't do a fade when selecting a module because the editor is so bulky the animation slows things down
|
// Don't do a fade when selecting a module because the editor is so bulky the animation slows things down
|
||||||
if (!(SidebarViewModel.SelectedItem is ModuleRootViewModel))
|
if (!(SidebarViewModel.SelectedItem is ModuleRootViewModel))
|
||||||
ActiveItemReady = false;
|
ActiveItemReady = false;
|
||||||
|
|
||||||
// Allow the menu to close, it's slower but feels more responsive, funny how that works right
|
// Allow the menu to close, it's slower but feels more responsive, funny how that works right
|
||||||
Execute.PostToUIThreadAsync(async () =>
|
Execute.PostToUIThreadAsync(async () =>
|
||||||
{
|
{
|
||||||
@ -209,13 +208,25 @@ namespace Artemis.UI.Screens
|
|||||||
ApplyColorSchemeSetting();
|
ApplyColorSchemeSetting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_frameTimeUpdateTimer?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Overrides of Screen
|
#region Overrides of Screen
|
||||||
|
|
||||||
protected override void OnViewLoaded()
|
protected override void OnViewLoaded()
|
||||||
{
|
{
|
||||||
MaterialWindow window = (MaterialWindow) View;
|
MaterialWindow window = (MaterialWindow) View;
|
||||||
if (_windowSize.Value != null)
|
if (_windowSize.Value != null)
|
||||||
|
{
|
||||||
_windowSize.Value.ApplyToWindow(window);
|
_windowSize.Value.ApplyToWindow(window);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_windowSize.Value = new WindowSize();
|
_windowSize.Value = new WindowSize();
|
||||||
@ -269,7 +280,7 @@ namespace Artemis.UI.Screens
|
|||||||
protected override void OnClose()
|
protected override void OnClose()
|
||||||
{
|
{
|
||||||
SidebarViewModel.Dispose();
|
SidebarViewModel.Dispose();
|
||||||
|
|
||||||
// Lets force the GC to run after closing the window so it is obvious to users watching task manager
|
// Lets force the GC to run after closing the window so it is obvious to users watching task manager
|
||||||
// that closing the UI will decrease the memory footprint of the application.
|
// that closing the UI will decrease the memory footprint of the application.
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
@ -10,14 +10,14 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||||
{
|
{
|
||||||
public class DataModelDebugViewModel : Screen
|
public sealed class DataModelDebugViewModel : Screen, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDataModelUIService _dataModelUIService;
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
private readonly Timer _updateTimer;
|
private readonly Timer _updateTimer;
|
||||||
|
|
||||||
private bool _isModuleFilterEnabled;
|
private bool _isModuleFilterEnabled;
|
||||||
private DataModelPropertiesViewModel _mainDataModel;
|
private DataModelPropertiesViewModel _mainDataModel;
|
||||||
private List<Module> _modules;
|
|
||||||
private string _propertySearch;
|
private string _propertySearch;
|
||||||
private Module _selectedModule;
|
private Module _selectedModule;
|
||||||
|
|
||||||
@ -69,6 +69,17 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Overrides of Screen
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnClose()
|
||||||
|
{
|
||||||
|
_updateTimer.Dispose();
|
||||||
|
base.OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
protected override void OnActivate()
|
protected override void OnActivate()
|
||||||
{
|
{
|
||||||
GetDataModel();
|
GetDataModel();
|
||||||
@ -126,5 +137,15 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
|||||||
else if (!SelectedModule.IsEnabled)
|
else if (!SelectedModule.IsEnabled)
|
||||||
SelectedModule = null;
|
SelectedModule = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_updateTimer?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11,7 +11,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
|
|||||||
{
|
{
|
||||||
private readonly ISettingsVmFactory _settingsVmFactory;
|
private readonly ISettingsVmFactory _settingsVmFactory;
|
||||||
private readonly ISurfaceService _surfaceService;
|
private readonly ISurfaceService _surfaceService;
|
||||||
private BindableCollection<DeviceSettingsViewModel> _deviceSettingsViewModels;
|
|
||||||
|
|
||||||
public DeviceSettingsTabViewModel(ISurfaceService surfaceService, ISettingsVmFactory settingsVmFactory)
|
public DeviceSettingsTabViewModel(ISurfaceService surfaceService, ISettingsVmFactory settingsVmFactory)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -125,34 +125,27 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
|
|
||||||
private PackIconKind GetIconKind()
|
private PackIconKind GetIconKind()
|
||||||
{
|
{
|
||||||
switch (Feature)
|
return Feature switch
|
||||||
{
|
{
|
||||||
case BaseDataModelExpansion _:
|
BaseDataModelExpansion => PackIconKind.TableAdd,
|
||||||
return PackIconKind.TableAdd;
|
DeviceProvider => PackIconKind.Devices,
|
||||||
case DeviceProvider _:
|
ProfileModule => PackIconKind.VectorRectangle,
|
||||||
return PackIconKind.Devices;
|
Module => PackIconKind.GearBox,
|
||||||
case ProfileModule _:
|
LayerBrushProvider => PackIconKind.Brush,
|
||||||
return PackIconKind.VectorRectangle;
|
LayerEffectProvider => PackIconKind.AutoAwesome,
|
||||||
case Module _:
|
_ => PackIconKind.Plugin
|
||||||
return PackIconKind.GearBox;
|
};
|
||||||
case LayerBrushProvider _:
|
|
||||||
return PackIconKind.Brush;
|
|
||||||
case LayerEffectProvider _:
|
|
||||||
return PackIconKind.AutoAwesome;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PackIconKind.Plugin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void OnFeatureEnabling(object? sender, PluginFeatureEventArgs e)
|
private void OnFeatureEnabling(object sender, PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PluginFeature != Feature) return;
|
if (e.PluginFeature != Feature) return;
|
||||||
Enabling = true;
|
Enabling = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFeatureEnableStopped(object? sender, PluginFeatureEventArgs e)
|
private void OnFeatureEnableStopped(object sender, PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PluginFeature != Feature) return;
|
if (e.PluginFeature != Feature) return;
|
||||||
Enabling = false;
|
Enabling = false;
|
||||||
|
|||||||
@ -146,14 +146,14 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
NotifyOfPropertyChange(nameof(CanOpenSettings));
|
NotifyOfPropertyChange(nameof(CanOpenSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PluginOnFeatureRemoved(object? sender, PluginFeatureEventArgs e)
|
private void PluginOnFeatureRemoved(object sender, PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
PluginFeatureViewModel viewModel = Items.FirstOrDefault(i => i.Feature == e.PluginFeature);
|
PluginFeatureViewModel viewModel = Items.FirstOrDefault(i => i.Feature == e.PluginFeature);
|
||||||
if (viewModel != null)
|
if (viewModel != null)
|
||||||
Items.Remove(viewModel);
|
Items.Remove(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PluginOnFeatureAdded(object? sender, PluginFeatureEventArgs e)
|
private void PluginOnFeatureAdded(object sender, PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(e.PluginFeature));
|
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(e.PluginFeature));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.Sidebar
|
namespace Artemis.UI.Screens.Sidebar
|
||||||
{
|
{
|
||||||
public class SidebarViewModel : PropertyChangedBase, IHandle<RequestSelectSidebarItemEvent>, IDisposable
|
public sealed class SidebarViewModel : PropertyChangedBase, IHandle<RequestSelectSidebarItemEvent>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly Timer _activeModulesUpdateTimer;
|
private readonly Timer _activeModulesUpdateTimer;
|
||||||
private readonly IKernel _kernel;
|
private readonly IKernel _kernel;
|
||||||
@ -196,16 +196,9 @@ namespace Artemis.UI.Screens.Sidebar
|
|||||||
|
|
||||||
#region IDisposable
|
#region IDisposable
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
_activeModulesUpdateTimer?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
_activeModulesUpdateTimer?.Dispose();
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -81,12 +81,12 @@ namespace Artemis.UI.Screens.Splash
|
|||||||
Status = "Enabling plugin: " + args.Plugin.Info.Name;
|
Status = "Enabling plugin: " + args.Plugin.Info.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PluginManagementServiceOnPluginFeatureEnabling(object? sender, PluginFeatureEventArgs e)
|
private void PluginManagementServiceOnPluginFeatureEnabling(object sender, PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
Status = "Enabling: " + e.PluginFeature.GetType().Name.Humanize();
|
Status = "Enabling: " + e.PluginFeature.GetType().Name.Humanize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PluginManagementServiceOnPluginFeatureEnabled(object? sender, PluginFeatureEventArgs e)
|
private void PluginManagementServiceOnPluginFeatureEnabled(object sender, PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
Status = "Initializing UI";
|
Status = "Initializing UI";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ using System.Windows.Media;
|
|||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Services.Interfaces;
|
using Artemis.UI.Services.Interfaces;
|
||||||
using Artemis.UI.Shared.Services;
|
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using SkiaSharp.Views.WPF;
|
using SkiaSharp.Views.WPF;
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ namespace Artemis.UI.Services
|
|||||||
{
|
{
|
||||||
private readonly ISettingsService _settingsService;
|
private readonly ISettingsService _settingsService;
|
||||||
|
|
||||||
public LayerEditorService(ISettingsService settingsService, IProfileEditorService profileEditorService)
|
public LayerEditorService(ISettingsService settingsService)
|
||||||
{
|
{
|
||||||
_settingsService = settingsService;
|
_settingsService = settingsService;
|
||||||
}
|
}
|
||||||
@ -93,11 +92,11 @@ namespace Artemis.UI.Services
|
|||||||
SKPath path = new SKPath();
|
SKPath path = new SKPath();
|
||||||
path.AddRect(layerBounds);
|
path.AddRect(layerBounds);
|
||||||
if (includeTranslation)
|
if (includeTranslation)
|
||||||
path.Transform(SKMatrix.MakeTranslation(x, y));
|
path.Transform(SKMatrix.CreateTranslation(x, y));
|
||||||
if (includeScale)
|
if (includeScale)
|
||||||
path.Transform(SKMatrix.MakeScale(layer.Transform.Scale.CurrentValue.Width / 100f, layer.Transform.Scale.CurrentValue.Height / 100f, anchorPosition.X, anchorPosition.Y));
|
path.Transform(SKMatrix.CreateScale(layer.Transform.Scale.CurrentValue.Width / 100f, layer.Transform.Scale.CurrentValue.Height / 100f, anchorPosition.X, anchorPosition.Y));
|
||||||
if (includeRotation)
|
if (includeRotation)
|
||||||
path.Transform(SKMatrix.MakeRotationDegrees(layer.Transform.Rotation.CurrentValue, anchorPosition.X, anchorPosition.Y));
|
path.Transform(SKMatrix.CreateRotationDegrees(layer.Transform.Rotation.CurrentValue, anchorPosition.X, anchorPosition.Y));
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@ -107,12 +106,10 @@ namespace Artemis.UI.Services
|
|||||||
{
|
{
|
||||||
double renderScale = _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
|
double renderScale = _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
|
||||||
if (absolute)
|
if (absolute)
|
||||||
{
|
|
||||||
return new SKPoint(
|
return new SKPoint(
|
||||||
100f / layer.Bounds.Width * ((float) (point.X * renderScale) - layer.Bounds.Left) / 100f,
|
100f / layer.Bounds.Width * ((float) (point.X * renderScale) - layer.Bounds.Left) / 100f,
|
||||||
100f / layer.Bounds.Height * ((float) (point.Y * renderScale) - layer.Bounds.Top) / 100f
|
100f / layer.Bounds.Height * ((float) (point.Y * renderScale) - layer.Bounds.Top) / 100f
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return new SKPoint(
|
return new SKPoint(
|
||||||
100f / layer.Bounds.Width * (float) (point.X * renderScale) / 100f,
|
100f / layer.Bounds.Width * (float) (point.X * renderScale) / 100f,
|
||||||
|
|||||||
@ -74,7 +74,7 @@ namespace Artemis.UI.Services
|
|||||||
_registeredBuiltInPropertyEditors = true;
|
_registeredBuiltInPropertyEditors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PluginServiceOnPluginLoaded(object? sender, PluginEventArgs e)
|
private void PluginServiceOnPluginLoaded(object sender, PluginEventArgs e)
|
||||||
{
|
{
|
||||||
e.Plugin.Kernel.Load(new[] {new PluginUIModule(e.Plugin)});
|
e.Plugin.Kernel.Load(new[] {new PluginUIModule(e.Plugin)});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
@ -26,7 +25,7 @@ namespace Artemis.UI.Stylet
|
|||||||
{
|
{
|
||||||
// If someone's calling us synchronously, and ValidationAsync does not complete synchronously,
|
// If someone's calling us synchronously, and ValidationAsync does not complete synchronously,
|
||||||
// we'll deadlock unless we continue on another thread.
|
// we'll deadlock unless we continue on another thread.
|
||||||
return (await _validator.ValidateAsync(_subject, CancellationToken.None, propertyName).ConfigureAwait(false))
|
return (await _validator.ValidateAsync(_subject, options => options.IncludeProperties(propertyName)).ConfigureAwait(false))
|
||||||
.Errors.Select(x => x.ErrorMessage);
|
.Errors.Select(x => x.ErrorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user