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

Started work on layer visualization

This commit is contained in:
SpoinkyNL 2019-12-16 22:57:13 +01:00
parent 8539f05d90
commit 6cf9fb9158
5 changed files with 192 additions and 1 deletions

View File

@ -184,6 +184,10 @@
</Compile>
<Compile Include="Screens\Module\ProfileEditor\LayerProperties\Timeline\LayerPropertiesTimelineViewModel.cs" />
<Compile Include="Screens\Module\ProfileEditor\Visualization\CanvasViewModel.cs" />
<Compile Include="Screens\Module\ProfileEditor\Visualization\ProfileLayerView.xaml.cs">
<DependentUpon>ProfileLayerView.xaml</DependentUpon>
</Compile>
<Compile Include="Screens\Module\ProfileEditor\Visualization\ProfileLayerViewModel.cs" />
<Compile Include="Screens\Module\ProfileEditor\Visualization\Tools\EllipseToolView.xaml.cs">
<DependentUpon>EllipseToolView.xaml</DependentUpon>
</Compile>
@ -332,6 +336,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Screens\Module\ProfileEditor\Visualization\ProfileLayerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Screens\Module\ProfileEditor\Visualization\ProfileView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -0,0 +1,14 @@
<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:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization"
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>

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
{
/// <summary>
/// Interaction logic for ProfileLayerView.xaml
/// </summary>
public partial class ProfileLayerView : UserControl
{
public ProfileLayerView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,101 @@
using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Surface;
using Artemis.UI.Extensions;
using RGB.NET.Core;
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
{
public class ProfileLayerViewModel : CanvasViewModel
{
public ProfileLayerViewModel(Layer layer)
{
Layer = layer;
CreateLayerGeometry();
Layer.RenderPropertiesUpdated += (sender, args) => CreateLayerGeometry();
}
public Layer Layer { get; }
public Geometry LayerGeometry { get; set; }
private void CreateLayerGeometry()
{
var layerGeometry = Geometry.Empty;
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.0);
else
geometry = CreateCustomGeometry(led, 1.0);
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);
break;
case Shape.Circle:
geometry = CreateCircleGeometry(led);
break;
default:
throw new ArgumentOutOfRangeException();
}
layerGeometry = Geometry.Combine(layerGeometry, geometry, GeometryCombineMode.Union, null, 5, ToleranceType.Absolute);
}
LayerGeometry = layerGeometry;
LayerGeometry.Freeze();
}
private Geometry CreateRectangleGeometry(ArtemisLed led)
{
return new RectangleGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1));
}
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);
}
private Geometry CreateCustomGeometry(ArtemisLed led, double deflateAmount)
{
try
{
var geometry = Geometry.Combine(
Geometry.Empty,
Geometry.Parse(led.RgbLed.ShapeData),
GeometryCombineMode.Union,
new TransformGroup
{
Children = new TransformCollection
{
new ScaleTransform(led.RgbLed.ActualSize.Width - deflateAmount, led.RgbLed.ActualSize.Height - deflateAmount),
new TranslateTransform(deflateAmount / 2, deflateAmount / 2)
}
}
);
return geometry;
}
catch (Exception)
{
return CreateRectangleGeometry(led);
}
}
}
}

View File

@ -42,14 +42,17 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
});
ApplySurfaceConfiguration(surfaceService.ActiveSurface);
ApplyActiveProfile();
CreateUpdateTrigger();
ActivateToolByIndex(0);
_profileEditorService.SelectedProfileChanged += OnSelectedProfileChanged;
_profileEditorService.SelectedProfileElementChanged += OnSelectedProfileElementChanged;
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementChanged;
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated;
eventAggregator.Subscribe(this);
}
public bool IsInitializing { get; private set; }
public ObservableCollection<CanvasViewModel> CanvasViewModels { get; set; }
public PanZoomViewModel PanZoomViewModel { get; set; }
@ -116,6 +119,31 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
ApplySurfaceConfiguration(e.Surface);
}
private void ApplyActiveProfile()
{
Execute.PostToUIThread(() =>
{
lock (CanvasViewModels)
{
var layerViewModels = CanvasViewModels.Where(vm => vm is ProfileLayerViewModel).Cast<ProfileLayerViewModel>().ToList();
var layers = _profileEditorService.SelectedProfile?.GetAllLayers() ?? new List<Layer>();
// Add new layers missing a VM
foreach (var layer in layers)
{
if (layerViewModels.All(vm => vm.Layer != layer))
CanvasViewModels.Add(new ProfileLayerViewModel(layer));
}
// Remove layers that no longer exist
var toRemove = layerViewModels.Where(vm => !layers.Contains(vm.Layer));
foreach (var profileLayerViewModel in toRemove)
CanvasViewModels.Remove(profileLayerViewModel);
}
});
}
private void ApplySurfaceConfiguration(ArtemisSurface surface)
{
var devices = new List<ArtemisDevice>();
@ -324,12 +352,24 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
UpdateLedsDimStatus();
}
private void OnSelectedProfileChanged(object sender, EventArgs e)
{
ApplyActiveProfile();
}
private void OnSelectedProfileElementChanged(object sender, EventArgs e)
{
UpdateLedsDimStatus();
CanApplyToLayer = _profileEditorService.SelectedProfileElement is Layer;
}
private void OnSelectedProfileElementUpdated(object sender, EventArgs e)
{
ApplyActiveProfile();
UpdateLedsDimStatus();
CanApplyToLayer = _profileEditorService.SelectedProfileElement is Layer;
}
public void Handle(MainWindowFocusChangedEvent message)
{
if (PauseRenderingOnFocusLoss == null || ScreenState != ScreenState.Active)