UI - Large amount of memory improvements in the VMs

Core - Minor memory improvements
This commit is contained in:
SpoinkyNL committed 2020-06-19 13:20:47 +02:00
1 parent 8d5ab86d11
commit b9dff33236
26 files changed
+243 -191

No files matched your search

@@ -86,9 +86,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
ProfileEditorService.CurrentTimeChanged -= ProfileEditorServiceOnCurrentTimeChanged;
ProfileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
PopulateProperties(null);
base.OnClose();
}
protected override void OnActivate()
{
PopulateProperties(ProfileEditorService.SelectedProfileElement as PropertiesProfileElement);
base.OnActivate();
}
protected override void OnDeactivate()
{
Pause();
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.Core.Utilities;
using Artemis.UI.Shared.Services.Interfaces;
@@ -13,8 +12,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
private readonly IProfileEditorService _profileEditorService;
public TimelineKeyframeViewModel(IProfileEditorService profileEditorService, TimelineViewModel timelineViewModel, LayerPropertyKeyframe<T> layerPropertyKeyframe)
: base(profileEditorService, timelineViewModel, layerPropertyKeyframe)
public TimelineKeyframeViewModel(IProfileEditorService profileEditorService, LayerPropertyKeyframe<T> layerPropertyKeyframe)
: base(profileEditorService, layerPropertyKeyframe)
{
_profileEditorService = profileEditorService;
LayerPropertyKeyframe = layerPropertyKeyframe;
@@ -48,13 +47,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
public abstract class TimelineKeyframeViewModel : PropertyChangedBase
{
private readonly IProfileEditorService _profileEditorService;
private readonly TimelineViewModel _timelineViewModel;
private int _pixelsPerSecond;
protected TimelineKeyframeViewModel(IProfileEditorService profileEditorService, TimelineViewModel timelineViewModel, BaseLayerPropertyKeyframe baseLayerPropertyKeyframe)
protected TimelineKeyframeViewModel(IProfileEditorService profileEditorService, BaseLayerPropertyKeyframe baseLayerPropertyKeyframe)
{
_profileEditorService = profileEditorService;
_timelineViewModel = timelineViewModel;
BaseLayerPropertyKeyframe = baseLayerPropertyKeyframe;
EasingViewModels = new BindableCollection<TimelineEasingViewModel>();
}
@@ -78,64 +75,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
#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
#region Easing
@@ -6,7 +6,7 @@ using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
public class TimelinePropertyGroupViewModel
public class TimelinePropertyGroupViewModel : PropertyChangedBase
{
public TimelinePropertyGroupViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel)
{
@@ -20,7 +20,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
public LayerPropertyGroupViewModel LayerPropertyGroupViewModel { get; }
public BindableCollection<double> TimelineKeyframeViewModels { get; set; }
public TimelineViewModel TimelineViewModel { get; set; }
public void UpdateKeyframes()
{
@@ -33,7 +33,7 @@
Height="10"
Margin="-5,6,0,0"
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}"
MouseUp="{s:Action KeyframeMouseUp}"
MouseMove="{s:Action KeyframeMouseMove}"
@@ -1,6 +1,5 @@
using System;
using System.Linq;
using Artemis.UI.Exceptions;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
using Artemis.UI.Shared.Services.Interfaces;
using Stylet;
@@ -26,9 +25,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
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
if (LayerPropertyViewModel.LayerProperty.KeyframesEnabled)
{
@@ -37,7 +33,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
TimelineKeyframeViewModels.RemoveRange(toRemove);
TimelineKeyframeViewModels.AddRange(
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
@@ -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)
{
@@ -76,7 +72,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
public LayerPropertyBaseViewModel LayerPropertyBaseViewModel { get; }
public TimelineViewModel TimelineViewModel { get; set; }
public BindableCollection<TimelineKeyframeViewModel> TimelineKeyframeViewModels { get; set; }
public abstract void Dispose();
@@ -4,19 +4,24 @@ using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
using Artemis.UI.Shared.Services.Interfaces;
using Artemis.UI.Shared.Utilities;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
public class TimelineViewModel : PropertyChangedBase
public class TimelineViewModel : Screen
{
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;
_profileEditorService = profileEditorService;
LayerPropertyGroups = layerPropertyGroups;
SelectionRectangle = new RectangleGeometry();
@@ -32,20 +37,82 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
foreach (var layerPropertyGroupViewModel in LayerPropertyGroups)
{
layerPropertyGroupViewModel.TimelinePropertyGroupViewModel.TimelineViewModel = this;
layerPropertyGroupViewModel.TimelinePropertyGroupViewModel.UpdateKeyframes();
foreach (var layerPropertyBaseViewModel in layerPropertyGroupViewModel.GetAllChildren())
{
if (layerPropertyBaseViewModel is LayerPropertyViewModel layerPropertyViewModel)
{
layerPropertyViewModel.TimelinePropertyBaseViewModel.TimelineViewModel = this;
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
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.LayerProperties.Abstract;
using Artemis.UI.Shared.Services.Interfaces;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
{
public class TreePropertyGroupViewModel
public class TreePropertyGroupViewModel : PropertyChangedBase
{
private readonly IDialogService _dialogService;
private readonly ILayerService _layerService;
@@ -5,6 +5,7 @@ using Artemis.Core.Utilities;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
using Artemis.UI.Shared.PropertyInput;
using Artemis.UI.Shared.Services.Interfaces;
using Stylet;
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)
{
@@ -135,6 +135,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
}
}
protected override void OnClose()
{
RootFolder?.Dispose();
RootFolder = null;
base.OnClose();
}
#region Event handlers
private void OnProfileElementSelected(object sender, EventArgs e)
@@ -55,6 +55,7 @@
Width="18"
Height="18"
IsChecked="{Binding ProfileElement.Enabled}"
Command="{s:Action EnableToggled}"
VerticalAlignment="Center" Padding="-25">
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
</ToggleButton>
@@ -7,6 +7,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
{
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
public FolderViewModel(ProfileElement folder,
IProfileEditorService profileEditorService,
@@ -48,6 +48,7 @@
Width="18"
Height="18"
IsChecked="{Binding ProfileElement.Enabled}"
Command="{s:Action EnableToggled}"
VerticalAlignment="Center" Padding="-25">
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
</ToggleButton>
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
@@ -12,7 +13,7 @@ using Stylet;
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 IFolderVmFactory _folderVmFactory;
@@ -38,16 +39,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
ProfileElement = profileElement;
Children = new BindableCollection<TreeItemViewModel>();
ProfileElement.PropertyChanged += HandleProfileElementEnabledChanged;
UpdateProfileElements();
}
private void HandleProfileElementEnabledChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ProfileElement.Enabled))
_profileEditorService.UpdateSelectedProfile();
}
public TreeItemViewModel Parent { get; set; }
public ProfileElement ProfileElement { get; set; }
@@ -208,5 +202,23 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
foreach (var treeItemViewModel in newChildren)
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
{
public class CanvasViewModel : PropertyChangedBase
public abstract class CanvasViewModel : PropertyChangedBase, IDisposable
{
public double X { 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 bool IsSelected { get; set; }
public void Dispose()
protected override void Dispose(bool disposing)
{
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
_profileEditorService.SelectedProfileElementUpdated -= OnSelectedProfileElementUpdated;
_profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
}
if (disposing)
{
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
_profileEditorService.SelectedProfileElementUpdated -= OnSelectedProfileElementUpdated;
_profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
}
base.Dispose(disposing);
}
private void Update()
{
IsSelected = _profileEditorService.SelectedProfileElement == Layer;
@@ -60,7 +60,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
});
ApplySurfaceConfiguration(_surfaceService.ActiveSurface);
ApplyActiveProfile();
ActivateToolByIndex(0);
eventAggregator.Subscribe(this);
@@ -151,10 +150,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
_profileEditorService.ProfileSelected -= OnProfileSelected;
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
_profileEditorService.SelectedProfileElementUpdated -= OnSelectedProfileElementUpdated;
if (_previousSelectedLayer != null)
_previousSelectedLayer.LayerBrushUpdated -= SelectedLayerOnLayerBrushUpdated;
OnlyShowSelectedShape.Save();
HighlightSelectedLayer.Save();
foreach (var canvasViewModel in CanvasViewModels)
canvasViewModel.Dispose();
CanvasViewModels.Clear();
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)
{
var counterRotatePath = new SKPath();
using var counterRotatePath = new SKPath();
counterRotatePath.AddPoly(skPoints, false);
counterRotatePath.Transform(SKMatrix.MakeRotationDegrees(layer.Transform.Rotation.CurrentValue * -1, pivot.X, pivot.Y));
if (includeScale)