mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-01-01 10:13:30 +00:00
Need this on another PC :))
This commit is contained in:
parent
6cf9fb9158
commit
94df1544c5
@ -98,7 +98,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
{
|
{
|
||||||
_layerShape = value;
|
_layerShape = value;
|
||||||
if (Path != null)
|
if (Path != null)
|
||||||
_layerShape.CalculateRenderProperties();
|
CalculateRenderProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,13 @@ namespace Artemis.Core.Models.Profile
|
|||||||
internal void CalculateRenderProperties()
|
internal void CalculateRenderProperties()
|
||||||
{
|
{
|
||||||
if (!Leds.Any())
|
if (!Leds.Any())
|
||||||
|
{
|
||||||
|
Rectangle = SKRect.Empty;
|
||||||
|
AbsoluteRectangle = SKRect.Empty;
|
||||||
|
Path = new SKPath();
|
||||||
|
OnRenderPropertiesUpdated();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine to top-left and bottom-right
|
// Determine to top-left and bottom-right
|
||||||
var minX = Leds.Min(l => l.AbsoluteRenderRectangle.Left);
|
var minX = Leds.Min(l => l.AbsoluteRenderRectangle.Left);
|
||||||
@ -237,6 +243,7 @@ namespace Artemis.Core.Models.Profile
|
|||||||
path.AddRect(artemisLed.AbsoluteRenderRectangle);
|
path.AddRect(artemisLed.AbsoluteRenderRectangle);
|
||||||
|
|
||||||
Path = path;
|
Path = path;
|
||||||
|
LayerShape.CalculateRenderProperties();
|
||||||
OnRenderPropertiesUpdated();
|
OnRenderPropertiesUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,12 +255,18 @@ namespace Artemis.Core.Models.Profile
|
|||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public event EventHandler RenderPropertiesUpdated;
|
public event EventHandler RenderPropertiesUpdated;
|
||||||
|
public event EventHandler ShapePropertiesUpdated;
|
||||||
|
|
||||||
private void OnRenderPropertiesUpdated()
|
private void OnRenderPropertiesUpdated()
|
||||||
{
|
{
|
||||||
RenderPropertiesUpdated?.Invoke(this, EventArgs.Empty);
|
RenderPropertiesUpdated?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnShapePropertiesUpdated()
|
||||||
|
{
|
||||||
|
ShapePropertiesUpdated?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,8 +9,6 @@ namespace Artemis.Core.Models.Profile.LayerShapes
|
|||||||
protected LayerShape(Layer layer)
|
protected LayerShape(Layer layer)
|
||||||
{
|
{
|
||||||
Layer = layer;
|
Layer = layer;
|
||||||
|
|
||||||
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LayerShape(Layer layer, ShapeEntity shapeEntity)
|
protected LayerShape(Layer layer, ShapeEntity shapeEntity)
|
||||||
@ -19,14 +17,8 @@ namespace Artemis.Core.Models.Profile.LayerShapes
|
|||||||
Anchor = new SKPoint(shapeEntity.Anchor?.X ?? 0, shapeEntity.Anchor?.Y ?? 0);
|
Anchor = new SKPoint(shapeEntity.Anchor?.X ?? 0, shapeEntity.Anchor?.Y ?? 0);
|
||||||
Position = new SKPoint(shapeEntity.Position?.X ?? 0, shapeEntity.Position?.Y ?? 0);
|
Position = new SKPoint(shapeEntity.Position?.X ?? 0, shapeEntity.Position?.Y ?? 0);
|
||||||
Size = new SKSize(shapeEntity.Width, shapeEntity.Height);
|
Size = new SKSize(shapeEntity.Width, shapeEntity.Height);
|
||||||
|
|
||||||
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerOnRenderPropertiesUpdated(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
CalculateRenderProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layer this shape is attached to
|
/// The layer this shape is attached to
|
||||||
|
|||||||
@ -95,9 +95,6 @@ namespace Artemis.Core.Services.Storage
|
|||||||
folder.ApplyToEntity();
|
folder.ApplyToEntity();
|
||||||
foreach (var layer in profile.GetAllLayers())
|
foreach (var layer in profile.GetAllLayers())
|
||||||
layer.ApplyToEntity();
|
layer.ApplyToEntity();
|
||||||
|
|
||||||
if (_surfaceService.ActiveSurface != null)
|
|
||||||
profile.PopulateLeds(_surfaceService.ActiveSurface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_profileRepository.Save(profile.ProfileEntity);
|
_profileRepository.Save(profile.ProfileEntity);
|
||||||
|
|||||||
@ -19,10 +19,11 @@ namespace Artemis.Plugins.Devices.Wooting
|
|||||||
|
|
||||||
public override void EnablePlugin()
|
public override void EnablePlugin()
|
||||||
{
|
{
|
||||||
PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(WootingRGBDevice<>), sender, args);
|
// Disabled for now because the DLLs aren't on the repo
|
||||||
RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "wooting-rgb-sdk64.dll"));
|
// PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(WootingRGBDevice<>), sender, args);
|
||||||
RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "wooting-rgb-sdk.dll"));
|
// RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "wooting-rgb-sdk64.dll"));
|
||||||
_rgbService.AddDeviceProvider(RgbDeviceProvider);
|
// RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX86NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x86", "wooting-rgb-sdk.dll"));
|
||||||
|
// _rgbService.AddDeviceProvider(RgbDeviceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DisablePlugin()
|
public override void DisablePlugin()
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Media.Animation;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using Artemis.Core.Ninject;
|
using Artemis.Core.Ninject;
|
||||||
using Artemis.Core.Services.Interfaces;
|
using Artemis.Core.Services.Interfaces;
|
||||||
|
|||||||
@ -2,21 +2,20 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Artemis.Core.Models.Profile;
|
using Artemis.Core.Models.Profile;
|
||||||
using Artemis.UI.Behaviors;
|
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem;
|
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem;
|
||||||
using Artemis.UI.Services.Interfaces;
|
using Artemis.UI.Services.Interfaces;
|
||||||
using GongSolutions.Wpf.DragDrop;
|
using GongSolutions.Wpf.DragDrop;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
||||||
{
|
{
|
||||||
public class ProfileTreeViewModel : ProfileEditorPanelViewModel, IDropTarget
|
public class ProfileTreeViewModel : ProfileEditorPanelViewModel, IDropTarget
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
|
||||||
private readonly IFolderViewModelFactory _folderViewModelFactory;
|
private readonly IFolderViewModelFactory _folderViewModelFactory;
|
||||||
private readonly ILayerViewModelFactory _layerViewModelFactory;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private TreeItemViewModel _selectedTreeItem;
|
private TreeItemViewModel _selectedTreeItem;
|
||||||
|
private bool _updatingTree;
|
||||||
|
|
||||||
|
|
||||||
public ProfileTreeViewModel(IProfileEditorService profileEditorService,
|
public ProfileTreeViewModel(IProfileEditorService profileEditorService,
|
||||||
IFolderViewModelFactory folderViewModelFactory,
|
IFolderViewModelFactory folderViewModelFactory,
|
||||||
@ -24,7 +23,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
|||||||
{
|
{
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
_folderViewModelFactory = folderViewModelFactory;
|
_folderViewModelFactory = folderViewModelFactory;
|
||||||
_layerViewModelFactory = layerViewModelFactory;
|
|
||||||
|
|
||||||
CreateRootFolderViewModel();
|
CreateRootFolderViewModel();
|
||||||
_profileEditorService.SelectedProfileChanged += OnSelectedProfileChanged;
|
_profileEditorService.SelectedProfileChanged += OnSelectedProfileChanged;
|
||||||
@ -38,6 +36,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
|||||||
get => _selectedTreeItem;
|
get => _selectedTreeItem;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
if (_updatingTree) return;
|
||||||
_selectedTreeItem = value;
|
_selectedTreeItem = value;
|
||||||
_profileEditorService.ChangeSelectedProfileElement(value?.ProfileElement);
|
_profileEditorService.ChangeSelectedProfileElement(value?.ProfileElement);
|
||||||
}
|
}
|
||||||
@ -98,6 +97,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
|||||||
|
|
||||||
private void CreateRootFolderViewModel()
|
private void CreateRootFolderViewModel()
|
||||||
{
|
{
|
||||||
|
_updatingTree = true;
|
||||||
var firstChild = _profileEditorService.SelectedProfile?.Children?.FirstOrDefault();
|
var firstChild = _profileEditorService.SelectedProfile?.Children?.FirstOrDefault();
|
||||||
if (!(firstChild is Folder folder))
|
if (!(firstChild is Folder folder))
|
||||||
{
|
{
|
||||||
@ -106,6 +106,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
|||||||
}
|
}
|
||||||
|
|
||||||
RootFolder = _folderViewModelFactory.Create(folder);
|
RootFolder = _folderViewModelFactory.Create(folder);
|
||||||
|
_updatingTree = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DragDropType GetDragDropType(IDropInfo dropInfo)
|
private static DragDropType GetDragDropType(IDropInfo dropInfo)
|
||||||
@ -141,32 +142,26 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
|||||||
|
|
||||||
private void OnSelectedElementChanged(object sender, EventArgs e)
|
private void OnSelectedElementChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var vms = RootFolder?.GetAllChildren();
|
if (_profileEditorService.SelectedProfileElement == SelectedTreeItem?.ProfileElement)
|
||||||
|
return;
|
||||||
|
|
||||||
// Don't set it using the setter or that will trigger the event again
|
if (RootFolder == null)
|
||||||
_selectedTreeItem = vms?.FirstOrDefault(vm => vm.ProfileElement == _profileEditorService.SelectedProfileElement);
|
|
||||||
|
|
||||||
if (_selectedTreeItem == null && _profileEditorService.SelectedProfileElement != null)
|
|
||||||
{
|
{
|
||||||
var parent = vms?.FirstOrDefault(vm => vm.ProfileElement == _profileEditorService.SelectedProfileElement.Parent);
|
CreateRootFolderViewModel();
|
||||||
if (parent == null)
|
return;
|
||||||
{
|
|
||||||
// Eh.. we did our best.. start over
|
|
||||||
CreateRootFolderViewModel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new TreeItemViewModel for the new ProfileElement
|
|
||||||
TreeItemViewModel treeItemViewModel;
|
|
||||||
if (_profileEditorService.SelectedProfileElement is Folder folder)
|
|
||||||
treeItemViewModel = _folderViewModelFactory.Create(parent, folder);
|
|
||||||
else
|
|
||||||
treeItemViewModel = _layerViewModelFactory.Create(parent, (Layer) _profileEditorService.SelectedProfileElement);
|
|
||||||
parent.AddExistingElement(treeItemViewModel);
|
|
||||||
_selectedTreeItem = treeItemViewModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyOfPropertyChange(() => SelectedTreeItem);
|
_updatingTree = true;
|
||||||
|
RootFolder.UpdateProfileElements();
|
||||||
|
_updatingTree = false;
|
||||||
|
if (_profileEditorService.SelectedProfileElement == null)
|
||||||
|
SelectedTreeItem = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var vms = RootFolder.GetAllChildren();
|
||||||
|
vms.Add(RootFolder);
|
||||||
|
SelectedTreeItem = vms.FirstOrDefault(vm => vm.ProfileElement == _profileEditorService.SelectedProfileElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSelectedProfileChanged(object sender, EventArgs e)
|
private void OnSelectedProfileChanged(object sender, EventArgs e)
|
||||||
|
|||||||
@ -21,7 +21,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
ProfileElement profileElement,
|
ProfileElement profileElement,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
IDialogService dialogService,
|
IDialogService dialogService,
|
||||||
IFolderViewModelFactory folderViewModelFactory,
|
IFolderViewModelFactory folderViewModelFactory,
|
||||||
ILayerViewModelFactory layerViewModelFactory)
|
ILayerViewModelFactory layerViewModelFactory)
|
||||||
{
|
{
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
@ -155,7 +155,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
_profileEditorService.UpdateSelectedProfile();
|
_profileEditorService.UpdateSelectedProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateProfileElements()
|
public void UpdateProfileElements()
|
||||||
{
|
{
|
||||||
// Order the children
|
// Order the children
|
||||||
var vmsList = Children.OrderBy(v => v.ProfileElement.Order).ToList();
|
var vmsList = Children.OrderBy(v => v.ProfileElement.Order).ToList();
|
||||||
@ -175,13 +175,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
|||||||
{
|
{
|
||||||
existing = Children.FirstOrDefault(p => p is FolderViewModel vm && vm.ProfileElement == folder);
|
existing = Children.FirstOrDefault(p => p is FolderViewModel vm && vm.ProfileElement == folder);
|
||||||
if (existing == null)
|
if (existing == null)
|
||||||
Children.Add(_folderViewModelFactory.Create((FolderViewModel) this, folder));
|
Children.Add(_folderViewModelFactory.Create((FolderViewModel)this, folder));
|
||||||
}
|
}
|
||||||
else if (profileElement is Layer layer)
|
else if (profileElement is Layer layer)
|
||||||
{
|
{
|
||||||
existing = Children.FirstOrDefault(p => p is LayerViewModel vm && vm.ProfileElement == layer);
|
existing = Children.FirstOrDefault(p => p is LayerViewModel vm && vm.ProfileElement == layer);
|
||||||
if (existing == null)
|
if (existing == null)
|
||||||
Children.Add(_layerViewModelFactory.Create((FolderViewModel) this, layer));
|
Children.Add(_layerViewModelFactory.Create((FolderViewModel)this, layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
existing?.UpdateProfileElements();
|
existing?.UpdateProfileElements();
|
||||||
|
|||||||
@ -1,14 +1,43 @@
|
|||||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.Visualization.ProfileLayerView"
|
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.Visualization.ProfileLayerView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization"
|
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800">
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
<Path Data="{Binding LayerGeometry, Mode=OneWay}" ClipToBounds="False" StrokeThickness="1">
|
<Canvas>
|
||||||
<Path.Stroke>
|
<!-- The part of the layer's shape that falls outside the layer -->
|
||||||
<SolidColorBrush Color="{StaticResource Accent400}" />
|
<Path Data="{Binding ShapeGeometry, Mode=OneWay}" >
|
||||||
</Path.Stroke>
|
<Path.Fill>
|
||||||
</Path>
|
<SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.25" />
|
||||||
</UserControl>
|
</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>
|
||||||
@ -3,9 +3,11 @@ using System.Linq;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Artemis.Core.Models.Profile;
|
using Artemis.Core.Models.Profile;
|
||||||
|
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 Rectangle = Artemis.Core.Models.Profile.LayerShapes.Rectangle;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||||
{
|
{
|
||||||
@ -15,18 +17,35 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
{
|
{
|
||||||
Layer = layer;
|
Layer = layer;
|
||||||
|
|
||||||
CreateLayerGeometry();
|
Update();
|
||||||
Layer.RenderPropertiesUpdated += (sender, args) => CreateLayerGeometry();
|
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Layer Layer { get; }
|
public Layer Layer { get; }
|
||||||
|
|
||||||
public Geometry LayerGeometry { get; set; }
|
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()
|
private void CreateLayerGeometry()
|
||||||
{
|
{
|
||||||
|
if (!Layer.Leds.Any())
|
||||||
|
{
|
||||||
|
LayerGeometry = Geometry.Empty;
|
||||||
|
OpacityGeometry = Geometry.Empty;
|
||||||
|
ViewportRectangle = Rect.Empty;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var layerGeometry = Geometry.Empty;
|
var layerGeometry = Geometry.Empty;
|
||||||
|
|
||||||
foreach (var led in Layer.Leds)
|
foreach (var led in Layer.Leds)
|
||||||
{
|
{
|
||||||
Geometry geometry;
|
Geometry geometry;
|
||||||
@ -34,15 +53,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
{
|
{
|
||||||
case Shape.Custom:
|
case Shape.Custom:
|
||||||
if (led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
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
|
else
|
||||||
geometry = CreateCustomGeometry(led, 1.0);
|
geometry = CreateCustomGeometry(led, 1);
|
||||||
break;
|
break;
|
||||||
case Shape.Rectangle:
|
case Shape.Rectangle:
|
||||||
if (led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
geometry = CreateRectangleGeometry(led);
|
||||||
geometry = CreateKeyCapGeometry(led);
|
|
||||||
else
|
|
||||||
geometry = CreateRectangleGeometry(led);
|
|
||||||
break;
|
break;
|
||||||
case Shape.Circle:
|
case Shape.Circle:
|
||||||
geometry = CreateCircleGeometry(led);
|
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);
|
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 = 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)
|
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)
|
private Geometry CreateCircleGeometry(ArtemisLed led)
|
||||||
{
|
{
|
||||||
return new EllipseGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1));
|
var rect = led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1);
|
||||||
}
|
rect.Inflate(1, 1);
|
||||||
|
return new EllipseGeometry(rect);
|
||||||
private Geometry CreateKeyCapGeometry(ArtemisLed led)
|
|
||||||
{
|
|
||||||
return new RectangleGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1), 1.6, 1.6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Geometry CreateCustomGeometry(ArtemisLed led, double deflateAmount)
|
private Geometry CreateCustomGeometry(ArtemisLed led, double deflateAmount)
|
||||||
{
|
{
|
||||||
|
var rect = led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1);
|
||||||
|
rect.Inflate(1, 1);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var geometry = Geometry.Combine(
|
var geometry = Geometry.Combine(
|
||||||
@ -85,11 +162,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
{
|
{
|
||||||
Children = new TransformCollection
|
Children = new TransformCollection
|
||||||
{
|
{
|
||||||
new ScaleTransform(led.RgbLed.ActualSize.Width - deflateAmount, led.RgbLed.ActualSize.Height - deflateAmount),
|
new ScaleTransform(rect.Width, rect.Height),
|
||||||
new TranslateTransform(deflateAmount / 2, deflateAmount / 2)
|
new TranslateTransform(rect.X, rect.Y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return geometry;
|
return geometry;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
@ -97,5 +175,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
return CreateRectangleGeometry(led);
|
return CreateRectangleGeometry(led);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LayerOnRenderPropertiesUpdated(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@
|
|||||||
</Path>
|
</Path>
|
||||||
|
|
||||||
<!-- Selection -->
|
<!-- 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>
|
<Path.Style>
|
||||||
<Style TargetType="{x:Type Path}">
|
<Style TargetType="{x:Type Path}">
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
|
|||||||
@ -145,7 +145,7 @@
|
|||||||
<materialDesign:Card Padding="8">
|
<materialDesign:Card Padding="8">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding HighlightSelectedLayer.Value}">
|
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding HighlightSelectedLayer.Value}">
|
||||||
Highlight selected layer
|
Dim LEDs outside selected layer
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" Margin="10 0 0 0" IsChecked="{Binding PauseRenderingOnFocusLoss.Value}">
|
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" Margin="10 0 0 0" IsChecked="{Binding PauseRenderingOnFocusLoss.Value}">
|
||||||
Pause visualization on focus loss
|
Pause visualization on focus loss
|
||||||
|
|||||||
@ -139,7 +139,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
// Remove layers that no longer exist
|
// Remove layers that no longer exist
|
||||||
var toRemove = layerViewModels.Where(vm => !layers.Contains(vm.Layer));
|
var toRemove = layerViewModels.Where(vm => !layers.Contains(vm.Layer));
|
||||||
foreach (var profileLayerViewModel in toRemove)
|
foreach (var profileLayerViewModel in toRemove)
|
||||||
|
{
|
||||||
|
profileLayerViewModel.Dispose();
|
||||||
CanvasViewModels.Remove(profileLayerViewModel);
|
CanvasViewModels.Remove(profileLayerViewModel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using Artemis.Core.Models.Profile;
|
||||||
|
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;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
||||||
{
|
{
|
||||||
@ -34,6 +38,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
|
|||||||
DragRectangle = GetSquareRectBetweenPoints(MouseDownStartPosition, position);
|
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)
|
public override void KeyUp(KeyEventArgs e)
|
||||||
{
|
{
|
||||||
base.KeyUp(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)
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user