UI - Performance improvements

This commit is contained in:
Robert committed 2021-09-04 20:52:03 +02:00
1 parent 7ad7eaad89
commit 13a16a1830
9 files changed
+165 -135

No files matched your search

@@ -583,30 +583,28 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
return;
}
Execute.PostToUIThread(() =>
TimeSpan newTime = ProfileEditorService.CurrentTime.Add(TimeSpan.FromSeconds(e.DeltaTime));
if (SelectedProfileElement != null)
{
TimeSpan newTime = ProfileEditorService.CurrentTime.Add(TimeSpan.FromSeconds(e.DeltaTime));
if (SelectedProfileElement != null)
if (Repeating && RepeatTimeline)
{
if (Repeating && RepeatTimeline)
{
if (newTime > SelectedProfileElement.Timeline.Length)
newTime = TimeSpan.Zero;
}
else if (Repeating && RepeatSegment)
{
if (newTime > GetCurrentSegmentEnd())
newTime = GetCurrentSegmentStart();
}
else if (newTime > SelectedProfileElement.Timeline.Length)
{
newTime = SelectedProfileElement.Timeline.Length;
Pause();
}
if (newTime > SelectedProfileElement.Timeline.Length)
newTime = TimeSpan.Zero;
}
else if (Repeating && RepeatSegment)
{
if (newTime > GetCurrentSegmentEnd())
newTime = GetCurrentSegmentStart();
}
else if (newTime > SelectedProfileElement.Timeline.Length)
{
newTime = SelectedProfileElement.Timeline.Length;
Pause();
}
}
ProfileEditorService.CurrentTime = newTime;
});
// Update current time on high priority to keep things buttery smooth as if you're using the mouse ༼ つ ◕_◕ ༽つ
Execute.OnUIThreadSync(() => ProfileEditorService.CurrentTime = newTime);
}
#endregion
@@ -8,6 +8,8 @@ using Artemis.UI.Extensions;
using Artemis.UI.Screens.Shared;
using Artemis.UI.Services;
using Artemis.UI.Shared.Services;
using SkiaSharp;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.Visualization
{
@@ -95,6 +97,16 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
CreateViewportRectangle();
}
#region Updating
private LayerShape _lastShape;
private Rect _lastBounds;
private SKPoint _lastAnchor;
private SKPoint _lastPosition;
private double _lastRotation;
private SKSize _lastScale;
private void CreateShapeGeometry()
{
if (Layer.LayerShape == null || !Layer.Leds.Any())
@@ -104,21 +116,22 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
}
Rect bounds = _layerEditorService.GetLayerBounds(Layer);
Geometry shapeGeometry = Geometry.Empty;
switch (Layer.LayerShape)
// Only bother the UI thread for both of these if we're sure
if (HasShapeChanged(bounds))
{
case EllipseShape _:
shapeGeometry = new EllipseGeometry(bounds);
break;
case RectangleShape _:
shapeGeometry = new RectangleGeometry(bounds);
break;
Execute.OnUIThreadSync(() =>
{
if (Layer.LayerShape is RectangleShape)
ShapeGeometry = new RectangleGeometry(bounds);
if (Layer.LayerShape is EllipseShape)
ShapeGeometry = new EllipseGeometry(bounds);
});
}
if ((Layer.LayerBrush == null || Layer.LayerBrush.SupportsTransformation) && HasTransformationChanged())
{
Execute.OnUIThreadSync(() => ShapeGeometry.Transform = _layerEditorService.GetLayerTransformGroup(Layer));
}
if (Layer.LayerBrush == null || Layer.LayerBrush.SupportsTransformation)
shapeGeometry.Transform = _layerEditorService.GetLayerTransformGroup(Layer);
ShapeGeometry = shapeGeometry;
}
private void CreateViewportRectangle()
@@ -132,44 +145,30 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
ViewportRectangle = _layerEditorService.GetLayerBounds(Layer);
}
private Geometry CreateRectangleGeometry(ArtemisLed led)
private bool HasShapeChanged(Rect bounds)
{
Rect rect = led.RgbLed.AbsoluteBoundary.ToWindowsRect(1);
return new RectangleGeometry(rect);
bool result = !Equals(_lastBounds, bounds) || !Equals(_lastShape, Layer.LayerShape);
_lastShape = Layer.LayerShape;
_lastBounds = bounds;
return result;
}
private Geometry CreateCircleGeometry(ArtemisLed led)
private bool HasTransformationChanged()
{
Rect rect = led.RgbLed.AbsoluteBoundary.ToWindowsRect(1);
return new EllipseGeometry(rect);
bool result = _lastAnchor != Layer.Transform.AnchorPoint.CurrentValue ||
_lastPosition != Layer.Transform.Position.CurrentValue ||
_lastRotation != Layer.Transform.Rotation.CurrentValue ||
_lastScale != Layer.Transform.Scale.CurrentValue;
_lastAnchor = Layer.Transform.AnchorPoint.CurrentValue;
_lastPosition = Layer.Transform.Position.CurrentValue;
_lastRotation = Layer.Transform.Rotation.CurrentValue;
_lastScale = Layer.Transform.Scale.CurrentValue;
return result;
}
private Geometry CreateCustomGeometry(ArtemisLed led, double deflateAmount)
{
Rect rect = led.RgbLed.AbsoluteBoundary.ToWindowsRect(1);
try
{
PathGeometry geometry = Geometry.Combine(
Geometry.Empty,
Geometry.Parse(led.RgbLed.ShapeData),
GeometryCombineMode.Union,
new TransformGroup
{
Children = new TransformCollection
{
new ScaleTransform(rect.Width, rect.Height),
new TranslateTransform(rect.X, rect.Y)
}
}
);
return geometry;
}
catch (Exception)
{
return CreateRectangleGeometry(led);
}
}
#endregion
#region Overrides of Screen
@@ -51,7 +51,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization.Tools
private void Update()
{
if (!(ProfileEditorService.SelectedProfileElement is Layer layer))
if (ProfileEditorService.SelectedProfileElement is not Layer layer)
return;
ShapePath = _layerEditorService.GetLayerPath(layer, true, true, true);
@@ -152,11 +152,6 @@ namespace Artemis.UI.Screens.Shared
PanY = rect.Top * -1 * Zoom;
}
public Rect TransformContainingRect(Rectangle rect)
{
return TransformContainingRect(rect.ToWindowsRect(1));
}
public Rect TransformContainingRect(Rect rect)
{
// Create the same transform group the view is using
@@ -168,6 +163,17 @@ namespace Artemis.UI.Screens.Shared
return transformGroup.TransformBounds(rect);
}
public Rect UnTransformContainingRect(Rect rect)
{
// Create the same transform group the view is using
TransformGroup transformGroup = new();
transformGroup.Children.Add(new TranslateTransform(PanX * -1, PanY * -1));
transformGroup.Children.Add(new ScaleTransform(1 / Zoom, 1 / Zoom));
// Apply it to the device rect
return transformGroup.TransformBounds(rect);
}
public Point GetRelativeMousePosition(object container, MouseEventArgs e)
{
// Get the mouse position relative to the panned / zoomed panel, not very MVVM but I can't find a better way
@@ -188,8 +188,7 @@
</ItemsControl.ItemTemplate>
</ItemsControl>
<Canvas>
<Rectangle ClipToBounds="False"
Width="{Binding MaxTextureSize}"
<Rectangle Width="{Binding MaxTextureSize}"
Height="{Binding MaxTextureSize}"
Stroke="{DynamicResource SecondaryHueMidBrush}"
StrokeThickness="{Binding MaxTextureSizeIndicatorThickness}"
@@ -18,6 +18,7 @@ using Artemis.UI.Screens.SurfaceEditor.Visualization;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using SkiaSharp;
using SkiaSharp.Views.WPF;
using Stylet;
using MouseButton = System.Windows.Input.MouseButton;
@@ -305,7 +306,7 @@ namespace Artemis.UI.Screens.SurfaceEditor
if (e.LeftButton == MouseButtonState.Pressed)
StartMouseDrag(sender, position, relative);
else
StopMouseDrag(sender, position);
StopMouseDrag(position);
}
// ReSharper disable once UnusedMember.Global - Called from view
@@ -323,7 +324,7 @@ namespace Artemis.UI.Screens.SurfaceEditor
if (_mouseDragStatus == MouseDragStatus.Dragging)
MoveSelected(relative);
else if (_mouseDragStatus == MouseDragStatus.Selecting)
UpdateSelection(sender, position);
UpdateSelection(position);
}
private void StartMouseDrag(object sender, Point position, Point relative)
@@ -360,17 +361,18 @@ namespace Artemis.UI.Screens.SurfaceEditor
ApplySurfaceSelection();
}
private void StopMouseDrag(object sender, Point position)
private void StopMouseDrag(Point position)
{
if (_mouseDragStatus != MouseDragStatus.Dragging)
{
RectangleGeometry selectedRect = new(new Rect(_mouseDragStartPoint, position));
List<SurfaceDeviceViewModel> devices = HitTestUtilities.GetHitViewModels<SurfaceDeviceViewModel>((Visual) sender, selectedRect);
SKRect hitTestRect = PanZoomViewModel.UnTransformContainingRect(new Rect(_mouseDragStartPoint, position)).ToSKRect();
foreach (SurfaceDeviceViewModel device in SurfaceDeviceViewModels)
if (devices.Contains(device))
{
if (device.Device.Rectangle.IntersectsWith(hitTestRect))
device.SelectionStatus = SelectionStatus.Selected;
else if (!Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.RightShift))
device.SelectionStatus = SelectionStatus.None;
}
}
else
{
@@ -382,7 +384,7 @@ namespace Artemis.UI.Screens.SurfaceEditor
ApplySurfaceSelection();
}
private void UpdateSelection(object sender, Point position)
private void UpdateSelection(Point position)
{
if (IsPanKeyDown())
return;
@@ -390,12 +392,14 @@ namespace Artemis.UI.Screens.SurfaceEditor
Rect selectedRect = new(_mouseDragStartPoint, position);
SelectionRectangle.Rect = selectedRect;
List<SurfaceDeviceViewModel> devices = HitTestUtilities.GetHitViewModels<SurfaceDeviceViewModel>((Visual) sender, SelectionRectangle);
SKRect hitTestRect = PanZoomViewModel.UnTransformContainingRect(new Rect(_mouseDragStartPoint, position)).ToSKRect();
foreach (SurfaceDeviceViewModel device in SurfaceDeviceViewModels)
if (devices.Contains(device))
{
if (device.Device.Rectangle.IntersectsWith(hitTestRect))
device.SelectionStatus = SelectionStatus.Selected;
else if (!Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.RightShift))
device.SelectionStatus = SelectionStatus.None;
}
ApplySurfaceSelection();
}