diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index e71a843b3..1de5eb131 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -2,14 +2,11 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using Artemis.Core.Events; -using Artemis.Core.Exceptions; using Artemis.Core.Extensions; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Models.Profile.LayerShapes; using Artemis.Core.Models.Surface; using Artemis.Core.Plugins.LayerBrush; -using Artemis.Core.Plugins.Models; using Artemis.Storage.Entities.Profile; using SkiaSharp; @@ -17,7 +14,6 @@ namespace Artemis.Core.Models.Profile { public sealed class Layer : ProfileElement { - private readonly Dictionary<(Guid, string), BaseLayerProperty> _properties; private LayerShape _layerShape; private List _leds; private SKPath _path; @@ -30,14 +26,12 @@ namespace Artemis.Core.Models.Profile Profile = profile; Parent = parent; Name = name; + Properties = new LayerPropertyCollection(this); _leds = new List(); - _properties = new Dictionary<(Guid, string), BaseLayerProperty>(); - CreateDefaultProperties(); ApplyShapeType(); - - ShapeTypeProperty.ValueChanged += (sender, args) => ApplyShapeType(); + Properties.ShapeType.ValueChanged += (sender, args) => ApplyShapeType(); } internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity) @@ -49,14 +43,12 @@ namespace Artemis.Core.Models.Profile Parent = parent; Name = layerEntity.Name; Order = layerEntity.Order; + Properties = new LayerPropertyCollection(this); _leds = new List(); - _properties = new Dictionary<(Guid, string), BaseLayerProperty>(); - CreateDefaultProperties(); ApplyShapeType(); - - ShapeTypeProperty.ValueChanged += (sender, args) => ApplyShapeType(); + Properties.ShapeType.ValueChanged += (sender, args) => ApplyShapeType(); } internal LayerEntity LayerEntity { get; set; } @@ -102,42 +94,9 @@ namespace Artemis.Core.Models.Profile } /// - /// A collection of all the properties on this layer + /// The properties of this layer /// - public ReadOnlyCollection Properties => _properties.Values.ToList().AsReadOnly(); - - public LayerProperty ShapeTypeProperty { get; set; } - - public LayerProperty FillTypeProperty { get; set; } - - public LayerProperty BlendModeProperty { get; set; } - - public LayerProperty BrushReferenceProperty { get; set; } - - /// - /// The anchor point property of this layer, also found in - /// - public LayerProperty AnchorPointProperty { get; private set; } - - /// - /// The position of this layer, also found in - /// - public LayerProperty PositionProperty { get; private set; } - - /// - /// The size property of this layer, also found in - /// - public LayerProperty ScaleProperty { get; private set; } - - /// - /// The rotation property of this layer range 0 - 360, also found in - /// - public LayerProperty RotationProperty { get; private set; } - - /// - /// The opacity property of this layer range 0 - 100, also found in - /// - public LayerProperty OpacityProperty { get; private set; } + public LayerPropertyCollection Properties { get; set; } /// /// The brush that will fill the . @@ -184,7 +143,7 @@ namespace Artemis.Core.Models.Profile private void ApplyShapeType() { - switch (ShapeTypeProperty.CurrentValue) + switch (Properties.ShapeType.CurrentValue) { case LayerShapeType.Ellipse: LayerShape = new Ellipse(this); @@ -199,16 +158,6 @@ namespace Artemis.Core.Models.Profile #endregion - private void OnLayerPropertyRegistered(LayerPropertyEventArgs e) - { - LayerPropertyRegistered?.Invoke(this, e); - } - - private void OnLayerPropertyRemoved(LayerPropertyEventArgs e) - { - LayerPropertyRemoved?.Invoke(this, e); - } - #region Rendering /// @@ -243,10 +192,10 @@ namespace Artemis.Core.Models.Profile using (var paint = new SKPaint()) { - paint.BlendMode = BlendModeProperty.CurrentValue; - paint.Color = new SKColor(0, 0, 0, (byte) (OpacityProperty.CurrentValue * 2.55f)); + paint.BlendMode = Properties.BlendMode.CurrentValue; + paint.Color = new SKColor(0, 0, 0, (byte) (Properties.Opacity.CurrentValue * 2.55f)); - switch (FillTypeProperty.CurrentValue) + switch (Properties.FillType.CurrentValue) { case LayerFillType.Stretch: StretchRender(canvas, canvasInfo, paint); @@ -265,11 +214,11 @@ namespace Artemis.Core.Models.Profile private void StretchRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint) { // Apply transformations - var sizeProperty = ScaleProperty.CurrentValue; - var rotationProperty = RotationProperty.CurrentValue; + var sizeProperty = Properties.Scale.CurrentValue; + var rotationProperty = Properties.Rotation.CurrentValue; var anchorPosition = GetLayerAnchorPosition(); - var anchorProperty = AnchorPointProperty.CurrentValue; + var anchorProperty = Properties.AnchorPoint.CurrentValue; // Translation originates from the unscaled center of the shape and is tied to the anchor var x = anchorPosition.X - Bounds.MidX - anchorProperty.X * Bounds.Width; @@ -286,11 +235,11 @@ namespace Artemis.Core.Models.Profile private void ClipRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint) { // Apply transformations - var sizeProperty = ScaleProperty.CurrentValue; - var rotationProperty = RotationProperty.CurrentValue; + var sizeProperty = Properties.Scale.CurrentValue; + var rotationProperty = Properties.Rotation.CurrentValue; var anchorPosition = GetLayerAnchorPosition(); - var anchorProperty = AnchorPointProperty.CurrentValue; + var anchorProperty = Properties.AnchorPoint.CurrentValue; // Translation originates from the unscaled center of the shape and is tied to the anchor var x = anchorPosition.X - Bounds.MidX - anchorProperty.X * Bounds.Width; @@ -343,7 +292,7 @@ namespace Artemis.Core.Models.Profile internal SKPoint GetLayerAnchorPosition() { - var positionProperty = PositionProperty.CurrentValue; + var positionProperty = Properties.Position.CurrentValue; // Start at the center of the shape var position = new SKPoint(Bounds.MidX, Bounds.MidY); @@ -418,131 +367,10 @@ namespace Artemis.Core.Models.Profile #endregion - #region Properties - - /// - /// Adds the provided layer property and its children to the layer. - /// If found, the last stored base value and keyframes will be applied to the provided property. - /// - /// The type of value of the layer property - /// The property to apply to the layer - /// True if an existing value was found and applied, otherwise false. - internal bool RegisterLayerProperty(LayerProperty layerProperty) - { - return RegisterLayerProperty((BaseLayerProperty) layerProperty); - } - - /// - /// Adds the provided layer property to the layer. - /// If found, the last stored base value and keyframes will be applied to the provided property. - /// - /// The property to apply to the layer - /// True if an existing value was found and applied, otherwise false. - internal bool RegisterLayerProperty(BaseLayerProperty layerProperty) - { - if (_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id))) - throw new ArtemisCoreException($"Duplicate property ID detected. Layer already contains a property with ID {layerProperty.Id}."); - - var propertyEntity = LayerEntity.PropertyEntities.FirstOrDefault(p => p.Id == layerProperty.Id && p.ValueType == layerProperty.Type.Name); - // TODO: Catch serialization exceptions and log them - if (propertyEntity != null) - layerProperty.ApplyToProperty(propertyEntity); - - _properties.Add((layerProperty.PluginInfo.Guid, layerProperty.Id), layerProperty); - OnLayerPropertyRegistered(new LayerPropertyEventArgs(layerProperty)); - return propertyEntity != null; - } - - /// - /// Removes the provided layer property from the layer. - /// - /// The type of value of the layer property - /// The property to remove from the layer - public void RemoveLayerProperty(LayerProperty layerProperty) - { - RemoveLayerProperty((BaseLayerProperty) layerProperty); - } - - /// - /// Removes the provided layer property from the layer. - /// - /// The property to remove from the layer - public void RemoveLayerProperty(BaseLayerProperty layerProperty) - { - if (!_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id))) - throw new ArtemisCoreException($"Could not find a property with ID {layerProperty.Id}."); - - var property = _properties[(layerProperty.PluginInfo.Guid, layerProperty.Id)]; - property.Parent?.Children.Remove(property); - _properties.Remove((layerProperty.PluginInfo.Guid, layerProperty.Id)); - - OnLayerPropertyRemoved(new LayerPropertyEventArgs(property)); - } - - /// - /// If found, returns the matching the provided ID - /// - /// The type of the layer property - /// The plugin this property belongs to - /// - /// - public LayerProperty GetLayerPropertyById(PluginInfo pluginInfo, string id) - { - if (!_properties.ContainsKey((pluginInfo.Guid, id))) - return null; - - var property = _properties[(pluginInfo.Guid, id)]; - if (property.Type != typeof(T)) - throw new ArtemisCoreException($"Property type mismatch. Expected property {property} to have type {typeof(T)} but it has {property.Type} instead."); - return (LayerProperty) _properties[(pluginInfo.Guid, id)]; - } - - private void CreateDefaultProperties() - { - // Shape - var shape = new LayerProperty(this, "Core.Shape", "Shape", "A collection of basic shape properties"); - ShapeTypeProperty = new LayerProperty(this, shape, "Core.ShapeType", "Shape type", "The type of shape to draw in this layer") {CanUseKeyframes = false}; - FillTypeProperty = new LayerProperty(this, shape, "Core.FillType", "Fill type", "How to make the shape adjust to scale changes") {CanUseKeyframes = false}; - BlendModeProperty = new LayerProperty(this, shape, "Core.BlendMode", "Blend mode", "How to blend this layer into the resulting image") {CanUseKeyframes = false}; - ShapeTypeProperty.Value = LayerShapeType.Rectangle; - FillTypeProperty.Value = LayerFillType.Stretch; - BlendModeProperty.Value = SKBlendMode.SrcOver; - - RegisterLayerProperty(shape); - foreach (var shapeProperty in shape.Children) - RegisterLayerProperty(shapeProperty); - - // Brush - var brush = new LayerProperty(this, "Core.Brush", "Brush", "A collection of properties that configure the selected brush"); - BrushReferenceProperty = new LayerProperty(this, brush, "Core.BrushReference", "Brush type", "The type of brush to use for this layer") {CanUseKeyframes = false}; - - RegisterLayerProperty(brush); - foreach (var brushProperty in brush.Children) - RegisterLayerProperty(brushProperty); - - // Transform - var transform = new LayerProperty(this, "Core.Transform", "Transform", "A collection of transformation properties") {ExpandByDefault = true}; - AnchorPointProperty = new LayerProperty(this, transform, "Core.AnchorPoint", "Anchor Point", "The point at which the shape is attached to its position") {InputStepSize = 0.001f}; - PositionProperty = new LayerProperty(this, transform, "Core.Position", "Position", "The position of the shape") {InputStepSize = 0.001f}; - ScaleProperty = new LayerProperty(this, transform, "Core.Scale", "Scale", "The scale of the shape") {InputAffix = "%", MinInputValue = 0f}; - RotationProperty = new LayerProperty(this, transform, "Core.Rotation", "Rotation", "The rotation of the shape in degrees") {InputAffix = "°"}; - OpacityProperty = new LayerProperty(this, transform, "Core.Opacity", "Opacity", "The opacity of the shape") {InputAffix = "%", MinInputValue = 0f, MaxInputValue = 100f}; - ScaleProperty.Value = new SKSize(100, 100); - OpacityProperty.Value = 100; - - RegisterLayerProperty(transform); - foreach (var transformProperty in transform.Children) - RegisterLayerProperty(transformProperty); - } - - #endregion - #region Events public event EventHandler RenderPropertiesUpdated; public event EventHandler ShapePropertiesUpdated; - public event EventHandler LayerPropertyRegistered; - public event EventHandler LayerPropertyRemoved; private void OnRenderPropertiesUpdated() { diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs index bbfc7091d..a84a2e375 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs @@ -241,7 +241,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties public int GetFlattenedIndex() { if (Parent == null) - return Layer.Properties.IndexOf(this); + return Layer.Properties.ToList().IndexOf(this); // Create a flattened list of all properties in their order as defined by the parent/child hierarchy var properties = new List(); diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyCollection.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyCollection.cs new file mode 100644 index 000000000..b8283a1aa --- /dev/null +++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyCollection.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Artemis.Core.Events; +using Artemis.Core.Exceptions; +using Artemis.Core.Plugins.Models; +using SkiaSharp; + +namespace Artemis.Core.Models.Profile.LayerProperties +{ + /// + /// Contains all the properties of the layer and provides easy access to the default properties. + /// + public class LayerPropertyCollection : IEnumerable + { + private readonly Dictionary<(Guid, string), BaseLayerProperty> _properties; + + internal LayerPropertyCollection(Layer layer) + { + _properties = new Dictionary<(Guid, string), BaseLayerProperty>(); + + Layer = layer; + CreateDefaultProperties(); + } + + /// + /// Gets the layer these properties are applied on + /// + public Layer Layer { get; } + + /// + public IEnumerator GetEnumerator() + { + return _properties.Values.GetEnumerator(); + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// Removes the provided layer property from the layer. + /// + /// The type of value of the layer property + /// The property to remove from the layer + public void RemoveLayerProperty(LayerProperty layerProperty) + { + RemoveLayerProperty((BaseLayerProperty) layerProperty); + } + + /// + /// Removes the provided layer property from the layer. + /// + /// The property to remove from the layer + public void RemoveLayerProperty(BaseLayerProperty layerProperty) + { + if (!_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id))) + throw new ArtemisCoreException($"Could not find a property with ID {layerProperty.Id}."); + + var property = _properties[(layerProperty.PluginInfo.Guid, layerProperty.Id)]; + property.Parent?.Children.Remove(property); + _properties.Remove((layerProperty.PluginInfo.Guid, layerProperty.Id)); + + OnLayerPropertyRemoved(new LayerPropertyEventArgs(property)); + } + + /// + /// If found, returns the matching the provided ID + /// + /// The type of the layer property + /// The plugin this property belongs to + /// + /// + public LayerProperty GetLayerPropertyById(PluginInfo pluginInfo, string id) + { + if (!_properties.ContainsKey((pluginInfo.Guid, id))) + return null; + + var property = _properties[(pluginInfo.Guid, id)]; + if (property.Type != typeof(T)) + throw new ArtemisCoreException($"Property type mismatch. Expected property {property} to have type {typeof(T)} but it has {property.Type} instead."); + return (LayerProperty) _properties[(pluginInfo.Guid, id)]; + } + + /// + /// Adds the provided layer property and its children to the layer. + /// If found, the last stored base value and keyframes will be applied to the provided property. + /// + /// The type of value of the layer property + /// The property to apply to the layer + /// True if an existing value was found and applied, otherwise false. + public bool RegisterLayerProperty(LayerProperty layerProperty) + { + return RegisterLayerProperty((BaseLayerProperty) layerProperty); + } + + /// + /// Adds the provided layer property to the layer. + /// If found, the last stored base value and keyframes will be applied to the provided property. + /// + /// The property to apply to the layer + /// True if an existing value was found and applied, otherwise false. + public bool RegisterLayerProperty(BaseLayerProperty layerProperty) + { + if (_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id))) + throw new ArtemisCoreException($"Duplicate property ID detected. Layer already contains a property with ID {layerProperty.Id}."); + + var entity = Layer.LayerEntity.PropertyEntities.FirstOrDefault(p => p.Id == layerProperty.Id && p.ValueType == layerProperty.Type.Name); + // TODO: Catch serialization exceptions and log them + if (entity != null) + layerProperty.ApplyToProperty(entity); + + _properties.Add((layerProperty.PluginInfo.Guid, layerProperty.Id), layerProperty); + OnLayerPropertyRegistered(new LayerPropertyEventArgs(layerProperty)); + return entity != null; + } + + #region Default properties + + /// + /// Gets the shape type property of the layer + /// + public LayerProperty ShapeType { get; private set; } + + /// + /// Gets the fill type property of the layer + /// + public LayerProperty FillType { get; private set; } + + /// + /// Gets the blend mode property of the layer + /// + public LayerProperty BlendMode { get; private set; } + + /// + /// Gets the brush reference property of the layer + /// + public LayerProperty BrushReference { get; private set; } + + /// + /// Gets the anchor point property of the layer + /// + public LayerProperty AnchorPoint { get; private set; } + + /// + /// Gets the position of the layer + /// + public LayerProperty Position { get; private set; } + + /// + /// Gets the size property of the layer + /// + public LayerProperty Scale { get; private set; } + + /// + /// Gets the rotation property of the layer range 0 - 360 + /// + public LayerProperty Rotation { get; private set; } + + /// + /// Gets the opacity property of the layer range 0 - 100 + /// + public LayerProperty Opacity { get; private set; } + + private void CreateDefaultProperties() + { + // Shape + var shape = new LayerProperty(Layer, "Core.Shape", "Shape", "A collection of basic shape properties"); + ShapeType = new LayerProperty(Layer, shape, "Core.ShapeType", "Shape type", "The type of shape to draw in this layer") {CanUseKeyframes = false}; + FillType = new LayerProperty(Layer, shape, "Core.FillType", "Fill type", "How to make the shape adjust to scale changes") {CanUseKeyframes = false}; + BlendMode = new LayerProperty(Layer, shape, "Core.BlendMode", "Blend mode", "How to blend this layer into the resulting image") {CanUseKeyframes = false}; + ShapeType.Value = LayerShapeType.Rectangle; + FillType.Value = LayerFillType.Stretch; + BlendMode.Value = SKBlendMode.SrcOver; + + RegisterLayerProperty(shape); + foreach (var shapeProperty in shape.Children) + RegisterLayerProperty(shapeProperty); + + // Brush + var brush = new LayerProperty(Layer, "Core.Brush", "Brush", "A collection of properties that configure the selected brush"); + BrushReference = new LayerProperty(Layer, brush, "Core.BrushReference", "Brush type", "The type of brush to use for this layer") {CanUseKeyframes = false}; + + RegisterLayerProperty(brush); + foreach (var brushProperty in brush.Children) + RegisterLayerProperty(brushProperty); + + // Transform + var transform = new LayerProperty(Layer, "Core.Transform", "Transform", "A collection of transformation properties") {ExpandByDefault = true}; + AnchorPoint = new LayerProperty(Layer, transform, "Core.AnchorPoint", "Anchor Point", "The point at which the shape is attached to its position") {InputStepSize = 0.001f}; + Position = new LayerProperty(Layer, transform, "Core.Position", "Position", "The position of the shape") {InputStepSize = 0.001f}; + Scale = new LayerProperty(Layer, transform, "Core.Scale", "Scale", "The scale of the shape") {InputAffix = "%", MinInputValue = 0f}; + Rotation = new LayerProperty(Layer, transform, "Core.Rotation", "Rotation", "The rotation of the shape in degrees") {InputAffix = "°"}; + Opacity = new LayerProperty(Layer, transform, "Core.Opacity", "Opacity", "The opacity of the shape") {InputAffix = "%", MinInputValue = 0f, MaxInputValue = 100f}; + Scale.Value = new SKSize(100, 100); + Opacity.Value = 100; + + RegisterLayerProperty(transform); + foreach (var transformProperty in transform.Children) + RegisterLayerProperty(transformProperty); + } + + #endregion + + #region Events + + public event EventHandler LayerPropertyRegistered; + public event EventHandler LayerPropertyRemoved; + + private void OnLayerPropertyRegistered(LayerPropertyEventArgs e) + { + LayerPropertyRegistered?.Invoke(this, e); + } + + private void OnLayerPropertyRemoved(LayerPropertyEventArgs e) + { + LayerPropertyRemoved?.Invoke(this, e); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/LayerBrush/LayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrush/LayerBrush.cs index 80fd93a05..e65b8461f 100644 --- a/src/Artemis.Core/Plugins/LayerBrush/LayerBrush.cs +++ b/src/Artemis.Core/Plugins/LayerBrush/LayerBrush.cs @@ -58,7 +58,7 @@ namespace Artemis.Core.Plugins.LayerBrush protected LayerProperty RegisterLayerProperty(BaseLayerProperty parent, string id, string name, string description, T defaultValue = default) { var property = new LayerProperty(Layer, Descriptor.LayerBrushProvider.PluginInfo, parent, id, name, description) {Value = defaultValue}; - Layer.RegisterLayerProperty(property); + Layer.Properties.RegisterLayerProperty(property); // It's fine if this is null, it'll be picked up by SetLayerService later _layerService?.InstantiateKeyframeEngine(property); return property; @@ -77,9 +77,9 @@ namespace Artemis.Core.Plugins.LayerBrush protected LayerProperty RegisterLayerProperty(string id, string name, string description, T defaultValue = default) { var property = new LayerProperty( - Layer, Descriptor.LayerBrushProvider.PluginInfo, Layer.BrushReferenceProperty.Parent, id, name, description + Layer, Descriptor.LayerBrushProvider.PluginInfo, Layer.Properties.BrushReference.Parent, id, name, description ) {Value = defaultValue}; - Layer.RegisterLayerProperty(property); + Layer.Properties.RegisterLayerProperty(property); // It's fine if this is null, it'll be picked up by SetLayerService later _layerService?.InstantiateKeyframeEngine(property); return property; diff --git a/src/Artemis.Core/Services/LayerService.cs b/src/Artemis.Core/Services/LayerService.cs index 6bbd0aacc..e1a4f03ea 100644 --- a/src/Artemis.Core/Services/LayerService.cs +++ b/src/Artemis.Core/Services/LayerService.cs @@ -28,7 +28,7 @@ namespace Artemis.Core.Services { RemoveLayerBrush(layer); - var descriptorReference = layer.BrushReferenceProperty.CurrentValue; + var descriptorReference = layer.Properties.BrushReference.CurrentValue; if (descriptorReference == null) return null; @@ -86,7 +86,7 @@ namespace Artemis.Core.Services var propertiesToRemove = layer.Properties.Where(l => l.PluginInfo == brush.Descriptor.LayerBrushProvider.PluginInfo).ToList(); foreach (var layerProperty in propertiesToRemove) - layer.RemoveLayerProperty(layerProperty); + layer.Properties.RemoveLayerProperty(layerProperty); brush.Dispose(); } } diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs index f21cb3859..9170409df 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs @@ -90,8 +90,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties if (_lastSelectedLayer != null) { - _lastSelectedLayer.LayerPropertyRegistered -= LayerOnPropertyRegistered; - _lastSelectedLayer.LayerPropertyRemoved -= LayerOnPropertyRemoved; + _lastSelectedLayer.Properties.LayerPropertyRegistered -= LayerOnPropertyRegistered; + _lastSelectedLayer.Properties.LayerPropertyRemoved -= LayerOnPropertyRemoved; } PropertyTree?.Dispose(); @@ -124,8 +124,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties { if (_lastSelectedLayer != null) { - _lastSelectedLayer.LayerPropertyRegistered -= LayerOnPropertyRegistered; - _lastSelectedLayer.LayerPropertyRemoved -= LayerOnPropertyRemoved; + _lastSelectedLayer.Properties.LayerPropertyRegistered -= LayerOnPropertyRegistered; + _lastSelectedLayer.Properties.LayerPropertyRemoved -= LayerOnPropertyRemoved; } if (profileElement is Layer layer) @@ -145,8 +145,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties } _lastSelectedLayer = layer; - layer.LayerPropertyRegistered += LayerOnPropertyRegistered; - layer.LayerPropertyRemoved += LayerOnPropertyRemoved; + layer.Properties.LayerPropertyRegistered += LayerOnPropertyRegistered; + layer.Properties.LayerPropertyRemoved += LayerOnPropertyRemoved; } else { diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs index 5a75152e8..2994814ce 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs @@ -94,7 +94,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools difference += 360; else if (difference > 350) difference -= 360; - newRotation = layer.RotationProperty.CurrentValue + difference; + newRotation = layer.Properties.Rotation.CurrentValue + difference; // Round the end-result to increments of 5 as well, to avoid staying on an offset if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) @@ -102,7 +102,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools else newRotation = (float) Math.Round(newRotation, 2, MidpointRounding.AwayFromZero); - layer.RotationProperty.SetCurrentValue(newRotation, ProfileEditorService.CurrentTime); + layer.Properties.Rotation.SetCurrentValue(newRotation, ProfileEditorService.CurrentTime); ProfileEditorService.UpdateProfilePreview(); } @@ -121,7 +121,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools var dragStart = GetRelativePosition(sender, e.MouseEventArgs).ToSKPoint(); _dragOffset = _layerEditorService.GetDragOffset(layer, dragStart); _dragStart = dragStart + _dragOffset; - _dragStartScale = layer.ScaleProperty.CurrentValue; + _dragStartScale = layer.Properties.Scale.CurrentValue; _isResizing = true; } @@ -159,19 +159,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools break; case ShapeControlPoint.TopCenter: height = VerticalResize(layer, position, ResizeOrigin.Top); - width = layer.ScaleProperty.CurrentValue.Width; + width = layer.Properties.Scale.CurrentValue.Width; break; case ShapeControlPoint.RightCenter: width = HorizontalResize(layer, position, ResizeOrigin.Right); - height = layer.ScaleProperty.CurrentValue.Height; + height = layer.Properties.Scale.CurrentValue.Height; break; case ShapeControlPoint.BottomCenter: - width = layer.ScaleProperty.CurrentValue.Width; + width = layer.Properties.Scale.CurrentValue.Width; height = VerticalResize(layer, position, ResizeOrigin.Bottom); break; case ShapeControlPoint.LeftCenter: width = HorizontalResize(layer, position, ResizeOrigin.Left); - height = layer.ScaleProperty.CurrentValue.Height; + height = layer.Properties.Scale.CurrentValue.Height; break; default: throw new ArgumentOutOfRangeException(); @@ -186,7 +186,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools height = (float) Math.Round(1.0 / bounds.Height * smallestSide, 2, MidpointRounding.AwayFromZero); } - layer.ScaleProperty.SetCurrentValue(new SKSize(width, height), ProfileEditorService.CurrentTime); + layer.Properties.Scale.SetCurrentValue(new SKSize(width, height), ProfileEditorService.CurrentTime); ProfileEditorService.UpdateProfilePreview(); } @@ -319,7 +319,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools // Scale down the resulting position and make it relative var scaled = _layerEditorService.GetScaledPoint(layer, position, true); // Round and update the position property - layer.PositionProperty.SetCurrentValue(RoundPoint(scaled, 3), ProfileEditorService.CurrentTime); + layer.Properties.Position.SetCurrentValue(RoundPoint(scaled, 3), ProfileEditorService.CurrentTime); ProfileEditorService.UpdateProfilePreview(); } @@ -338,13 +338,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools var scaled = _layerEditorService.GetScaledPoint(layer, countered[1], false); // Update the anchor point, this causes the shape to move - layer.AnchorPointProperty.SetCurrentValue(RoundPoint(scaled, 3), ProfileEditorService.CurrentTime); + layer.Properties.AnchorPoint.SetCurrentValue(RoundPoint(scaled, 3), ProfileEditorService.CurrentTime); // TopLeft is not updated yet and acts as a snapshot of the top-left before changing the anchor var path = _layerEditorService.GetLayerPath(layer, true, true, true); // Calculate the (scaled) difference between the old and now position var difference = _layerEditorService.GetScaledPoint(layer, _topLeft - path.Points[0], false); // Apply the difference so that the shape effectively stays in place - layer.PositionProperty.SetCurrentValue(RoundPoint(layer.PositionProperty.CurrentValue + difference, 3), ProfileEditorService.CurrentTime); + layer.Properties.Position.SetCurrentValue(RoundPoint(layer.Properties.Position.CurrentValue + difference, 3), ProfileEditorService.CurrentTime); ProfileEditorService.UpdateProfilePreview(); } @@ -362,9 +362,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools { var counterRotatePath = new SKPath(); counterRotatePath.AddPoly(skPoints, false); - counterRotatePath.Transform(SKMatrix.MakeRotationDegrees(layer.RotationProperty.CurrentValue * -1, pivot.X, pivot.Y)); + counterRotatePath.Transform(SKMatrix.MakeRotationDegrees(layer.Properties.Rotation.CurrentValue * -1, pivot.X, pivot.Y)); if (includeScale) - counterRotatePath.Transform(SKMatrix.MakeScale(1f / (layer.ScaleProperty.CurrentValue.Width / 100f), 1f / (layer.ScaleProperty.CurrentValue.Height / 100f))); + counterRotatePath.Transform(SKMatrix.MakeScale(1f / (layer.Properties.Scale.CurrentValue.Width / 100f), 1f / (layer.Properties.Scale.CurrentValue.Height / 100f))); return counterRotatePath.Points; } diff --git a/src/Artemis.UI/Services/LayerEditorService.cs b/src/Artemis.UI/Services/LayerEditorService.cs index 8efcaeb13..83c654db3 100644 --- a/src/Artemis.UI/Services/LayerEditorService.cs +++ b/src/Artemis.UI/Services/LayerEditorService.cs @@ -35,7 +35,7 @@ namespace Artemis.UI.Services public Point GetLayerAnchorPosition(Layer layer, SKPoint? positionOverride = null) { var layerBounds = GetLayerBounds(layer).ToSKRect(); - var positionProperty = layer.PositionProperty.CurrentValue; + var positionProperty = layer.Properties.Position.CurrentValue; if (positionOverride != null) positionProperty = positionOverride.Value; @@ -59,7 +59,7 @@ namespace Artemis.UI.Services // the layer using the structure of the XAML while the Core has to deal with that by applying the layer // position to the translation var anchorPosition = GetLayerAnchorPosition(layer); - var anchorProperty = layer.AnchorPointProperty.CurrentValue; + var anchorProperty = layer.Properties.AnchorPoint.CurrentValue; // Translation originates from the unscaled center of the shape and is tied to the anchor var x = anchorPosition.X - layerBounds.MidX - anchorProperty.X * layerBounds.Width; @@ -67,8 +67,8 @@ namespace Artemis.UI.Services var transformGroup = new TransformGroup(); transformGroup.Children.Add(new TranslateTransform(x, y)); - transformGroup.Children.Add(new ScaleTransform(layer.ScaleProperty.CurrentValue.Width / 100f, layer.ScaleProperty.CurrentValue.Height / 100f, anchorPosition.X, anchorPosition.Y)); - transformGroup.Children.Add(new RotateTransform(layer.RotationProperty.CurrentValue, anchorPosition.X, anchorPosition.Y)); + transformGroup.Children.Add(new ScaleTransform(layer.Properties.Scale.CurrentValue.Width / 100f, layer.Properties.Scale.CurrentValue.Height / 100f, anchorPosition.X, anchorPosition.Y)); + transformGroup.Children.Add(new RotateTransform(layer.Properties.Rotation.CurrentValue, anchorPosition.X, anchorPosition.Y)); return transformGroup; } @@ -83,7 +83,7 @@ namespace Artemis.UI.Services if (anchorOverride != null) anchorPosition = anchorOverride.Value; - var anchorProperty = layer.AnchorPointProperty.CurrentValue; + var anchorProperty = layer.Properties.AnchorPoint.CurrentValue; // Translation originates from the unscaled center of the shape and is tied to the anchor var x = anchorPosition.X - layerBounds.MidX - anchorProperty.X * layerBounds.Width; @@ -94,9 +94,9 @@ namespace Artemis.UI.Services if (includeTranslation) path.Transform(SKMatrix.MakeTranslation(x, y)); if (includeScale) - path.Transform(SKMatrix.MakeScale(layer.ScaleProperty.CurrentValue.Width / 100f, layer.ScaleProperty.CurrentValue.Height / 100f, anchorPosition.X, anchorPosition.Y)); + path.Transform(SKMatrix.MakeScale(layer.Properties.Scale.CurrentValue.Width / 100f, layer.Properties.Scale.CurrentValue.Height / 100f, anchorPosition.X, anchorPosition.Y)); if (includeRotation) - path.Transform(SKMatrix.MakeRotationDegrees(layer.RotationProperty.CurrentValue, anchorPosition.X, anchorPosition.Y)); + path.Transform(SKMatrix.MakeRotationDegrees(layer.Properties.Rotation.CurrentValue, anchorPosition.X, anchorPosition.Y)); return path; }