1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Shared UI - Renamed DataModelVisualizationService

Databindings - Started on some basic UI elements
This commit is contained in:
Robert 2020-08-27 20:46:20 +02:00
parent babd862b40
commit a177188ce7
31 changed files with 423 additions and 185 deletions

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Artemis.Core.Events;
using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Storage.Entities.Profile;
@ -71,6 +72,9 @@ namespace Artemis.Core.Models.Profile.LayerProperties
/// </summary>
public bool IsCoreProperty { get; internal set; }
/// <summary>
/// Gets the description attribute applied to this property
/// </summary>
public PropertyDescriptionAttribute PropertyDescription { get; internal set; }
/// <summary>
@ -81,8 +85,21 @@ namespace Artemis.Core.Models.Profile.LayerProperties
internal PropertyEntity PropertyEntity { get; set; }
internal LayerPropertyGroup LayerPropertyGroup { get; set; }
/// <summary>
/// Overrides the property value with the default value
/// </summary>
public abstract void ApplyDefaultValue();
/// <summary>
/// Returns the type of the property
/// </summary>
public abstract Type GetPropertyType();
/// <summary>
/// Returns a list of properties to which data bindings can be applied
/// </summary>
/// <returns></returns>
public abstract List<PropertyInfo> GetDataBindingProperties();
/// <summary>
/// Applies the provided property entity to the layer property by deserializing the JSON base value and keyframe values

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Artemis.Core.Exceptions;
using Artemis.Core.Utilities;
using Artemis.Storage.Entities.Profile;
@ -166,12 +167,22 @@ namespace Artemis.Core.Models.Profile.LayerProperties
RemoveKeyframe(layerPropertyKeyframe);
}
/// <inheritdoc />
public override void ApplyDefaultValue()
{
BaseValue = DefaultValue;
CurrentValue = DefaultValue;
}
/// <inheritdoc />
public override Type GetPropertyType() => typeof(T);
/// <inheritdoc />
public override List<PropertyInfo> GetDataBindingProperties()
{
return new List<PropertyInfo> {GetType().GetProperty(nameof(CurrentValue))};
}
/// <summary>
/// Called every update (if keyframes are both supported and enabled) to determine the new <see cref="CurrentValue" />
/// based on the provided progress
@ -206,8 +217,8 @@ namespace Artemis.Core.Models.Profile.LayerProperties
else
{
var timeDiff = NextKeyframe.Position - CurrentKeyframe.Position;
var keyframeProgress = (float)((ProfileElement.TimelinePosition - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
var keyframeProgressEased = (float)Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
var keyframeProgress = (float) ((ProfileElement.TimelinePosition - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
var keyframeProgressEased = (float) Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
UpdateCurrentValue(keyframeProgress, keyframeProgressEased);
}
@ -245,7 +256,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
_keyframes.AddRange(entity.KeyframeEntities.Select(k => new LayerPropertyKeyframe<T>(
JsonConvert.DeserializeObject<T>(k.Value),
k.Position,
(Easings.Functions)k.EasingFunction,
(Easings.Functions) k.EasingFunction,
this
)));
}
@ -274,7 +285,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
{
Value = JsonConvert.SerializeObject(k.Value),
Position = k.Position,
EasingFunction = (int)k.EasingFunction
EasingFunction = (int) k.EasingFunction
}));
}
}

View File

@ -1,4 +1,7 @@
using SkiaSharp;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using SkiaSharp;
namespace Artemis.Core.Models.Profile.LayerProperties.Types
{
@ -20,5 +23,10 @@ namespace Artemis.Core.Models.Profile.LayerProperties.Types
var heightDiff = NextKeyframe.Value.Height - CurrentKeyframe.Value.Height;
CurrentValue = new SKSize(CurrentKeyframe.Value.Width + widthDiff * keyframeProgressEased, CurrentKeyframe.Value.Height + heightDiff * keyframeProgressEased);
}
public override List<PropertyInfo> GetDataBindingProperties()
{
return typeof(SKSize).GetProperties().ToList();
}
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
using Artemis.Core.Services.Interfaces;
namespace Artemis.Core.Services
{
public class DataBindingService : IDataBindingService
{
}
}

View File

@ -0,0 +1,6 @@
namespace Artemis.Core.Services.Interfaces
{
public interface IDataBindingService : IArtemisService
{
}
}

View File

@ -3,20 +3,21 @@ using System.Collections.Generic;
using Artemis.Core;
using Artemis.Core.Plugins;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Interfaces;
namespace Artemis.UI.Shared.DataModelVisualization
{
public class DataModelVisualizationRegistration
{
private readonly IDataModelVisualizationService _dataModelVisualizationService;
private readonly IDataModelUIService _dataModelUIService;
public DataModelVisualizationRegistration(IDataModelVisualizationService dataModelVisualizationService,
public DataModelVisualizationRegistration(IDataModelUIService dataModelUIService,
RegistrationType registrationType,
PluginInfo pluginInfo,
Type supportedType,
Type viewModelType)
{
_dataModelVisualizationService = dataModelVisualizationService;
_dataModelUIService = dataModelUIService;
RegistrationType = registrationType;
PluginInfo = pluginInfo;
SupportedType = supportedType;
@ -42,9 +43,9 @@ namespace Artemis.UI.Shared.DataModelVisualization
private void InstanceOnPluginDisabled(object sender, EventArgs e)
{
if (RegistrationType == RegistrationType.Input)
_dataModelVisualizationService.RemoveDataModelInput(this);
_dataModelUIService.RemoveDataModelInput(this);
else if (RegistrationType == RegistrationType.Display)
_dataModelVisualizationService.RemoveDataModelDisplay(this);
_dataModelUIService.RemoveDataModelDisplay(this);
}
}

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Reflection;
using Artemis.Core.Plugins.DataModelExpansions;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Interfaces;
namespace Artemis.UI.Shared.DataModelVisualization.Shared
{
@ -38,16 +39,16 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
public override string DisplayPropertyPath => null;
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
public override void Update(IDataModelUIService dataModelUIService)
{
// Display value gets updated by parent, don't do anything if it is null
if (DisplayValue == null)
return;
ListType = DisplayValue.GetType();
PopulateProperties(dataModelVisualizationService);
PopulateProperties(dataModelUIService);
foreach (var dataModelVisualizationViewModel in Children)
dataModelVisualizationViewModel.Update(dataModelVisualizationService);
dataModelVisualizationViewModel.Update(dataModelUIService);
}
public override object GetCurrentValue()
@ -55,14 +56,14 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
return DisplayValue;
}
private void PopulateProperties(IDataModelVisualizationService dataModelVisualizationService)
private void PopulateProperties(IDataModelUIService dataModelUIService)
{
if (Children.Any())
return;
foreach (var propertyInfo in ListType.GetProperties())
{
var child = CreateChild(dataModelVisualizationService, propertyInfo, GetChildDepth());
var child = CreateChild(dataModelUIService, propertyInfo, GetChildDepth());
if (child != null)
Children.Add(child);
}

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Reflection;
using Artemis.Core.Plugins.DataModelExpansions;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Interfaces;
namespace Artemis.UI.Shared.DataModelVisualization.Shared
{
@ -32,14 +33,14 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
return DisplayValue;
}
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
public override void Update(IDataModelUIService dataModelUIService)
{
// Display value gets updated by parent, don't do anything if it is null
if (DisplayValue == null)
return;
if (DisplayViewModel == null && dataModelVisualizationService.RegisteredDataModelDisplays.Any(d => d.SupportedType == DisplayValue.GetType()))
dataModelVisualizationService.GetDataModelDisplayViewModel(DisplayValue.GetType());
if (DisplayViewModel == null && dataModelUIService.RegisteredDataModelDisplays.Any(d => d.SupportedType == DisplayValue.GetType()))
dataModelUIService.GetDataModelDisplayViewModel(DisplayValue.GetType());
ListType = DisplayValue.GetType();
UpdateDisplayParameters();

View File

@ -4,6 +4,7 @@ using System.Reflection;
using Artemis.Core.Extensions;
using Artemis.Core.Plugins.DataModelExpansions;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Interfaces;
using Stylet;
namespace Artemis.UI.Shared.DataModelVisualization.Shared
@ -33,16 +34,16 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
set => SetAndNotify(ref _count, value);
}
public DataModelPropertiesViewModel GetListTypeViewModel(IDataModelVisualizationService dataModelVisualizationService)
public DataModelPropertiesViewModel GetListTypeViewModel(IDataModelUIService dataModelUIService)
{
// Create a property VM describing the type of the list
var viewModel = CreateListChild(dataModelVisualizationService, List.GetType().GenericTypeArguments[0]);
var viewModel = CreateListChild(dataModelUIService, List.GetType().GenericTypeArguments[0]);
// Put an empty value into the list type property view model
if (viewModel is DataModelListPropertiesViewModel dataModelListClassViewModel)
{
dataModelListClassViewModel.DisplayValue = Activator.CreateInstance(dataModelListClassViewModel.ListType);
dataModelListClassViewModel.Update(dataModelVisualizationService);
dataModelListClassViewModel.Update(dataModelUIService);
return dataModelListClassViewModel;
}
@ -57,7 +58,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
return null;
}
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
public override void Update(IDataModelUIService dataModelUIService)
{
if (Parent != null && !Parent.IsVisualizationExpanded)
return;
@ -72,7 +73,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
DataModelVisualizationViewModel child;
if (ListChildren.Count <= index)
{
child = CreateListChild(dataModelVisualizationService, item.GetType());
child = CreateListChild(dataModelUIService, item.GetType());
ListChildren.Add(child);
}
else
@ -89,7 +90,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
dataModelListPropertyViewModel.Index = index;
}
child.Update(dataModelVisualizationService);
child.Update(dataModelUIService);
index++;
}
@ -99,10 +100,10 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
Count = $"{ListChildren.Count} {(ListChildren.Count == 1 ? "item" : "items")}";
}
protected DataModelVisualizationViewModel CreateListChild(IDataModelVisualizationService dataModelVisualizationService, Type listType)
protected DataModelVisualizationViewModel CreateListChild(IDataModelUIService dataModelUIService, Type listType)
{
// If a display VM was found, prefer to use that in any case
var typeViewModel = dataModelVisualizationService.GetDataModelDisplayViewModel(listType);
var typeViewModel = dataModelUIService.GetDataModelDisplayViewModel(listType);
if (typeViewModel != null)
return new DataModelListPropertyViewModel(DataModel, this, PropertyInfo) {DisplayViewModel = typeViewModel};
// For primitives, create a property view model, it may be null that is fine

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Reflection;
using Artemis.Core.Plugins.DataModelExpansions;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Interfaces;
namespace Artemis.UI.Shared.DataModelVisualization.Shared
{
@ -12,17 +13,17 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
{
}
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
public override void Update(IDataModelUIService dataModelUIService)
{
// Always populate properties
PopulateProperties(dataModelVisualizationService);
PopulateProperties(dataModelUIService);
// Only update children if the parent is expanded
if (Parent != null && !Parent.IsVisualizationExpanded && !Parent.IsRootViewModel)
return;
foreach (var dataModelVisualizationViewModel in Children)
dataModelVisualizationViewModel.Update(dataModelVisualizationService);
dataModelVisualizationViewModel.Update(dataModelUIService);
}
public override object GetCurrentValue()
@ -30,7 +31,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
return Parent.IsRootViewModel ? DataModel : base.GetCurrentValue();
}
private void PopulateProperties(IDataModelVisualizationService dataModelVisualizationService)
private void PopulateProperties(IDataModelUIService dataModelUIService)
{
if (IsRootViewModel)
return;
@ -42,7 +43,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
if (Children.Any(c => c.PropertyInfo.Equals(propertyInfo)))
continue;
var child = CreateChild(dataModelVisualizationService, propertyInfo, GetChildDepth());
var child = CreateChild(dataModelUIService, propertyInfo, GetChildDepth());
if (child != null)
Children.Add(child);
}

View File

@ -2,6 +2,7 @@
using System.Reflection;
using Artemis.Core.Plugins.DataModelExpansions;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Interfaces;
namespace Artemis.UI.Shared.DataModelVisualization.Shared
{
@ -47,13 +48,13 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
set => SetAndNotify(ref _showViewModel, value);
}
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
public override void Update(IDataModelUIService dataModelUIService)
{
if (Parent != null && !Parent.IsVisualizationExpanded && !Parent.IsRootViewModel)
return;
if (DisplayViewModel == null && dataModelVisualizationService.RegisteredDataModelDisplays.Any(d => d.SupportedType == PropertyInfo.PropertyType))
dataModelVisualizationService.GetDataModelDisplayViewModel(PropertyInfo.PropertyType);
if (DisplayViewModel == null && dataModelUIService.RegisteredDataModelDisplays.Any(d => d.SupportedType == PropertyInfo.PropertyType))
dataModelUIService.GetDataModelDisplayViewModel(PropertyInfo.PropertyType);
DisplayValue = GetCurrentValue();
UpdateDisplayParameters();

View File

@ -10,6 +10,7 @@ using Artemis.Core.Plugins.DataModelExpansions;
using Artemis.Core.Plugins.DataModelExpansions.Attributes;
using Artemis.UI.Shared.Exceptions;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Interfaces;
using Humanizer;
using Stylet;
@ -122,8 +123,8 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
/// <summary>
/// Updates the datamodel and if in an parent, any children
/// </summary>
/// <param name="dataModelVisualizationService"></param>
public abstract void Update(IDataModelVisualizationService dataModelVisualizationService);
/// <param name="dataModelUIService"></param>
public abstract void Update(IDataModelUIService dataModelUIService);
public virtual object GetCurrentValue()
{
@ -230,7 +231,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
}
}
protected DataModelVisualizationViewModel CreateChild(IDataModelVisualizationService dataModelVisualizationService, PropertyInfo propertyInfo, int depth)
protected DataModelVisualizationViewModel CreateChild(IDataModelUIService dataModelUIService, PropertyInfo propertyInfo, int depth)
{
if (depth > MaxDepth)
return null;
@ -242,7 +243,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
return null;
// If a display VM was found, prefer to use that in any case
var typeViewModel = dataModelVisualizationService.GetDataModelDisplayViewModel(propertyInfo.PropertyType);
var typeViewModel = dataModelUIService.GetDataModelDisplayViewModel(propertyInfo.PropertyType);
if (typeViewModel != null)
return new DataModelPropertyViewModel(DataModel, this, propertyInfo) {DisplayViewModel = typeViewModel, Depth = depth};
// For primitives, create a property view model, it may be null that is fine

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using Artemis.UI.Shared.Services.Interfaces;
namespace Artemis.UI.Shared.Services
{
public class DataBindingUIService : IDataBindingUIService
{
public object GetDataBindingViewModel(Type propertyType)
{
return null;
}
}
}

View File

@ -1,30 +1,26 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Artemis.Core.Extensions;
using Artemis.Core.Plugins;
using Artemis.Core.Plugins.DataModelExpansions.Attributes;
using Artemis.Core.Plugins.Exceptions;
using Artemis.Core.Services.Interfaces;
using Artemis.UI.Shared.DataModelVisualization;
using Artemis.UI.Shared.DataModelVisualization.Shared;
using Artemis.UI.Shared.Services.DataModelVisualization;
using Artemis.UI.Shared.Services.Interfaces;
using Ninject;
using Ninject.Parameters;
using Stylet;
namespace Artemis.UI.Shared.Services
{
internal class DataModelVisualizationService : IDataModelVisualizationService
internal class DataModelUIService : IDataModelUIService
{
private readonly IDataModelService _dataModelService;
private readonly IKernel _kernel;
private readonly List<DataModelVisualizationRegistration> _registeredDataModelDisplays;
private readonly List<DataModelVisualizationRegistration> _registeredDataModelEditors;
public DataModelVisualizationService(IDataModelService dataModelService, IKernel kernel)
public DataModelUIService(IDataModelService dataModelService, IKernel kernel)
{
_dataModelService = dataModelService;
_kernel = kernel;
@ -61,18 +57,7 @@ namespace Artemis.UI.Shared.Services
viewModel.UpdateRequested += (sender, args) => viewModel.Update(this);
return viewModel;
}
// public DataModelPropertiesViewModel GetListDataModelVisualization(IList list)
// {
// var viewModel = new DataModelPropertiesViewModel(null, null, null);
// viewModel.Children.Add(new DataModelListPropertiesViewModel(null, viewModel, null) {DisplayValue = list});
//
// // Update to populate children
// viewModel.Update(this);
// viewModel.UpdateRequested += (sender, args) => viewModel.Update(this);
// return viewModel;
// }
public bool GetPluginExtendsDataModel(Plugin plugin)
{
return _dataModelService.GetPluginExtendsDataModel(plugin);
@ -90,8 +75,11 @@ namespace Artemis.UI.Shared.Services
if (existing != null)
{
if (existing.PluginInfo != pluginInfo)
{
throw new ArtemisPluginException($"Cannot register data model input for type {supportedType.Name} " +
$"because an editor was already registered by {pluginInfo.Name}");
}
return existing;
}
@ -119,8 +107,11 @@ namespace Artemis.UI.Shared.Services
if (existing != null)
{
if (existing.PluginInfo != pluginInfo)
{
throw new ArtemisPluginException($"Cannot register data model display for type {supportedType.Name} " +
$"because an editor was already registered by {pluginInfo.Name}");
}
return existing;
}
@ -214,27 +205,4 @@ namespace Artemis.UI.Shared.Services
return viewModel;
}
}
public interface IDataModelVisualizationService : IArtemisSharedUIService
{
DataModelPropertiesViewModel GetMainDataModelVisualization();
DataModelPropertiesViewModel GetPluginDataModelVisualization(Plugin plugin);
/// <summary>
/// Determines whether the given plugin expands the main data model
/// </summary>
/// <param name="plugin"></param>
/// <returns></returns>
bool GetPluginExtendsDataModel(Plugin plugin);
DataModelVisualizationRegistration RegisterDataModelInput<T>(PluginInfo pluginInfo, IReadOnlyCollection<Type> compatibleConversionTypes) where T : DataModelInputViewModel;
DataModelVisualizationRegistration RegisterDataModelDisplay<T>(PluginInfo pluginInfo) where T : DataModelDisplayViewModel;
void RemoveDataModelInput(DataModelVisualizationRegistration registration);
void RemoveDataModelDisplay(DataModelVisualizationRegistration registration);
DataModelDisplayViewModel GetDataModelDisplayViewModel(Type propertyType);
DataModelInputViewModel GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute description, object initialValue, Action<object, bool> updateCallback);
IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelEditors { get; }
IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelDisplays { get; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using Artemis.Core.Services.Interfaces;
namespace Artemis.UI.Shared.Services.Interfaces
{
public interface IDataBindingUIService : IArtemisSharedUIService
{
object GetDataBindingViewModel(Type propertyType);
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using Artemis.Core.Plugins;
using Artemis.Core.Plugins.DataModelExpansions.Attributes;
using Artemis.UI.Shared.DataModelVisualization;
using Artemis.UI.Shared.DataModelVisualization.Shared;
namespace Artemis.UI.Shared.Services.Interfaces
{
public interface IDataModelUIService : IArtemisSharedUIService
{
DataModelPropertiesViewModel GetMainDataModelVisualization();
DataModelPropertiesViewModel GetPluginDataModelVisualization(Plugin plugin);
/// <summary>
/// Determines whether the given plugin expands the main data model
/// </summary>
/// <param name="plugin"></param>
/// <returns></returns>
bool GetPluginExtendsDataModel(Plugin plugin);
DataModelVisualizationRegistration RegisterDataModelInput<T>(PluginInfo pluginInfo, IReadOnlyCollection<Type> compatibleConversionTypes) where T : DataModelInputViewModel;
DataModelVisualizationRegistration RegisterDataModelDisplay<T>(PluginInfo pluginInfo) where T : DataModelDisplayViewModel;
void RemoveDataModelInput(DataModelVisualizationRegistration registration);
void RemoveDataModelDisplay(DataModelVisualizationRegistration registration);
DataModelDisplayViewModel GetDataModelDisplayViewModel(Type propertyType);
DataModelInputViewModel GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute description, object initialValue, Action<object, bool> updateCallback);
IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelEditors { get; }
IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelDisplays { get; }
}
}

View File

@ -14,15 +14,16 @@ namespace Artemis.UI.Shared.Services.Interfaces
{
Profile SelectedProfile { get; }
RenderProfileElement SelectedProfileElement { get; }
BaseLayerProperty SelectedDataBinding { get; }
TimeSpan CurrentTime { get; set; }
int PixelsPerSecond { get; set; }
IReadOnlyList<PropertyInputRegistration> RegisteredPropertyEditors { get; }
IKernel Kernel { get; }
void ChangeSelectedProfile(Profile profile);
void UpdateSelectedProfile();
void ChangeSelectedProfileElement(RenderProfileElement profileElement);
void UpdateSelectedProfileElement();
void ChangeSelectedDataBinding(BaseLayerProperty layerProperty);
void UpdateProfilePreview();
bool UndoUpdateProfile();
bool RedoUpdateProfile();
@ -48,6 +49,11 @@ namespace Artemis.UI.Shared.Services.Interfaces
/// </summary>
event EventHandler<RenderProfileElementEventArgs> SelectedProfileElementUpdated;
/// <summary>
/// Occurs when the currently selected data binding layer property is changed
/// </summary>
event EventHandler SelectedDataBindingChanged;
/// <summary>
/// Occurs when the current editor time is changed
/// </summary>
@ -86,5 +92,5 @@ namespace Artemis.UI.Shared.Services.Interfaces
/// <param name="excludedKeyframe">A keyframe to exclude during keyframe snapping</param>
/// <returns></returns>
TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, bool snapToKeyframes, BaseLayerPropertyKeyframe excludedKeyframe = null);
}
}
}

View File

@ -41,6 +41,7 @@ namespace Artemis.UI.Shared.Services
public IReadOnlyList<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
public Profile SelectedProfile { get; private set; }
public RenderProfileElement SelectedProfileElement { get; private set; }
public BaseLayerProperty SelectedDataBinding { get; private set; }
public TimeSpan CurrentTime
{
@ -131,6 +132,12 @@ namespace Artemis.UI.Shared.Services
}
}
public void ChangeSelectedDataBinding(BaseLayerProperty layerProperty)
{
SelectedDataBinding = layerProperty;
OnSelectedDataBindingChanged();
}
public void UpdateProfilePreview()
{
if (SelectedProfile == null)
@ -276,6 +283,7 @@ namespace Artemis.UI.Shared.Services
public event EventHandler<ProfileEventArgs> SelectedProfileUpdated;
public event EventHandler<RenderProfileElementEventArgs> ProfileElementSelected;
public event EventHandler<RenderProfileElementEventArgs> SelectedProfileElementUpdated;
public event EventHandler SelectedDataBindingChanged;
public event EventHandler CurrentTimeChanged;
public event EventHandler PixelsPerSecondChanged;
public event EventHandler ProfilePreviewUpdated;
@ -325,5 +333,10 @@ namespace Artemis.UI.Shared.Services
{
Execute.PostToUIThread(() => ChangeSelectedProfile(null));
}
protected virtual void OnSelectedDataBindingChanged()
{
SelectedDataBindingChanged?.Invoke(this, EventArgs.Empty);
}
}
}

View File

@ -24,7 +24,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public class DisplayConditionListPredicateViewModel : DisplayConditionViewModel, IHandle<MainWindowKeyEvent>, IHandle<MainWindowMouseEvent>
{
private readonly IDataModelService _dataModelService;
private readonly IDataModelVisualizationService _dataModelVisualizationService;
private readonly IDataModelUIService _dataModelUIService;
private readonly IEventAggregator _eventAggregator;
private readonly IProfileEditorService _profileEditorService;
private readonly Timer _updateTimer;
@ -45,13 +45,13 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
DisplayConditionListPredicate displayConditionListPredicate,
DisplayConditionViewModel parent,
IProfileEditorService profileEditorService,
IDataModelVisualizationService dataModelVisualizationService,
IDataModelUIService dataModelUIService,
IDataModelService dataModelService,
ISettingsService settingsService,
IEventAggregator eventAggregator) : base(displayConditionListPredicate, parent)
{
_profileEditorService = profileEditorService;
_dataModelVisualizationService = dataModelVisualizationService;
_dataModelUIService = dataModelUIService;
_dataModelService = dataModelService;
_eventAggregator = eventAggregator;
_updateTimer = new Timer(500);
@ -180,7 +180,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
RightSideDataModel.UpdateRequested += RightDataModelUpdateRequested;
// Determine which types are currently supported
var editors = _dataModelVisualizationService.RegisteredDataModelEditors;
var editors = _dataModelUIService.RegisteredDataModelEditors;
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
@ -272,7 +272,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
return;
RightSideTransitionIndex = 1;
RightSideInputViewModel = _dataModelVisualizationService.GetDataModelInputViewModel(
RightSideInputViewModel = _dataModelUIService.GetDataModelInputViewModel(
SelectedLeftSideProperty.PropertyInfo.PropertyType,
SelectedLeftSideProperty.PropertyDescription,
DisplayConditionListPredicate.RightStaticValue,
@ -290,9 +290,9 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
{
if (LeftSideDataModelOpen)
LeftSideDataModel.Update(_dataModelVisualizationService);
LeftSideDataModel.Update(_dataModelUIService);
else if (RightSideDataModelOpen)
RightSideDataModel.Update(_dataModelVisualizationService);
RightSideDataModel.Update(_dataModelUIService);
}
private void RightDataModelUpdateRequested(object sender, EventArgs e)
@ -319,16 +319,16 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
if (DisplayConditionListPredicate.ListDataModel == null || DisplayConditionListPredicate.ListPropertyPath == null)
throw new ArtemisUIException("Cannot create a list predicate without first selecting a target list");
var dataModel = _dataModelVisualizationService.GetMainDataModelVisualization();
if (!_dataModelVisualizationService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule()))
dataModel.Children.Add(_dataModelVisualizationService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
var dataModel = _dataModelUIService.GetMainDataModelVisualization();
if (!_dataModelUIService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule()))
dataModel.Children.Add(_dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
var listDataModel = (DataModelListViewModel) dataModel.GetChildByPath(
DisplayConditionListPredicate.ListDataModel.PluginInfo.Guid,
DisplayConditionListPredicate.ListPropertyPath
);
return listDataModel.GetListTypeViewModel(_dataModelVisualizationService);
return listDataModel.GetListTypeViewModel(_dataModelUIService);
}
private void ExecuteSelectLeftProperty(object context)

View File

@ -19,7 +19,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public class DisplayConditionListViewModel : DisplayConditionViewModel
{
private readonly IProfileEditorService _profileEditorService;
private readonly IDataModelVisualizationService _dataModelVisualizationService;
private readonly IDataModelUIService _dataModelUIService;
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
private bool _isInitialized;
private DataModelListViewModel _selectedListProperty;
@ -30,12 +30,12 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
DisplayConditionList displayConditionList,
DisplayConditionViewModel parent,
IProfileEditorService profileEditorService,
IDataModelVisualizationService dataModelVisualizationService,
IDataModelUIService dataModelUIService,
IDisplayConditionsVmFactory displayConditionsVmFactory,
ISettingsService settingsService) : base(displayConditionList, parent)
{
_profileEditorService = profileEditorService;
_dataModelVisualizationService = dataModelVisualizationService;
_dataModelUIService = dataModelUIService;
_displayConditionsVmFactory = displayConditionsVmFactory;
_updateTimer = new Timer(500);
@ -111,9 +111,9 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public void Initialize()
{
// Get the data models
TargetDataModel = _dataModelVisualizationService.GetMainDataModelVisualization();
if (!_dataModelVisualizationService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule()))
TargetDataModel.Children.Add(_dataModelVisualizationService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
TargetDataModel = _dataModelUIService.GetMainDataModelVisualization();
if (!_dataModelUIService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule()))
TargetDataModel.Children.Add(_dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
TargetDataModel.UpdateRequested += TargetDataModelUpdateRequested;
@ -135,8 +135,8 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
{
if (TargetDataModelOpen)
{
TargetDataModel?.Update(_dataModelVisualizationService);
SelectedListProperty?.Update(_dataModelVisualizationService);
TargetDataModel?.Update(_dataModelUIService);
SelectedListProperty?.Update(_dataModelUIService);
}
}

View File

@ -23,7 +23,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public class DisplayConditionPredicateViewModel : DisplayConditionViewModel, IHandle<MainWindowKeyEvent>, IHandle<MainWindowMouseEvent>
{
private readonly IDataModelService _dataModelService;
private readonly IDataModelVisualizationService _dataModelVisualizationService;
private readonly IDataModelUIService _dataModelUIService;
private readonly IEventAggregator _eventAggregator;
private readonly IProfileEditorService _profileEditorService;
private bool _isInitialized;
@ -44,13 +44,13 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
DisplayConditionPredicate displayConditionPredicate,
DisplayConditionViewModel parent,
IProfileEditorService profileEditorService,
IDataModelVisualizationService dataModelVisualizationService,
IDataModelUIService dataModelUIService,
IDataModelService dataModelService,
ISettingsService settingsService,
IEventAggregator eventAggregator) : base(displayConditionPredicate, parent)
{
_profileEditorService = profileEditorService;
_dataModelVisualizationService = dataModelVisualizationService;
_dataModelUIService = dataModelUIService;
_dataModelService = dataModelService;
_eventAggregator = eventAggregator;
_updateTimer = new Timer(500);
@ -173,16 +173,16 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public void Initialize()
{
// Get the data models
LeftSideDataModel = _dataModelVisualizationService.GetMainDataModelVisualization();
RightSideDataModel = _dataModelVisualizationService.GetMainDataModelVisualization();
if (!_dataModelVisualizationService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule()))
LeftSideDataModel = _dataModelUIService.GetMainDataModelVisualization();
RightSideDataModel = _dataModelUIService.GetMainDataModelVisualization();
if (!_dataModelUIService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule()))
{
LeftSideDataModel.Children.Add(_dataModelVisualizationService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
RightSideDataModel.Children.Add(_dataModelVisualizationService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
LeftSideDataModel.Children.Add(_dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
RightSideDataModel.Children.Add(_dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
}
// Determine which types are currently supported
var editors = _dataModelVisualizationService.RegisteredDataModelEditors;
var editors = _dataModelUIService.RegisteredDataModelEditors;
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
@ -274,7 +274,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
return;
RightSideTransitionIndex = 1;
RightSideInputViewModel = _dataModelVisualizationService.GetDataModelInputViewModel(
RightSideInputViewModel = _dataModelUIService.GetDataModelInputViewModel(
SelectedLeftSideProperty.PropertyInfo.PropertyType,
SelectedLeftSideProperty.PropertyDescription,
DisplayConditionPredicate.RightStaticValue,
@ -292,9 +292,9 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
{
if (LeftSideDataModelOpen)
LeftSideDataModel.Update(_dataModelVisualizationService);
LeftSideDataModel.Update(_dataModelUIService);
else if (RightSideDataModelOpen)
RightSideDataModel.Update(_dataModelVisualizationService);
RightSideDataModel.Update(_dataModelUIService);
}
private void RightDataModelUpdateRequested(object sender, EventArgs e)

View File

@ -0,0 +1,12 @@
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DataBindingsTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
</Grid>
</UserControl>

View File

@ -0,0 +1,20 @@
using System.Reflection;
using Artemis.Core.Models.Profile.LayerProperties;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
public class DataBindingsTabViewModel : PropertyChangedBase
{
public DataBindingsTabViewModel(BaseLayerProperty layerProperty, PropertyInfo dataBindingProperty)
{
DisplayName = dataBindingProperty.Name.ToUpper();
LayerProperty = layerProperty;
DataBindingProperty = dataBindingProperty;
}
public string DisplayName { get; }
public BaseLayerProperty LayerProperty { get; }
public PropertyInfo DataBindingProperty { get; }
}
}

View File

@ -0,0 +1,24 @@
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DataBindingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:DataBindingsViewModel}">
<TabControl Margin="0 -1 0 0"
ItemsSource="{Binding Tabs}"
DisplayMemberPath="DisplayName"
Style="{StaticResource MaterialDesignTabControl}">
<TabControl.ContentTemplate>
<DataTemplate>
<materialDesign:TransitioningContent OpeningEffect="{materialDesign:TransitionEffect FadeIn}">
<ContentControl s:View.Model="{Binding}" TextElement.Foreground="{DynamicResource MaterialDesignBody}" />
</materialDesign:TransitioningContent>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</UserControl>

View File

@ -0,0 +1,25 @@
using Artemis.Core.Models.Profile.LayerProperties;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
public class DataBindingsViewModel : PropertyChangedBase
{
public DataBindingsViewModel(BaseLayerProperty layerProperty)
{
Tabs = new BindableCollection<DataBindingsTabViewModel>();
LayerProperty = layerProperty;
Initialise();
}
public BindableCollection<DataBindingsTabViewModel> Tabs { get; set; }
public BaseLayerProperty LayerProperty { get; }
private void Initialise()
{
foreach (var dataBindingProperty in LayerProperty.GetDataBindingProperties())
Tabs.Add(new DataBindingsTabViewModel(LayerProperty, dataBindingProperty));
}
}
}

View File

@ -147,7 +147,7 @@
<Grid>
<ContentControl s:View.Model="{Binding EffectsViewModel}" />
<!-- Transitions only work when the command comes from inside the transitioner but we want the button outside,
by setting the command target to this hidden button we cercumvent that -->
by setting the command target to this hidden button we circumvent that -->
<Button x:Name="TransitionCommandAnchor"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
@ -164,58 +164,35 @@
<GridSplitter Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Width="15" HorizontalAlignment="Stretch" Cursor="SizeWE" Margin="-15 0" Background="Transparent" />
<!-- Right side -->
<Grid Grid.Row="0" Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="56" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<materialDesign:Transitioner Grid.Row="0"
Grid.Column="2"
x:Name="RightSideTransitioner"
SelectedIndex="{Binding RightSideIndex}"
DefaultTransitionOrigin="0, 0.5"
AutoApplyTransitionOrigins="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="56" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Timeline headers -->
<ScrollViewer Grid.Row="0" x:Name="TimelineHeaderScrollViewer" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" ScrollChanged="TimelineScrollChanged">
<Canvas Background="{DynamicResource MaterialDesignCardBackground}" Width="{Binding ActualWidth, ElementName=PropertyTimeLine}">
<!-- Timeline segments -->
<ContentControl Canvas.Left="{Binding EndTimelineSegmentViewModel.SegmentStartPosition}" s:View.Model="{Binding EndTimelineSegmentViewModel}" />
<ContentControl Canvas.Left="{Binding MainTimelineSegmentViewModel.SegmentStartPosition}" s:View.Model="{Binding MainTimelineSegmentViewModel}" />
<ContentControl Canvas.Left="{Binding StartTimelineSegmentViewModel.SegmentStartPosition}" s:View.Model="{Binding StartTimelineSegmentViewModel}" />
<!-- Timeline headers -->
<ScrollViewer Grid.Row="0" x:Name="TimelineHeaderScrollViewer" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" ScrollChanged="TimelineScrollChanged">
<Canvas Background="{DynamicResource MaterialDesignCardBackground}" Width="{Binding ActualWidth, ElementName=PropertyTimeLine}">
<!-- Timeline segments -->
<ContentControl Canvas.Left="{Binding EndTimelineSegmentViewModel.SegmentStartPosition}" s:View.Model="{Binding EndTimelineSegmentViewModel}" />
<ContentControl Canvas.Left="{Binding MainTimelineSegmentViewModel.SegmentStartPosition}" s:View.Model="{Binding MainTimelineSegmentViewModel}" />
<ContentControl Canvas.Left="{Binding StartTimelineSegmentViewModel.SegmentStartPosition}" s:View.Model="{Binding StartTimelineSegmentViewModel}" />
<!-- Timeline caret -->
<Polygon Canvas.Left="{Binding TimeCaretPosition}"
Cursor="SizeWE"
MouseDown="{s:Action TimelineMouseDown}"
MouseUp="{s:Action TimelineMouseUp}"
MouseMove="{s:Action TimelineMouseMove}"
Points="-8,0 -8,8 0,20, 8,8 8,0"
Fill="{StaticResource SecondaryAccentBrush}" />
<Line Canvas.Left="{Binding TimeCaretPosition}"
Cursor="SizeWE"
MouseDown="{s:Action TimelineMouseDown}"
MouseUp="{s:Action TimelineMouseUp}"
MouseMove="{s:Action TimelineMouseMove}"
X1="0"
X2="0"
Y1="0"
Y2="{Binding ActualHeight, ElementName=ContainerGrid}"
StrokeThickness="2"
Stroke="{StaticResource SecondaryAccentBrush}" />
<!-- Timeline header body -->
<controls:PropertyTimelineHeader Margin="0 25 0 0"
Fill="{DynamicResource MaterialDesignBody}"
PixelsPerSecond="{Binding ProfileEditorService.PixelsPerSecond}"
HorizontalOffset="{Binding ContentHorizontalOffset, ElementName=TimelineHeaderScrollViewer}"
VisibleWidth="{Binding ActualWidth, ElementName=TimelineHeaderScrollViewer}"
OffsetFirstValue="True"
Width="{Binding ActualWidth, ElementName=PropertyTimeLine}" />
</Canvas>
</ScrollViewer>
<!-- Timeline rails -->
<ScrollViewer x:Name="TimelineRailsScrollViewer" Grid.Row="1" Style="{StaticResource SvStyle}" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
ScrollChanged="TimelineScrollChanged">
<Grid Background="{DynamicResource MaterialDesignToolBarBackground}">
<Canvas Grid.Column="0" Panel.ZIndex="1">
<!-- Timeline caret -->
<Polygon Canvas.Left="{Binding TimeCaretPosition}"
Cursor="SizeWE"
MouseDown="{s:Action TimelineMouseDown}"
MouseUp="{s:Action TimelineMouseUp}"
MouseMove="{s:Action TimelineMouseMove}"
Points="-8,0 -8,8 0,20, 8,8 8,0"
Fill="{StaticResource SecondaryAccentBrush}" />
<Line Canvas.Left="{Binding TimeCaretPosition}"
Cursor="SizeWE"
MouseDown="{s:Action TimelineMouseDown}"
@ -227,12 +204,49 @@
Y2="{Binding ActualHeight, ElementName=ContainerGrid}"
StrokeThickness="2"
Stroke="{StaticResource SecondaryAccentBrush}" />
</Canvas>
<ContentControl Grid.Column="0" s:View.Model="{Binding TimelineViewModel}" x:Name="PropertyTimeLine" />
</Grid>
</ScrollViewer>
</Grid>
<!-- Timeline header body -->
<controls:PropertyTimelineHeader Margin="0 25 0 0"
Fill="{DynamicResource MaterialDesignBody}"
PixelsPerSecond="{Binding ProfileEditorService.PixelsPerSecond}"
HorizontalOffset="{Binding ContentHorizontalOffset, ElementName=TimelineHeaderScrollViewer}"
VisibleWidth="{Binding ActualWidth, ElementName=TimelineHeaderScrollViewer}"
OffsetFirstValue="True"
Width="{Binding ActualWidth, ElementName=PropertyTimeLine}" />
</Canvas>
</ScrollViewer>
<!-- Timeline rails -->
<ScrollViewer x:Name="TimelineRailsScrollViewer" Grid.Row="1" Style="{StaticResource SvStyle}" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
ScrollChanged="TimelineScrollChanged">
<Grid Background="{DynamicResource MaterialDesignToolBarBackground}">
<Canvas Grid.Column="0" Panel.ZIndex="1">
<Line Canvas.Left="{Binding TimeCaretPosition}"
Cursor="SizeWE"
MouseDown="{s:Action TimelineMouseDown}"
MouseUp="{s:Action TimelineMouseUp}"
MouseMove="{s:Action TimelineMouseMove}"
X1="0"
X2="0"
Y1="0"
Y2="{Binding ActualHeight, ElementName=ContainerGrid}"
StrokeThickness="2"
Stroke="{StaticResource SecondaryAccentBrush}" />
</Canvas>
<ContentControl Grid.Column="0" s:View.Model="{Binding TimelineViewModel}" x:Name="PropertyTimeLine" />
</Grid>
</ScrollViewer>
</Grid>
<materialDesign:TransitionerSlide>
<materialDesign:TransitionerSlide.BackwardWipe>
<materialDesign:CircleWipe />
</materialDesign:TransitionerSlide.BackwardWipe>
<ContentControl s:View.Model="{Binding DataBindingsViewModel}" Background="White"/>
</materialDesign:TransitionerSlide>
</materialDesign:Transitioner>
<!-- Bottom row, a bit hacky but has a ZIndex of 2 to cut off the time caret that overlaps the entire timeline -->
<Grid Grid.Row="1"

View File

@ -12,6 +12,7 @@ using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Services;
using Artemis.Core.Services.Interfaces;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree;
@ -33,11 +34,13 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
private int _propertyTreeIndex;
private bool _repeatAfterLastKeyframe;
private RenderProfileElement _selectedProfileElement;
private DataBindingsViewModel _dataBindingsViewModel;
private TimelineViewModel _timelineViewModel;
private TreeViewModel _treeViewModel;
private TimelineSegmentViewModel _startTimelineSegmentViewModel;
private TimelineSegmentViewModel _mainTimelineSegmentViewModel;
private TimelineSegmentViewModel _endTimelineSegmentViewModel;
private int _rightSideIndex;
public LayerPropertiesViewModel(IProfileEditorService profileEditorService, ICoreService coreService, ISettingsService settingsService,
ILayerPropertyVmFactory layerPropertyVmFactory)
@ -87,6 +90,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
}
}
public int RightSideIndex
{
get => _rightSideIndex;
set => SetAndNotify(ref _rightSideIndex, value);
}
public bool PropertyTreeVisible => PropertyTreeIndex == 0;
public RenderProfileElement SelectedProfileElement
@ -102,7 +111,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
public Layer SelectedLayer => SelectedProfileElement as Layer;
public Folder SelectedFolder => SelectedProfileElement as Folder;
public BindableCollection<LayerPropertyGroupViewModel> LayerPropertyGroups
{
get => _layerPropertyGroups;
@ -121,6 +130,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
set => SetAndNotify(ref _effectsViewModel, value);
}
public DataBindingsViewModel DataBindingsViewModel
{
get => _dataBindingsViewModel;
set => SetAndNotify(ref _dataBindingsViewModel, value);
}
public TimelineViewModel TimelineViewModel
{
get => _timelineViewModel;
@ -151,6 +166,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
ProfileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
ProfileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged;
ProfileEditorService.SelectedDataBindingChanged += ProfileEditorServiceOnSelectedDataBindingChanged;
ProfileEditorService.PixelsPerSecondChanged += ProfileEditorServiceOnPixelsPerSecondChanged;
base.OnInitialActivate();
@ -160,6 +176,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
{
ProfileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
ProfileEditorService.CurrentTimeChanged -= ProfileEditorServiceOnCurrentTimeChanged;
ProfileEditorService.SelectedDataBindingChanged -= ProfileEditorServiceOnSelectedDataBindingChanged;
ProfileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
PopulateProperties(null);
@ -204,6 +221,19 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
NotifyOfPropertyChange(nameof(TimeCaretPosition));
}
private void ProfileEditorServiceOnSelectedDataBindingChanged(object? sender, EventArgs e)
{
if (ProfileEditorService.SelectedDataBinding != null)
{
RightSideIndex = 1;
DataBindingsViewModel = new DataBindingsViewModel(ProfileEditorService.SelectedDataBinding);
} else
{
RightSideIndex = 0;
DataBindingsViewModel = null;
}
}
#region View model managament
public List<LayerPropertyGroupViewModel> GetAllLayerPropertyGroupViewModels()
@ -266,7 +296,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
ApplyLayerBrush();
ApplyEffects();
}
private void SelectedLayerOnLayerBrushUpdated(object sender, EventArgs e)
{
ApplyLayerBrush();
@ -599,7 +629,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
#endregion
#region Segments
public void EnableSegment(string segment)
{
if (segment == "Start")

View File

@ -51,7 +51,8 @@
ToolTip="Change the property's data binding"
Width="24"
Height="24"
VerticalAlignment="Center">
VerticalAlignment="Center"
Command="{s:Action OpenDataBindings}">
<materialDesign:PackIcon Kind="VectorLink" Height="16" Width="16" />
</Button>
</Grid>

View File

@ -37,6 +37,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
set => ApplyKeyframesEnabled(value);
}
public void OpenDataBindings()
{
_profileEditorService.ChangeSelectedDataBinding(LayerPropertyViewModel.BaseLayerProperty);
}
public override void Dispose()
{
PropertyInputViewModel.Dispose();

View File

@ -5,13 +5,14 @@ using Artemis.Core.Events;
using Artemis.Core.Services.Interfaces;
using Artemis.UI.Shared.DataModelVisualization.Shared;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Interfaces;
using Stylet;
namespace Artemis.UI.Screens.Settings.Debug.Tabs
{
public class DataModelDebugViewModel : Screen
{
private readonly IDataModelVisualizationService _dataModelVisualizationService;
private readonly IDataModelUIService _dataModelUIService;
private readonly IPluginService _pluginService;
private readonly Timer _updateTimer;
private bool _isModuleFilterEnabled;
@ -20,9 +21,9 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
private string _propertySearch;
private Core.Plugins.Modules.Module _selectedModule;
public DataModelDebugViewModel(IDataModelVisualizationService dataModelVisualizationService, IPluginService pluginService)
public DataModelDebugViewModel(IDataModelUIService dataModelUIService, IPluginService pluginService)
{
_dataModelVisualizationService = dataModelVisualizationService;
_dataModelUIService = dataModelUIService;
_pluginService = pluginService;
_updateTimer = new Timer(500);
@ -92,14 +93,14 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs args)
{
MainDataModel.Update(_dataModelVisualizationService);
MainDataModel.Update(_dataModelUIService);
}
private void GetDataModel()
{
MainDataModel = SelectedModule != null
? _dataModelVisualizationService.GetPluginDataModelVisualization(SelectedModule)
: _dataModelVisualizationService.GetMainDataModelVisualization();
? _dataModelUIService.GetPluginDataModelVisualization(SelectedModule)
: _dataModelUIService.GetMainDataModelVisualization();
}
private void PluginServiceOnPluginToggled(object? sender, PluginEventArgs e)

View File

@ -10,15 +10,15 @@ namespace Artemis.UI.Services
{
public class RegistrationService : IRegistrationService
{
private readonly IDataModelVisualizationService _dataModelVisualizationService;
private readonly IDataModelUIService _dataModelUIService;
private readonly IProfileEditorService _profileEditorService;
private bool _registeredBuiltInDataModelDisplays;
private bool _registeredBuiltInDataModelInputs;
private bool _registeredBuiltInPropertyEditors;
public RegistrationService(IDataModelVisualizationService dataModelVisualizationService, IProfileEditorService profileEditorService)
public RegistrationService(IDataModelUIService dataModelUIService, IProfileEditorService profileEditorService)
{
_dataModelVisualizationService = dataModelVisualizationService;
_dataModelUIService = dataModelUIService;
_profileEditorService = profileEditorService;
}
@ -27,7 +27,7 @@ namespace Artemis.UI.Services
if (_registeredBuiltInDataModelDisplays)
return;
_dataModelVisualizationService.RegisterDataModelDisplay<SKColorDataModelDisplayViewModel>(Constants.CorePluginInfo);
_dataModelUIService.RegisterDataModelDisplay<SKColorDataModelDisplayViewModel>(Constants.CorePluginInfo);
_registeredBuiltInDataModelDisplays = true;
}
@ -37,9 +37,9 @@ namespace Artemis.UI.Services
if (_registeredBuiltInDataModelInputs)
return;
_dataModelVisualizationService.RegisterDataModelInput<StringDataModelInputViewModel>(Constants.CorePluginInfo, null);
_dataModelVisualizationService.RegisterDataModelInput<IntDataModelInputViewModel>(Constants.CorePluginInfo, Constants.IntegralNumberTypes);
_dataModelVisualizationService.RegisterDataModelInput<DoubleDataModelInputViewModel>(Constants.CorePluginInfo, Constants.FloatNumberTypes);
_dataModelUIService.RegisterDataModelInput<StringDataModelInputViewModel>(Constants.CorePluginInfo, null);
_dataModelUIService.RegisterDataModelInput<IntDataModelInputViewModel>(Constants.CorePluginInfo, Constants.IntegralNumberTypes);
_dataModelUIService.RegisterDataModelInput<DoubleDataModelInputViewModel>(Constants.CorePluginInfo, Constants.FloatNumberTypes);
_registeredBuiltInDataModelInputs = true;
}