mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Need this on another PC :))
This commit is contained in:
1 parent
2afb1ea284
commit
6c05bc5410
13 files changed
+232
-77
No files matched your search
@@ -1,14 +1,43 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.Visualization.ProfileLayerView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization"
|
||||
mc:Ignorable="d"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Path Data="{Binding LayerGeometry, Mode=OneWay}" ClipToBounds="False" StrokeThickness="1">
|
||||
<Path.Stroke>
|
||||
<SolidColorBrush Color="{StaticResource Accent400}" />
|
||||
</Path.Stroke>
|
||||
</Path>
|
||||
</UserControl>
|
||||
<Canvas>
|
||||
<!-- The part of the layer's shape that falls outside the layer -->
|
||||
<Path Data="{Binding ShapeGeometry, Mode=OneWay}" >
|
||||
<Path.Fill>
|
||||
<SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.25" />
|
||||
</Path.Fill>
|
||||
<Path.Stroke>
|
||||
<SolidColorBrush Color="{StaticResource Accent700}" />
|
||||
</Path.Stroke>
|
||||
</Path>
|
||||
|
||||
<!-- The part of the layer's shape that is inside the layer -->
|
||||
<Path Data="{Binding ShapeGeometry, Mode=OneWay}" >
|
||||
<Path.Fill>
|
||||
<SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.25" />
|
||||
</Path.Fill>
|
||||
<Path.Stroke>
|
||||
<SolidColorBrush Color="{StaticResource Accent700}" />
|
||||
</Path.Stroke>
|
||||
<Path.OpacityMask>
|
||||
<VisualBrush >
|
||||
<VisualBrush.Visual>
|
||||
<Path Data="{Binding LayerGeometry, Mode=OneWay}" ClipToBounds="False" Fill="Black" />
|
||||
</VisualBrush.Visual>
|
||||
</VisualBrush>
|
||||
</Path.OpacityMask>
|
||||
</Path>
|
||||
|
||||
<Path Data="{Binding LayerGeometry, Mode=OneWay}" ClipToBounds="False" StrokeThickness="1.5" StrokeLineJoin="Round" x:Name="LayerPath">
|
||||
<Path.Stroke>
|
||||
<SolidColorBrush Color="{StaticResource Accent400}" />
|
||||
</Path.Stroke>
|
||||
</Path>
|
||||
</Canvas>
|
||||
</UserControl>
|
||||
+107
-19
@@ -3,9 +3,11 @@ using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Profile.LayerShapes;
|
||||
using Artemis.Core.Models.Surface;
|
||||
using Artemis.UI.Extensions;
|
||||
using RGB.NET.Core;
|
||||
using Rectangle = Artemis.Core.Models.Profile.LayerShapes.Rectangle;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
@@ -15,18 +17,35 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
Layer = layer;
|
||||
|
||||
CreateLayerGeometry();
|
||||
Layer.RenderPropertiesUpdated += (sender, args) => CreateLayerGeometry();
|
||||
Update();
|
||||
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
||||
}
|
||||
|
||||
public Layer Layer { get; }
|
||||
|
||||
public Geometry LayerGeometry { get; set; }
|
||||
public Geometry OpacityGeometry { get; set; }
|
||||
public Geometry ShapeGeometry { get; set; }
|
||||
public Rect ViewportRectangle { get; set; }
|
||||
|
||||
private void Update()
|
||||
{
|
||||
CreateLayerGeometry();
|
||||
CreateShapeGeometry();
|
||||
CreateViewportRectangle();
|
||||
}
|
||||
|
||||
private void CreateLayerGeometry()
|
||||
{
|
||||
if (!Layer.Leds.Any())
|
||||
{
|
||||
LayerGeometry = Geometry.Empty;
|
||||
OpacityGeometry = Geometry.Empty;
|
||||
ViewportRectangle = Rect.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
var layerGeometry = Geometry.Empty;
|
||||
|
||||
foreach (var led in Layer.Leds)
|
||||
{
|
||||
Geometry geometry;
|
||||
@@ -34,15 +53,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
case Shape.Custom:
|
||||
if (led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
||||
geometry = CreateCustomGeometry(led, 2.0);
|
||||
geometry = CreateCustomGeometry(led, 2);
|
||||
else
|
||||
geometry = CreateCustomGeometry(led, 1.0);
|
||||
geometry = CreateCustomGeometry(led, 1);
|
||||
break;
|
||||
case Shape.Rectangle:
|
||||
if (led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
||||
geometry = CreateKeyCapGeometry(led);
|
||||
else
|
||||
geometry = CreateRectangleGeometry(led);
|
||||
geometry = CreateRectangleGeometry(led);
|
||||
break;
|
||||
case Shape.Circle:
|
||||
geometry = CreateCircleGeometry(led);
|
||||
@@ -54,27 +70,88 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
layerGeometry = Geometry.Combine(layerGeometry, geometry, GeometryCombineMode.Union, null, 5, ToleranceType.Absolute);
|
||||
}
|
||||
|
||||
var opacityGeometry = Geometry.Combine(Geometry.Empty, layerGeometry, GeometryCombineMode.Exclude, new TranslateTransform());
|
||||
layerGeometry.Freeze();
|
||||
opacityGeometry.Freeze();
|
||||
LayerGeometry = layerGeometry;
|
||||
LayerGeometry.Freeze();
|
||||
OpacityGeometry = opacityGeometry;
|
||||
}
|
||||
|
||||
private void CreateShapeGeometry()
|
||||
{
|
||||
if (Layer.LayerShape == null || !Layer.Leds.Any())
|
||||
{
|
||||
ShapeGeometry = Geometry.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
var x = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.X);
|
||||
var y = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.Y);
|
||||
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 rect = new Rect(
|
||||
x + width * Layer.LayerShape.Position.X,
|
||||
y + height * Layer.LayerShape.Position.Y,
|
||||
width * Layer.LayerShape.Size.Width,
|
||||
height * Layer.LayerShape.Size.Height
|
||||
);
|
||||
var shapeGeometry = Geometry.Empty;
|
||||
switch (Layer.LayerShape)
|
||||
{
|
||||
case Ellipse _:
|
||||
shapeGeometry = new EllipseGeometry(rect);
|
||||
break;
|
||||
case Fill _:
|
||||
shapeGeometry = LayerGeometry;
|
||||
break;
|
||||
case Polygon _:
|
||||
// TODO
|
||||
shapeGeometry = new RectangleGeometry(rect);
|
||||
break;
|
||||
case Rectangle _:
|
||||
shapeGeometry = new RectangleGeometry(rect);
|
||||
break;
|
||||
}
|
||||
|
||||
shapeGeometry.Freeze();
|
||||
ShapeGeometry = shapeGeometry;
|
||||
}
|
||||
|
||||
|
||||
private void CreateViewportRectangle()
|
||||
{
|
||||
if (!Layer.Leds.Any())
|
||||
{
|
||||
ViewportRectangle = Rect.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
var x = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.X);
|
||||
var y = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.Y);
|
||||
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;
|
||||
ViewportRectangle = new Rect(x - x * Layer.LayerShape.Position.X, y - y * Layer.LayerShape.Position.Y, width, height);
|
||||
}
|
||||
|
||||
private Geometry CreateRectangleGeometry(ArtemisLed led)
|
||||
{
|
||||
return new RectangleGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1));
|
||||
var rect = led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1);
|
||||
rect.Inflate(1, 1);
|
||||
return new RectangleGeometry(rect);
|
||||
}
|
||||
|
||||
private Geometry CreateCircleGeometry(ArtemisLed led)
|
||||
{
|
||||
return new EllipseGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1));
|
||||
}
|
||||
|
||||
private Geometry CreateKeyCapGeometry(ArtemisLed led)
|
||||
{
|
||||
return new RectangleGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1), 1.6, 1.6);
|
||||
var rect = led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1);
|
||||
rect.Inflate(1, 1);
|
||||
return new EllipseGeometry(rect);
|
||||
}
|
||||
|
||||
private Geometry CreateCustomGeometry(ArtemisLed led, double deflateAmount)
|
||||
{
|
||||
var rect = led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1);
|
||||
rect.Inflate(1, 1);
|
||||
try
|
||||
{
|
||||
var geometry = Geometry.Combine(
|
||||
@@ -85,11 +162,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
Children = new TransformCollection
|
||||
{
|
||||
new ScaleTransform(led.RgbLed.ActualSize.Width - deflateAmount, led.RgbLed.ActualSize.Height - deflateAmount),
|
||||
new TranslateTransform(deflateAmount / 2, deflateAmount / 2)
|
||||
new ScaleTransform(rect.Width, rect.Height),
|
||||
new TranslateTransform(rect.X, rect.Y)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -97,5 +175,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
return CreateRectangleGeometry(led);
|
||||
}
|
||||
}
|
||||
|
||||
private void LayerOnRenderPropertiesUpdated(object sender, EventArgs e)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@
|
||||
</Path>
|
||||
|
||||
<!-- Selection -->
|
||||
<Path Data="{Binding DisplayGeometry, Mode=OneWay}" ClipToBounds="False" StrokeThickness="1">
|
||||
<Path Data="{Binding DisplayGeometry, Mode=OneWay}" ClipToBounds="False" StrokeThickness="1" StrokeLineJoin="Round">
|
||||
<Path.Style>
|
||||
<Style TargetType="{x:Type Path}">
|
||||
<Style.Triggers>
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
<materialDesign:Card Padding="8">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding HighlightSelectedLayer.Value}">
|
||||
Highlight selected layer
|
||||
Dim LEDs outside selected layer
|
||||
</CheckBox>
|
||||
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" Margin="10 0 0 0" IsChecked="{Binding PauseRenderingOnFocusLoss.Value}">
|
||||
Pause visualization on focus loss
|
||||
|
||||
@@ -139,7 +139,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
// Remove layers that no longer exist
|
||||
var toRemove = layerViewModels.Where(vm => !layers.Contains(vm.Layer));
|
||||
foreach (var profileLayerViewModel in toRemove)
|
||||
{
|
||||
profileLayerViewModel.Dispose();
|
||||
CanvasViewModels.Remove(profileLayerViewModel);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+36
@@ -1,8 +1,12 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Profile.LayerShapes;
|
||||
using Artemis.UI.Properties;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
||||
{
|
||||
@@ -34,6 +38,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
||||
DragRectangle = GetSquareRectBetweenPoints(MouseDownStartPosition, position);
|
||||
}
|
||||
|
||||
public override void MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
base.MouseUp(sender, e);
|
||||
|
||||
if (ProfileEditorService.SelectedProfileElement is Layer layer)
|
||||
{
|
||||
GetShapePosition(out var point, out var size);
|
||||
layer.LayerShape = new Ellipse(layer) {Size = size, Position = point};
|
||||
ProfileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
}
|
||||
|
||||
public override void KeyUp(KeyEventArgs e)
|
||||
{
|
||||
base.KeyUp(e);
|
||||
@@ -49,5 +65,25 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
||||
if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
|
||||
_shiftDown = true;
|
||||
}
|
||||
|
||||
private void GetShapePosition(out SKPoint point, out SKSize size)
|
||||
{
|
||||
var layer = (Layer) ProfileEditorService.SelectedProfileElement;
|
||||
var x = layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.X);
|
||||
var y = layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.Y);
|
||||
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 widthScale = width / 100f;
|
||||
var heightScale = height / 100f;
|
||||
var rect = new Rect(
|
||||
x - width / DragRectangle.X,
|
||||
y - height / DragRectangle.Y,
|
||||
width / DragRectangle.Width,
|
||||
height / DragRectangle.Height
|
||||
);
|
||||
point = new SKPoint(0.5f,0.5f);
|
||||
size = new SKSize((float) (DragRectangle.Width * widthScale), (float) (DragRectangle.Height * heightScale));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user