diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 549f6a304..def2607a6 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -211,7 +211,6 @@ - diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index 2384236f6..a34d7a40a 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -50,13 +50,19 @@ namespace Artemis.Core.Models.Profile _properties = new Dictionary(); CreateDefaultProperties(); + CreateShapeType(); - switch (layerEntity.ShapeType) + ShapeTypeProperty.ValueChanged += (sender, args) => CreateShapeType(); + } + + private void CreateShapeType() + { + switch (ShapeTypeProperty.CurrentValue) { - case ShapeEntityType.Ellipse: + case LayerShapeType.Ellipse: LayerShape = new Ellipse(this); break; - case ShapeEntityType.Rectangle: + case LayerShapeType.Rectangle: LayerShape = new Rectangle(this); break; default: @@ -111,6 +117,12 @@ namespace Artemis.Core.Models.Profile /// public ReadOnlyCollection Properties => _properties.Values.ToList().AsReadOnly(); + public LayerProperty ShapeTypeProperty { get; set; } + + public LayerProperty FillTypeProperty { get; set; } + + public LayerProperty BlendModeProperty { get; set; } + /// /// The anchor point property of this layer, also found in /// @@ -124,7 +136,7 @@ namespace Artemis.Core.Models.Profile /// /// The size property of this layer, also found in /// - public LayerProperty SizeProperty { get; private set; } + public LayerProperty ScaleProperty { get; private set; } /// /// The rotation property of this layer range 0 - 360, also found in @@ -162,41 +174,48 @@ namespace Artemis.Core.Models.Profile canvas.Save(); canvas.ClipPath(Path); - // Apply transformations - var sizeProperty = SizeProperty.CurrentValue; - var rotationProperty = RotationProperty.CurrentValue; - - var anchorPosition = GetLayerAnchorPosition(); - var anchorProperty = AnchorPointProperty.CurrentValue; - - // Translation originates from the unscaled center of the layer and is tied to the anchor - var x = anchorPosition.X - Bounds.MidX - anchorProperty.X * Bounds.Width; - var y = anchorPosition.Y - Bounds.MidY - anchorProperty.Y * Bounds.Height; - - // Rotation is always applied on the canvas - canvas.RotateDegrees(rotationProperty, anchorPosition.X, anchorPosition.Y); - // canvas.Scale(sizeProperty.Width, sizeProperty.Height, anchorPosition.X, anchorPosition.Y); - // Once the other transformations are done it is save to translate - // canvas.Translate(x, y); - - // Placeholder - if (LayerShape?.Path != null) + using (var paint = new SKPaint()) { - var testColors = new List(); - for (var i = 0; i < 9; i++) + paint.BlendMode = BlendModeProperty.CurrentValue; + paint.Color = new SKColor(0, 0, 0, (byte) (OpacityProperty.CurrentValue * 2.55f)); + + // Apply transformations + var sizeProperty = ScaleProperty.CurrentValue; + var rotationProperty = RotationProperty.CurrentValue; + + var anchorPosition = GetLayerAnchorPosition(); + var anchorProperty = AnchorPointProperty.CurrentValue; + + // Translation originates from the unscaled center of the layer and is tied to the anchor + var x = anchorPosition.X - Bounds.MidX - anchorProperty.X * Bounds.Width; + var y = anchorPosition.Y - Bounds.MidY - anchorProperty.Y * Bounds.Height; + + // Rotation is always applied on the canvas + canvas.RotateDegrees(rotationProperty, anchorPosition.X, anchorPosition.Y); + // canvas.Scale(sizeProperty.Width, sizeProperty.Height, anchorPosition.X, anchorPosition.Y); + // Once the other transformations are done it is save to translate + // canvas.Translate(x, y); + + // Placeholder + if (LayerShape?.Path != null) { - if (i != 8) - testColors.Add(SKColor.FromHsv(i * 32, 100, 100)); - else - testColors.Add(SKColor.FromHsv(0, 100, 100)); + var testColors = new List(); + for (var i = 0; i < 9; i++) + { + if (i != 8) + testColors.Add(SKColor.FromHsv(i * 32, 100, 100)); + else + testColors.Add(SKColor.FromHsv(0, 100, 100)); + } + + var path = new SKPath(LayerShape.Path); + path.Transform(SKMatrix.MakeTranslation(x, y)); + path.Transform(SKMatrix.MakeScale(sizeProperty.Width / 100f, sizeProperty.Height / 100f, anchorPosition.X, anchorPosition.Y)); + + + paint.Shader = SKShader.CreateSweepGradient(new SKPoint(path.Bounds.MidX, path.Bounds.MidY), testColors.ToArray()); + canvas.DrawPath(path, paint); } - - var path = new SKPath(LayerShape.Path); - path.Transform(SKMatrix.MakeTranslation(x, y)); - path.Transform(SKMatrix.MakeScale(sizeProperty.Width, sizeProperty.Height, anchorPosition.X, anchorPosition.Y)); - - var shader = SKShader.CreateSweepGradient(new SKPoint(path.Bounds.MidX, path.Bounds.MidY), testColors.ToArray()); - canvas.DrawPath(path, new SKPaint {Shader = shader, Color = new SKColor(0, 0, 0, (byte) (OpacityProperty.CurrentValue * 2.55f))}); } LayerBrush?.Render(canvas); @@ -253,9 +272,6 @@ namespace Artemis.Core.Models.Profile Configuration = JsonConvert.SerializeObject(LayerBrush.Settings) }; } - - // Shape - LayerShape?.ApplyToEntity(); } /// @@ -397,22 +413,43 @@ namespace Artemis.Core.Models.Profile private void CreateDefaultProperties() { - var transformProperty = new LayerProperty(this, null, "Core.Transform", "Transform", "The default properties collection every layer has, allows you to transform the shape.") - {ExpandByDefault = true}; - AnchorPointProperty = new LayerProperty(this, transformProperty, "Core.AnchorPoint", "Anchor Point", "The point at which the shape is attached to its position."); - PositionProperty = new LayerProperty(this, transformProperty, "Core.Position", "Position", "The position of the shape."); - SizeProperty = new LayerProperty(this, transformProperty, "Core.Size", "Size", "The size of the shape.") {InputAffix = "%"}; - RotationProperty = new LayerProperty(this, transformProperty, "Core.Rotation", "Rotation", "The rotation of the shape in degrees.") {InputAffix = "°"}; - OpacityProperty = new LayerProperty(this, transformProperty, "Core.Opacity", "Opacity", "The opacity of the shape.") {InputAffix = "%"}; - transformProperty.Children.Add(AnchorPointProperty); - transformProperty.Children.Add(PositionProperty); - transformProperty.Children.Add(SizeProperty); - transformProperty.Children.Add(RotationProperty); - transformProperty.Children.Add(OpacityProperty); + var shape = new LayerProperty(this, null, "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}; + shape.Children.Add(ShapeTypeProperty); + shape.Children.Add(FillTypeProperty); + shape.Children.Add(BlendModeProperty); - AddLayerProperty(transformProperty); - foreach (var transformPropertyChild in transformProperty.Children) - AddLayerProperty(transformPropertyChild); + var transform = new LayerProperty(this, null, "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."); + PositionProperty = new LayerProperty(this, transform, "Core.Position", "Position", "The position of the shape."); + ScaleProperty = new LayerProperty(this, transform, "Core.Scale", "Scale", "The scale of the shape.") {InputAffix = "%"}; + 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 = "%"}; + transform.Children.Add(AnchorPointProperty); + transform.Children.Add(PositionProperty); + transform.Children.Add(ScaleProperty); + transform.Children.Add(RotationProperty); + + // Set default values + ShapeTypeProperty.Value = LayerShapeType.Rectangle; + FillTypeProperty.Value = LayerFillType.Stretch; + BlendModeProperty.Value = SKBlendMode.SrcOver; + + ScaleProperty.Value = new SKSize(100, 100); + OpacityProperty.Value = 100; + + + transform.Children.Add(OpacityProperty); + + AddLayerProperty(shape); + foreach (var shapeProperty in shape.Children) + AddLayerProperty(shapeProperty); + + AddLayerProperty(transform); + foreach (var transformProperty in transform.Children) + AddLayerProperty(transformProperty); } #endregion @@ -434,4 +471,17 @@ namespace Artemis.Core.Models.Profile #endregion } + + public enum LayerShapeType + { + Ellipse, + Rectangle + } + + public enum LayerFillType + { + Stretch, + Clip, + Tile + } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs index be69fd077..7e279c61b 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs @@ -182,7 +182,9 @@ namespace Artemis.Core.Models.Profile.LayerProperties /// public void ClearKeyframes() { - BaseValue = KeyframeEngine.GetCurrentValue(); + if (KeyframeEngine != null) + BaseValue = KeyframeEngine.GetCurrentValue(); + BaseKeyframes.Clear(); } @@ -265,6 +267,9 @@ namespace Artemis.Core.Models.Profile.LayerProperties #region Events + /// + /// Occurs when this property's value was changed outside regular keyframe updates + /// public event EventHandler ValueChanged; protected virtual void OnValueChanged() diff --git a/src/Artemis.Core/Models/Profile/LayerShapes/Ellipse.cs b/src/Artemis.Core/Models/Profile/LayerShapes/Ellipse.cs index 58c6a6d9e..68cbca838 100644 --- a/src/Artemis.Core/Models/Profile/LayerShapes/Ellipse.cs +++ b/src/Artemis.Core/Models/Profile/LayerShapes/Ellipse.cs @@ -15,10 +15,5 @@ namespace Artemis.Core.Models.Profile.LayerShapes path.AddOval(Layer.Bounds); Path = path; } - - public override void ApplyToEntity() - { - Layer.LayerEntity.ShapeType = ShapeEntityType.Ellipse; - } } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/LayerShapes/LayerShape.cs b/src/Artemis.Core/Models/Profile/LayerShapes/LayerShape.cs index 7b462a3d7..d05e62bfc 100644 --- a/src/Artemis.Core/Models/Profile/LayerShapes/LayerShape.cs +++ b/src/Artemis.Core/Models/Profile/LayerShapes/LayerShape.cs @@ -20,7 +20,5 @@ namespace Artemis.Core.Models.Profile.LayerShapes public SKPath Path { get; protected set; } public abstract void CalculateRenderProperties(); - - public abstract void ApplyToEntity(); } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/LayerShapes/Rectangle.cs b/src/Artemis.Core/Models/Profile/LayerShapes/Rectangle.cs index 740b6f5b9..8b059f432 100644 --- a/src/Artemis.Core/Models/Profile/LayerShapes/Rectangle.cs +++ b/src/Artemis.Core/Models/Profile/LayerShapes/Rectangle.cs @@ -15,10 +15,5 @@ namespace Artemis.Core.Models.Profile.LayerShapes path.AddRect(Layer.Bounds); Path = path; } - - public override void ApplyToEntity() - { - Layer.LayerEntity.ShapeType = ShapeEntityType.Rectangle; - } } } \ No newline at end of file diff --git a/src/Artemis.Plugins.LayerBrushes.Color/Artemis.Plugins.LayerBrushes.Color.csproj b/src/Artemis.Plugins.LayerBrushes.Color/Artemis.Plugins.LayerBrushes.Color.csproj index a9b3d6761..1fbedfc38 100644 --- a/src/Artemis.Plugins.LayerBrushes.Color/Artemis.Plugins.LayerBrushes.Color.csproj +++ b/src/Artemis.Plugins.LayerBrushes.Color/Artemis.Plugins.LayerBrushes.Color.csproj @@ -12,7 +12,7 @@ v4.7.2 512 true - false + false @@ -102,6 +102,10 @@ Artemis.Core False + + {adb357e6-151d-4d0d-87cb-68fd0bc29812} + Artemis.UI.Shared + diff --git a/src/Artemis.Plugins.LayerBrushes.Color/ColorBrushViewModel.cs b/src/Artemis.Plugins.LayerBrushes.Color/ColorBrushViewModel.cs index d13a65287..54ba5429e 100644 --- a/src/Artemis.Plugins.LayerBrushes.Color/ColorBrushViewModel.cs +++ b/src/Artemis.Plugins.LayerBrushes.Color/ColorBrushViewModel.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using Artemis.Core.Plugins.LayerBrush; -using Artemis.Core.Utilities; +using Artemis.UI.Shared.Utilities; namespace Artemis.Plugins.LayerBrushes.Color { diff --git a/src/Artemis.Plugins.LayerBrushes.Noise/NoiseBrushViewModel.cs b/src/Artemis.Plugins.LayerBrushes.Noise/NoiseBrushViewModel.cs index 577728125..69c7a98c2 100644 --- a/src/Artemis.Plugins.LayerBrushes.Noise/NoiseBrushViewModel.cs +++ b/src/Artemis.Plugins.LayerBrushes.Noise/NoiseBrushViewModel.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using Artemis.Core.Plugins.LayerBrush; -using Artemis.Core.Utilities; +using Artemis.UI.Shared.Utilities; using SkiaSharp; namespace Artemis.Plugins.LayerBrushes.Noise diff --git a/src/Artemis.Storage/Entities/Profile/LayerEntity.cs b/src/Artemis.Storage/Entities/Profile/LayerEntity.cs index bf11bd782..65bcf2b64 100644 --- a/src/Artemis.Storage/Entities/Profile/LayerEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/LayerEntity.cs @@ -23,7 +23,6 @@ namespace Artemis.Storage.Entities.Profile public List PropertyEntities { get; set; } public List Condition { get; set; } - public ShapeEntityType ShapeType { get; set; } public BrushEntity BrushEntity { get; set; } [BsonRef("ProfileEntity")] @@ -31,10 +30,4 @@ namespace Artemis.Storage.Entities.Profile public Guid ProfileId { get; set; } } - - public enum ShapeEntityType - { - Ellipse, - Rectangle - } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index d0dd9a1a4..7699b36c0 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -13,7 +13,7 @@ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 true - false + false @@ -38,6 +38,9 @@ MinimumRecommendedRules.ruleset + + ..\packages\Humanizer.Core.2.7.9\lib\netstandard2.0\Humanizer.dll + ..\packages\MaterialDesignColors.1.2.0\lib\net45\MaterialDesignColors.dll @@ -76,6 +79,7 @@ + Designer MSBuild:Compile diff --git a/src/Artemis.Core/Utilities/EnumUtilities.cs b/src/Artemis.UI.Shared/Utilities/EnumUtilities.cs similarity index 90% rename from src/Artemis.Core/Utilities/EnumUtilities.cs rename to src/Artemis.UI.Shared/Utilities/EnumUtilities.cs index 94b8546ba..4fe404335 100644 --- a/src/Artemis.Core/Utilities/EnumUtilities.cs +++ b/src/Artemis.UI.Shared/Utilities/EnumUtilities.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; +using Humanizer; -namespace Artemis.Core.Utilities +namespace Artemis.UI.Shared.Utilities { public static class EnumUtilities { @@ -25,7 +26,7 @@ namespace Artemis.Core.Utilities if (!t.IsEnum) throw new ArgumentException($"{nameof(t)} must be an enum type"); - return Enum.GetValues(t).Cast().Select(e => new ValueDescription {Value = e, Description = e.Description()}).ToList(); + return Enum.GetValues(t).Cast().Select(e => new ValueDescription {Value = e, Description = e.Humanize()}).ToList(); } } diff --git a/src/Artemis.UI.Shared/packages.config b/src/Artemis.UI.Shared/packages.config index 255195166..79da121c3 100644 --- a/src/Artemis.UI.Shared/packages.config +++ b/src/Artemis.UI.Shared/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 426741974..4394e7bc9 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -52,8 +52,8 @@ ..\packages\gong-wpf-dragdrop.2.1.0\lib\net47\GongSolutions.WPF.DragDrop.dll - - ..\packages\Humanizer.Core.2.6.2\lib\netstandard2.0\Humanizer.dll + + ..\packages\Humanizer.Core.2.7.9\lib\netstandard2.0\Humanizer.dll ..\packages\MaterialDesignColors.1.2.2\lib\net45\MaterialDesignColors.dll @@ -169,6 +169,10 @@ + + EnumPropertyInputView.xaml + + @@ -298,6 +302,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + MSBuild:Compile Designer diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml index de275c1f2..0b249b0df 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml @@ -19,6 +19,43 @@ + @@ -74,7 +111,11 @@ - + @@ -113,7 +154,12 @@ - + - diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml.cs index 430339120..a8fff5257 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml.cs @@ -17,8 +17,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties { if (sender == TimelineHeaderScrollViewer) TimelineRailsScrollViewer.ScrollToHorizontalOffset(e.HorizontalOffset); + else if (sender == PropertyTreeScrollViewer) + TimelineRailsScrollViewer.ScrollToVerticalOffset(e.VerticalOffset); else if (sender == TimelineRailsScrollViewer) + { TimelineHeaderScrollViewer.ScrollToHorizontalOffset(e.HorizontalOffset); + PropertyTreeScrollViewer.ScrollToVerticalOffset(e.VerticalOffset); + } } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs index 561826b72..2c06a0b91 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.UI.Ninject.Factories; @@ -58,14 +59,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties // Force the keyframe engine to update, the new keyframe is the current keyframe LayerProperty.IsUsingKeyframes = _keyframesEnabled; - LayerProperty.KeyframeEngine.Update(0); + LayerProperty.KeyframeEngine?.Update(0); _profileEditorService.UpdateSelectedProfileElement(); } public PropertyInputViewModel GetPropertyInputViewModel() { - var match = _kernel.Get>().FirstOrDefault(p => p.CompatibleTypes.Contains(LayerProperty.Type)); + // If the type is an enum type, search for Enum instead. + var type = LayerProperty.Type; + if (type.IsEnum) + type = typeof(Enum); + + var match = _kernel.Get>().FirstOrDefault(p => p.CompatibleTypes.Contains(type)); if (match == null) return null; diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml new file mode 100644 index 000000000..416b66bf6 --- /dev/null +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml.cs new file mode 100644 index 000000000..ecbd7ab17 --- /dev/null +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputView.xaml.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput +{ + /// + /// Interaction logic for EnumPropertyInputView.xaml + /// + public partial class EnumPropertyInputView : UserControl + { + public EnumPropertyInputView() + { + InitializeComponent(); + } + + private void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e) + { + e.Handled = true; + } + } +} diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputViewModel.cs new file mode 100644 index 000000000..1519e3f63 --- /dev/null +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/EnumPropertyInputViewModel.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Utilities; + +namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput +{ + public class EnumPropertyInputViewModel : PropertyInputViewModel + { + public EnumPropertyInputViewModel(IProfileEditorService profileEditorService) : base(profileEditorService) + { + } + + public IEnumerable EnumValues { get; private set; } + + public sealed override List CompatibleTypes { get; } = new List {typeof(Enum)}; + + public object EnumInputValue + { + get => InputValue ?? Enum.GetValues(LayerPropertyViewModel.LayerProperty.Type).Cast().First(); + set => InputValue = value; + } + + protected override void OnInitialized() + { + EnumValues = EnumUtilities.GetAllValuesAndDescriptions(LayerPropertyViewModel.LayerProperty.Type); + } + + public override void Update() + { + NotifyOfPropertyChange(() => EnumInputValue); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputView.xaml index e7438d926..350c7f1eb 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput" 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:FloatPropertyInputViewModel}"> @@ -15,7 +16,8 @@ Padding="0 -1" materialDesign:ValidationAssist.UsePopup="True" HorizontalAlignment="Left" - Text="{Binding FloatInputValue}" /> + Text="{Binding FloatInputValue}" + RequestBringIntoView="{s:Action OnRequestBringIntoView}"/> \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputView.xaml index 0b262da99..939600474 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput" 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:IntPropertyInputViewModel}"> @@ -15,7 +16,8 @@ Padding="0 -1" materialDesign:ValidationAssist.UsePopup="True" HorizontalAlignment="Left" - Text="{Binding IntInputValue}" /> + Text="{Binding IntInputValue}" + RequestBringIntoView="{s:Action OnRequestBringIntoView}"/> \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs index 4396fdca3..2d835c563 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Windows; using Artemis.UI.Exceptions; using Artemis.UI.Services.Interfaces; using Stylet; @@ -28,16 +29,31 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P public void Initialize(LayerPropertyViewModel layerPropertyViewModel) { + var type = layerPropertyViewModel.LayerProperty.Type; + if (type.IsEnum) + type = typeof(Enum); if (Initialized) throw new ArtemisUIException("Cannot initialize the same property input VM twice"); - if (!CompatibleTypes.Contains(layerPropertyViewModel.LayerProperty.Type)) - throw new ArtemisUIException($"This input VM does not support the provided type {layerPropertyViewModel.LayerProperty.Type.Name}"); + if (!CompatibleTypes.Contains(type)) + throw new ArtemisUIException($"This input VM does not support the provided type {type.Name}"); LayerPropertyViewModel = layerPropertyViewModel; layerPropertyViewModel.LayerProperty.ValueChanged += (sender, args) => Update(); Update(); Initialized = true; + + OnInitialized(); + } + + /// + /// Called by the view, prevents scrolling into view when scrubbing through the timeline + /// + /// + /// + public void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e) + { + e.Handled = true; } private void UpdateInputValue(object value) @@ -49,6 +65,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P ProfileEditorService.UpdateSelectedProfileElement(); } + protected virtual void OnInitialized() + { + } + public abstract void Update(); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputView.xaml index 2a786dd17..60f797e7d 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:s="https://github.com/canton7/Stylet" mc:Ignorable="d" d:DesignHeight="25" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:SKPointPropertyInputViewModel}"> @@ -16,7 +17,8 @@ materialDesign:ValidationAssist.UsePopup="True" HorizontalAlignment="Left" ToolTip="X-coordinate (horizontal)" - Text="{Binding X}" /> + Text="{Binding X}" + RequestBringIntoView="{s:Action OnRequestBringIntoView}"/> , + Text="{Binding Y}" + RequestBringIntoView="{s:Action OnRequestBringIntoView}"/> \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputView.xaml index 23321ad95..6b33cd6dd 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput" 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:SKSizePropertyInputViewModel}"> @@ -16,7 +17,8 @@ materialDesign:ValidationAssist.UsePopup="True" HorizontalAlignment="Left" ToolTip="Height" - Text="{Binding Height}" /> + Text="{Binding Height}" + RequestBringIntoView="{s:Action OnRequestBringIntoView}"/> , + Text="{Binding Width}" + RequestBringIntoView="{s:Action OnRequestBringIntoView}"/> \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeChildView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeChildView.xaml index ae91ca1d9..c58a40810 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeChildView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeChildView.xaml @@ -23,6 +23,7 @@ Width="18" Height="18" IsChecked="{Binding LayerPropertyViewModel.KeyframesEnabled}" + IsEnabled="{Binding LayerPropertyViewModel.LayerProperty.CanUseKeyframes}" VerticalAlignment="Center" Padding="-25"> diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeView.xaml index e85a9df21..cb405f2f6 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeView.xaml @@ -82,6 +82,7 @@