mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 09:43:46 +00:00
UI - Large amount of memory improvements in the VMs
Core - Minor memory improvements
This commit is contained in:
parent
63cb6d211e
commit
24afb6b0f5
@ -1,4 +1,5 @@
|
|||||||
using RGB.NET.Core;
|
using System.Text;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
|
||||||
namespace Artemis.Core.Extensions
|
namespace Artemis.Core.Extensions
|
||||||
{
|
{
|
||||||
@ -6,11 +7,17 @@ namespace Artemis.Core.Extensions
|
|||||||
{
|
{
|
||||||
public static string GetDeviceIdentifier(this IRGBDevice rgbDevice)
|
public static string GetDeviceIdentifier(this IRGBDevice rgbDevice)
|
||||||
{
|
{
|
||||||
return rgbDevice.DeviceInfo.DeviceName +
|
var builder = new StringBuilder();
|
||||||
"-" + rgbDevice.DeviceInfo.Manufacturer +
|
builder.Append(rgbDevice.DeviceInfo.DeviceName);
|
||||||
"-" + rgbDevice.DeviceInfo.Model +
|
builder.Append('-');
|
||||||
"-" + rgbDevice.DeviceInfo.DeviceType +
|
builder.Append(rgbDevice.DeviceInfo.Manufacturer);
|
||||||
"-" + rgbDevice.DeviceInfo.Lighting;
|
builder.Append('-');
|
||||||
|
builder.Append(rgbDevice.DeviceInfo.Model);
|
||||||
|
builder.Append('-');
|
||||||
|
builder.Append(rgbDevice.DeviceInfo.DeviceType);
|
||||||
|
builder.Append('-');
|
||||||
|
builder.Append(rgbDevice.DeviceInfo.Lighting);
|
||||||
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
{
|
{
|
||||||
if (!Enabled || Path == null || !Children.Any(c => c.Enabled))
|
if (!Enabled || Path == null || !Children.Any(c => c.Enabled))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_folderBitmap == null)
|
if (_folderBitmap == null)
|
||||||
_folderBitmap = new SKBitmap(new SKImageInfo((int) Path.Bounds.Width, (int) Path.Bounds.Height));
|
_folderBitmap = new SKBitmap(new SKImageInfo((int) Path.Bounds.Width, (int) Path.Bounds.Height));
|
||||||
else if (_folderBitmap.Info.Width != (int) Path.Bounds.Width || _folderBitmap.Info.Height != (int) Path.Bounds.Height)
|
else if (_folderBitmap.Info.Width != (int) Path.Bounds.Width || _folderBitmap.Info.Height != (int) Path.Bounds.Height)
|
||||||
@ -89,11 +89,11 @@ namespace Artemis.Core.Models.Profile
|
|||||||
_folderBitmap = new SKBitmap(new SKImageInfo((int) Path.Bounds.Width, (int) Path.Bounds.Height));
|
_folderBitmap = new SKBitmap(new SKImageInfo((int) Path.Bounds.Width, (int) Path.Bounds.Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using var folderPath = new SKPath(Path);
|
||||||
using var folderCanvas = new SKCanvas(_folderBitmap);
|
using var folderCanvas = new SKCanvas(_folderBitmap);
|
||||||
using var folderPaint = new SKPaint();
|
using var folderPaint = new SKPaint();
|
||||||
folderCanvas.Clear();
|
folderCanvas.Clear();
|
||||||
|
|
||||||
var folderPath = new SKPath(Path);
|
|
||||||
folderPath.Transform(SKMatrix.MakeTranslation(folderPath.Bounds.Left * -1, folderPath.Bounds.Top * -1));
|
folderPath.Transform(SKMatrix.MakeTranslation(folderPath.Bounds.Left * -1, folderPath.Bounds.Top * -1));
|
||||||
|
|
||||||
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||||
@ -112,7 +112,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
|
|
||||||
canvas.Save();
|
canvas.Save();
|
||||||
|
|
||||||
var clipPath = new SKPath(folderPath);
|
using var clipPath = new SKPath(folderPath);
|
||||||
clipPath.Transform(SKMatrix.MakeTranslation(targetLocation.X, targetLocation.Y));
|
clipPath.Transform(SKMatrix.MakeTranslation(targetLocation.X, targetLocation.Y));
|
||||||
canvas.ClipPath(clipPath);
|
canvas.ClipPath(clipPath);
|
||||||
|
|
||||||
|
|||||||
@ -246,6 +246,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
_layerBitmap = new SKBitmap(new SKImageInfo((int)Path.Bounds.Width, (int)Path.Bounds.Height));
|
_layerBitmap = new SKBitmap(new SKImageInfo((int)Path.Bounds.Width, (int)Path.Bounds.Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using var layerPath = new SKPath(Path);
|
||||||
using var layerCanvas = new SKCanvas(_layerBitmap);
|
using var layerCanvas = new SKCanvas(_layerBitmap);
|
||||||
using var layerPaint = new SKPaint
|
using var layerPaint = new SKPaint
|
||||||
{
|
{
|
||||||
@ -254,8 +255,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
Color = new SKColor(0, 0, 0, (byte) (Transform.Opacity.CurrentValue * 2.55f))
|
Color = new SKColor(0, 0, 0, (byte) (Transform.Opacity.CurrentValue * 2.55f))
|
||||||
};
|
};
|
||||||
layerCanvas.Clear();
|
layerCanvas.Clear();
|
||||||
|
|
||||||
var layerPath = new SKPath(Path);
|
|
||||||
layerPath.Transform(SKMatrix.MakeTranslation(layerPath.Bounds.Left * -1, layerPath.Bounds.Top * -1));
|
layerPath.Transform(SKMatrix.MakeTranslation(layerPath.Bounds.Left * -1, layerPath.Bounds.Top * -1));
|
||||||
|
|
||||||
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||||
@ -278,11 +278,13 @@ namespace Artemis.Core.Models.Profile
|
|||||||
targetLocation = Path.Bounds.Location - parentFolder.Path.Bounds.Location;
|
targetLocation = Path.Bounds.Location - parentFolder.Path.Bounds.Location;
|
||||||
|
|
||||||
canvas.DrawBitmap(_layerBitmap, targetLocation, layerPaint);
|
canvas.DrawBitmap(_layerBitmap, targetLocation, layerPaint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SimpleRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint, SKPath layerPath)
|
private void SimpleRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint, SKPath layerPath)
|
||||||
{
|
{
|
||||||
LayerBrush.InternalRender(canvas, canvasInfo, new SKPath(LayerShape.Path), paint);
|
using var renderPath = new SKPath(LayerShape.Path);
|
||||||
|
LayerBrush.InternalRender(canvas, canvasInfo, renderPath, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StretchRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint, SKPath layerPath)
|
private void StretchRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint, SKPath layerPath)
|
||||||
@ -302,8 +304,9 @@ namespace Artemis.Core.Models.Profile
|
|||||||
canvas.RotateDegrees(rotationProperty, anchorPosition.X, anchorPosition.Y);
|
canvas.RotateDegrees(rotationProperty, anchorPosition.X, anchorPosition.Y);
|
||||||
canvas.Scale(sizeProperty.Width / 100f, sizeProperty.Height / 100f, anchorPosition.X, anchorPosition.Y);
|
canvas.Scale(sizeProperty.Width / 100f, sizeProperty.Height / 100f, anchorPosition.X, anchorPosition.Y);
|
||||||
canvas.Translate(x, y);
|
canvas.Translate(x, y);
|
||||||
|
|
||||||
LayerBrush.InternalRender(canvas, canvasInfo, new SKPath(LayerShape.Path), paint);
|
using var renderPath = new SKPath(LayerShape.Path);
|
||||||
|
LayerBrush.InternalRender(canvas, canvasInfo, renderPath, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClipRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint, SKPath layerPath)
|
private void ClipRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint, SKPath layerPath)
|
||||||
@ -319,7 +322,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
var x = anchorPosition.X - layerPath.Bounds.MidX - anchorProperty.X * layerPath.Bounds.Width;
|
var x = anchorPosition.X - layerPath.Bounds.MidX - anchorProperty.X * layerPath.Bounds.Width;
|
||||||
var y = anchorPosition.Y - layerPath.Bounds.MidY - anchorProperty.Y * layerPath.Bounds.Height;
|
var y = anchorPosition.Y - layerPath.Bounds.MidY - anchorProperty.Y * layerPath.Bounds.Height;
|
||||||
|
|
||||||
var clipPath = new SKPath(LayerShape.Path);
|
using var clipPath = new SKPath(LayerShape.Path);
|
||||||
clipPath.Transform(SKMatrix.MakeTranslation(x, y));
|
clipPath.Transform(SKMatrix.MakeTranslation(x, y));
|
||||||
clipPath.Transform(SKMatrix.MakeScale(sizeProperty.Width / 100f, sizeProperty.Height / 100f, anchorPosition.X, anchorPosition.Y));
|
clipPath.Transform(SKMatrix.MakeScale(sizeProperty.Width / 100f, sizeProperty.Height / 100f, anchorPosition.X, anchorPosition.Y));
|
||||||
clipPath.Transform(SKMatrix.MakeRotationDegrees(rotationProperty, anchorPosition.X, anchorPosition.Y));
|
clipPath.Transform(SKMatrix.MakeRotationDegrees(rotationProperty, anchorPosition.X, anchorPosition.Y));
|
||||||
@ -336,7 +339,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
Math.Max(clipPath.Bounds.Right - x, Bounds.Right - x),
|
Math.Max(clipPath.Bounds.Right - x, Bounds.Right - x),
|
||||||
Math.Max(clipPath.Bounds.Bottom - y, Bounds.Bottom - y)
|
Math.Max(clipPath.Bounds.Bottom - y, Bounds.Bottom - y)
|
||||||
);
|
);
|
||||||
var renderPath = new SKPath();
|
using var renderPath = new SKPath();
|
||||||
renderPath.AddRect(boundsRect);
|
renderPath.AddRect(boundsRect);
|
||||||
|
|
||||||
LayerBrush.InternalRender(canvas, canvasInfo, renderPath, paint);
|
LayerBrush.InternalRender(canvas, canvasInfo, renderPath, paint);
|
||||||
|
|||||||
@ -4,8 +4,6 @@ namespace Artemis.Core.Models.Profile.LayerShapes
|
|||||||
{
|
{
|
||||||
public abstract class LayerShape
|
public abstract class LayerShape
|
||||||
{
|
{
|
||||||
private SKPath _path;
|
|
||||||
|
|
||||||
protected LayerShape(Layer layer)
|
protected LayerShape(Layer layer)
|
||||||
{
|
{
|
||||||
Layer = layer;
|
Layer = layer;
|
||||||
@ -17,13 +15,9 @@ namespace Artemis.Core.Models.Profile.LayerShapes
|
|||||||
public Layer Layer { get; set; }
|
public Layer Layer { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a copy of the path outlining the shape
|
/// Gets a the path outlining the shape
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SKPath Path
|
public SKPath Path { get; protected set; }
|
||||||
{
|
|
||||||
get => _path != null ? new SKPath(_path) : null;
|
|
||||||
protected set => _path = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void CalculateRenderProperties();
|
public abstract void CalculateRenderProperties();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,12 +11,12 @@ namespace Artemis.Core.Models.Profile
|
|||||||
private SKPath _path;
|
private SKPath _path;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a copy of the path containing all the LEDs this entity is applied to, any rendering outside the entity Path is
|
/// Gets the path containing all the LEDs this entity is applied to, any rendering outside the entity Path is
|
||||||
/// clipped.
|
/// clipped.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SKPath Path
|
public SKPath Path
|
||||||
{
|
{
|
||||||
get => _path != null ? new SKPath(_path) : null;
|
get => _path;
|
||||||
protected set
|
protected set
|
||||||
{
|
{
|
||||||
_path = value;
|
_path = value;
|
||||||
|
|||||||
@ -98,7 +98,7 @@ namespace Artemis.Core.RGB.NET
|
|||||||
var bitmapWidth = Bitmap.Width;
|
var bitmapWidth = Bitmap.Width;
|
||||||
var bitmapHeight = Bitmap.Height;
|
var bitmapHeight = Bitmap.Height;
|
||||||
|
|
||||||
var pixmap = Bitmap.PeekPixels();
|
using var pixmap = Bitmap.PeekPixels();
|
||||||
foreach (var renderTarget in renderTargets)
|
foreach (var renderTarget in renderTargets)
|
||||||
{
|
{
|
||||||
// SKRect has all the good stuff we need
|
// SKRect has all the good stuff we need
|
||||||
|
|||||||
@ -1,56 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using Artemis.Core.Extensions;
|
|
||||||
using RGB.NET.Core;
|
|
||||||
using SkiaSharp;
|
|
||||||
|
|
||||||
namespace Artemis.Core.RGB.NET
|
|
||||||
{
|
|
||||||
public class GraphicsDecorator : AbstractDecorator, IBrushDecorator, IDisposable
|
|
||||||
{
|
|
||||||
private readonly double _scale;
|
|
||||||
|
|
||||||
public GraphicsDecorator(ILedGroup ledGroup, double scale)
|
|
||||||
{
|
|
||||||
_scale = scale;
|
|
||||||
|
|
||||||
var leds = ledGroup.GetLeds().ToList();
|
|
||||||
if (!leds.Any())
|
|
||||||
return;
|
|
||||||
|
|
||||||
var width = Math.Min(leds.Max(l => l.AbsoluteLedRectangle.Location.X + l.AbsoluteLedRectangle.Size.Width) * scale, 4096);
|
|
||||||
var height = Math.Min(leds.Max(l => l.AbsoluteLedRectangle.Location.Y + l.AbsoluteLedRectangle.Size.Height) * scale, 4096);
|
|
||||||
Bitmap = new SKBitmap(new SKImageInfo(width.RoundToInt(), height.RoundToInt()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public SKBitmap Bitmap { get; private set; }
|
|
||||||
|
|
||||||
public Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color)
|
|
||||||
{
|
|
||||||
if (Bitmap == null)
|
|
||||||
return new Color(0, 0, 0);
|
|
||||||
|
|
||||||
var x = renderTarget.Led.AbsoluteLedRectangle.Center.X * _scale;
|
|
||||||
var y = renderTarget.Led.AbsoluteLedRectangle.Center.Y * _scale;
|
|
||||||
|
|
||||||
var pixel = Bitmap.GetPixel(RoundToInt(x), RoundToInt(y));
|
|
||||||
return new Color(pixel.Alpha, pixel.Red, pixel.Green, pixel.Blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDetached(IDecoratable decoratable)
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Bitmap?.Dispose();
|
|
||||||
Bitmap = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int RoundToInt(double number)
|
|
||||||
{
|
|
||||||
return (int) Math.Round(number, MidpointRounding.AwayFromZero);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +1,15 @@
|
|||||||
using System.Windows;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace Artemis.UI.Behaviors
|
namespace Artemis.UI.Behaviors
|
||||||
{
|
{
|
||||||
public class InputBindingBehavior
|
public class InputBindingBehavior
|
||||||
{
|
{
|
||||||
|
private static List<Tuple<FrameworkElement, Window, InputBinding>> _movedInputBindings = new List<Tuple<FrameworkElement, Window, InputBinding>>();
|
||||||
|
|
||||||
public static readonly DependencyProperty PropagateInputBindingsToWindowProperty =
|
public static readonly DependencyProperty PropagateInputBindingsToWindowProperty =
|
||||||
DependencyProperty.RegisterAttached("PropagateInputBindingsToWindow", typeof(bool), typeof(InputBindingBehavior),
|
DependencyProperty.RegisterAttached("PropagateInputBindingsToWindow", typeof(bool), typeof(InputBindingBehavior),
|
||||||
new PropertyMetadata(false, OnPropagateInputBindingsToWindowChanged));
|
new PropertyMetadata(false, OnPropagateInputBindingsToWindowChanged));
|
||||||
@ -21,13 +27,13 @@ namespace Artemis.UI.Behaviors
|
|||||||
private static void OnPropagateInputBindingsToWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void OnPropagateInputBindingsToWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
((FrameworkElement) d).Loaded += OnLoaded;
|
((FrameworkElement) d).Loaded += OnLoaded;
|
||||||
|
((FrameworkElement) d).Unloaded += OnUnloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnLoaded(object sender, RoutedEventArgs e)
|
private static void OnLoaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var frameworkElement = (FrameworkElement) sender;
|
var frameworkElement = (FrameworkElement) sender;
|
||||||
frameworkElement.Loaded -= OnLoaded;
|
|
||||||
|
|
||||||
var window = Window.GetWindow(frameworkElement);
|
var window = Window.GetWindow(frameworkElement);
|
||||||
if (window == null) return;
|
if (window == null) return;
|
||||||
|
|
||||||
@ -37,7 +43,23 @@ namespace Artemis.UI.Behaviors
|
|||||||
var inputBinding = frameworkElement.InputBindings[i];
|
var inputBinding = frameworkElement.InputBindings[i];
|
||||||
window.InputBindings.Add(inputBinding);
|
window.InputBindings.Add(inputBinding);
|
||||||
frameworkElement.InputBindings.Remove(inputBinding);
|
frameworkElement.InputBindings.Remove(inputBinding);
|
||||||
|
|
||||||
|
_movedInputBindings.Add(new Tuple<FrameworkElement, Window, InputBinding>(frameworkElement, window, inputBinding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void OnUnloaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var frameworkElement = (FrameworkElement) sender;
|
||||||
|
|
||||||
|
var toRemove = _movedInputBindings.Where(m => m.Item1 == frameworkElement).ToList();
|
||||||
|
foreach (var (_, window, inputBinding) in toRemove)
|
||||||
|
{
|
||||||
|
if (window.InputBindings.Contains(inputBinding))
|
||||||
|
window.InputBindings.Remove(inputBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
_movedInputBindings = _movedInputBindings.Where(b => b.Item1 != frameworkElement).ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,9 +86,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
|||||||
ProfileEditorService.CurrentTimeChanged -= ProfileEditorServiceOnCurrentTimeChanged;
|
ProfileEditorService.CurrentTimeChanged -= ProfileEditorServiceOnCurrentTimeChanged;
|
||||||
ProfileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
|
ProfileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
|
||||||
|
|
||||||
|
PopulateProperties(null);
|
||||||
base.OnClose();
|
base.OnClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnActivate()
|
||||||
|
{
|
||||||
|
PopulateProperties(ProfileEditorService.SelectedProfileElement as PropertiesProfileElement);
|
||||||
|
base.OnActivate();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnDeactivate()
|
protected override void OnDeactivate()
|
||||||
{
|
{
|
||||||
Pause();
|
Pause();
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
|
||||||
using Artemis.Core.Models.Profile.LayerProperties;
|
using Artemis.Core.Models.Profile.LayerProperties;
|
||||||
using Artemis.Core.Utilities;
|
using Artemis.Core.Utilities;
|
||||||
using Artemis.UI.Shared.Services.Interfaces;
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
@ -13,8 +12,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
|
||||||
public TimelineKeyframeViewModel(IProfileEditorService profileEditorService, TimelineViewModel timelineViewModel, LayerPropertyKeyframe<T> layerPropertyKeyframe)
|
public TimelineKeyframeViewModel(IProfileEditorService profileEditorService, LayerPropertyKeyframe<T> layerPropertyKeyframe)
|
||||||
: base(profileEditorService, timelineViewModel, layerPropertyKeyframe)
|
: base(profileEditorService, layerPropertyKeyframe)
|
||||||
{
|
{
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
LayerPropertyKeyframe = layerPropertyKeyframe;
|
LayerPropertyKeyframe = layerPropertyKeyframe;
|
||||||
@ -48,13 +47,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
public abstract class TimelineKeyframeViewModel : PropertyChangedBase
|
public abstract class TimelineKeyframeViewModel : PropertyChangedBase
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private readonly TimelineViewModel _timelineViewModel;
|
|
||||||
private int _pixelsPerSecond;
|
private int _pixelsPerSecond;
|
||||||
|
|
||||||
protected TimelineKeyframeViewModel(IProfileEditorService profileEditorService, TimelineViewModel timelineViewModel, BaseLayerPropertyKeyframe baseLayerPropertyKeyframe)
|
protected TimelineKeyframeViewModel(IProfileEditorService profileEditorService, BaseLayerPropertyKeyframe baseLayerPropertyKeyframe)
|
||||||
{
|
{
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
_timelineViewModel = timelineViewModel;
|
|
||||||
BaseLayerPropertyKeyframe = baseLayerPropertyKeyframe;
|
BaseLayerPropertyKeyframe = baseLayerPropertyKeyframe;
|
||||||
EasingViewModels = new BindableCollection<TimelineEasingViewModel>();
|
EasingViewModels = new BindableCollection<TimelineEasingViewModel>();
|
||||||
}
|
}
|
||||||
@ -78,64 +75,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
|
|
||||||
#region Keyframe movement
|
#region Keyframe movement
|
||||||
|
|
||||||
public void KeyframeMouseDown(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.LeftButton == MouseButtonState.Released)
|
|
||||||
return;
|
|
||||||
|
|
||||||
((IInputElement) sender).CaptureMouse();
|
|
||||||
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) && !IsSelected)
|
|
||||||
_timelineViewModel.SelectKeyframe(this, true, false);
|
|
||||||
else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
|
||||||
_timelineViewModel.SelectKeyframe(this, false, true);
|
|
||||||
else if (!IsSelected)
|
|
||||||
_timelineViewModel.SelectKeyframe(this, false, false);
|
|
||||||
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void KeyframeMouseUp(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
_profileEditorService.UpdateSelectedProfileElement();
|
|
||||||
_timelineViewModel.ReleaseSelectedKeyframes();
|
|
||||||
|
|
||||||
((IInputElement) sender).ReleaseMouseCapture();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void KeyframeMouseMove(object sender, MouseEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.LeftButton == MouseButtonState.Pressed)
|
|
||||||
_timelineViewModel.MoveSelectedKeyframes(GetCursorTime(e.GetPosition(ParentView)));
|
|
||||||
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TimeSpan GetCursorTime(Point position)
|
|
||||||
{
|
|
||||||
// Get the parent grid, need that for our position
|
|
||||||
var x = Math.Max(0, position.X);
|
|
||||||
var time = TimeSpan.FromSeconds(x / _pixelsPerSecond);
|
|
||||||
|
|
||||||
// Round the time to something that fits the current zoom level
|
|
||||||
if (_pixelsPerSecond < 200)
|
|
||||||
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds / 5.0) * 5.0);
|
|
||||||
else if (_pixelsPerSecond < 500)
|
|
||||||
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds / 2.0) * 2.0);
|
|
||||||
else
|
|
||||||
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds));
|
|
||||||
|
|
||||||
// If shift is held, snap to the current time
|
|
||||||
// Take a tolerance of 5 pixels (half a keyframe width)
|
|
||||||
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
|
|
||||||
{
|
|
||||||
var tolerance = 1000f / _pixelsPerSecond * 5;
|
|
||||||
if (Math.Abs(_profileEditorService.CurrentTime.TotalMilliseconds - time.TotalMilliseconds) < tolerance)
|
|
||||||
time = _profileEditorService.CurrentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Easing
|
#region Easing
|
||||||
|
|||||||
@ -6,7 +6,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||||
{
|
{
|
||||||
public class TimelinePropertyGroupViewModel
|
public class TimelinePropertyGroupViewModel : PropertyChangedBase
|
||||||
{
|
{
|
||||||
public TimelinePropertyGroupViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel)
|
public TimelinePropertyGroupViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel)
|
||||||
{
|
{
|
||||||
@ -20,7 +20,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
|
|
||||||
public LayerPropertyGroupViewModel LayerPropertyGroupViewModel { get; }
|
public LayerPropertyGroupViewModel LayerPropertyGroupViewModel { get; }
|
||||||
public BindableCollection<double> TimelineKeyframeViewModels { get; set; }
|
public BindableCollection<double> TimelineKeyframeViewModels { get; set; }
|
||||||
public TimelineViewModel TimelineViewModel { get; set; }
|
|
||||||
|
|
||||||
public void UpdateKeyframes()
|
public void UpdateKeyframes()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
Height="10"
|
Height="10"
|
||||||
Margin="-5,6,0,0"
|
Margin="-5,6,0,0"
|
||||||
ToolTip="{Binding Timestamp}"
|
ToolTip="{Binding Timestamp}"
|
||||||
s:View.ActionTarget="{Binding}"
|
s:View.ActionTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:TimelineView}}, Path=DataContext}"
|
||||||
MouseDown="{s:Action KeyframeMouseDown}"
|
MouseDown="{s:Action KeyframeMouseDown}"
|
||||||
MouseUp="{s:Action KeyframeMouseUp}"
|
MouseUp="{s:Action KeyframeMouseUp}"
|
||||||
MouseMove="{s:Action KeyframeMouseMove}"
|
MouseMove="{s:Action KeyframeMouseMove}"
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.UI.Exceptions;
|
|
||||||
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
||||||
using Artemis.UI.Shared.Services.Interfaces;
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
@ -26,9 +25,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
|
|
||||||
public override void UpdateKeyframes()
|
public override void UpdateKeyframes()
|
||||||
{
|
{
|
||||||
if (TimelineViewModel == null)
|
|
||||||
throw new ArtemisUIException("Timeline view model must be set before keyframes can be updated");
|
|
||||||
|
|
||||||
// Only show keyframes if they are enabled
|
// Only show keyframes if they are enabled
|
||||||
if (LayerPropertyViewModel.LayerProperty.KeyframesEnabled)
|
if (LayerPropertyViewModel.LayerProperty.KeyframesEnabled)
|
||||||
{
|
{
|
||||||
@ -37,7 +33,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
TimelineKeyframeViewModels.RemoveRange(toRemove);
|
TimelineKeyframeViewModels.RemoveRange(toRemove);
|
||||||
TimelineKeyframeViewModels.AddRange(
|
TimelineKeyframeViewModels.AddRange(
|
||||||
keyframes.Where(k => TimelineKeyframeViewModels.All(t => t.BaseLayerPropertyKeyframe != k))
|
keyframes.Where(k => TimelineKeyframeViewModels.All(t => t.BaseLayerPropertyKeyframe != k))
|
||||||
.Select(k => new TimelineKeyframeViewModel<T>(_profileEditorService, TimelineViewModel, k))
|
.Select(k => new TimelineKeyframeViewModel<T>(_profileEditorService, k))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -67,7 +63,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class TimelinePropertyViewModel : IDisposable
|
public abstract class TimelinePropertyViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
protected TimelinePropertyViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel)
|
protected TimelinePropertyViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel)
|
||||||
{
|
{
|
||||||
@ -76,7 +72,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LayerPropertyBaseViewModel LayerPropertyBaseViewModel { get; }
|
public LayerPropertyBaseViewModel LayerPropertyBaseViewModel { get; }
|
||||||
public TimelineViewModel TimelineViewModel { get; set; }
|
|
||||||
public BindableCollection<TimelineKeyframeViewModel> TimelineKeyframeViewModels { get; set; }
|
public BindableCollection<TimelineKeyframeViewModel> TimelineKeyframeViewModels { get; set; }
|
||||||
|
|
||||||
public abstract void Dispose();
|
public abstract void Dispose();
|
||||||
|
|||||||
@ -4,19 +4,24 @@ using System.Linq;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Shapes;
|
||||||
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
||||||
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
using Artemis.UI.Shared.Utilities;
|
using Artemis.UI.Shared.Utilities;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||||
{
|
{
|
||||||
public class TimelineViewModel : PropertyChangedBase
|
public class TimelineViewModel : Screen
|
||||||
{
|
{
|
||||||
private readonly LayerPropertiesViewModel _layerPropertiesViewModel;
|
private readonly LayerPropertiesViewModel _layerPropertiesViewModel;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
|
||||||
public TimelineViewModel(LayerPropertiesViewModel layerPropertiesViewModel, BindableCollection<LayerPropertyGroupViewModel> layerPropertyGroups)
|
public TimelineViewModel(LayerPropertiesViewModel layerPropertiesViewModel, BindableCollection<LayerPropertyGroupViewModel> layerPropertyGroups,
|
||||||
|
IProfileEditorService profileEditorService)
|
||||||
{
|
{
|
||||||
_layerPropertiesViewModel = layerPropertiesViewModel;
|
_layerPropertiesViewModel = layerPropertiesViewModel;
|
||||||
|
_profileEditorService = profileEditorService;
|
||||||
LayerPropertyGroups = layerPropertyGroups;
|
LayerPropertyGroups = layerPropertyGroups;
|
||||||
SelectionRectangle = new RectangleGeometry();
|
SelectionRectangle = new RectangleGeometry();
|
||||||
|
|
||||||
@ -32,20 +37,82 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
|||||||
{
|
{
|
||||||
foreach (var layerPropertyGroupViewModel in LayerPropertyGroups)
|
foreach (var layerPropertyGroupViewModel in LayerPropertyGroups)
|
||||||
{
|
{
|
||||||
layerPropertyGroupViewModel.TimelinePropertyGroupViewModel.TimelineViewModel = this;
|
|
||||||
layerPropertyGroupViewModel.TimelinePropertyGroupViewModel.UpdateKeyframes();
|
layerPropertyGroupViewModel.TimelinePropertyGroupViewModel.UpdateKeyframes();
|
||||||
|
|
||||||
foreach (var layerPropertyBaseViewModel in layerPropertyGroupViewModel.GetAllChildren())
|
foreach (var layerPropertyBaseViewModel in layerPropertyGroupViewModel.GetAllChildren())
|
||||||
{
|
{
|
||||||
if (layerPropertyBaseViewModel is LayerPropertyViewModel layerPropertyViewModel)
|
if (layerPropertyBaseViewModel is LayerPropertyViewModel layerPropertyViewModel)
|
||||||
{
|
|
||||||
layerPropertyViewModel.TimelinePropertyBaseViewModel.TimelineViewModel = this;
|
|
||||||
layerPropertyViewModel.TimelinePropertyBaseViewModel.UpdateKeyframes();
|
layerPropertyViewModel.TimelinePropertyBaseViewModel.UpdateKeyframes();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Command handlers
|
||||||
|
|
||||||
|
public void KeyframeMouseDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.LeftButton == MouseButtonState.Released)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var viewModel = (sender as Ellipse)?.DataContext as TimelineKeyframeViewModel;
|
||||||
|
if (viewModel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
((IInputElement) sender).CaptureMouse();
|
||||||
|
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) && !viewModel.IsSelected)
|
||||||
|
SelectKeyframe(viewModel, true, false);
|
||||||
|
else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
||||||
|
SelectKeyframe(viewModel, false, true);
|
||||||
|
else if (!viewModel.IsSelected)
|
||||||
|
SelectKeyframe(viewModel, false, false);
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void KeyframeMouseUp(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
ReleaseSelectedKeyframes();
|
||||||
|
|
||||||
|
((IInputElement) sender).ReleaseMouseCapture();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void KeyframeMouseMove(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.LeftButton == MouseButtonState.Pressed)
|
||||||
|
MoveSelectedKeyframes(GetCursorTime(e.GetPosition(View)));
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeSpan GetCursorTime(Point position)
|
||||||
|
{
|
||||||
|
// Get the parent grid, need that for our position
|
||||||
|
var x = Math.Max(0, position.X);
|
||||||
|
var time = TimeSpan.FromSeconds(x / _profileEditorService.PixelsPerSecond);
|
||||||
|
|
||||||
|
// Round the time to something that fits the current zoom level
|
||||||
|
if (_profileEditorService.PixelsPerSecond < 200)
|
||||||
|
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds / 5.0) * 5.0);
|
||||||
|
else if (_profileEditorService.PixelsPerSecond < 500)
|
||||||
|
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds / 2.0) * 2.0);
|
||||||
|
else
|
||||||
|
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds));
|
||||||
|
|
||||||
|
// If shift is held, snap to the current time
|
||||||
|
// Take a tolerance of 5 pixels (half a keyframe width)
|
||||||
|
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
|
||||||
|
{
|
||||||
|
var tolerance = 1000f / _profileEditorService.PixelsPerSecond * 5;
|
||||||
|
if (Math.Abs(_profileEditorService.CurrentTime.TotalMilliseconds - time.TotalMilliseconds) < tolerance)
|
||||||
|
time = _profileEditorService.CurrentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Keyframe movement
|
#region Keyframe movement
|
||||||
|
|
||||||
public void MoveSelectedKeyframes(TimeSpan cursorTime)
|
public void MoveSelectedKeyframes(TimeSpan cursorTime)
|
||||||
|
|||||||
@ -4,10 +4,11 @@ using Artemis.Core.Services.Interfaces;
|
|||||||
using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
||||||
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
||||||
using Artemis.UI.Shared.Services.Interfaces;
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
|
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
|
||||||
{
|
{
|
||||||
public class TreePropertyGroupViewModel
|
public class TreePropertyGroupViewModel : PropertyChangedBase
|
||||||
{
|
{
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
private readonly ILayerService _layerService;
|
private readonly ILayerService _layerService;
|
||||||
|
|||||||
@ -5,6 +5,7 @@ using Artemis.Core.Utilities;
|
|||||||
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
||||||
using Artemis.UI.Shared.PropertyInput;
|
using Artemis.UI.Shared.PropertyInput;
|
||||||
using Artemis.UI.Shared.Services.Interfaces;
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
|
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
|
||||||
{
|
{
|
||||||
@ -56,7 +57,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class TreePropertyViewModel : IDisposable
|
public abstract class TreePropertyViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
protected TreePropertyViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel)
|
protected TreePropertyViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -135,6 +135,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnClose()
|
||||||
|
{
|
||||||
|
RootFolder?.Dispose();
|
||||||
|
RootFolder = null;
|
||||||
|
base.OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void OnProfileElementSelected(object sender, EventArgs e)
|
private void OnProfileElementSelected(object sender, EventArgs e)
|
||||||
|
|||||||
@ -55,6 +55,7 @@
|
|||||||
Width="18"
|
Width="18"
|
||||||
Height="18"
|
Height="18"
|
||||||
IsChecked="{Binding ProfileElement.Enabled}"
|
IsChecked="{Binding ProfileElement.Enabled}"
|
||||||
|
Command="{s:Action EnableToggled}"
|
||||||
VerticalAlignment="Center" Padding="-25">
|
VerticalAlignment="Center" Padding="-25">
|
||||||
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
|
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
|
|||||||
@ -7,6 +7,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
{
|
{
|
||||||
public class FolderViewModel : TreeItemViewModel
|
public class FolderViewModel : TreeItemViewModel
|
||||||
{
|
{
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
foreach (var treeItemViewModel in Children)
|
||||||
|
treeItemViewModel.Dispose();
|
||||||
|
Children.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
// I hate this about DI, oh well
|
// I hate this about DI, oh well
|
||||||
public FolderViewModel(ProfileElement folder,
|
public FolderViewModel(ProfileElement folder,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
|
|||||||
@ -48,6 +48,7 @@
|
|||||||
Width="18"
|
Width="18"
|
||||||
Height="18"
|
Height="18"
|
||||||
IsChecked="{Binding ProfileElement.Enabled}"
|
IsChecked="{Binding ProfileElement.Enabled}"
|
||||||
|
Command="{s:Action EnableToggled}"
|
||||||
VerticalAlignment="Center" Padding="-25">
|
VerticalAlignment="Center" Padding="-25">
|
||||||
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
|
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -12,7 +13,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||||
{
|
{
|
||||||
public abstract class TreeItemViewModel : PropertyChangedBase
|
public abstract class TreeItemViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
private readonly IFolderVmFactory _folderVmFactory;
|
private readonly IFolderVmFactory _folderVmFactory;
|
||||||
@ -38,16 +39,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
ProfileElement = profileElement;
|
ProfileElement = profileElement;
|
||||||
|
|
||||||
Children = new BindableCollection<TreeItemViewModel>();
|
Children = new BindableCollection<TreeItemViewModel>();
|
||||||
ProfileElement.PropertyChanged += HandleProfileElementEnabledChanged;
|
|
||||||
UpdateProfileElements();
|
UpdateProfileElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleProfileElementEnabledChanged(object sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.PropertyName == nameof(ProfileElement.Enabled))
|
|
||||||
_profileEditorService.UpdateSelectedProfile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TreeItemViewModel Parent { get; set; }
|
public TreeItemViewModel Parent { get; set; }
|
||||||
public ProfileElement ProfileElement { get; set; }
|
public ProfileElement ProfileElement { get; set; }
|
||||||
|
|
||||||
@ -208,5 +202,23 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
foreach (var treeItemViewModel in newChildren)
|
foreach (var treeItemViewModel in newChildren)
|
||||||
treeItemViewModel.UpdateProfileElements();
|
treeItemViewModel.UpdateProfileElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void EnableToggled()
|
||||||
|
{
|
||||||
|
_profileEditorService.UpdateSelectedProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,10 +1,24 @@
|
|||||||
using Stylet;
|
using System;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||||
{
|
{
|
||||||
public class CanvasViewModel : PropertyChangedBase
|
public abstract class CanvasViewModel : PropertyChangedBase, IDisposable
|
||||||
{
|
{
|
||||||
public double X { get; set; }
|
public double X { get; set; }
|
||||||
public double Y { get; set; }
|
public double Y { get; set; }
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,14 +44,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
public Thickness LayerPosition => new Thickness(ViewportRectangle.Left, ViewportRectangle.Top, 0, 0);
|
public Thickness LayerPosition => new Thickness(ViewportRectangle.Left, ViewportRectangle.Top, 0, 0);
|
||||||
public bool IsSelected { get; set; }
|
public bool IsSelected { get; set; }
|
||||||
|
|
||||||
public void Dispose()
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
|
if (disposing)
|
||||||
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
|
{
|
||||||
_profileEditorService.SelectedProfileElementUpdated -= OnSelectedProfileElementUpdated;
|
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
|
||||||
_profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
|
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
|
||||||
}
|
_profileEditorService.SelectedProfileElementUpdated -= OnSelectedProfileElementUpdated;
|
||||||
|
_profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
IsSelected = _profileEditorService.SelectedProfileElement == Layer;
|
IsSelected = _profileEditorService.SelectedProfileElement == Layer;
|
||||||
|
|||||||
@ -60,7 +60,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
});
|
});
|
||||||
|
|
||||||
ApplySurfaceConfiguration(_surfaceService.ActiveSurface);
|
ApplySurfaceConfiguration(_surfaceService.ActiveSurface);
|
||||||
ApplyActiveProfile();
|
|
||||||
ActivateToolByIndex(0);
|
ActivateToolByIndex(0);
|
||||||
|
|
||||||
eventAggregator.Subscribe(this);
|
eventAggregator.Subscribe(this);
|
||||||
@ -151,10 +150,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
_profileEditorService.ProfileSelected -= OnProfileSelected;
|
_profileEditorService.ProfileSelected -= OnProfileSelected;
|
||||||
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
|
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
|
||||||
_profileEditorService.SelectedProfileElementUpdated -= OnSelectedProfileElementUpdated;
|
_profileEditorService.SelectedProfileElementUpdated -= OnSelectedProfileElementUpdated;
|
||||||
|
if (_previousSelectedLayer != null)
|
||||||
|
_previousSelectedLayer.LayerBrushUpdated -= SelectedLayerOnLayerBrushUpdated;
|
||||||
|
|
||||||
OnlyShowSelectedShape.Save();
|
OnlyShowSelectedShape.Save();
|
||||||
HighlightSelectedLayer.Save();
|
HighlightSelectedLayer.Save();
|
||||||
|
|
||||||
|
foreach (var canvasViewModel in CanvasViewModels)
|
||||||
|
canvasViewModel.Dispose();
|
||||||
|
CanvasViewModels.Clear();
|
||||||
|
|
||||||
base.OnClose();
|
base.OnClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -361,7 +361,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
|
|
||||||
private SKPoint[] UnTransformPoints(SKPoint[] skPoints, Layer layer, SKPoint pivot, bool includeScale)
|
private SKPoint[] UnTransformPoints(SKPoint[] skPoints, Layer layer, SKPoint pivot, bool includeScale)
|
||||||
{
|
{
|
||||||
var counterRotatePath = new SKPath();
|
using var counterRotatePath = new SKPath();
|
||||||
counterRotatePath.AddPoly(skPoints, false);
|
counterRotatePath.AddPoly(skPoints, false);
|
||||||
counterRotatePath.Transform(SKMatrix.MakeRotationDegrees(layer.Transform.Rotation.CurrentValue * -1, pivot.X, pivot.Y));
|
counterRotatePath.Transform(SKMatrix.MakeRotationDegrees(layer.Transform.Rotation.CurrentValue * -1, pivot.X, pivot.Y));
|
||||||
if (includeScale)
|
if (includeScale)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
using Artemis.Core.Plugins.LayerBrush.Abstract;
|
using Artemis.Core.Plugins.LayerBrush.Abstract;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
@ -13,14 +14,19 @@ namespace Artemis.Plugins.LayerBrushes.Color
|
|||||||
|
|
||||||
public override void EnableLayerBrush()
|
public override void EnableLayerBrush()
|
||||||
{
|
{
|
||||||
Layer.RenderPropertiesUpdated += (sender, args) => CreateShader();
|
Layer.RenderPropertiesUpdated += HandleShaderChange;
|
||||||
Properties.GradientType.BaseValueChanged += (sender, args) => CreateShader();
|
Properties.GradientType.BaseValueChanged += HandleShaderChange;
|
||||||
Properties.Color.BaseValueChanged += (sender, args) => CreateShader();
|
Properties.Color.BaseValueChanged += HandleShaderChange;
|
||||||
Properties.Gradient.BaseValue.PropertyChanged += (sender, args) => CreateShader();
|
Properties.Gradient.BaseValue.PropertyChanged += BaseValueOnPropertyChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DisableLayerBrush()
|
public override void DisableLayerBrush()
|
||||||
{
|
{
|
||||||
|
Layer.RenderPropertiesUpdated -= HandleShaderChange;
|
||||||
|
Properties.GradientType.BaseValueChanged -= HandleShaderChange;
|
||||||
|
Properties.Color.BaseValueChanged -= HandleShaderChange;
|
||||||
|
Properties.Gradient.BaseValue.PropertyChanged -= BaseValueOnPropertyChanged;
|
||||||
|
|
||||||
_paint?.Dispose();
|
_paint?.Dispose();
|
||||||
_shader?.Dispose();
|
_shader?.Dispose();
|
||||||
_paint = null;
|
_paint = null;
|
||||||
@ -50,6 +56,16 @@ namespace Artemis.Plugins.LayerBrushes.Color
|
|||||||
canvas.DrawPath(path, paint);
|
canvas.DrawPath(path, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void BaseValueOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
CreateShader();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleShaderChange(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
CreateShader();
|
||||||
|
}
|
||||||
|
|
||||||
private void CreateShader()
|
private void CreateShader()
|
||||||
{
|
{
|
||||||
var center = new SKPoint(_shaderBounds.MidX, _shaderBounds.MidY);
|
var center = new SKPoint(_shaderBounds.MidX, _shaderBounds.MidY);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user