1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Implemented ellipse shape application

This commit is contained in:
SpoinkyNL 2019-12-17 22:42:17 +01:00
parent 94df1544c5
commit 8dc15f6894
11 changed files with 104 additions and 54 deletions

View File

@ -39,6 +39,8 @@ namespace Artemis.Core.Models.Profile
Name = layerEntity.Name; Name = layerEntity.Name;
Order = layerEntity.Order; Order = layerEntity.Order;
_leds = new List<ArtemisLed>();
switch (layerEntity.ShapeEntity?.Type) switch (layerEntity.ShapeEntity?.Type)
{ {
case ShapeEntityType.Ellipse: case ShapeEntityType.Ellipse:
@ -59,8 +61,6 @@ namespace Artemis.Core.Models.Profile
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
_leds = new List<ArtemisLed>();
} }
internal LayerEntity LayerEntity { get; set; } internal LayerEntity LayerEntity { get; set; }
@ -243,7 +243,7 @@ namespace Artemis.Core.Models.Profile
path.AddRect(artemisLed.AbsoluteRenderRectangle); path.AddRect(artemisLed.AbsoluteRenderRectangle);
Path = path; Path = path;
LayerShape.CalculateRenderProperties(); LayerShape?.CalculateRenderProperties();
OnRenderPropertiesUpdated(); OnRenderPropertiesUpdated();
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Linq;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
using SkiaSharp; using SkiaSharp;
@ -6,6 +7,9 @@ namespace Artemis.Core.Models.Profile.LayerShapes
{ {
public abstract class LayerShape public abstract class LayerShape
{ {
private SKPoint _position;
private SKSize _size;
protected LayerShape(Layer layer) protected LayerShape(Layer layer)
{ {
Layer = layer; Layer = layer;
@ -33,12 +37,28 @@ namespace Artemis.Core.Models.Profile.LayerShapes
/// <summary> /// <summary>
/// The position of the shape /// The position of the shape
/// </summary> /// </summary>
public SKPoint Position { get; set; } public SKPoint Position
{
get => _position;
set
{
_position = value;
Layer.CalculateRenderProperties();
}
}
/// <summary> /// <summary>
/// The size of the shape /// The size of the shape
/// </summary> /// </summary>
public SKSize Size { get; set; } public SKSize Size
{
get => _size;
set
{
_size = value;
Layer.CalculateRenderProperties();
}
}
/// <summary> /// <summary>
/// A render rectangle relative to the layer /// A render rectangle relative to the layer
@ -56,11 +76,48 @@ namespace Artemis.Core.Models.Profile.LayerShapes
{ {
Layer.LayerEntity.ShapeEntity = new ShapeEntity Layer.LayerEntity.ShapeEntity = new ShapeEntity
{ {
Anchor = new ShapePointEntity { X = Anchor.X, Y = Anchor.Y }, Anchor = new ShapePointEntity {X = Anchor.X, Y = Anchor.Y},
Position = new ShapePointEntity { X = Position.X, Y = Position.Y }, Position = new ShapePointEntity {X = Position.X, Y = Position.Y},
Width = Size.Width, Width = Size.Width,
Height = Size.Height Height = Size.Height
}; };
} }
/// <summary>
/// Updates Position and Size using the provided unscaled rectangle
/// </summary>
/// <param name="rect">An unscaled rectangle where 1px = 1mm</param>
public void SetFromUnscaledRectangle(SKRect rect)
{
if (!Layer.Leds.Any())
{
Position = SKPoint.Empty;
Size = SKSize.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;
Position = new SKPoint((float) (100f / width * (rect.Left - x)) / 100f, (float) (100f / height * (rect.Top - y)) / 100f);
Size = new SKSize((float) (100f / width * rect.Width) / 100f, (float) (100f / height * rect.Height) / 100f);
}
public SKRect GetUnscaledRectangle()
{
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;
return SKRect.Create(
(float) (x + width * Position.X),
(float) (y + height * Position.Y),
(float) (width * Size.Width),
(float) (height * Size.Height)
);
}
} }
} }

View File

@ -61,9 +61,14 @@
<Name>Artemis.Core</Name> <Name>Artemis.Core</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup />
<ItemGroup> <ItemGroup>
<Folder Include="x64\" /> <Content Include="x64\wooting-rgb-sdk64.dll">
<Folder Include="x86\" /> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="x86\wooting-rgb-sdk.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>

View File

@ -19,11 +19,10 @@ namespace Artemis.Plugins.Devices.Wooting
public override void EnablePlugin() public override void EnablePlugin()
{ {
// Disabled for now because the DLLs aren't on the repo PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(WootingRGBDevice<>), sender, args);
// PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(WootingRGBDevice<>), sender, args); RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "wooting-rgb-sdk64.dll"));
// RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "wooting-rgb-sdk64.dll")); RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "wooting-rgb-sdk.dll"));
// RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "wooting-rgb-sdk.dll")); _rgbService.AddDeviceProvider(RgbDeviceProvider);
// _rgbService.AddDeviceProvider(RgbDeviceProvider);
} }
public override void DisablePlugin() public override void DisablePlugin()

View File

@ -10,23 +10,23 @@
<!-- The part of the layer's shape that falls outside the layer --> <!-- The part of the layer's shape that falls outside the layer -->
<Path Data="{Binding ShapeGeometry, Mode=OneWay}" > <Path Data="{Binding ShapeGeometry, Mode=OneWay}" >
<Path.Fill> <Path.Fill>
<SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.25" /> <SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.05" />
</Path.Fill> </Path.Fill>
<Path.Stroke> <Path.Stroke>
<SolidColorBrush Color="{StaticResource Accent700}" /> <SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.15" />
</Path.Stroke> </Path.Stroke>
</Path> </Path>
<!-- The part of the layer's shape that is inside the layer --> <!-- The part of the layer's shape that is inside the layer -->
<Path Data="{Binding ShapeGeometry, Mode=OneWay}" > <Path Data="{Binding ShapeGeometry, Mode=OneWay}" >
<Path.Fill> <Path.Fill>
<SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.25" /> <SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.35" />
</Path.Fill> </Path.Fill>
<Path.Stroke> <Path.Stroke>
<SolidColorBrush Color="{StaticResource Accent700}" /> <SolidColorBrush Color="{StaticResource Accent700}" />
</Path.Stroke> </Path.Stroke>
<Path.OpacityMask> <Path.OpacityMask>
<VisualBrush > <VisualBrush Viewport="{Binding ViewportRectangle}" ViewportUnits="Absolute">
<VisualBrush.Visual> <VisualBrush.Visual>
<Path Data="{Binding LayerGeometry, Mode=OneWay}" ClipToBounds="False" Fill="Black" /> <Path Data="{Binding LayerGeometry, Mode=OneWay}" ClipToBounds="False" Fill="Black" />
</VisualBrush.Visual> </VisualBrush.Visual>

View File

@ -7,6 +7,7 @@ using Artemis.Core.Models.Profile.LayerShapes;
using Artemis.Core.Models.Surface; using Artemis.Core.Models.Surface;
using Artemis.UI.Extensions; using Artemis.UI.Extensions;
using RGB.NET.Core; using RGB.NET.Core;
using SkiaSharp.Views.WPF;
using Rectangle = Artemis.Core.Models.Profile.LayerShapes.Rectangle; using Rectangle = Artemis.Core.Models.Profile.LayerShapes.Rectangle;
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
@ -85,17 +86,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
return; return;
} }
var x = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.X); var skRect = Layer.LayerShape.GetUnscaledRectangle();
var y = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.Y); var rect = new Rect(skRect.Left, skRect.Top, skRect.Width, skRect.Height);
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; var shapeGeometry = Geometry.Empty;
switch (Layer.LayerShape) switch (Layer.LayerShape)
{ {
@ -121,17 +113,20 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
private void CreateViewportRectangle() private void CreateViewportRectangle()
{ {
if (!Layer.Leds.Any()) if (!Layer.Leds.Any() || Layer.LayerShape == null)
{ {
ViewportRectangle = Rect.Empty; ViewportRectangle = Rect.Empty;
return; return;
} }
var x = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.X); var x = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.X);
var y = Layer.Leds.Min(l => l.RgbLed.AbsoluteLedRectangle.Location.Y); 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 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;
ViewportRectangle = new Rect(x - x * Layer.LayerShape.Position.X, y - y * Layer.LayerShape.Position.Y, width, height);
var rect = new Rect(x, y, width, height);
ViewportRectangle = rect;
} }
private Geometry CreateRectangleGeometry(ArtemisLed led) private Geometry CreateRectangleGeometry(ArtemisLed led)

View File

@ -183,7 +183,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
lock (CanvasViewModels) lock (CanvasViewModels)
{ {
foreach (var device in Devices.OrderBy(d => d.ZIndex).ToList()) foreach (var device in Devices.OrderBy(d => d.ZIndex).ToList())
CanvasViewModels.Move(CanvasViewModels.IndexOf(device), device.ZIndex - 1); {
var newIndex = Math.Max(device.ZIndex - 1, CanvasViewModels.Count - 1);
CanvasViewModels.Move(CanvasViewModels.IndexOf(device), newIndex);
}
} }
}); });
} }

View File

@ -7,6 +7,7 @@ using Artemis.Core.Models.Profile.LayerShapes;
using Artemis.UI.Properties; using Artemis.UI.Properties;
using Artemis.UI.Services.Interfaces; using Artemis.UI.Services.Interfaces;
using SkiaSharp; using SkiaSharp;
using SkiaSharp.Views.WPF;
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
{ {
@ -44,8 +45,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
if (ProfileEditorService.SelectedProfileElement is Layer layer) if (ProfileEditorService.SelectedProfileElement is Layer layer)
{ {
GetShapePosition(out var point, out var size); if (!(layer.LayerShape is Ellipse))
layer.LayerShape = new Ellipse(layer) {Size = size, Position = point}; layer.LayerShape = new Ellipse(layer);
layer.LayerShape.SetFromUnscaledRectangle(DragRectangle.ToSKRect());
ProfileEditorService.UpdateSelectedProfileElement(); ProfileEditorService.UpdateSelectedProfileElement();
} }
} }
@ -65,25 +67,5 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
if (e.Key == Key.LeftShift || e.Key == Key.RightShift) if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
_shiftDown = true; _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));
}
} }
} }

View File

@ -7,6 +7,7 @@ using Artemis.Core.Models.Surface;
using Artemis.UI.Extensions; using Artemis.UI.Extensions;
using Artemis.UI.Properties; using Artemis.UI.Properties;
using Artemis.UI.Services.Interfaces; using Artemis.UI.Services.Interfaces;
using SkiaSharp;
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
{ {
@ -46,8 +47,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
// Apply the selection to the selected layer layer // Apply the selection to the selected layer layer
if (ProfileEditorService.SelectedProfileElement is Layer layer) if (ProfileEditorService.SelectedProfileElement is Layer layer)
{ {
// If the layer has a shape, save it's size
var shapeSize = SKRect.Empty;
if (layer.LayerShape != null)
shapeSize = layer.LayerShape.GetUnscaledRectangle();
layer.ClearLeds(); layer.ClearLeds();
layer.AddLeds(selectedLeds); layer.AddLeds(selectedLeds);
// Restore the saved size
if (layer.LayerShape != null)
layer.LayerShape.SetFromUnscaledRectangle(shapeSize);
ProfileEditorService.UpdateSelectedProfileElement(); ProfileEditorService.UpdateSelectedProfileElement();
} }
// If no layer selected, apply it to a new layer in the selected folder // If no layer selected, apply it to a new layer in the selected folder