mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
130 lines
4.4 KiB
C#
130 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Data;
|
|
using System.Windows.Input;
|
|
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
|
|
using Artemis.UI.Shared.Exceptions;
|
|
using Stylet;
|
|
|
|
namespace Artemis.UI.Shared.DataModelVisualization
|
|
{
|
|
public abstract class DataModelInputViewModel<T> : DataModelInputViewModel
|
|
{
|
|
private T _inputValue;
|
|
|
|
protected DataModelInputViewModel(DataModelPropertyAttribute description, T initialValue)
|
|
{
|
|
Description = description;
|
|
InputValue = initialValue;
|
|
}
|
|
|
|
public T InputValue
|
|
{
|
|
get => _inputValue;
|
|
set => SetAndNotify(ref _inputValue, value);
|
|
}
|
|
|
|
public DataModelPropertyAttribute Description { get; }
|
|
internal override object InternalGuard { get; } = null;
|
|
|
|
/// <inheritdoc />
|
|
public sealed override void Submit()
|
|
{
|
|
foreach (var sourceUpdatingBinding in BindingOperations.GetSourceUpdatingBindings(View))
|
|
sourceUpdatingBinding.UpdateSource();
|
|
|
|
OnSubmit();
|
|
UpdateCallback(InputValue, true);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public sealed override void Cancel()
|
|
{
|
|
OnCancel();
|
|
UpdateCallback(InputValue, false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// May be called to convert an object to one of the types defined in CompatibleConversionTypes
|
|
/// </summary>
|
|
/// <param name="source">The object to convert, will always be of a type contained in CompatibleConversionTypes</param>
|
|
/// <returns>The converted value</returns>
|
|
protected virtual T ConvertToSupportedType(object source)
|
|
{
|
|
return default;
|
|
}
|
|
|
|
internal override object InternalConvertToSupportedType(object source)
|
|
{
|
|
if (CompatibleConversionTypes != null && CompatibleConversionTypes.Contains(source.GetType()))
|
|
return ConvertToSupportedType(source);
|
|
|
|
throw new ArtemisSharedUIException($"Cannot convert source of type {source.GetType().Name} because the data model input view model does not support it.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// For internal use only, implement <see cref="DataModelInputViewModel{T}" /> instead.
|
|
/// </summary>
|
|
public abstract class DataModelInputViewModel : PropertyChangedBase, IViewAware
|
|
{
|
|
/// <summary>
|
|
/// Prevents this type being implemented directly, implement <see cref="DataModelInputViewModel{T}" /> instead.
|
|
/// </summary>
|
|
// ReSharper disable once UnusedMember.Global
|
|
internal abstract object InternalGuard { get; }
|
|
|
|
internal Action<object, bool> UpdateCallback { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets the types this input view model can support through type conversion
|
|
/// </summary>
|
|
internal IReadOnlyCollection<Type> CompatibleConversionTypes { get; set; }
|
|
|
|
public void AttachView(UIElement view)
|
|
{
|
|
if (View != null)
|
|
throw new InvalidOperationException(string.Format("Tried to attach View {0} to ViewModel {1}, but it already has a view attached", view.GetType().Name, GetType().Name));
|
|
|
|
View = view;
|
|
|
|
// After the animation finishes attempt to focus the input field
|
|
Task.Run(async () =>
|
|
{
|
|
await Task.Delay(400);
|
|
await Execute.OnUIThreadAsync(() => View.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)));
|
|
});
|
|
}
|
|
|
|
public UIElement View { get; set; }
|
|
|
|
/// <summary>
|
|
/// Submits the input value and removes this view model
|
|
/// </summary>
|
|
public abstract void Submit();
|
|
|
|
/// <summary>
|
|
/// Discards changes to the input value and removes this view model
|
|
/// </summary>
|
|
public abstract void Cancel();
|
|
|
|
/// <summary>
|
|
/// Called before the current value is submitted
|
|
/// </summary>
|
|
protected virtual void OnSubmit()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called before the current value is discarded
|
|
/// </summary>
|
|
protected virtual void OnCancel()
|
|
{
|
|
}
|
|
|
|
internal abstract object InternalConvertToSupportedType(object source);
|
|
}
|
|
} |