mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Core port - Updated projects to new project layout Core port - Changed the way devices are identified to be consistent across different frameworks Core port - Updated plugin system to no longer use AppDomain but AssemblyLoadContext (through McMaster.NETCore.Plugins) Core port - Renamed a few events to keep Fody from getting confused
207 lines
7.1 KiB
C#
207 lines
7.1 KiB
C#
using System;
|
|
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 Artemis.UI.Services.Interfaces;
|
|
using RGB.NET.Core;
|
|
using Stylet;
|
|
using Rectangle = Artemis.Core.Models.Profile.LayerShapes.Rectangle;
|
|
|
|
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|
{
|
|
public class ProfileLayerViewModel : CanvasViewModel
|
|
{
|
|
private readonly ILayerEditorService _layerEditorService;
|
|
private readonly IProfileEditorService _profileEditorService;
|
|
|
|
public ProfileLayerViewModel(Layer layer, IProfileEditorService profileEditorService, ILayerEditorService layerEditorService)
|
|
{
|
|
_profileEditorService = profileEditorService;
|
|
_layerEditorService = layerEditorService;
|
|
Layer = layer;
|
|
|
|
Update();
|
|
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
|
_profileEditorService.ProfileElementSelected += OnProfileElementSelected;
|
|
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated;
|
|
_profileEditorService.ProfilePreviewUpdated += ProfileEditorServiceOnProfilePreviewUpdated;
|
|
}
|
|
|
|
public Layer Layer { get; }
|
|
|
|
public Geometry LayerGeometry { get; set; }
|
|
public Geometry OpacityGeometry { get; set; }
|
|
public Geometry ShapeGeometry { get; set; }
|
|
public Rect ViewportRectangle { get; set; }
|
|
public bool IsSelected { get; set; }
|
|
|
|
public void Dispose()
|
|
{
|
|
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
|
|
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
|
|
_profileEditorService.SelectedProfileElementUpdated -= OnSelectedProfileElementUpdated;
|
|
_profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
IsSelected = _profileEditorService.SelectedProfileElement == Layer;
|
|
CreateLayerGeometry();
|
|
CreateShapeGeometry();
|
|
CreateViewportRectangle();
|
|
}
|
|
|
|
private void CreateLayerGeometry()
|
|
{
|
|
if (!Layer.Leds.Any())
|
|
{
|
|
LayerGeometry = Geometry.Empty;
|
|
OpacityGeometry = Geometry.Empty;
|
|
ViewportRectangle = Rect.Empty;
|
|
return;
|
|
}
|
|
|
|
var group = new GeometryGroup();
|
|
group.FillRule = FillRule.Nonzero;
|
|
|
|
foreach (var led in Layer.Leds)
|
|
{
|
|
Geometry geometry;
|
|
switch (led.RgbLed.Shape)
|
|
{
|
|
case Shape.Custom:
|
|
if (led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
|
geometry = CreateCustomGeometry(led, 2);
|
|
else
|
|
geometry = CreateCustomGeometry(led, 1);
|
|
break;
|
|
case Shape.Rectangle:
|
|
geometry = CreateRectangleGeometry(led);
|
|
break;
|
|
case Shape.Circle:
|
|
geometry = CreateCircleGeometry(led);
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
|
|
group.Children.Add(geometry);
|
|
}
|
|
|
|
var layerGeometry = group.GetOutlinedPathGeometry();
|
|
var opacityGeometry = Geometry.Combine(Geometry.Empty, layerGeometry, GeometryCombineMode.Exclude, new TranslateTransform());
|
|
|
|
LayerGeometry = layerGeometry;
|
|
OpacityGeometry = opacityGeometry;
|
|
}
|
|
|
|
private void CreateShapeGeometry()
|
|
{
|
|
if (Layer.LayerShape == null || !Layer.Leds.Any())
|
|
{
|
|
ShapeGeometry = Geometry.Empty;
|
|
return;
|
|
}
|
|
|
|
Execute.PostToUIThread(() =>
|
|
{
|
|
var bounds = _layerEditorService.GetLayerBounds(Layer);
|
|
var shapeGeometry = Geometry.Empty;
|
|
switch (Layer.LayerShape)
|
|
{
|
|
case Ellipse _:
|
|
shapeGeometry = new EllipseGeometry(bounds);
|
|
break;
|
|
case Rectangle _:
|
|
shapeGeometry = new RectangleGeometry(bounds);
|
|
break;
|
|
}
|
|
|
|
shapeGeometry.Transform = _layerEditorService.GetLayerTransformGroup(Layer);
|
|
ShapeGeometry = shapeGeometry;
|
|
});
|
|
}
|
|
|
|
private void CreateViewportRectangle()
|
|
{
|
|
if (!Layer.Leds.Any() || Layer.LayerShape == null)
|
|
{
|
|
ViewportRectangle = Rect.Empty;
|
|
return;
|
|
}
|
|
|
|
ViewportRectangle = _layerEditorService.GetLayerBounds(Layer);
|
|
}
|
|
|
|
private Geometry CreateRectangleGeometry(ArtemisLed led)
|
|
{
|
|
var rect = led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1);
|
|
rect.Inflate(1, 1);
|
|
return new RectangleGeometry(rect);
|
|
}
|
|
|
|
private Geometry CreateCircleGeometry(ArtemisLed led)
|
|
{
|
|
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(
|
|
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);
|
|
}
|
|
}
|
|
|
|
#region Event handlers
|
|
|
|
private void LayerOnRenderPropertiesUpdated(object sender, EventArgs e)
|
|
{
|
|
Update();
|
|
}
|
|
|
|
private void OnProfileElementSelected(object sender, EventArgs e)
|
|
{
|
|
IsSelected = _profileEditorService.SelectedProfileElement == Layer;
|
|
}
|
|
|
|
private void OnSelectedProfileElementUpdated(object sender, EventArgs e)
|
|
{
|
|
Update();
|
|
}
|
|
|
|
private void ProfileEditorServiceOnProfilePreviewUpdated(object sender, EventArgs e)
|
|
{
|
|
CreateShapeGeometry();
|
|
CreateViewportRectangle();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |