diff --git a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs index 418438700..f347c932a 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs @@ -14,7 +14,6 @@ namespace Artemis.Core /// public class ArtemisDevice : CorePropertyChanged { - private ReadOnlyCollection _leds; private SKPath? _renderPath; private SKRect _renderRectangle; @@ -28,13 +27,14 @@ namespace Artemis.Core Rotation = 0; Scale = 1; ZIndex = 1; - + deviceProvider.DeviceLayoutPaths.TryGetValue(rgbDevice, out string? layoutPath); LayoutPath = layoutPath; - + InputIdentifiers = new List(); - _leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly(); + Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly(); + LedIds = new ReadOnlyDictionary(Leds.ToDictionary(l => l.RgbLed.Id, l => l)); ApplyToEntity(); CalculateRenderProperties(); } @@ -45,7 +45,7 @@ namespace Artemis.Core RgbDevice = rgbDevice; DeviceProvider = deviceProvider; Surface = surface; - + deviceProvider.DeviceLayoutPaths.TryGetValue(rgbDevice, out string? layoutPath); LayoutPath = layoutPath; @@ -53,7 +53,8 @@ namespace Artemis.Core foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers) InputIdentifiers.Add(new ArtemisDeviceInputIdentifier(identifierEntity.InputProvider, identifierEntity.Identifier)); - _leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly(); + Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly(); + LedIds = new ReadOnlyDictionary(Leds.ToDictionary(l => l.RgbLed.Id, l => l)); } /// @@ -92,11 +93,13 @@ namespace Artemis.Core /// /// Gets a read only collection containing the LEDs of this device /// - public ReadOnlyCollection Leds - { - get => _leds; - private set => SetAndNotify(ref _leds, value); - } + public ReadOnlyCollection Leds { get; } + + /// + /// Gets a dictionary containing all the LEDs of this device with their corresponding RGB.NET as + /// key + /// + public ReadOnlyDictionary LedIds { get; } /// /// Gets a list of input identifiers associated with this device @@ -182,16 +185,24 @@ namespace Artemis.Core } /// - /// Occurs when the underlying RGB.NET device was updated + /// Attempts to retrieve the that corresponds the provided RGB.NET /// - public event EventHandler? DeviceUpdated; + /// The RGB.NET to find the corresponding for + /// If found, the corresponding ; otherwise . + public ArtemisLed? GetLed(Led led) + { + return GetLed(led.Id); + } /// - /// Invokes the event + /// Attempts to retrieve the that corresponds the provided RGB.NET /// - protected virtual void OnDeviceUpdated() + /// The RGB.NET to find the corresponding for + /// If found, the corresponding ; otherwise . + public ArtemisLed? GetLed(LedId ledId) { - DeviceUpdated?.Invoke(this, EventArgs.Empty); + LedIds.TryGetValue(ledId, out ArtemisLed? artemisLed); + return artemisLed; } internal void ApplyToEntity() @@ -247,5 +258,22 @@ namespace Artemis.Core RenderPath = path; } + + #region Events + + /// + /// Occurs when the underlying RGB.NET device was updated + /// + public event EventHandler? DeviceUpdated; + + /// + /// Invokes the event + /// + protected virtual void OnDeviceUpdated() + { + DeviceUpdated?.Invoke(this, EventArgs.Empty); + } + + #endregion } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Surface/ArtemisSurface.cs b/src/Artemis.Core/Models/Surface/ArtemisSurface.cs index 9a4fabcc1..9f88cc73d 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisSurface.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisSurface.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using Artemis.Storage.Entities.Surface; using RGB.NET.Core; @@ -11,7 +12,8 @@ namespace Artemis.Core /// public class ArtemisSurface : CorePropertyChanged { - private List _devices; + private List _devices = new List(); + private ReadOnlyDictionary _ledMap = new ReadOnlyDictionary(new Dictionary()); private bool _isActive; private string _name; private double _scale; @@ -26,9 +28,6 @@ namespace Artemis.Core _scale = scale; _isActive = false; - // Devices are not populated here but as they are detected - _devices = new List(); - ApplyToEntity(); } @@ -41,9 +40,6 @@ namespace Artemis.Core _scale = scale; _name = surfaceEntity.Name; _isActive = surfaceEntity.IsActive; - - // Devices are not populated here but as they are detected - _devices = new List(); } /// @@ -87,6 +83,16 @@ namespace Artemis.Core internal set => SetAndNotify(ref _devices, value); } + /// + /// Gets a dictionary containing all s on the surface with their corresponding RGB.NET + /// as key + /// + public ReadOnlyDictionary LedMap + { + get => _ledMap; + private set => SetAndNotify(ref _ledMap, value); + } + internal SurfaceEntity SurfaceEntity { get; set; } internal Guid EntityId { get; set; } @@ -103,6 +109,24 @@ namespace Artemis.Core OnScaleChanged(); } + /// + /// Attempts to retrieve the that corresponds the provided RGB.NET + /// + /// The RGB.NET to find the corresponding for + /// If found, the corresponding ; otherwise . + public ArtemisLed? GetArtemisLed(Led led) + { + LedMap.TryGetValue(led, out ArtemisLed? artemisLed); + return artemisLed; + } + + internal void UpdateLedMap() + { + LedMap = new ReadOnlyDictionary( + _devices.SelectMany(d => d.Leds.Select(al => new KeyValuePair(al.RgbLed, al))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value) + ); + } + internal void ApplyToEntity() { SurfaceEntity.Id = EntityId; diff --git a/src/Artemis.Core/RGB.NET/BitmapBrush.cs b/src/Artemis.Core/RGB.NET/BitmapBrush.cs index a7d4a656b..3f6926c4a 100644 --- a/src/Artemis.Core/RGB.NET/BitmapBrush.cs +++ b/src/Artemis.Core/RGB.NET/BitmapBrush.cs @@ -176,6 +176,7 @@ namespace Artemis.Core } internal bool IsDisposed { get; set; } + internal ArtemisSurface? Surface { get; set; } #endregion } diff --git a/src/Artemis.Core/Services/Input/InputService.cs b/src/Artemis.Core/Services/Input/InputService.cs index c3fb070ab..88112ea9a 100644 --- a/src/Artemis.Core/Services/Input/InputService.cs +++ b/src/Artemis.Core/Services/Input/InputService.cs @@ -192,11 +192,11 @@ namespace Artemis.Core.Services if (UpdatePressedKeys(e.Device, e.Key, e.IsDown)) return; - // Get the LED - TODO: leverage a lookup + // Get the LED bool foundLedId = InputKeyUtilities.KeyboardKeyLedIdMap.TryGetValue(e.Key, out LedId ledId); ArtemisLed? led = null; if (foundLedId && e.Device != null) - led = e.Device.Leds.FirstOrDefault(l => l.RgbLed.Id == ledId); + led = e.Device.GetLed(ledId); // Create the UpDown event args because it can be used for every event ArtemisKeyboardKeyUpDownEventArgs eventArgs = new ArtemisKeyboardKeyUpDownEventArgs(e.Device, led, e.Key, keyboardModifierKey, e.IsDown); diff --git a/src/Artemis.Core/Services/Interfaces/IRgbService.cs b/src/Artemis.Core/Services/Interfaces/IRgbService.cs index ad1d51644..6e50576fa 100644 --- a/src/Artemis.Core/Services/Interfaces/IRgbService.cs +++ b/src/Artemis.Core/Services/Interfaces/IRgbService.cs @@ -58,6 +58,7 @@ namespace Artemis.Core.Services /// /// Recalculates the LED group used by the /// - void UpdateSurfaceLedGroup(); + /// + void UpdateSurfaceLedGroup(ArtemisSurface artemisSurface); } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/RgbService.cs b/src/Artemis.Core/Services/RgbService.cs index 81031d862..d2e1cfa3d 100644 --- a/src/Artemis.Core/Services/RgbService.cs +++ b/src/Artemis.Core/Services/RgbService.cs @@ -88,7 +88,8 @@ namespace Artemis.Core.Services private void RenderScaleSettingOnSettingChanged(object? sender, EventArgs e) { - UpdateSurfaceLedGroup(); + // The surface hasn't changed so we can safely reuse it + UpdateSurfaceLedGroup(BitmapBrush?.Surface); } private void TargetFrameRateSettingOnSettingChanged(object? sender, EventArgs e) @@ -107,8 +108,11 @@ namespace Artemis.Core.Services public event EventHandler? DeviceLoaded; public event EventHandler? DeviceReloaded; - public void UpdateSurfaceLedGroup() + public void UpdateSurfaceLedGroup(ArtemisSurface? artemisSurface) { + if (artemisSurface == null) + return; + if (_surfaceLedGroup == null || BitmapBrush == null) { // Apply the application wide brush and decorator @@ -124,6 +128,7 @@ namespace Artemis.Core.Services // Apply the application wide brush and decorator BitmapBrush.Scale = new Scale(_renderScaleSetting.Value); + BitmapBrush.Surface = artemisSurface; _surfaceLedGroup = new ListLedGroup(Surface.Leds) {Brush = BitmapBrush}; } } diff --git a/src/Artemis.Core/Services/Storage/Models/SurfaceArrangement.cs b/src/Artemis.Core/Services/Storage/Models/SurfaceArrangement.cs new file mode 100644 index 000000000..464a78519 --- /dev/null +++ b/src/Artemis.Core/Services/Storage/Models/SurfaceArrangement.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using RGB.NET.Core; + +namespace Artemis.Core.Services.Models +{ + internal class SurfaceArrangement + { + public SurfaceArrangement() + { + Devices = new List(); + } + + public List Devices { get; } + + internal static SurfaceArrangement GetDefaultArrangement() + { + SurfaceArrangement arrangement = new SurfaceArrangement(); + arrangement.Devices.Add(new SurfaceArrangementDevice(null, RGBDeviceType.Keyboard, ArrangementPosition.Right)); + return arrangement; + } + } + + +} diff --git a/src/Artemis.Core/Services/Storage/Models/SurfaceArrangementDevice.cs b/src/Artemis.Core/Services/Storage/Models/SurfaceArrangementDevice.cs new file mode 100644 index 000000000..945f03754 --- /dev/null +++ b/src/Artemis.Core/Services/Storage/Models/SurfaceArrangementDevice.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Linq; +using RGB.NET.Core; + +namespace Artemis.Core.Services.Models +{ + internal class SurfaceArrangementDevice + { + public SurfaceArrangementDevice? Anchor { get; } + public RGBDeviceType DeviceType { get; } + public ArrangementPosition Position { get; } + + public SurfaceArrangementDevice(SurfaceArrangementDevice? anchor, RGBDeviceType deviceType, ArrangementPosition position) + { + Anchor = anchor; + DeviceType = deviceType; + Position = position; + } + + public void Apply(ArtemisSurface surface) + { + List devices = surface.Devices.Where(d => d.RgbDevice.DeviceInfo.DeviceType == DeviceType).ToList(); + ArtemisDevice? previous = null; + foreach (ArtemisDevice artemisDevice in devices) + { + if (previous != null) + { + + } + previous = artemisDevice; + } + } + } + + internal enum ArrangementPosition + { + Left, + Right, + Top, + Bottom, + Center + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Storage/SurfaceService.cs b/src/Artemis.Core/Services/Storage/SurfaceService.cs index b7340bd56..efccae435 100644 --- a/src/Artemis.Core/Services/Storage/SurfaceService.cs +++ b/src/Artemis.Core/Services/Storage/SurfaceService.cs @@ -88,7 +88,7 @@ namespace Artemis.Core.Services device.ApplyToRgbDevice(); // Update the RGB service's graphics decorator to work with the new surface entity - _rgbService.UpdateSurfaceLedGroup(); + _rgbService.UpdateSurfaceLedGroup(ActiveSurface); OnActiveSurfaceConfigurationChanged(new SurfaceConfigurationEventArgs(ActiveSurface)); } @@ -104,9 +104,10 @@ namespace Artemis.Core.Services deviceConfiguration.ApplyToRgbDevice(); } } + surface.UpdateLedMap(); _surfaceRepository.Save(surface.SurfaceEntity); - _rgbService.UpdateSurfaceLedGroup(); + _rgbService.UpdateSurfaceLedGroup(ActiveSurface); OnSurfaceConfigurationUpdated(new SurfaceConfigurationEventArgs(surface)); } @@ -199,6 +200,19 @@ namespace Artemis.Core.Services #endregion + #region AutoLayout + + public void AutoLayout() + { + // Phase one, bottom layer + // Keyboard + + // Phase two, top layer + + } + + #endregion + #region Event handlers private void RgbServiceOnDeviceLoaded(object? sender, DeviceEventArgs e) diff --git a/src/Artemis.UI.Shared/Screens/Dialogs/ConfirmDialogView.xaml b/src/Artemis.UI.Shared/Screens/Dialogs/ConfirmDialogView.xaml index c8afa5fa8..9fced07e6 100644 --- a/src/Artemis.UI.Shared/Screens/Dialogs/ConfirmDialogView.xaml +++ b/src/Artemis.UI.Shared/Screens/Dialogs/ConfirmDialogView.xaml @@ -11,19 +11,23 @@ d:DataContext="{d:DesignInstance dialogs:ConfirmDialogViewModel}"> - +