From 920aea669563edbac60961e687d073d50686a07f Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Mon, 22 Jun 2020 22:14:33 +0200 Subject: [PATCH] Device visualizer - Added support for rotation and scale Profile editor - Fixed keyframe context menu actions --- .../Artemis.UI.Shared.csproj | 5 -- .../Controls/DeviceVisualizer.cs | 64 ++++++++++++++++--- .../Controls/DeviceVisualizerLed.cs | 12 ++-- .../Controls/DraggableFloat.xaml | 12 ++-- .../PropertyInput/PropertyInputViewModel.cs | 9 ++- .../Screens/Dialogs/ExceptionDialogView.xaml | 2 +- .../Dialogs/ExceptionDialogViewModel.cs | 8 ++- .../Services/Dialog/DialogService.cs | 27 +++++--- .../Services/Dialog/DialogViewModelBase.cs | 16 ++++- .../Timeline/TimelineKeyframeViewModel.cs | 20 ++---- .../Timeline/TimelinePropertyView.xaml | 4 +- .../Timeline/TimelineViewModel.cs | 46 ++++++++++--- .../Dialogs/SurfaceDeviceConfigViewModel.cs | 11 +++- .../Visualization/SurfaceDeviceView.xaml | 8 +-- .../Layouts/Corsair/Customs/PUMP.xml | 19 ++++-- 15 files changed, 185 insertions(+), 78 deletions(-) diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index c456eb1e2..72ee9b69a 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -30,16 +30,11 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs index 7f5f9498f..f0698d57f 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs @@ -1,16 +1,15 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using Artemis.Core.Models.Surface; using RGB.NET.Core; -using Point = System.Windows.Point; +using Size = System.Windows.Size; namespace Artemis.UI.Shared.Controls { @@ -29,6 +28,7 @@ namespace Artemis.UI.Shared.Controls private readonly List _deviceVisualizerLeds; private BitmapImage _deviceImage; private bool _subscribed; + private ArtemisDevice _oldDevice; public DeviceVisualizer() { @@ -38,7 +38,7 @@ namespace Artemis.UI.Shared.Controls Loaded += (sender, args) => SubscribeToUpdate(true); Unloaded += (sender, args) => SubscribeToUpdate(false); } - + public ArtemisDevice Device { get => (ArtemisDevice) GetValue(DeviceProperty); @@ -68,9 +68,10 @@ namespace Artemis.UI.Shared.Controls return; // Determine the scale required to fit the desired size of the control - var scale = Math.Min(DesiredSize.Width / Device.RgbDevice.Size.Width, DesiredSize.Height / Device.RgbDevice.Size.Height); - var scaledRect = new Rect(0, 0, Device.RgbDevice.Size.Width * scale, Device.RgbDevice.Size.Height * scale); - + var measureSize = MeasureOverride(Size.Empty); + var scale = Math.Min(DesiredSize.Width / measureSize.Width, DesiredSize.Height / measureSize.Height); + var scaledRect = new Rect(0, 0, measureSize.Width * scale, measureSize.Height * scale); + // Center and scale the visualization in the desired bounding box if (DesiredSize.Width > 0 && DesiredSize.Height > 0) { @@ -78,16 +79,45 @@ namespace Artemis.UI.Shared.Controls drawingContext.PushTransform(new ScaleTransform(scale, scale)); } + // Determine the offset required to rotate within bounds + var rotationRect = new Rect(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height); + rotationRect.Transform(new RotateTransform(Device.Rotation).Value); + + // Apply device rotation + drawingContext.PushTransform(new TranslateTransform(0 - rotationRect.Left, 0 - rotationRect.Top)); + drawingContext.PushTransform(new RotateTransform(Device.Rotation)); + + // Apply device scale + drawingContext.PushTransform(new ScaleTransform(Device.Scale, Device.Scale)); + // Render device and LED images if (_deviceImage != null) drawingContext.DrawImage(_deviceImage, new Rect(0, 0, Device.RgbDevice.Size.Width, Device.RgbDevice.Size.Height)); - + foreach (var deviceVisualizerLed in _deviceVisualizerLeds) deviceVisualizerLed.RenderImage(drawingContext); drawingContext.DrawDrawing(_backingStore); } + protected override Size MeasureOverride(Size availableSize) + { + if (Device == null) + return Size.Empty; + + var rotationRect = new Rect(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height); + rotationRect.Transform(new RotateTransform(Device.Rotation).Value); + + return rotationRect.Size; + } + + + private void UpdateTransform() + { + InvalidateVisual(); + InvalidateMeasure(); + } + private void SubscribeToUpdate(bool subscribe) { if (_subscribed == subscribe) @@ -121,6 +151,13 @@ namespace Artemis.UI.Shared.Controls if (Device == null) return; + if (_oldDevice != null) + Device.RgbDevice.PropertyChanged -= DevicePropertyChanged; + _oldDevice = Device; + + Device.RgbDevice.PropertyChanged += DevicePropertyChanged; + UpdateTransform(); + // Load the device main image if (Device.RgbDevice?.DeviceInfo?.Image?.AbsolutePath != null && File.Exists(Device.RgbDevice.DeviceInfo.Image.AbsolutePath)) _deviceImage = new BitmapImage(Device.RgbDevice.DeviceInfo.Image); @@ -130,7 +167,10 @@ namespace Artemis.UI.Shared.Controls _deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed)); if (!ShowColors) + { + InvalidateMeasure(); return; + } // Create the opacity drawing group var opacityDrawingGroup = new DrawingGroup(); @@ -157,6 +197,14 @@ namespace Artemis.UI.Shared.Controls var bitmapBrush = new ImageBrush(bitmap); bitmapBrush.Freeze(); _backingStore.OpacityMask = bitmapBrush; + + InvalidateMeasure(); + } + + private void DevicePropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(Device.RgbDevice.Scale) || e.PropertyName == nameof(Device.RgbDevice.Rotation)) + UpdateTransform(); } private void RgbSurfaceOnUpdated(UpdatedEventArgs e) diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs index 79470d567..e0599504b 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs @@ -13,12 +13,14 @@ namespace Artemis.UI.Shared.Controls { public DeviceVisualizerLed(ArtemisLed led) { + if (led.Device.Scale != 1) + Console.WriteLine(); Led = led; LedRect = new Rect( - Led.RgbLed.LedRectangle.Location.X, - Led.RgbLed.LedRectangle.Location.Y, - Led.RgbLed.LedRectangle.Size.Width, - Led.RgbLed.LedRectangle.Size.Height + Led.RgbLed.Location.X, + Led.RgbLed.Location.Y, + Led.RgbLed.Size.Width, + Led.RgbLed.Size.Height ); if (Led.RgbLed.Image != null && File.Exists(Led.RgbLed.Image.AbsolutePath)) @@ -97,7 +99,7 @@ namespace Artemis.UI.Shared.Controls } // Stroke geometry is the display geometry excluding the inner geometry - DisplayGeometry.Transform = new TranslateTransform(Led.RgbLed.LedRectangle.Location.X, Led.RgbLed.LedRectangle.Location.Y); + DisplayGeometry.Transform = new TranslateTransform(Led.RgbLed.Location.X, Led.RgbLed.Location.Y); // Try to gain some performance DisplayGeometry.Freeze(); } diff --git a/src/Artemis.UI.Shared/Controls/DraggableFloat.xaml b/src/Artemis.UI.Shared/Controls/DraggableFloat.xaml index c9c7dc315..2155218ae 100644 --- a/src/Artemis.UI.Shared/Controls/DraggableFloat.xaml +++ b/src/Artemis.UI.Shared/Controls/DraggableFloat.xaml @@ -12,7 +12,7 @@ - + @@ -28,8 +28,8 @@ - + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/PropertyInput/PropertyInputViewModel.cs b/src/Artemis.UI.Shared/PropertyInput/PropertyInputViewModel.cs index fb08cfe80..ab1856305 100644 --- a/src/Artemis.UI.Shared/PropertyInput/PropertyInputViewModel.cs +++ b/src/Artemis.UI.Shared/PropertyInput/PropertyInputViewModel.cs @@ -8,6 +8,7 @@ namespace Artemis.UI.Shared.PropertyInput public abstract class PropertyInputViewModel : ValidatingModelBase, IDisposable { private T _inputValue; + private bool _inputDragging; protected PropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService) { @@ -30,14 +31,18 @@ namespace Artemis.UI.Shared.PropertyInput public LayerProperty LayerProperty { get; } public IProfileEditorService ProfileEditorService { get; } - public bool InputDragging { get; private set; } + public bool InputDragging + { + get => _inputDragging; + private set => SetAndNotify(ref _inputDragging, value); + } public T InputValue { get => _inputValue; set { - _inputValue = value; + SetAndNotify(ref _inputValue, value); ApplyInputValue(); } } diff --git a/src/Artemis.UI.Shared/Screens/Dialogs/ExceptionDialogView.xaml b/src/Artemis.UI.Shared/Screens/Dialogs/ExceptionDialogView.xaml index 0ac419bdc..95ed127ab 100644 --- a/src/Artemis.UI.Shared/Screens/Dialogs/ExceptionDialogView.xaml +++ b/src/Artemis.UI.Shared/Screens/Dialogs/ExceptionDialogView.xaml @@ -14,7 +14,7 @@ - + diff --git a/src/Artemis.UI.Shared/Screens/Dialogs/ExceptionDialogViewModel.cs b/src/Artemis.UI.Shared/Screens/Dialogs/ExceptionDialogViewModel.cs index 01e14799f..0090cbc28 100644 --- a/src/Artemis.UI.Shared/Screens/Dialogs/ExceptionDialogViewModel.cs +++ b/src/Artemis.UI.Shared/Screens/Dialogs/ExceptionDialogViewModel.cs @@ -7,6 +7,8 @@ namespace Artemis.UI.Shared.Screens.Dialogs { public class ExceptionDialogViewModel : DialogViewModelBase { + private List _exceptions; + public ExceptionDialogViewModel(string message, Exception exception) { Header = message; @@ -21,8 +23,12 @@ namespace Artemis.UI.Shared.Screens.Dialogs } public string Header { get; } - public List Exceptions { get; set; } + public List Exceptions + { + get => _exceptions; + set => SetAndNotify(ref _exceptions, value); + } public void Close() { diff --git a/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs b/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs index 18dfe74d8..62a761d62 100644 --- a/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs +++ b/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs @@ -96,18 +96,25 @@ namespace Artemis.UI.Shared.Services.Dialog new ConstructorArgument("exception", exception) }; - await Execute.OnUIThreadAsync(async () => + try { - try + await Execute.OnUIThreadAsync(async () => { - DialogHost.CloseDialogCommand.Execute(new object(), null); - await ShowDialog(arguments); - } - catch (Exception) - { - // ignored - } - }); + try + { + DialogHost.CloseDialogCommand.Execute(new object(), null); + await ShowDialog(arguments); + } + catch (Exception) + { + // ignored + } + }); + } + catch (Exception) + { + // ignored + } } private async Task ShowDialog(string identifier, DialogViewModelBase viewModel) diff --git a/src/Artemis.UI.Shared/Services/Dialog/DialogViewModelBase.cs b/src/Artemis.UI.Shared/Services/Dialog/DialogViewModelBase.cs index 3e71803d0..1501a95a1 100644 --- a/src/Artemis.UI.Shared/Services/Dialog/DialogViewModelBase.cs +++ b/src/Artemis.UI.Shared/Services/Dialog/DialogViewModelBase.cs @@ -5,6 +5,9 @@ namespace Artemis.UI.Shared.Services.Dialog { public abstract class DialogViewModelBase : ValidatingModelBase { + private DialogViewModelHost _dialogViewModelHost; + private DialogSession _session; + protected DialogViewModelBase(IModelValidator validator) : base(validator) { } @@ -13,8 +16,17 @@ namespace Artemis.UI.Shared.Services.Dialog { } - public DialogViewModelHost DialogViewModelHost { get; set; } - public DialogSession Session { get; private set; } + public DialogViewModelHost DialogViewModelHost + { + get => _dialogViewModelHost; + set => SetAndNotify(ref _dialogViewModelHost, value); + } + + public DialogSession Session + { + get => _session; + private set => SetAndNotify(ref _session, value); + } public void OnDialogOpened(object sender, DialogOpenedEventArgs e) { diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs index 0b821cefb..4545a2205 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs @@ -23,7 +23,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline #region Context menu actions - public void Copy() + public override void Copy() { var newKeyframe = new LayerPropertyKeyframe( LayerPropertyKeyframe.Value, @@ -35,7 +35,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline _profileEditorService.UpdateSelectedProfileElement(); } - public void Delete() + public override void Delete() { LayerPropertyKeyframe.LayerProperty.RemoveKeyframe(LayerPropertyKeyframe); _profileEditorService.UpdateSelectedProfileElement(); @@ -73,23 +73,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline Timestamp = $"{Math.Floor(BaseLayerPropertyKeyframe.Position.TotalSeconds):00}.{BaseLayerPropertyKeyframe.Position.Milliseconds:000}"; } - #region Keyframe movement + public abstract void Copy(); - #endregion + public abstract void Delete(); #region Easing - public void ContextMenuOpening() - { - CreateEasingViewModels(); - } - - public void ContextMenuClosing() - { - EasingViewModels.Clear(); - } - - private void CreateEasingViewModels() + public void CreateEasingViewModels() { EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast().Select(v => new TimelineEasingViewModel(this, v))); } diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyView.xaml index 350b4c634..87f5eaa42 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyView.xaml @@ -63,12 +63,12 @@ - + - + diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineViewModel.cs index 959a10457..2a13b80ef 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineViewModel.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.Linq; using System.Windows; +using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; +using Artemis.Core.Models.Profile.LayerProperties; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract; using Artemis.UI.Shared.Services.Interfaces; using Artemis.UI.Shared.Utilities; @@ -58,7 +60,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline if (viewModel == null) return; - ((IInputElement) sender).CaptureMouse(); + ((IInputElement)sender).CaptureMouse(); if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) && !viewModel.IsSelected) SelectKeyframe(viewModel, true, false); else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) @@ -74,7 +76,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline _profileEditorService.UpdateSelectedProfileElement(); ReleaseSelectedKeyframes(); - ((IInputElement) sender).ReleaseMouseCapture(); + ((IInputElement)sender).ReleaseMouseCapture(); } public void KeyframeMouseMove(object sender, MouseEventArgs e) @@ -85,6 +87,32 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline e.Handled = true; } + #region Context menu actions + + public void ContextMenuOpening(object sender, ContextMenuEventArgs e) + { + var viewModel = (sender as Ellipse)?.DataContext as TimelineKeyframeViewModel; + viewModel?.CreateEasingViewModels(); + } + + public void ContextMenuClosing(object sender, ContextMenuEventArgs e) + { + var viewModel = (sender as Ellipse)?.DataContext as TimelineKeyframeViewModel; + viewModel?.EasingViewModels.Clear(); + } + + public void Copy(TimelineKeyframeViewModel viewModel) + { + viewModel.Copy(); + } + + public void Delete(TimelineKeyframeViewModel viewModel) + { + viewModel.Delete(); + } + + #endregion + private TimeSpan GetCursorTime(Point position) { // Get the parent grid, need that for our position @@ -148,10 +176,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline if (e.LeftButton == MouseButtonState.Released) return; - ((IInputElement) sender).CaptureMouse(); + ((IInputElement)sender).CaptureMouse(); SelectionRectangle.Rect = new Rect(); - _mouseDragStartPoint = e.GetPosition((IInputElement) sender); + _mouseDragStartPoint = e.GetPosition((IInputElement)sender); _mouseDragging = true; e.Handled = true; } @@ -162,25 +190,25 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline if (!_mouseDragging) return; - var position = e.GetPosition((IInputElement) sender); + var position = e.GetPosition((IInputElement)sender); var selectedRect = new Rect(_mouseDragStartPoint, position); SelectionRectangle.Rect = selectedRect; var keyframeViewModels = GetAllKeyframeViewModels(); - var selectedKeyframes = HitTestUtilities.GetHitViewModels((Visual) sender, SelectionRectangle); + var selectedKeyframes = HitTestUtilities.GetHitViewModels((Visual)sender, SelectionRectangle); foreach (var keyframeViewModel in keyframeViewModels) keyframeViewModel.IsSelected = selectedKeyframes.Contains(keyframeViewModel); _mouseDragging = false; e.Handled = true; - ((IInputElement) sender).ReleaseMouseCapture(); + ((IInputElement)sender).ReleaseMouseCapture(); } public void TimelineCanvasMouseMove(object sender, MouseEventArgs e) { if (_mouseDragging && e.LeftButton == MouseButtonState.Pressed) { - var position = e.GetPosition((IInputElement) sender); + var position = e.GetPosition((IInputElement)sender); var selectedRect = new Rect(_mouseDragStartPoint, position); SelectionRectangle.Rect = selectedRect; e.Handled = true; @@ -236,7 +264,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline viewModels.AddRange(layerPropertyGroupViewModel.GetAllChildren()); var keyframes = viewModels.Where(vm => vm is LayerPropertyViewModel) - .SelectMany(vm => ((LayerPropertyViewModel) vm).TimelinePropertyBaseViewModel.TimelineKeyframeViewModels) + .SelectMany(vm => ((LayerPropertyViewModel)vm).TimelinePropertyBaseViewModel.TimelineKeyframeViewModels) .ToList(); return keyframes; diff --git a/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModel.cs b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModel.cs index 5ad430311..d8c942332 100644 --- a/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModel.cs +++ b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModel.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Artemis.Core.Services.Interfaces; using Artemis.UI.Screens.SurfaceEditor.Visualization; using Artemis.UI.Shared.Services.Dialog; using Stylet; @@ -7,9 +8,12 @@ namespace Artemis.UI.Screens.SurfaceEditor.Dialogs { public class SurfaceDeviceConfigViewModel : DialogViewModelBase { - public SurfaceDeviceConfigViewModel(SurfaceDeviceViewModel surfaceDeviceViewModel, IModelValidator validator) + private readonly ICoreService _coreService; + + public SurfaceDeviceConfigViewModel(SurfaceDeviceViewModel surfaceDeviceViewModel, ICoreService coreService, IModelValidator validator) : base(validator) { + _coreService = coreService; SurfaceDeviceViewModel = surfaceDeviceViewModel; Title = $"{SurfaceDeviceViewModel.Device.RgbDevice.DeviceInfo.DeviceName} - Properties"; @@ -33,11 +37,16 @@ namespace Artemis.UI.Screens.SurfaceEditor.Dialogs if (HasErrors) return; + _coreService.ModuleRenderingDisabled = true; + await Task.Delay(100); + SurfaceDeviceViewModel.Device.X = X; SurfaceDeviceViewModel.Device.Y = Y; SurfaceDeviceViewModel.Device.Scale = Scale; SurfaceDeviceViewModel.Device.Rotation = Rotation; + _coreService.ModuleRenderingDisabled = false; + Session.Close(true); } diff --git a/src/Artemis.UI/Screens/SurfaceEditor/Visualization/SurfaceDeviceView.xaml b/src/Artemis.UI/Screens/SurfaceEditor/Visualization/SurfaceDeviceView.xaml index 2acf46f6f..7694e73a9 100644 --- a/src/Artemis.UI/Screens/SurfaceEditor/Visualization/SurfaceDeviceView.xaml +++ b/src/Artemis.UI/Screens/SurfaceEditor/Visualization/SurfaceDeviceView.xaml @@ -21,12 +21,8 @@ - - - - - - + + Key Corsair H115i RGB Pump - 80 - 80 - 62 - 63 + 60 + 60 + 1 + 1 Images\Corsair\Customs PUMP.png M0.192,0.053 L0.115,0.114 L0.047,0.194 L0.034,0.499 L0.048,0.828 L0.119,0.91 L0.197,0.97 L0.508,0.978 L0.828,0.965 L0.905,0.903 L0.971,0.831 L0.983,0.538 L0.974,0.197 L0.916,0.117 L0.834,0.05 L0.59,0.038 L0.29,0.042z M0.208,0.091 L0.135,0.149 L0.091,0.208 L0.078,0.503 L0.091,0.815 L0.146,0.877 L0.21,0.924 L0.493,0.935 L0.809,0.924 L0.875,0.868 L0.93,0.807 L0.943,0.537 L0.932,0.21 L0.875,0.138 L0.813,0.09 L0.587,0.079 L0.305,0.081z M0.388,0.429 L0.403,0.491 L0.391,0.544 L0.369,0.582 L0.431,0.554 L0.53,0.524 L0.609,0.519 L0.625,0.527 L0.636,0.542 L0.648,0.531 L0.654,0.503 L0.649,0.481 L0.627,0.45 L0.574,0.407 L0.509,0.36 L0.521,0.393 L0.526,0.443 L0.519,0.492 L0.512,0.509 L0.515,0.477 L0.517,0.435 L0.45,0.394 L0.459,0.429 L0.462,0.477 L0.448,0.521 L0.455,0.485 L0.454,0.457 L0.397,0.425z M0.404,0.389 L0.414,0.407 L0.418,0.433 L0.451,0.44 L0.449,0.428 L0.439,0.405z M0.459,0.351 L0.471,0.373 L0.477,0.405 L0.512,0.414 L0.514,0.405 L0.514,0.405 L0.499,0.372z M0.519,0.307 L0.533,0.34 L0.541,0.374 L0.567,0.383 L0.593,0.402 L0.605,0.42 L0.612,0.415 L0.613,0.398 L0.597,0.362 L0.546,0.317z M0.324,0.632 L0.323,0.61 L0.308,0.603 L0.276,0.602 L0.254,0.618 L0.245,0.645 L0.253,0.673 L0.275,0.69 L0.309,0.691 L0.327,0.682 L0.329,0.656 L0.322,0.658 L0.312,0.675 L0.283,0.676 L0.267,0.656 L0.266,0.634 L0.28,0.616 L0.298,0.612 L0.314,0.62z M0.377,0.604 L0.358,0.605 L0.338,0.623 L0.333,0.651 L0.344,0.677 L0.363,0.69 L0.393,0.69 L0.413,0.674 L0.422,0.647 L0.418,0.624 L0.403,0.607z M0.377,0.612 L0.359,0.625 L0.353,0.65 L0.361,0.673 L0.387,0.674 L0.4,0.656 L0.4,0.637 L0.391,0.619z M0.419,0.603 L0.427,0.613 L0.427,0.677 L0.42,0.69 L0.453,0.69 L0.446,0.679 L0.447,0.608 L0.461,0.61 L0.468,0.624 L0.466,0.641 L0.45,0.65 L0.466,0.675 L0.48,0.691 L0.496,0.697 L0.506,0.695 L0.497,0.687 L0.48,0.659 L0.473,0.648 L0.469,0.646 L0.481,0.646 L0.488,0.633 L0.488,0.619 L0.482,0.604 L0.457,0.599 L0.433,0.602z M0.556,0.624 L0.554,0.609 L0.541,0.6 L0.523,0.6 L0.506,0.611 L0.502,0.634 L0.513,0.648 L0.531,0.657 L0.541,0.666 L0.538,0.675 L0.523,0.68 L0.512,0.671 L0.505,0.661 L0.5,0.662 L0.502,0.681 L0.52,0.69 L0.546,0.687 L0.557,0.677 L0.562,0.663 L0.558,0.65 L0.545,0.639 L0.527,0.632 L0.518,0.623 L0.523,0.611 L0.538,0.61z M0.595,0.603 L0.566,0.677 L0.555,0.692 L0.587,0.691 L0.578,0.68 L0.584,0.663 L0.609,0.664 L0.617,0.679 L0.609,0.689 L0.645,0.689 L0.638,0.677 L0.606,0.603z M0.646,0.604 L0.653,0.612 L0.654,0.677 L0.647,0.689 L0.681,0.689 L0.675,0.677 L0.675,0.612 L0.684,0.603z M0.688,0.603 L0.691,0.612 L0.691,0.681 L0.686,0.69 L0.72,0.69 L0.715,0.678 L0.712,0.674 L0.712,0.613 L0.719,0.61 L0.731,0.615 L0.735,0.634 L0.718,0.651 L0.738,0.683 L0.754,0.695 L0.774,0.695 L0.761,0.684 L0.741,0.65 L0.737,0.648 L0.748,0.648 L0.757,0.629 L0.755,0.613 L0.739,0.602 L0.707,0.601z - 8.6 - 7.2 + 6 + 5.4 + 47.5 + 47.5 @@ -25,5 +27,10 @@ + + + + + \ No newline at end of file