mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 17:53:32 +00:00
Added keyframe creation outside the timeline
Added existing shape moving
This commit is contained in:
parent
a138ec916d
commit
7ddf816ca5
@ -21,68 +21,82 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
|||||||
Name = name;
|
Name = name;
|
||||||
Description = description;
|
Description = description;
|
||||||
Type = type;
|
Type = type;
|
||||||
|
CanUseKeyframes = true;
|
||||||
|
|
||||||
Children = new List<BaseLayerProperty>();
|
Children = new List<BaseLayerProperty>();
|
||||||
BaseKeyframes = new List<BaseKeyframe>();
|
BaseKeyframes = new List<BaseKeyframe>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layer this property applies to
|
/// Gets the layer this property applies to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Layer Layer { get; }
|
public Layer Layer { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The parent property of this property.
|
/// Gets the parent property of this property.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BaseLayerProperty Parent { get; }
|
public BaseLayerProperty Parent { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The child properties of this property.
|
/// Gets or sets the child properties of this property.
|
||||||
/// <remarks>If the layer has children it cannot contain a value or keyframes.</remarks>
|
/// <remarks>If the layer has children it cannot contain a value or keyframes.</remarks>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<BaseLayerProperty> Children { get; set; }
|
public List<BaseLayerProperty> Children { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A unique identifier for this property, a layer may not contain two properties with the same ID.
|
/// Gets or sets a unique identifier for this property, a layer may not contain two properties with the same ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user-friendly name for this property, shown in the UI.
|
/// Gets or sets the user-friendly name for this property, shown in the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user-friendly description for this property, shown in the UI.
|
/// Gets or sets the user-friendly description for this property, shown in the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether to expand this property by default, this is useful for important parent properties.
|
/// Gets or sets whether to expand this property by default, this is useful for important parent properties.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ExpandByDefault { get; set; }
|
public bool ExpandByDefault { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An optional input prefix to show before input elements in the UI.
|
/// Gets or sets the an optional input prefix to show before input elements in the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string InputPrefix { get; set; }
|
public string InputPrefix { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An optional input affix to show behind input elements in the UI.
|
/// Gets or sets an optional input affix to show behind input elements in the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string InputAffix { get; set; }
|
public string InputAffix { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of value this layer property contains.
|
/// Gets or sets whether this property can use keyframes, True by default.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Type Type { get; set; }
|
public bool CanUseKeyframes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of keyframes defining different values of the property in time, this list contains the untyped
|
/// Gets or sets whether this property is using keyframes.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsUsingKeyframes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of value this layer property contains.
|
||||||
|
/// </summary>
|
||||||
|
public Type Type { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of keyframes defining different values of the property in time, this list contains the untyped
|
||||||
/// <see cref="BaseKeyframe" />.
|
/// <see cref="BaseKeyframe" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyCollection<BaseKeyframe> UntypedKeyframes => BaseKeyframes.AsReadOnly();
|
public IReadOnlyCollection<BaseKeyframe> UntypedKeyframes => BaseKeyframes.AsReadOnly();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the keyframe engine instance of this property
|
||||||
|
/// </summary>
|
||||||
public KeyframeEngine KeyframeEngine { get; set; }
|
public KeyframeEngine KeyframeEngine { get; set; }
|
||||||
|
|
||||||
protected List<BaseKeyframe> BaseKeyframes { get; set; }
|
protected List<BaseKeyframe> BaseKeyframes { get; set; }
|
||||||
@ -113,6 +127,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
|||||||
|
|
||||||
propertyEntity.ValueType = Type.Name;
|
propertyEntity.ValueType = Type.Name;
|
||||||
propertyEntity.Value = JsonConvert.SerializeObject(BaseValue);
|
propertyEntity.Value = JsonConvert.SerializeObject(BaseValue);
|
||||||
|
propertyEntity.IsUsingKeyframes = IsUsingKeyframes;
|
||||||
|
|
||||||
propertyEntity.KeyframeEntities.Clear();
|
propertyEntity.KeyframeEntities.Clear();
|
||||||
foreach (var baseKeyframe in BaseKeyframes)
|
foreach (var baseKeyframe in BaseKeyframes)
|
||||||
@ -129,6 +144,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
|||||||
internal void ApplyToProperty(PropertyEntity propertyEntity)
|
internal void ApplyToProperty(PropertyEntity propertyEntity)
|
||||||
{
|
{
|
||||||
BaseValue = DeserializePropertyValue(propertyEntity.Value);
|
BaseValue = DeserializePropertyValue(propertyEntity.Value);
|
||||||
|
IsUsingKeyframes = propertyEntity.IsUsingKeyframes;
|
||||||
|
|
||||||
BaseKeyframes.Clear();
|
BaseKeyframes.Clear();
|
||||||
foreach (var keyframeEntity in propertyEntity.KeyframeEntities.OrderBy(e => e.Position))
|
foreach (var keyframeEntity in propertyEntity.KeyframeEntities.OrderBy(e => e.Position))
|
||||||
@ -170,6 +186,33 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
|||||||
BaseKeyframes.Clear();
|
BaseKeyframes.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current value using the regular value or keyframes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to set.</param>
|
||||||
|
/// <param name="time">
|
||||||
|
/// An optional time to set the value add, if provided and property is using keyframes the value will be set to an new
|
||||||
|
/// or existing keyframe.
|
||||||
|
/// </param>
|
||||||
|
public void SetCurrentValue(object value, TimeSpan? time)
|
||||||
|
{
|
||||||
|
if (value != null && value.GetType() != Type)
|
||||||
|
throw new ArtemisCoreException($"Cannot set value of type {value.GetType()} on property {this}, expected type is {Type}.");
|
||||||
|
|
||||||
|
if (time == null || !CanUseKeyframes || !IsUsingKeyframes)
|
||||||
|
BaseValue = value;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If on a keyframe, update the keyframe
|
||||||
|
var currentKeyframe = UntypedKeyframes.FirstOrDefault(k => k.Position == time.Value);
|
||||||
|
// Create a new keyframe if none found
|
||||||
|
if (currentKeyframe == null)
|
||||||
|
currentKeyframe = CreateNewKeyframe(time.Value);
|
||||||
|
|
||||||
|
currentKeyframe.BaseValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void SortKeyframes()
|
internal void SortKeyframes()
|
||||||
{
|
{
|
||||||
BaseKeyframes = BaseKeyframes.OrderBy(k => k.Position).ToList();
|
BaseKeyframes = BaseKeyframes.OrderBy(k => k.Position).ToList();
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Artemis.Core.Models.Profile.LayerProperties
|
namespace Artemis.Core.Models.Profile.LayerProperties
|
||||||
@ -10,7 +11,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value of the property without any keyframes applied
|
/// Gets or sets the value of the property without any keyframes applied
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public T Value
|
public T Value
|
||||||
{
|
{
|
||||||
@ -19,12 +20,12 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value of the property with keyframes applied
|
/// Gets the value of the property with keyframes applied
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public T CurrentValue => KeyframeEngine != null ? (T) KeyframeEngine.GetCurrentValue() : Value;
|
public T CurrentValue => KeyframeEngine != null ? (T) KeyframeEngine.GetCurrentValue() : Value;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of keyframes defining different values of the property in time, this list contains the strongly typed
|
/// Gets a list of keyframes defining different values of the property in time, this list contains the strongly typed
|
||||||
/// <see cref="Keyframe{T}" />
|
/// <see cref="Keyframe{T}" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<Keyframe<T>> Keyframes => BaseKeyframes.Cast<Keyframe<T>>().ToList().AsReadOnly();
|
public ReadOnlyCollection<Keyframe<T>> Keyframes => BaseKeyframes.Cast<Keyframe<T>>().ToList().AsReadOnly();
|
||||||
@ -50,7 +51,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current value using the keyframes
|
/// Gets the current value using the regular value or if present, keyframes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public T GetCurrentValue()
|
public T GetCurrentValue()
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
@ -41,13 +42,14 @@ namespace Artemis.Core.Models.Profile.LayerShapes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates Position and Size using the provided unscaled rectangle
|
/// Updates Position and Size using the provided unscaled rectangle
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rect">An unscaled rectangle where 1px = 1mm</param>
|
/// <param name="rect">An unscaled rectangle which is relative to the layer (1.0 being full width/height, 0.5 being half).</param>
|
||||||
public void SetFromUnscaledRectangle(SKRect rect)
|
/// <param name="time">An optional timespan to indicate where to set the properties, if null the properties' base values will be used.</param>
|
||||||
|
public void SetFromUnscaledRectangle(SKRect rect, TimeSpan? time)
|
||||||
{
|
{
|
||||||
if (!Layer.Leds.Any())
|
if (!Layer.Leds.Any())
|
||||||
{
|
{
|
||||||
Layer.PositionProperty.Value = SKPoint.Empty;
|
Layer.PositionProperty.SetCurrentValue(SKPoint.Empty, time);
|
||||||
Layer.SizeProperty.Value = SKSize.Empty;
|
Layer.SizeProperty.SetCurrentValue(SKSize.Empty, time);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +58,9 @@ namespace Artemis.Core.Models.Profile.LayerShapes
|
|||||||
var width = Layer.Leds.Max(l => l.RgbLed.AbsoluteLedRectangle.Location.X + l.RgbLed.AbsoluteLedRectangle.Size.Width) - x;
|
var width = Layer.Leds.Max(l => l.RgbLed.AbsoluteLedRectangle.Location.X + l.RgbLed.AbsoluteLedRectangle.Size.Width) - x;
|
||||||
var height = Layer.Leds.Max(l => l.RgbLed.AbsoluteLedRectangle.Location.Y + l.RgbLed.AbsoluteLedRectangle.Size.Height) - y;
|
var height = Layer.Leds.Max(l => l.RgbLed.AbsoluteLedRectangle.Location.Y + l.RgbLed.AbsoluteLedRectangle.Size.Height) - y;
|
||||||
|
|
||||||
Layer.PositionProperty.Value = new SKPoint((float) (100f / width * (rect.Left - x)) / 100f, (float) (100f / height * (rect.Top - y)) / 100f);
|
Layer.PositionProperty.SetCurrentValue(new SKPoint((float) (100f / width * (rect.Left - x)) / 100f, (float) (100f / height * (rect.Top - y)) / 100f), time);
|
||||||
Layer.SizeProperty.Value = new SKSize((float) (100f / width * rect.Width) / 100f, (float) (100f / height * rect.Height) / 100f);
|
Layer.SizeProperty.SetCurrentValue(new SKSize((float) (100f / width * rect.Width) / 100f, (float) (100f / height * rect.Height) / 100f), time);
|
||||||
|
|
||||||
// TODO: Update keyframes
|
|
||||||
CalculateRenderProperties(Layer.PositionProperty.CurrentValue, Layer.SizeProperty.CurrentValue);
|
CalculateRenderProperties(Layer.PositionProperty.CurrentValue, Layer.SizeProperty.CurrentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string ValueType { get; set; }
|
public string ValueType { get; set; }
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
|
public bool IsUsingKeyframes { get; set; }
|
||||||
|
|
||||||
public List<KeyframeEntity> KeyframeEntities { get; set; }
|
public List<KeyframeEntity> KeyframeEntities { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,25 +40,25 @@
|
|||||||
<!-- Misc controls & time display -->
|
<!-- Misc controls & time display -->
|
||||||
<DockPanel Grid.Row="0" VerticalAlignment="Center">
|
<DockPanel Grid.Row="0" VerticalAlignment="Center">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Play from start (Shift+Space)" Command="{s:Action PlayFromStart}">
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Play from start (Shift+Space)" Command="{s:Action PlayFromStart}" Focusable="False">
|
||||||
<materialDesign:PackIcon Kind="StepForward" />
|
<materialDesign:PackIcon Kind="StepForward" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Toggle play/pause (Space)" Command="{s:Action Play}">
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Toggle play/pause (Space)" Command="{s:Action Play}" Focusable="False">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<materialDesign:PackIcon Kind="Play" Visibility="{Binding Playing, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}" />
|
<materialDesign:PackIcon Kind="Play" Visibility="{Binding Playing, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}" />
|
||||||
<materialDesign:PackIcon Kind="Pause" Visibility="{Binding Playing, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
|
<materialDesign:PackIcon Kind="Pause" Visibility="{Binding Playing, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</Button>
|
||||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Go to start" Command="{s:Action GoToStart}">
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Go to start" Command="{s:Action GoToStart}" Focusable="False">
|
||||||
<materialDesign:PackIcon Kind="SkipBackward" />
|
<materialDesign:PackIcon Kind="SkipBackward" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Go to end" Command="{s:Action GoToEnd}">
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Go to end" Command="{s:Action GoToEnd}" Focusable="False">
|
||||||
<materialDesign:PackIcon Kind="SkipForward" />
|
<materialDesign:PackIcon Kind="SkipForward" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Previous frame" Command="{s:Action GoToPreviousFrame}">
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Previous frame" Command="{s:Action GoToPreviousFrame}" Focusable="False">
|
||||||
<materialDesign:PackIcon Kind="SkipPrevious" />
|
<materialDesign:PackIcon Kind="SkipPrevious" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Next frame" Command="{s:Action GoToNextFrame}">
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Next frame" Command="{s:Action GoToNextFrame}" Focusable="False">
|
||||||
<materialDesign:PackIcon Kind="SkipNext" />
|
<materialDesign:PackIcon Kind="SkipNext" />
|
||||||
</Button>
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@ -19,7 +19,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
|||||||
{
|
{
|
||||||
_kernel = kernel;
|
_kernel = kernel;
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
_keyframesEnabled = layerProperty.UntypedKeyframes.Any();
|
_keyframesEnabled = layerProperty.IsUsingKeyframes;
|
||||||
|
|
||||||
LayerProperty = layerProperty;
|
LayerProperty = layerProperty;
|
||||||
Parent = parent;
|
Parent = parent;
|
||||||
@ -56,6 +56,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
|||||||
LayerProperty.ClearKeyframes();
|
LayerProperty.ClearKeyframes();
|
||||||
|
|
||||||
// Force the keyframe engine to update, the new keyframe is the current keyframe
|
// 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();
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
|
|
||||||
public float FloatInputValue
|
public float FloatInputValue
|
||||||
{
|
{
|
||||||
get => (float) InputValue;
|
get => (float?) InputValue ?? 0f;
|
||||||
set => InputValue = value;
|
set => InputValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,17 +23,5 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
{
|
{
|
||||||
NotifyOfPropertyChange(() => FloatInputValue);
|
NotifyOfPropertyChange(() => FloatInputValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateBaseValue(object value)
|
|
||||||
{
|
|
||||||
var layerProperty = (LayerProperty<float>) LayerPropertyViewModel.LayerProperty;
|
|
||||||
layerProperty.Value = (float) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value)
|
|
||||||
{
|
|
||||||
var keyframe = (Keyframe<float>) baseKeyframe;
|
|
||||||
keyframe.Value = (float) value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
|
|
||||||
public int IntInputValue
|
public int IntInputValue
|
||||||
{
|
{
|
||||||
get => (int) InputValue;
|
get => (int?) InputValue ?? 0;
|
||||||
set => InputValue = value;
|
set => InputValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,17 +23,5 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
{
|
{
|
||||||
NotifyOfPropertyChange(() => IntInputValue);
|
NotifyOfPropertyChange(() => IntInputValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateBaseValue(object value)
|
|
||||||
{
|
|
||||||
var layerProperty = (LayerProperty<int>) LayerPropertyViewModel.LayerProperty;
|
|
||||||
layerProperty.Value = (int) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value)
|
|
||||||
{
|
|
||||||
var keyframe = (Keyframe<int>) baseKeyframe;
|
|
||||||
keyframe.Value = (int) value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core.Models.Profile.LayerProperties;
|
|
||||||
using Artemis.UI.Exceptions;
|
using Artemis.UI.Exceptions;
|
||||||
using Artemis.UI.Services.Interfaces;
|
using Artemis.UI.Services.Interfaces;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
@ -43,29 +42,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
|
|
||||||
private void UpdateInputValue(object value)
|
private void UpdateInputValue(object value)
|
||||||
{
|
{
|
||||||
// If keyframes are disabled, update the base value
|
LayerPropertyViewModel.LayerProperty.SetCurrentValue(value, ProfileEditorService.CurrentTime);
|
||||||
if (!LayerPropertyViewModel.KeyframesEnabled)
|
|
||||||
{
|
|
||||||
UpdateBaseValue(value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If on a keyframe, update the keyframe
|
|
||||||
var currentKeyframe = LayerPropertyViewModel.LayerProperty.UntypedKeyframes.FirstOrDefault(k => k.Position == ProfileEditorService.CurrentTime);
|
|
||||||
// Create a new keyframe if none found
|
|
||||||
if (currentKeyframe == null)
|
|
||||||
currentKeyframe = LayerPropertyViewModel.LayerProperty.CreateNewKeyframe(ProfileEditorService.CurrentTime);
|
|
||||||
|
|
||||||
UpdateKeyframeValue(currentKeyframe, value);
|
|
||||||
// Force the keyframe engine to update, the edited keyframe might affect the current keyframe progress
|
// Force the keyframe engine to update, the edited keyframe might affect the current keyframe progress
|
||||||
LayerPropertyViewModel.LayerProperty.KeyframeEngine.Update(0);
|
LayerPropertyViewModel.LayerProperty.KeyframeEngine.Update(0);
|
||||||
|
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
ProfileEditorService.UpdateSelectedProfileElement();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void Update();
|
public abstract void Update();
|
||||||
protected abstract void UpdateBaseValue(object value);
|
|
||||||
protected abstract void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,14 +19,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
[DependsOn(nameof(InputValue))]
|
[DependsOn(nameof(InputValue))]
|
||||||
public float X
|
public float X
|
||||||
{
|
{
|
||||||
get => ((SKPoint) InputValue).X;
|
get => ((SKPoint?) InputValue)?.X ?? 0;
|
||||||
set => InputValue = new SKPoint(value, Y);
|
set => InputValue = new SKPoint(value, Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DependsOn(nameof(InputValue))]
|
[DependsOn(nameof(InputValue))]
|
||||||
public float Y
|
public float Y
|
||||||
{
|
{
|
||||||
get => ((SKPoint) InputValue).Y;
|
get => ((SKPoint?)InputValue)?.Y ?? 0;
|
||||||
set => InputValue = new SKPoint(X, value);
|
set => InputValue = new SKPoint(X, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,17 +35,5 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
NotifyOfPropertyChange(() => X);
|
NotifyOfPropertyChange(() => X);
|
||||||
NotifyOfPropertyChange(() => Y);
|
NotifyOfPropertyChange(() => Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateBaseValue(object value)
|
|
||||||
{
|
|
||||||
var layerProperty = (LayerProperty<SKPoint>) LayerPropertyViewModel.LayerProperty;
|
|
||||||
layerProperty.Value = (SKPoint) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value)
|
|
||||||
{
|
|
||||||
var keyframe = (Keyframe<SKPoint>) baseKeyframe;
|
|
||||||
keyframe.Value = (SKPoint) value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,14 +19,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
[DependsOn(nameof(InputValue))]
|
[DependsOn(nameof(InputValue))]
|
||||||
public float Width
|
public float Width
|
||||||
{
|
{
|
||||||
get => ((SKSize) InputValue).Width;
|
get => ((SKSize?) InputValue)?.Width ?? 0;
|
||||||
set => InputValue = new SKSize(value, Height);
|
set => InputValue = new SKSize(value, Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DependsOn(nameof(InputValue))]
|
[DependsOn(nameof(InputValue))]
|
||||||
public float Height
|
public float Height
|
||||||
{
|
{
|
||||||
get => ((SKSize) InputValue).Height;
|
get => ((SKSize?)InputValue)?.Height ?? 0;
|
||||||
set => InputValue = new SKSize(Width, value);
|
set => InputValue = new SKSize(Width, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,17 +35,5 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
|||||||
NotifyOfPropertyChange(() => Width);
|
NotifyOfPropertyChange(() => Width);
|
||||||
NotifyOfPropertyChange(() => Height);
|
NotifyOfPropertyChange(() => Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateBaseValue(object value)
|
|
||||||
{
|
|
||||||
var layerProperty = (LayerProperty<SKSize>) LayerPropertyViewModel.LayerProperty;
|
|
||||||
layerProperty.Value = (SKSize) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value)
|
|
||||||
{
|
|
||||||
var keyframe = (Keyframe<SKSize>) baseKeyframe;
|
|
||||||
keyframe.Value = (SKSize) value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using Artemis.Core.Models.Profile;
|
using Artemis.Core.Models.Profile;
|
||||||
|
using Artemis.Core.Services.Interfaces;
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
using Artemis.UI.Services.Interfaces;
|
using Artemis.UI.Services.Interfaces;
|
||||||
|
|
||||||
@ -10,9 +11,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
public FolderViewModel(ProfileElement folder,
|
public FolderViewModel(ProfileElement folder,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
IDialogService dialogService,
|
IDialogService dialogService,
|
||||||
|
ILayerService layerService,
|
||||||
IFolderViewModelFactory folderViewModelFactory,
|
IFolderViewModelFactory folderViewModelFactory,
|
||||||
ILayerViewModelFactory layerViewModelFactory) :
|
ILayerViewModelFactory layerViewModelFactory) :
|
||||||
base(null, folder, profileEditorService, dialogService, folderViewModelFactory, layerViewModelFactory)
|
base(null, folder, profileEditorService, dialogService, layerService, folderViewModelFactory, layerViewModelFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,9 +22,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
ProfileElement folder,
|
ProfileElement folder,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
IDialogService dialogService,
|
IDialogService dialogService,
|
||||||
|
ILayerService layerService,
|
||||||
IFolderViewModelFactory folderViewModelFactory,
|
IFolderViewModelFactory folderViewModelFactory,
|
||||||
ILayerViewModelFactory layerViewModelFactory) :
|
ILayerViewModelFactory layerViewModelFactory) :
|
||||||
base(parent, folder, profileEditorService, dialogService, folderViewModelFactory, layerViewModelFactory)
|
base(parent, folder, profileEditorService, dialogService, layerService, folderViewModelFactory, layerViewModelFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Artemis.Core.Models.Profile;
|
using Artemis.Core.Models.Profile;
|
||||||
|
using Artemis.Core.Services.Interfaces;
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
using Artemis.UI.Services.Interfaces;
|
using Artemis.UI.Services.Interfaces;
|
||||||
|
|
||||||
@ -10,9 +11,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
ProfileElement folder,
|
ProfileElement folder,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
IDialogService dialogService,
|
IDialogService dialogService,
|
||||||
|
ILayerService layerService,
|
||||||
IFolderViewModelFactory folderViewModelFactory,
|
IFolderViewModelFactory folderViewModelFactory,
|
||||||
ILayerViewModelFactory layerViewModelFactory) :
|
ILayerViewModelFactory layerViewModelFactory) :
|
||||||
base(parent, folder, profileEditorService, dialogService, folderViewModelFactory, layerViewModelFactory)
|
base(parent, folder, profileEditorService, dialogService, layerService, folderViewModelFactory, layerViewModelFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core.Models.Profile;
|
using Artemis.Core.Models.Profile;
|
||||||
|
using Artemis.Core.Services.Interfaces;
|
||||||
using Artemis.UI.Exceptions;
|
using Artemis.UI.Exceptions;
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
||||||
@ -13,6 +14,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
public abstract class TreeItemViewModel : PropertyChangedBase
|
public abstract class TreeItemViewModel : PropertyChangedBase
|
||||||
{
|
{
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
|
private readonly ILayerService _layerService;
|
||||||
private readonly IFolderViewModelFactory _folderViewModelFactory;
|
private readonly IFolderViewModelFactory _folderViewModelFactory;
|
||||||
private readonly ILayerViewModelFactory _layerViewModelFactory;
|
private readonly ILayerViewModelFactory _layerViewModelFactory;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
@ -21,11 +23,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
ProfileElement profileElement,
|
ProfileElement profileElement,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
IDialogService dialogService,
|
IDialogService dialogService,
|
||||||
|
ILayerService layerService,
|
||||||
IFolderViewModelFactory folderViewModelFactory,
|
IFolderViewModelFactory folderViewModelFactory,
|
||||||
ILayerViewModelFactory layerViewModelFactory)
|
ILayerViewModelFactory layerViewModelFactory)
|
||||||
{
|
{
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
|
_layerService = layerService;
|
||||||
_folderViewModelFactory = folderViewModelFactory;
|
_folderViewModelFactory = folderViewModelFactory;
|
||||||
_layerViewModelFactory = layerViewModelFactory;
|
_layerViewModelFactory = layerViewModelFactory;
|
||||||
|
|
||||||
@ -117,7 +121,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
if (!SupportsChildren)
|
if (!SupportsChildren)
|
||||||
throw new ArtemisUIException("Cannot add a layer to a profile element of type " + ProfileElement.GetType().Name);
|
throw new ArtemisUIException("Cannot add a layer to a profile element of type " + ProfileElement.GetType().Name);
|
||||||
|
|
||||||
ProfileElement.AddChild(new Layer(ProfileElement.Profile, ProfileElement, "New layer"));
|
var layer = new Layer(ProfileElement.Profile, ProfileElement, "New layer");
|
||||||
|
foreach (var baseLayerProperty in layer.Properties)
|
||||||
|
_layerService.InstantiateKeyframeEngine(baseLayerProperty);
|
||||||
|
ProfileElement.AddChild(layer);
|
||||||
UpdateProfileElements();
|
UpdateProfileElements();
|
||||||
_profileEditorService.UpdateSelectedProfile();
|
_profileEditorService.UpdateSelectedProfile();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,9 +28,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
||||||
_profileEditorService.SelectedProfileElementChanged += OnSelectedProfileElementChanged;
|
_profileEditorService.SelectedProfileElementChanged += OnSelectedProfileElementChanged;
|
||||||
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated;
|
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated;
|
||||||
_profileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged;
|
_profileEditorService.ProfilePreviewUpdated += ProfileEditorServiceOnProfilePreviewUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Layer Layer { get; }
|
public Layer Layer { get; }
|
||||||
|
|
||||||
public Geometry LayerGeometry { get; set; }
|
public Geometry LayerGeometry { get; set; }
|
||||||
@ -102,7 +103,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
}
|
}
|
||||||
|
|
||||||
var skRect = Layer.LayerShape.GetUnscaledRectangle();
|
var skRect = Layer.LayerShape.GetUnscaledRectangle();
|
||||||
var rect = new Rect(skRect.Left, skRect.Top, Math.Max(0, skRect.Width), Math.Max(0,skRect.Height));
|
var rect = new Rect(skRect.Left, skRect.Top, Math.Max(0, skRect.Width), Math.Max(0, skRect.Height));
|
||||||
|
|
||||||
var shapeGeometry = Geometry.Empty;
|
var shapeGeometry = Geometry.Empty;
|
||||||
switch (Layer.LayerShape)
|
switch (Layer.LayerShape)
|
||||||
@ -208,7 +209,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileEditorServiceOnCurrentTimeChanged(object sender, EventArgs e)
|
private void ProfileEditorServiceOnProfilePreviewUpdated(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (!IsSelected)
|
if (!IsSelected)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -9,15 +9,20 @@
|
|||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
d:DataContext="{d:DesignInstance {x:Type local:EditToolViewModel}}">
|
d:DataContext="{d:DesignInstance {x:Type local:EditToolViewModel}}">
|
||||||
<Canvas>
|
<Canvas UseLayoutRounding="False">
|
||||||
<!-- The rectangle around the shape that allows modification -->
|
<!-- The rectangle around the shape that allows modification -->
|
||||||
<Rectangle Width="{Binding ShapeSkRect.Width}"
|
<Rectangle Width="{Binding ShapeSkRect.Width}"
|
||||||
Height="{Binding ShapeSkRect.Height}"
|
Height="{Binding ShapeSkRect.Height}"
|
||||||
Canvas.Left="{Binding ShapeSkRect.Left}"
|
Canvas.Left="{Binding ShapeSkRect.Left}"
|
||||||
Canvas.Top="{Binding ShapeSkRect.Top}"
|
Canvas.Top="{Binding ShapeSkRect.Top}"
|
||||||
|
Fill="Transparent"
|
||||||
Stroke="{DynamicResource PrimaryHueMidBrush}"
|
Stroke="{DynamicResource PrimaryHueMidBrush}"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
StrokeDashArray="2 2" />
|
StrokeDashArray="2 2"
|
||||||
|
Cursor="Hand"
|
||||||
|
MouseDown="{s:Action ShapeEditMouseDown}"
|
||||||
|
MouseUp="{s:Action ShapeEditMouseUp}"
|
||||||
|
MouseMove="{s:Action Move}"/>
|
||||||
|
|
||||||
<!-- Top left display -->
|
<!-- Top left display -->
|
||||||
<Rectangle Width="4" Height="4" Canvas.Left="{Binding ShapeSkRect.Left}" Canvas.Top="{Binding ShapeSkRect.Top}" Fill="{DynamicResource SecondaryAccentBrush}" Margin="-2,-2,0,0" />
|
<Rectangle Width="4" Height="4" Canvas.Left="{Binding ShapeSkRect.Left}" Canvas.Top="{Binding ShapeSkRect.Top}" Fill="{DynamicResource SecondaryAccentBrush}" Margin="-2,-2,0,0" />
|
||||||
|
|||||||
@ -10,7 +10,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
{
|
{
|
||||||
public class EditToolViewModel : VisualizationToolViewModel
|
public class EditToolViewModel : VisualizationToolViewModel
|
||||||
{
|
{
|
||||||
private bool _mouseDown;
|
private bool _isDragging;
|
||||||
|
private double _dragOffsetY;
|
||||||
|
private double _dragOffsetX;
|
||||||
|
|
||||||
public EditToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService) : base(profileViewModel, profileEditorService)
|
public EditToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService) : base(profileViewModel, profileEditorService)
|
||||||
{
|
{
|
||||||
@ -19,7 +21,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
profileEditorService.SelectedProfileChanged += (sender, args) => Update();
|
profileEditorService.SelectedProfileChanged += (sender, args) => Update();
|
||||||
profileEditorService.SelectedProfileElementUpdated += (sender, args) => Update();
|
profileEditorService.SelectedProfileElementUpdated += (sender, args) => Update();
|
||||||
profileEditorService.CurrentTimeChanged += (sender, args) => Update();
|
profileEditorService.ProfilePreviewUpdated += (sender, args) => Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
@ -34,41 +36,64 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
public void ShapeEditMouseDown(object sender, MouseButtonEventArgs e)
|
public void ShapeEditMouseDown(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (_isDragging)
|
||||||
|
return;
|
||||||
|
|
||||||
((IInputElement) sender).CaptureMouse();
|
((IInputElement) sender).CaptureMouse();
|
||||||
_mouseDown = true;
|
if (ProfileEditorService.SelectedProfileElement is Layer layer)
|
||||||
|
{
|
||||||
|
var dragStartPosition = GetRelativePosition(sender, e);
|
||||||
|
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
||||||
|
_dragOffsetX = skRect.Left - dragStartPosition.X;
|
||||||
|
_dragOffsetY = skRect.Top - dragStartPosition.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isDragging = true;
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShapeEditMouseUp(object sender, MouseButtonEventArgs e)
|
public void ShapeEditMouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
((IInputElement) sender).ReleaseMouseCapture();
|
((IInputElement) sender).ReleaseMouseCapture();
|
||||||
_mouseDown = false;
|
ProfileEditorService.UpdateSelectedProfileElement();
|
||||||
|
|
||||||
|
_isDragging = false;
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Move(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isDragging || !(ProfileEditorService.SelectedProfileElement is Layer layer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var position = GetRelativePosition(sender, e);
|
||||||
|
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
||||||
|
layer.LayerShape.SetFromUnscaledRectangle(
|
||||||
|
SKRect.Create((float) (position.X + _dragOffsetX), (float) (position.Y + _dragOffsetY), skRect.Width, skRect.Height),
|
||||||
|
ProfileEditorService.CurrentTime
|
||||||
|
);
|
||||||
|
ProfileEditorService.UpdateProfilePreview();
|
||||||
|
}
|
||||||
|
|
||||||
public void TopLeftRotate(object sender, MouseEventArgs e)
|
public void TopLeftRotate(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TopLeftResize(object sender, MouseEventArgs e)
|
public void TopLeftResize(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TopCenterResize(object sender, MouseEventArgs e)
|
public void TopCenterResize(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (!_mouseDown)
|
if (!_isDragging || !(ProfileEditorService.SelectedProfileElement is Layer layer))
|
||||||
return;
|
|
||||||
if (!(ProfileEditorService.SelectedProfileElement is Layer layer))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var position = GetRelativePosition(sender, e);
|
var position = GetRelativePosition(sender, e);
|
||||||
|
|
||||||
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
||||||
skRect.Top = (float) Math.Min(position.Y, skRect.Bottom);
|
skRect.Top = (float) Math.Min(position.Y, skRect.Bottom);
|
||||||
layer.LayerShape.SetFromUnscaledRectangle(skRect);
|
layer.LayerShape.SetFromUnscaledRectangle(skRect, ProfileEditorService.CurrentTime);
|
||||||
|
ProfileEditorService.UpdateProfilePreview();
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TopRightRotate(object sender, MouseEventArgs e)
|
public void TopRightRotate(object sender, MouseEventArgs e)
|
||||||
@ -81,18 +106,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
public void CenterRightResize(object sender, MouseEventArgs e)
|
public void CenterRightResize(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (!_mouseDown)
|
if (!_isDragging || !(ProfileEditorService.SelectedProfileElement is Layer layer))
|
||||||
return;
|
|
||||||
if (!(ProfileEditorService.SelectedProfileElement is Layer layer))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var position = GetRelativePosition(sender, e);
|
var position = GetRelativePosition(sender, e);
|
||||||
|
|
||||||
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
||||||
skRect.Right = (float) Math.Max(position.X, skRect.Left);
|
skRect.Right = (float) Math.Max(position.X, skRect.Left);
|
||||||
layer.LayerShape.SetFromUnscaledRectangle(skRect);
|
layer.LayerShape.SetFromUnscaledRectangle(skRect, ProfileEditorService.CurrentTime);
|
||||||
|
ProfileEditorService.UpdateProfilePreview();
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Point GetRelativePosition(object sender, MouseEventArgs mouseEventArgs)
|
private Point GetRelativePosition(object sender, MouseEventArgs mouseEventArgs)
|
||||||
@ -111,18 +133,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
public void BottomCenterResize(object sender, MouseEventArgs e)
|
public void BottomCenterResize(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (!_mouseDown)
|
if (!_isDragging || !(ProfileEditorService.SelectedProfileElement is Layer layer))
|
||||||
return;
|
|
||||||
if (!(ProfileEditorService.SelectedProfileElement is Layer layer))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var position = GetRelativePosition(sender, e);
|
var position = GetRelativePosition(sender, e);
|
||||||
|
|
||||||
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
||||||
skRect.Bottom = (float) Math.Max(position.Y, skRect.Top);
|
skRect.Bottom = (float) Math.Max(position.Y, skRect.Top);
|
||||||
layer.LayerShape.SetFromUnscaledRectangle(skRect);
|
layer.LayerShape.SetFromUnscaledRectangle(skRect, ProfileEditorService.CurrentTime);
|
||||||
|
ProfileEditorService.UpdateProfilePreview();
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BottomLeftRotate(object sender, MouseEventArgs e)
|
public void BottomLeftRotate(object sender, MouseEventArgs e)
|
||||||
@ -135,18 +154,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
public void CenterLeftResize(object sender, MouseEventArgs e)
|
public void CenterLeftResize(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (!_mouseDown)
|
if (!_isDragging || !(ProfileEditorService.SelectedProfileElement is Layer layer))
|
||||||
return;
|
|
||||||
if (!(ProfileEditorService.SelectedProfileElement is Layer layer))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var position = GetRelativePosition(sender, e);
|
var position = GetRelativePosition(sender, e);
|
||||||
|
|
||||||
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
var skRect = layer.LayerShape.GetUnscaledRectangle();
|
||||||
skRect.Left = (float) Math.Min(position.X, skRect.Right);
|
skRect.Left = (float) Math.Min(position.X, skRect.Right);
|
||||||
layer.LayerShape.SetFromUnscaledRectangle(skRect);
|
layer.LayerShape.SetFromUnscaledRectangle(skRect, ProfileEditorService.CurrentTime);
|
||||||
|
ProfileEditorService.UpdateProfilePreview();
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
layer.LayerShape = new Ellipse(layer);
|
layer.LayerShape = new Ellipse(layer);
|
||||||
|
|
||||||
// Apply the drag rectangle
|
// Apply the drag rectangle
|
||||||
layer.LayerShape.SetFromUnscaledRectangle(DragRectangle.ToSKRect());
|
layer.LayerShape.SetFromUnscaledRectangle(DragRectangle.ToSKRect(), ProfileEditorService.CurrentTime);
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
ProfileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
layer.LayerShape = new Rectangle(layer);
|
layer.LayerShape = new Rectangle(layer);
|
||||||
|
|
||||||
// Apply the drag rectangle
|
// Apply the drag rectangle
|
||||||
layer.LayerShape.SetFromUnscaledRectangle(DragRectangle.ToSKRect());
|
layer.LayerShape.SetFromUnscaledRectangle(DragRectangle.ToSKRect(), ProfileEditorService.CurrentTime);
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
ProfileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
layer.AddLeds(selectedLeds);
|
layer.AddLeds(selectedLeds);
|
||||||
// Restore the saved size
|
// Restore the saved size
|
||||||
if (layer.LayerShape != null)
|
if (layer.LayerShape != null)
|
||||||
layer.LayerShape.SetFromUnscaledRectangle(shapeSize);
|
layer.LayerShape.SetFromUnscaledRectangle(shapeSize, ProfileEditorService.CurrentTime);
|
||||||
|
|
||||||
ProfileEditorService.UpdateSelectedProfileElement();
|
ProfileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Core.Models.Profile;
|
using Artemis.Core.Models.Profile;
|
||||||
|
using Artemis.Core.Models.Profile.LayerProperties;
|
||||||
|
|
||||||
namespace Artemis.UI.Services.Interfaces
|
namespace Artemis.UI.Services.Interfaces
|
||||||
{
|
{
|
||||||
@ -13,6 +14,7 @@ namespace Artemis.UI.Services.Interfaces
|
|||||||
void UpdateSelectedProfile();
|
void UpdateSelectedProfile();
|
||||||
void ChangeSelectedProfileElement(ProfileElement profileElement);
|
void ChangeSelectedProfileElement(ProfileElement profileElement);
|
||||||
void UpdateSelectedProfileElement();
|
void UpdateSelectedProfileElement();
|
||||||
|
void UpdateProfilePreview();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a new profile is selected
|
/// Occurs when a new profile is selected
|
||||||
@ -38,5 +40,10 @@ namespace Artemis.UI.Services.Interfaces
|
|||||||
/// Occurs when the current editor time is changed
|
/// Occurs when the current editor time is changed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event EventHandler CurrentTimeChanged;
|
event EventHandler CurrentTimeChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the profile preview has been updated
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler ProfilePreviewUpdated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ namespace Artemis.UI.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void UpdateProfilePreview()
|
public void UpdateProfilePreview()
|
||||||
{
|
{
|
||||||
if (SelectedProfile == null)
|
if (SelectedProfile == null)
|
||||||
return;
|
return;
|
||||||
@ -78,6 +78,7 @@ namespace Artemis.UI.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
_lastUpdateTime = CurrentTime;
|
_lastUpdateTime = CurrentTime;
|
||||||
|
OnProfilePreviewUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler SelectedProfileChanged;
|
public event EventHandler SelectedProfileChanged;
|
||||||
@ -85,6 +86,7 @@ namespace Artemis.UI.Services
|
|||||||
public event EventHandler SelectedProfileElementChanged;
|
public event EventHandler SelectedProfileElementChanged;
|
||||||
public event EventHandler SelectedProfileElementUpdated;
|
public event EventHandler SelectedProfileElementUpdated;
|
||||||
public event EventHandler CurrentTimeChanged;
|
public event EventHandler CurrentTimeChanged;
|
||||||
|
public event EventHandler ProfilePreviewUpdated;
|
||||||
|
|
||||||
protected virtual void OnSelectedProfileElementUpdated()
|
protected virtual void OnSelectedProfileElementUpdated()
|
||||||
{
|
{
|
||||||
@ -110,5 +112,10 @@ namespace Artemis.UI.Services
|
|||||||
{
|
{
|
||||||
CurrentTimeChanged?.Invoke(this, EventArgs.Empty);
|
CurrentTimeChanged?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void OnProfilePreviewUpdated()
|
||||||
|
{
|
||||||
|
ProfilePreviewUpdated?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user