mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Profile editor - Redesigned adding/removing timeline segments
General module - Added some basic window information to the data model Profiles - Don't render when opacity is 0 Profile editor - Render non-selected layers in their main segment Profile editor - Condition editor fixes
This commit is contained in:
1 parent
732ee2f429
commit
64a1010100
39 files changed
+831
-261
No files matched your search
@@ -167,7 +167,7 @@ namespace Artemis.UI.Shared.Controls
|
||||
private void Input_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
var seperator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
|
||||
var regex = new Regex("^[" + seperator + "][0-9]+$|^[0-9]*[" + seperator + "]{0,1}[0-9]*$");
|
||||
var regex = new Regex("^[" + seperator + "][-|0-9]+$|^-?[0-9]*[" + seperator + "]{0,1}[0-9]*$");
|
||||
e.Handled = !regex.IsMatch(e.Text);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
|
||||
foreach (var propertyInfo in ListType.GetProperties())
|
||||
{
|
||||
var child = CreateChild(dataModelVisualizationService, propertyInfo);
|
||||
var child = CreateChild(dataModelVisualizationService, propertyInfo, GetChildDepth());
|
||||
if (child != null)
|
||||
Children.Add(child);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
|
||||
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
|
||||
{
|
||||
if (Parent != null && !Parent.IsVisualizationExpanded)
|
||||
return;
|
||||
|
||||
List = GetCurrentValue() as IList;
|
||||
if (List == null)
|
||||
return;
|
||||
|
||||
+14
-3
@@ -10,10 +10,16 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
internal DataModelPropertiesViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, PropertyInfo propertyInfo) : base(dataModel, parent, propertyInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
|
||||
{
|
||||
// Always populate properties
|
||||
PopulateProperties(dataModelVisualizationService);
|
||||
|
||||
// Only update children if the parent is expanded
|
||||
if (Parent != null && !Parent.IsVisualizationExpanded && !Parent.IsRootViewModel)
|
||||
return;
|
||||
|
||||
foreach (var dataModelVisualizationViewModel in Children)
|
||||
dataModelVisualizationViewModel.Update(dataModelVisualizationService);
|
||||
}
|
||||
@@ -22,7 +28,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
{
|
||||
return Parent.IsRootViewModel ? DataModel : base.GetCurrentValue();
|
||||
}
|
||||
|
||||
|
||||
private void PopulateProperties(IDataModelVisualizationService dataModelVisualizationService)
|
||||
{
|
||||
if (Children.Any())
|
||||
@@ -31,10 +37,15 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
var modelType = Parent.IsRootViewModel ? DataModel.GetType() : PropertyInfo.PropertyType;
|
||||
foreach (var propertyInfo in modelType.GetProperties())
|
||||
{
|
||||
var child = CreateChild(dataModelVisualizationService, propertyInfo);
|
||||
var child = CreateChild(dataModelVisualizationService, propertyInfo, GetChildDepth());
|
||||
if (child != null)
|
||||
Children.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
protected int GetChildDepth()
|
||||
{
|
||||
return PropertyDescription != null && !PropertyDescription.ResetsDepth ? Depth + 1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,9 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
|
||||
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
|
||||
{
|
||||
if (Parent != null && !Parent.IsVisualizationExpanded && !Parent.IsRootViewModel)
|
||||
return;
|
||||
|
||||
if (DisplayViewModel == null && dataModelVisualizationService.RegisteredDataModelDisplays.Any(d => d.SupportedType == PropertyInfo.PropertyType))
|
||||
dataModelVisualizationService.GetDataModelDisplayViewModel(PropertyInfo.PropertyType);
|
||||
|
||||
|
||||
+63
-7
@@ -15,9 +15,11 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
{
|
||||
public abstract class DataModelVisualizationViewModel : PropertyChangedBase
|
||||
{
|
||||
private const int MaxDepth = 4;
|
||||
private BindableCollection<DataModelVisualizationViewModel> _children;
|
||||
private DataModel _dataModel;
|
||||
private bool _isMatchingFilteredTypes;
|
||||
private bool _isVisualizationExpanded;
|
||||
private DataModelVisualizationViewModel _parent;
|
||||
private DataModelPropertyAttribute _propertyDescription;
|
||||
private PropertyInfo _propertyInfo;
|
||||
@@ -37,6 +39,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
}
|
||||
|
||||
public bool IsRootViewModel { get; }
|
||||
public int Depth { get; set; }
|
||||
|
||||
public DataModel DataModel
|
||||
{
|
||||
@@ -74,6 +77,16 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
set => SetAndNotify(ref _isMatchingFilteredTypes, value);
|
||||
}
|
||||
|
||||
public bool IsVisualizationExpanded
|
||||
{
|
||||
get => _isVisualizationExpanded;
|
||||
set
|
||||
{
|
||||
if (!SetAndNotify(ref _isVisualizationExpanded, value)) return;
|
||||
RequestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public string PropertyPath
|
||||
{
|
||||
get
|
||||
@@ -104,11 +117,26 @@ 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);
|
||||
|
||||
public virtual object GetCurrentValue()
|
||||
{
|
||||
return Parent == null ? null : PropertyInfo.GetValue(Parent.GetCurrentValue());
|
||||
try
|
||||
{
|
||||
if (PropertyInfo.GetGetMethod() == null)
|
||||
return null;
|
||||
|
||||
return Parent == null ? null : PropertyInfo.GetValue(Parent.GetCurrentValue());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored, who knows what kind of shit can go wrong here...
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyTypeFilter(bool looseMatch, params Type[] filteredTypes)
|
||||
@@ -157,6 +185,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
{
|
||||
if (predicate.LeftDataModel == null || predicate.LeftPropertyPath == null)
|
||||
return null;
|
||||
|
||||
return GetChildByPath(predicate.LeftDataModel.PluginInfo.Guid, predicate.LeftPropertyPath);
|
||||
}
|
||||
|
||||
@@ -167,6 +196,14 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
|
||||
public DataModelVisualizationViewModel GetChildByPath(Guid dataModelGuid, string propertyPath)
|
||||
{
|
||||
// Ensure children are populated by requesting an update
|
||||
if (!IsVisualizationExpanded)
|
||||
{
|
||||
IsVisualizationExpanded = true;
|
||||
RequestUpdate();
|
||||
IsVisualizationExpanded = false;
|
||||
}
|
||||
|
||||
var path = propertyPath.Split(".");
|
||||
var currentPart = path.First();
|
||||
|
||||
@@ -187,8 +224,10 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
}
|
||||
}
|
||||
|
||||
protected DataModelVisualizationViewModel CreateChild(IDataModelVisualizationService dataModelVisualizationService, PropertyInfo propertyInfo)
|
||||
protected DataModelVisualizationViewModel CreateChild(IDataModelVisualizationService dataModelVisualizationService, PropertyInfo propertyInfo, int depth)
|
||||
{
|
||||
if (depth > MaxDepth)
|
||||
return null;
|
||||
// Skip properties decorated with DataModelIgnore
|
||||
if (Attribute.IsDefined(propertyInfo, typeof(DataModelIgnoreAttribute)))
|
||||
return null;
|
||||
@@ -196,19 +235,36 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
// If a display VM was found, prefer to use that in any case
|
||||
var typeViewModel = dataModelVisualizationService.GetDataModelDisplayViewModel(propertyInfo.PropertyType);
|
||||
if (typeViewModel != null)
|
||||
return new DataModelPropertyViewModel(DataModel, this, propertyInfo) {DisplayViewModel = typeViewModel};
|
||||
return new DataModelPropertyViewModel(DataModel, this, propertyInfo) {DisplayViewModel = typeViewModel, Depth = depth};
|
||||
// For primitives, create a property view model, it may be null that is fine
|
||||
if (propertyInfo.PropertyType.IsPrimitive || propertyInfo.PropertyType == typeof(string))
|
||||
return new DataModelPropertyViewModel(DataModel, this, propertyInfo);
|
||||
return new DataModelPropertyViewModel(DataModel, this, propertyInfo) {Depth = depth};
|
||||
if (typeof(IList).IsAssignableFrom(propertyInfo.PropertyType))
|
||||
return new DataModelListViewModel(DataModel, this, propertyInfo);
|
||||
return new DataModelListViewModel(DataModel, this, propertyInfo) {Depth = depth};
|
||||
// For other value types create a child view model
|
||||
if (propertyInfo.PropertyType.IsClass || propertyInfo.PropertyType.IsStruct())
|
||||
return new DataModelPropertiesViewModel(DataModel, this, propertyInfo);
|
||||
return new DataModelPropertiesViewModel(DataModel, this, propertyInfo) {Depth = depth};
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler UpdateRequested;
|
||||
|
||||
protected virtual void OnUpdateRequested()
|
||||
{
|
||||
UpdateRequested?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void RequestUpdate()
|
||||
{
|
||||
Parent?.RequestUpdate();
|
||||
OnUpdateRequested();
|
||||
}
|
||||
|
||||
private void GetDescription()
|
||||
{
|
||||
// If this is the first child of a root view model, use the data model description
|
||||
@@ -218,7 +274,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
else if (PropertyInfo != null)
|
||||
{
|
||||
PropertyDescription = (DataModelPropertyAttribute) Attribute.GetCustomAttribute(PropertyInfo, typeof(DataModelPropertyAttribute)) ??
|
||||
new DataModelPropertyAttribute {Name = PropertyInfo.Name.Humanize()};
|
||||
new DataModelPropertyAttribute {Name = PropertyInfo.Name.Humanize(), ResetsDepth = false};
|
||||
}
|
||||
else
|
||||
throw new ArtemisSharedUIException("Failed to get property description because plugin info is null but the parent has a datamodel");
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Artemis.UI.Shared.Services
|
||||
|
||||
// Update to populate children
|
||||
viewModel.Update(this);
|
||||
viewModel.UpdateRequested += (sender, args) => viewModel.Update(this);
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
@@ -56,6 +57,7 @@ namespace Artemis.UI.Shared.Services
|
||||
|
||||
// Update to populate children
|
||||
viewModel.Update(this);
|
||||
viewModel.UpdateRequested += (sender, args) => viewModel.Update(this);
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
@@ -185,6 +187,7 @@ namespace Artemis.UI.Shared.Services
|
||||
if (initialValue == null)
|
||||
initialValue = Activator.CreateInstance(registration.SupportedType);
|
||||
}
|
||||
|
||||
// This assumes the type can be converted, that has been checked when the VM was created
|
||||
if (initialValue != null && initialValue.GetType() != registration.SupportedType)
|
||||
initialValue = Convert.ChangeType(initialValue, registration.SupportedType);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.Core.Plugins.Abstract;
|
||||
using Artemis.Core.Plugins.Models;
|
||||
using Artemis.UI.Shared.Events;
|
||||
@@ -53,7 +54,7 @@ namespace Artemis.UI.Shared.Services.Interfaces
|
||||
/// Occurs when the current editor time is changed
|
||||
/// </summary>
|
||||
event EventHandler CurrentTimeChanged;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the pixels per second (zoom level) is changed
|
||||
/// </summary>
|
||||
@@ -76,11 +77,16 @@ namespace Artemis.UI.Shared.Services.Interfaces
|
||||
void RemovePropertyInput(PropertyInputRegistration registration);
|
||||
|
||||
/// <summary>
|
||||
/// Snaps the given time to the closest relevant element in the timeline, this can be the cursor, a keyframe or a segment end.
|
||||
/// Snaps the given time to the closest relevant element in the timeline, this can be the cursor, a keyframe or a
|
||||
/// segment end.
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <param name="tolerance">How close the time must be to snap</param>
|
||||
/// <param name="snapToSegments">Enable snapping to timeline segments</param>
|
||||
/// <param name="snapToCurrentTime">Enable snapping to the current time of the editor</param>
|
||||
/// <param name="snapToKeyframes">Enable snapping to visible keyframes</param>
|
||||
/// <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);
|
||||
TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, bool snapToKeyframes, BaseLayerPropertyKeyframe excludedKeyframe = null);
|
||||
}
|
||||
}
|
||||
@@ -113,20 +113,11 @@ namespace Artemis.UI.Shared.Services
|
||||
if (SelectedProfile == null)
|
||||
return;
|
||||
|
||||
var delta = CurrentTime - _lastUpdateTime;
|
||||
foreach (var folder in SelectedProfile.GetAllFolders())
|
||||
{
|
||||
foreach (var baseLayerEffect in folder.LayerEffects)
|
||||
baseLayerEffect.Update(delta.TotalSeconds);
|
||||
}
|
||||
|
||||
foreach (var layer in SelectedProfile.GetAllLayers())
|
||||
{
|
||||
layer.OverrideProgress(CurrentTime);
|
||||
layer.LayerBrush?.Update(delta.TotalSeconds);
|
||||
foreach (var baseLayerEffect in layer.LayerEffects)
|
||||
baseLayerEffect.Update(delta.TotalSeconds);
|
||||
}
|
||||
// Stick to the main segment for any element that is not currently selected
|
||||
foreach (var folder in SelectedProfile.GetAllFolders())
|
||||
folder.OverrideProgress(CurrentTime, folder != SelectedProfileElement);
|
||||
foreach (var layer in SelectedProfile.GetAllLayers())
|
||||
layer.OverrideProgress(CurrentTime, layer != SelectedProfileElement);
|
||||
|
||||
_lastUpdateTime = CurrentTime;
|
||||
OnProfilePreviewUpdated();
|
||||
@@ -205,7 +196,7 @@ namespace Artemis.UI.Shared.Services
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, bool snapToKeyframes)
|
||||
public TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, bool snapToKeyframes, BaseLayerPropertyKeyframe excludedKeyframe = null)
|
||||
{
|
||||
if (snapToSegments)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user