mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge branch 'master' into development
This commit is contained in:
commit
5c337e9c5e
@ -1,5 +1,8 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cadaption/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cadaptionhints/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cadaption_005Chints/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cconditions_005Cwrappers/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cconditions_005Cwrappers/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes_005Cconditional/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes_005Cconditional/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
@ -0,0 +1,75 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a hint that adapts layers to a certain category of devices
|
||||||
|
/// </summary>
|
||||||
|
public class CategoryAdaptionHint : IAdaptionHint
|
||||||
|
{
|
||||||
|
public CategoryAdaptionHint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CategoryAdaptionHint(CategoryAdaptionHintEntity entity)
|
||||||
|
{
|
||||||
|
Category = (DeviceCategory) entity.Category;
|
||||||
|
Skip = entity.Skip;
|
||||||
|
LimitAmount = entity.LimitAmount;
|
||||||
|
Amount = entity.Amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the category of devices LEDs will be applied to
|
||||||
|
/// </summary>
|
||||||
|
public DeviceCategory Category { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the amount of devices to skip
|
||||||
|
/// </summary>
|
||||||
|
public int Skip { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether a limited amount of devices should be used
|
||||||
|
/// </summary>
|
||||||
|
public bool LimitAmount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the amount of devices to limit to if <see cref="LimitAmount" /> is <see langword="true" />
|
||||||
|
/// </summary>
|
||||||
|
public int Amount { get; set; }
|
||||||
|
|
||||||
|
#region Implementation of IAdaptionHint
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Apply(Layer layer, List<ArtemisDevice> devices)
|
||||||
|
{
|
||||||
|
IEnumerable<ArtemisDevice> matches = devices
|
||||||
|
.Where(d => d.Categories.Contains(Category))
|
||||||
|
.OrderBy(d => d.Rectangle.Top)
|
||||||
|
.ThenBy(d => d.Rectangle.Left)
|
||||||
|
.Skip(Skip);
|
||||||
|
if (LimitAmount)
|
||||||
|
matches = matches.Take(Amount);
|
||||||
|
|
||||||
|
foreach (ArtemisDevice artemisDevice in matches)
|
||||||
|
layer.AddLeds(artemisDevice.Leds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IAdaptionHintEntity GetEntry()
|
||||||
|
{
|
||||||
|
return new CategoryAdaptionHintEntity {Amount = Amount, LimitAmount = LimitAmount, Category = (int) Category, Skip = Skip};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Category adaption - {nameof(Category)}: {Category}, {nameof(Skip)}: {Skip}, {nameof(LimitAmount)}: {LimitAmount}, {nameof(Amount)}: {Amount}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a hint that adapts layers to a certain type of devices
|
||||||
|
/// </summary>
|
||||||
|
public class DeviceAdaptionHint : IAdaptionHint
|
||||||
|
{
|
||||||
|
public DeviceAdaptionHint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DeviceAdaptionHint(DeviceAdaptionHintEntity entity)
|
||||||
|
{
|
||||||
|
DeviceType = (RGBDeviceType) entity.DeviceType;
|
||||||
|
Skip = entity.Skip;
|
||||||
|
LimitAmount = entity.LimitAmount;
|
||||||
|
Amount = entity.Amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the type of devices LEDs will be applied to
|
||||||
|
/// </summary>
|
||||||
|
public RGBDeviceType DeviceType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the amount of devices to skip
|
||||||
|
/// </summary>
|
||||||
|
public int Skip { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether a limited amount of devices should be used
|
||||||
|
/// </summary>
|
||||||
|
public bool LimitAmount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the amount of devices to limit to if <see cref="LimitAmount" /> is <see langword="true" />
|
||||||
|
/// </summary>
|
||||||
|
public int Amount { get; set; }
|
||||||
|
|
||||||
|
#region Implementation of IAdaptionHint
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Apply(Layer layer, List<ArtemisDevice> devices)
|
||||||
|
{
|
||||||
|
IEnumerable<ArtemisDevice> matches = devices
|
||||||
|
.Where(d => d.RgbDevice.DeviceInfo.DeviceType == DeviceType)
|
||||||
|
.OrderBy(d => d.Rectangle.Top)
|
||||||
|
.ThenBy(d => d.Rectangle.Left)
|
||||||
|
.Skip(Skip);
|
||||||
|
if (LimitAmount)
|
||||||
|
matches = matches.Take(Amount);
|
||||||
|
|
||||||
|
foreach (ArtemisDevice artemisDevice in matches)
|
||||||
|
layer.AddLeds(artemisDevice.Leds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IAdaptionHintEntity GetEntry()
|
||||||
|
{
|
||||||
|
return new DeviceAdaptionHintEntity {Amount = Amount, LimitAmount = LimitAmount, DeviceType = (int) DeviceType, Skip = Skip};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Device adaption - {nameof(DeviceType)}: {DeviceType}, {nameof(Skip)}: {Skip}, {nameof(LimitAmount)}: {LimitAmount}, {nameof(Amount)}: {Amount}";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an adaption hint that's used to adapt a layer to a set of devices
|
||||||
|
/// </summary>
|
||||||
|
public interface IAdaptionHint
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Applies the adaptive action to the provided layer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="layer">The layer to adapt</param>
|
||||||
|
/// <param name="devices">The devices to adapt the layer for</param>
|
||||||
|
void Apply(Layer layer, List<ArtemisDevice> devices);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an adaption hint entry for this adaption hint used for persistent storage
|
||||||
|
/// </summary>
|
||||||
|
IAdaptionHintEntity GetEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a hint that adapts layers to a certain region of keyboards
|
||||||
|
/// </summary>
|
||||||
|
public class KeyboardSectionAdaptionHint : IAdaptionHint
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<KeyboardSection, List<LedId>> RegionLedIds = new()
|
||||||
|
{
|
||||||
|
{KeyboardSection.MacroKeys, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_Programmable1 && l <= LedId.Keyboard_Programmable32).ToList()},
|
||||||
|
{KeyboardSection.LedStrips, Enum.GetValues<LedId>().Where(l => l >= LedId.LedStripe1 && l <= LedId.LedStripe128).ToList()},
|
||||||
|
{KeyboardSection.Extra, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_Custom1 && l <= LedId.Keyboard_Custom64).ToList()}
|
||||||
|
};
|
||||||
|
|
||||||
|
public KeyboardSectionAdaptionHint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal KeyboardSectionAdaptionHint(KeyboardSectionAdaptionHintEntity entity)
|
||||||
|
{
|
||||||
|
Section = (KeyboardSection) entity.Section;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the section this hint will apply LEDs to
|
||||||
|
/// </summary>
|
||||||
|
public KeyboardSection Section { get; set; }
|
||||||
|
|
||||||
|
#region Implementation of IAdaptionHint
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Apply(Layer layer, List<ArtemisDevice> devices)
|
||||||
|
{
|
||||||
|
// Only keyboards should have the LEDs we care about
|
||||||
|
foreach (ArtemisDevice keyboard in devices.Where(d => d.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard))
|
||||||
|
{
|
||||||
|
List<LedId> ledIds = RegionLedIds[Section];
|
||||||
|
layer.AddLeds(keyboard.Leds.Where(l => ledIds.Contains(l.RgbLed.Id)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IAdaptionHintEntity GetEntry()
|
||||||
|
{
|
||||||
|
return new KeyboardSectionAdaptionHintEntity {Section = (int) Section};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Keyboard section adaption - {nameof(Section)}: {Section}";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a section of LEDs on a keyboard
|
||||||
|
/// </summary>
|
||||||
|
public enum KeyboardSection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A region containing the macro keys of a keyboard
|
||||||
|
/// </summary>
|
||||||
|
MacroKeys,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A region containing the LED strips of a keyboard
|
||||||
|
/// </summary>
|
||||||
|
LedStrips,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A region containing extra non-standard LEDs of a keyboard
|
||||||
|
/// </summary>
|
||||||
|
Extra
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ using Artemis.Core.LayerBrushes;
|
|||||||
using Artemis.Core.LayerEffects;
|
using Artemis.Core.LayerEffects;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.Storage.Entities.Profile.Abstract;
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
|
using RGB.NET.Core;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
@ -42,6 +43,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
_leds = new List<ArtemisLed>();
|
_leds = new List<ArtemisLed>();
|
||||||
|
|
||||||
|
Adapter = new LayerAdapter(this);
|
||||||
Initialize();
|
Initialize();
|
||||||
Parent.AddChild(this, 0);
|
Parent.AddChild(this, 0);
|
||||||
}
|
}
|
||||||
@ -65,6 +67,7 @@ namespace Artemis.Core
|
|||||||
_leds = new List<ArtemisLed>();
|
_leds = new List<ArtemisLed>();
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
|
Adapter = new LayerAdapter(this);
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +124,11 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerEntity LayerEntity { get; internal set; }
|
public LayerEntity LayerEntity { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the layer adapter that can be used to adapt this layer to a different set of devices
|
||||||
|
/// </summary>
|
||||||
|
public LayerAdapter Adapter { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool ShouldBeEnabled => !Suspended && DisplayConditionMet;
|
public override bool ShouldBeEnabled => !Suspended && DisplayConditionMet;
|
||||||
|
|
||||||
@ -147,7 +155,15 @@ namespace Artemis.Core
|
|||||||
return $"[Layer] {nameof(Name)}: {Name}, {nameof(Order)}: {Order}";
|
return $"[Layer] {nameof(Name)}: {Name}, {nameof(Order)}: {Order}";
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IDisposable
|
/// <summary>
|
||||||
|
/// Occurs when a property affecting the rendering properties of this layer has been updated
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? RenderPropertiesUpdated;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the layer brush of this layer has been updated
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? LayerBrushUpdated;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
@ -162,7 +178,10 @@ namespace Artemis.Core
|
|||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
internal void OnLayerBrushUpdated()
|
||||||
|
{
|
||||||
|
LayerBrushUpdated?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
@ -190,6 +209,28 @@ namespace Artemis.Core
|
|||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LayerBrushStoreOnLayerBrushRemoved(object? sender, LayerBrushStoreEvent e)
|
||||||
|
{
|
||||||
|
if (LayerBrush?.Descriptor == e.Registration.LayerBrushDescriptor)
|
||||||
|
DeactivateLayerBrush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LayerBrushStoreOnLayerBrushAdded(object? sender, LayerBrushStoreEvent e)
|
||||||
|
{
|
||||||
|
if (LayerBrush != null || !General.PropertiesInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LayerBrushReference? current = General.BrushReference.CurrentValue;
|
||||||
|
if (e.Registration.PluginFeature.Id == current?.LayerBrushProviderId &&
|
||||||
|
e.Registration.LayerBrushDescriptor.LayerBrushType.Name == current.BrushType)
|
||||||
|
ActivateLayerBrush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRenderPropertiesUpdated()
|
||||||
|
{
|
||||||
|
RenderPropertiesUpdated?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
#region Storage
|
#region Storage
|
||||||
|
|
||||||
internal override void Load()
|
internal override void Load()
|
||||||
@ -229,7 +270,8 @@ namespace Artemis.Core
|
|||||||
LedEntity ledEntity = new()
|
LedEntity ledEntity = new()
|
||||||
{
|
{
|
||||||
DeviceIdentifier = artemisLed.Device.Identifier,
|
DeviceIdentifier = artemisLed.Device.Identifier,
|
||||||
LedName = artemisLed.RgbLed.Id.ToString()
|
LedName = artemisLed.RgbLed.Id.ToString(),
|
||||||
|
PhysicalLayout = artemisLed.Device.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard ? (int) artemisLed.Device.PhysicalLayout : null
|
||||||
};
|
};
|
||||||
LayerEntity.Leds.Add(ledEntity);
|
LayerEntity.Leds.Add(ledEntity);
|
||||||
}
|
}
|
||||||
@ -575,7 +617,7 @@ namespace Artemis.Core
|
|||||||
if (Disposed)
|
if (Disposed)
|
||||||
throw new ObjectDisposedException("Layer");
|
throw new ObjectDisposedException("Layer");
|
||||||
|
|
||||||
_leds.AddRange(leds);
|
_leds.AddRange(leds.Except(_leds));
|
||||||
CalculateRenderProperties();
|
CalculateRenderProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,51 +734,6 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Event handlers
|
|
||||||
|
|
||||||
private void LayerBrushStoreOnLayerBrushRemoved(object? sender, LayerBrushStoreEvent e)
|
|
||||||
{
|
|
||||||
if (LayerBrush?.Descriptor == e.Registration.LayerBrushDescriptor)
|
|
||||||
DeactivateLayerBrush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LayerBrushStoreOnLayerBrushAdded(object? sender, LayerBrushStoreEvent e)
|
|
||||||
{
|
|
||||||
if (LayerBrush != null || !General.PropertiesInitialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
LayerBrushReference? current = General.BrushReference.CurrentValue;
|
|
||||||
if (e.Registration.PluginFeature.Id == current?.LayerBrushProviderId &&
|
|
||||||
e.Registration.LayerBrushDescriptor.LayerBrushType.Name == current.BrushType)
|
|
||||||
ActivateLayerBrush();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Events
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when a property affecting the rendering properties of this layer has been updated
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler? RenderPropertiesUpdated;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when the layer brush of this layer has been updated
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler? LayerBrushUpdated;
|
|
||||||
|
|
||||||
private void OnRenderPropertiesUpdated()
|
|
||||||
{
|
|
||||||
RenderPropertiesUpdated?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void OnLayerBrushUpdated()
|
|
||||||
{
|
|
||||||
LayerBrushUpdated?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
144
src/Artemis.Core/Models/Profile/LayerAdapter.cs
Normal file
144
src/Artemis.Core/Models/Profile/LayerAdapter.cs
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.Storage.Entities.Profile;
|
||||||
|
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an adapter that adapts a layer to a certain set of devices using <see cref="IAdaptionHint" />s
|
||||||
|
/// </summary>
|
||||||
|
public class LayerAdapter : IStorageModel
|
||||||
|
{
|
||||||
|
internal LayerAdapter(Layer layer)
|
||||||
|
{
|
||||||
|
Layer = layer;
|
||||||
|
AdaptionHints = new List<IAdaptionHint>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the layer this adapter can adapt
|
||||||
|
/// </summary>
|
||||||
|
public Layer Layer { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a list containing the adaption hints used by this adapter
|
||||||
|
/// </summary>
|
||||||
|
public List<IAdaptionHint> AdaptionHints { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Modifies the layer, adapting it to the provided <paramref name="devices" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="devices">The devices to adapt the layer to</param>
|
||||||
|
public void Adapt(List<ArtemisDevice> devices)
|
||||||
|
{
|
||||||
|
// Use adaption hints if provided
|
||||||
|
if (AdaptionHints.Any())
|
||||||
|
{
|
||||||
|
foreach (IAdaptionHint adaptionHint in AdaptionHints)
|
||||||
|
adaptionHint.Apply(Layer, devices);
|
||||||
|
}
|
||||||
|
// If there are no hints, try to find matching LEDs anyway
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<ArtemisLed> availableLeds = devices.SelectMany(d => d.Leds).ToList();
|
||||||
|
List<ArtemisLed> usedLeds = new();
|
||||||
|
|
||||||
|
foreach (LedEntity ledEntity in Layer.LayerEntity.Leds)
|
||||||
|
{
|
||||||
|
// TODO: If this is a keyboard LED and the layouts don't match, convert it before looking for it on the devices
|
||||||
|
|
||||||
|
LedId ledId = Enum.Parse<LedId>(ledEntity.LedName);
|
||||||
|
ArtemisLed? led = availableLeds.FirstOrDefault(l => l.RgbLed.Id == ledId);
|
||||||
|
|
||||||
|
if (led != null)
|
||||||
|
{
|
||||||
|
availableLeds.Remove(led);
|
||||||
|
usedLeds.Add(led);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Layer.AddLeds(usedLeds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Automatically determine hints for this layer
|
||||||
|
/// </summary>
|
||||||
|
public List<IAdaptionHint> DetermineHints(IEnumerable<ArtemisDevice> devices)
|
||||||
|
{
|
||||||
|
List<IAdaptionHint> newHints = new();
|
||||||
|
// Any fully covered device will add a device adaption hint for that type
|
||||||
|
foreach (IGrouping<ArtemisDevice, ArtemisLed> deviceLeds in Layer.Leds.GroupBy(l => l.Device))
|
||||||
|
{
|
||||||
|
ArtemisDevice device = deviceLeds.Key;
|
||||||
|
// If there is already an adaption hint for this type, don't add another
|
||||||
|
if (AdaptionHints.Any(h => h is DeviceAdaptionHint d && d.DeviceType == device.RgbDevice.DeviceInfo.DeviceType))
|
||||||
|
continue;
|
||||||
|
if (DoesLayerCoverDevice(device))
|
||||||
|
{
|
||||||
|
DeviceAdaptionHint hint = new() {DeviceType = device.RgbDevice.DeviceInfo.DeviceType};
|
||||||
|
AdaptionHints.Add(hint);
|
||||||
|
newHints.Add(hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any fully covered category will add a category adaption hint for its category
|
||||||
|
foreach (DeviceCategory deviceCategory in Enum.GetValues<DeviceCategory>())
|
||||||
|
{
|
||||||
|
if (AdaptionHints.Any(h => h is CategoryAdaptionHint c && c.Category == deviceCategory))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
List<ArtemisDevice> categoryDevices = devices.Where(d => d.Categories.Contains(deviceCategory)).ToList();
|
||||||
|
if (categoryDevices.Any() && categoryDevices.All(DoesLayerCoverDevice))
|
||||||
|
{
|
||||||
|
CategoryAdaptionHint hint = new() {Category = deviceCategory};
|
||||||
|
AdaptionHints.Add(hint);
|
||||||
|
newHints.Add(hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newHints;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DoesLayerCoverDevice(ArtemisDevice device)
|
||||||
|
{
|
||||||
|
return device.Leds.All(l => Layer.Leds.Contains(l));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Implementation of IStorageModel
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
AdaptionHints.Clear();
|
||||||
|
// Kind of meh.
|
||||||
|
// This leaves the adapter responsible for finding the right hint for the right entity, but it's gotta be done somewhere..
|
||||||
|
foreach (IAdaptionHintEntity hintEntity in Layer.LayerEntity.AdaptionHints)
|
||||||
|
switch (hintEntity)
|
||||||
|
{
|
||||||
|
case DeviceAdaptionHintEntity entity:
|
||||||
|
AdaptionHints.Add(new DeviceAdaptionHint(entity));
|
||||||
|
break;
|
||||||
|
case CategoryAdaptionHintEntity entity:
|
||||||
|
AdaptionHints.Add(new CategoryAdaptionHint(entity));
|
||||||
|
break;
|
||||||
|
case KeyboardSectionAdaptionHintEntity entity:
|
||||||
|
AdaptionHints.Add(new KeyboardSectionAdaptionHint(entity));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
Layer.LayerEntity.AdaptionHints.Clear();
|
||||||
|
foreach (IAdaptionHint adaptionHint in AdaptionHints)
|
||||||
|
Layer.LayerEntity.AdaptionHints.Add(adaptionHint.GetEntry());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -36,10 +36,12 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
||||||
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
||||||
|
Categories = new HashSet<DeviceCategory>();
|
||||||
|
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
ApplyKeyboardLayout();
|
ApplyKeyboardLayout();
|
||||||
ApplyToEntity();
|
ApplyToEntity();
|
||||||
|
ApplyDefaultCategories();
|
||||||
CalculateRenderProperties();
|
CalculateRenderProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +54,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
||||||
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
||||||
|
Categories = new HashSet<DeviceCategory>();
|
||||||
|
|
||||||
foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers)
|
foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers)
|
||||||
InputIdentifiers.Add(new ArtemisDeviceInputIdentifier(identifierEntity.InputProvider, identifierEntity.Identifier));
|
InputIdentifiers.Add(new ArtemisDeviceInputIdentifier(identifierEntity.InputProvider, identifierEntity.Identifier));
|
||||||
@ -114,6 +117,11 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<ArtemisLed, ArtemisLed> InputMappings { get; }
|
public Dictionary<ArtemisLed, ArtemisLed> InputMappings { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list containing the categories of this device
|
||||||
|
/// </summary>
|
||||||
|
public HashSet<DeviceCategory> Categories { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the X-position of the device
|
/// Gets or sets the X-position of the device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -383,6 +391,46 @@ namespace Artemis.Core
|
|||||||
OnDeviceUpdated();
|
OnDeviceUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies the default categories for this device to the <see cref="Categories"/> list
|
||||||
|
/// </summary>
|
||||||
|
public void ApplyDefaultCategories()
|
||||||
|
{
|
||||||
|
switch (RgbDevice.DeviceInfo.DeviceType)
|
||||||
|
{
|
||||||
|
case RGBDeviceType.Keyboard:
|
||||||
|
case RGBDeviceType.Mouse:
|
||||||
|
case RGBDeviceType.Headset:
|
||||||
|
case RGBDeviceType.Mousepad:
|
||||||
|
case RGBDeviceType.HeadsetStand:
|
||||||
|
case RGBDeviceType.Keypad:
|
||||||
|
if (!Categories.Contains(DeviceCategory.Peripherals))
|
||||||
|
Categories.Add(DeviceCategory.Peripherals);
|
||||||
|
break;
|
||||||
|
case RGBDeviceType.Mainboard:
|
||||||
|
case RGBDeviceType.GraphicsCard:
|
||||||
|
case RGBDeviceType.DRAM:
|
||||||
|
case RGBDeviceType.Fan:
|
||||||
|
case RGBDeviceType.LedStripe:
|
||||||
|
case RGBDeviceType.Cooler:
|
||||||
|
if (!Categories.Contains(DeviceCategory.Case))
|
||||||
|
Categories.Add(DeviceCategory.Case);
|
||||||
|
break;
|
||||||
|
case RGBDeviceType.Speaker:
|
||||||
|
if (!Categories.Contains(DeviceCategory.Desk))
|
||||||
|
Categories.Add(DeviceCategory.Desk);
|
||||||
|
break;
|
||||||
|
case RGBDeviceType.Monitor:
|
||||||
|
if (!Categories.Contains(DeviceCategory.Monitor))
|
||||||
|
Categories.Add(DeviceCategory.Monitor);
|
||||||
|
break;
|
||||||
|
case RGBDeviceType.LedMatrix:
|
||||||
|
if (!Categories.Contains(DeviceCategory.Room))
|
||||||
|
Categories.Add(DeviceCategory.Room);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void ApplyToEntity()
|
internal void ApplyToEntity()
|
||||||
{
|
{
|
||||||
// Other properties are computed
|
// Other properties are computed
|
||||||
@ -401,6 +449,10 @@ namespace Artemis.Core
|
|||||||
DeviceEntity.InputMappings.Clear();
|
DeviceEntity.InputMappings.Clear();
|
||||||
foreach (var (original, mapped) in InputMappings)
|
foreach (var (original, mapped) in InputMappings)
|
||||||
DeviceEntity.InputMappings.Add(new InputMappingEntity {OriginalLedId = (int) original.RgbLed.Id, MappedLedId = (int) mapped.RgbLed.Id});
|
DeviceEntity.InputMappings.Add(new InputMappingEntity {OriginalLedId = (int) original.RgbLed.Id, MappedLedId = (int) mapped.RgbLed.Id});
|
||||||
|
|
||||||
|
DeviceEntity.Categories.Clear();
|
||||||
|
foreach (DeviceCategory deviceCategory in Categories)
|
||||||
|
DeviceEntity.Categories.Add((int) deviceCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ApplyToRgbDevice()
|
internal void ApplyToRgbDevice()
|
||||||
@ -419,6 +471,12 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
if (!RgbDevice.ColorCorrections.Any())
|
if (!RgbDevice.ColorCorrections.Any())
|
||||||
RgbDevice.ColorCorrections.Add(new ScaleColorCorrection(this));
|
RgbDevice.ColorCorrections.Add(new ScaleColorCorrection(this));
|
||||||
|
|
||||||
|
Categories.Clear();
|
||||||
|
foreach (int deviceEntityCategory in DeviceEntity.Categories)
|
||||||
|
Categories.Add((DeviceCategory) deviceEntityCategory);
|
||||||
|
if (!Categories.Any())
|
||||||
|
ApplyDefaultCategories();
|
||||||
|
|
||||||
CalculateRenderProperties();
|
CalculateRenderProperties();
|
||||||
OnDeviceUpdated();
|
OnDeviceUpdated();
|
||||||
@ -472,4 +530,13 @@ namespace Artemis.Core
|
|||||||
LogicalLayout = DeviceEntity.LogicalLayout;
|
LogicalLayout = DeviceEntity.LogicalLayout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum DeviceCategory
|
||||||
|
{
|
||||||
|
Desk,
|
||||||
|
Monitor,
|
||||||
|
Case,
|
||||||
|
Room,
|
||||||
|
Peripherals
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -314,6 +314,9 @@ namespace Artemis.Core.Services
|
|||||||
{
|
{
|
||||||
SurfaceArrangement surfaceArrangement = SurfaceArrangement.GetDefaultArrangement();
|
SurfaceArrangement surfaceArrangement = SurfaceArrangement.GetDefaultArrangement();
|
||||||
surfaceArrangement.Arrange(_devices);
|
surfaceArrangement.Arrange(_devices);
|
||||||
|
foreach (ArtemisDevice artemisDevice in _devices)
|
||||||
|
artemisDevice.ApplyDefaultCategories();
|
||||||
|
|
||||||
SaveDevices();
|
SaveDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -121,5 +121,11 @@ namespace Artemis.Core.Services
|
|||||||
/// <param name="nameAffix">Text to add after the name of the profile (separated by a dash)</param>
|
/// <param name="nameAffix">Text to add after the name of the profile (separated by a dash)</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ProfileDescriptor ImportProfile(string json, ProfileModule profileModule, string nameAffix = "imported");
|
ProfileDescriptor ImportProfile(string json, ProfileModule profileModule, string nameAffix = "imported");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adapts a given profile to the currently active devices
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="profile">The profile to adapt</param>
|
||||||
|
void AdaptProfile(Profile profile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ namespace Artemis.Core.Services
|
|||||||
ProfileEntity entity = _profileRepository.Get(module.ActiveProfile.EntityId);
|
ProfileEntity entity = _profileRepository.Get(module.ActiveProfile.EntityId);
|
||||||
Profile profile = new(module, entity);
|
Profile profile = new(module, entity);
|
||||||
InstantiateProfile(profile);
|
InstantiateProfile(profile);
|
||||||
|
|
||||||
module.ChangeActiveProfile(null, _rgbService.EnabledDevices);
|
module.ChangeActiveProfile(null, _rgbService.EnabledDevices);
|
||||||
module.ChangeActiveProfile(profile, _rgbService.EnabledDevices);
|
module.ChangeActiveProfile(profile, _rgbService.EnabledDevices);
|
||||||
}
|
}
|
||||||
@ -166,7 +166,6 @@ namespace Artemis.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void ClearActiveProfile(ProfileModule module)
|
public void ClearActiveProfile(ProfileModule module)
|
||||||
{
|
{
|
||||||
module.ChangeActiveProfile(null, _rgbService.EnabledDevices);
|
module.ChangeActiveProfile(null, _rgbService.EnabledDevices);
|
||||||
@ -294,13 +293,21 @@ namespace Artemis.Core.Services
|
|||||||
return new ProfileDescriptor(profileModule, profileEntity);
|
return new ProfileDescriptor(profileModule, profileEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void AdaptProfile(Profile profile)
|
||||||
|
{
|
||||||
|
List<ArtemisDevice> devices = _rgbService.EnabledDevices.ToList();
|
||||||
|
foreach (Layer layer in profile.GetAllLayers())
|
||||||
|
layer.Adapter.Adapt(devices);
|
||||||
|
}
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void RgbServiceOnLedsChanged(object? sender, EventArgs e)
|
private void RgbServiceOnLedsChanged(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ActiveProfilesPopulateLeds();
|
ActiveProfilesPopulateLeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
namespace Artemis.Storage.Entities.Profile.AdaptionHints
|
||||||
|
{
|
||||||
|
public class CategoryAdaptionHintEntity : IAdaptionHintEntity
|
||||||
|
{
|
||||||
|
public int Category { get; set; }
|
||||||
|
|
||||||
|
public bool LimitAmount { get; set; }
|
||||||
|
public int Skip { get; set; }
|
||||||
|
public int Amount { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
namespace Artemis.Storage.Entities.Profile.AdaptionHints
|
||||||
|
{
|
||||||
|
public class DeviceAdaptionHintEntity : IAdaptionHintEntity
|
||||||
|
{
|
||||||
|
public int DeviceType { get; set; }
|
||||||
|
|
||||||
|
public bool LimitAmount { get; set; }
|
||||||
|
public int Skip { get; set; }
|
||||||
|
public int Amount { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace Artemis.Storage.Entities.Profile.AdaptionHints
|
||||||
|
{
|
||||||
|
public interface IAdaptionHintEntity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
namespace Artemis.Storage.Entities.Profile.AdaptionHints
|
||||||
|
{
|
||||||
|
public class KeyboardSectionAdaptionHintEntity : IAdaptionHintEntity
|
||||||
|
{
|
||||||
|
public int Section { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Artemis.Storage.Entities.Profile.Abstract;
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
|
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Profile
|
namespace Artemis.Storage.Entities.Profile
|
||||||
@ -10,6 +11,7 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
public LayerEntity()
|
public LayerEntity()
|
||||||
{
|
{
|
||||||
Leds = new List<LedEntity>();
|
Leds = new List<LedEntity>();
|
||||||
|
AdaptionHints = new List<IAdaptionHintEntity>();
|
||||||
PropertyEntities = new List<PropertyEntity>();
|
PropertyEntities = new List<PropertyEntity>();
|
||||||
LayerEffects = new List<LayerEffectEntity>();
|
LayerEffects = new List<LayerEffectEntity>();
|
||||||
ExpandedPropertyGroups = new List<string>();
|
ExpandedPropertyGroups = new List<string>();
|
||||||
@ -20,6 +22,7 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
public bool Suspended { get; set; }
|
public bool Suspended { get; set; }
|
||||||
|
|
||||||
public List<LedEntity> Leds { get; set; }
|
public List<LedEntity> Leds { get; set; }
|
||||||
|
public List<IAdaptionHintEntity> AdaptionHints { get; set; }
|
||||||
|
|
||||||
[BsonRef("ProfileEntity")]
|
[BsonRef("ProfileEntity")]
|
||||||
public ProfileEntity Profile { get; set; }
|
public ProfileEntity Profile { get; set; }
|
||||||
|
|||||||
@ -4,5 +4,7 @@
|
|||||||
{
|
{
|
||||||
public string LedName { get; set; }
|
public string LedName { get; set; }
|
||||||
public string DeviceIdentifier { get; set; }
|
public string DeviceIdentifier { get; set; }
|
||||||
|
|
||||||
|
public int? PhysicalLayout { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,8 +8,9 @@ namespace Artemis.Storage.Entities.Surface
|
|||||||
{
|
{
|
||||||
InputIdentifiers = new List<DeviceInputIdentifierEntity>();
|
InputIdentifiers = new List<DeviceInputIdentifierEntity>();
|
||||||
InputMappings = new List<InputMappingEntity>();
|
InputMappings = new List<InputMappingEntity>();
|
||||||
|
Categories = new List<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public float X { get; set; }
|
public float X { get; set; }
|
||||||
public float Y { get; set; }
|
public float Y { get; set; }
|
||||||
@ -27,7 +28,7 @@ namespace Artemis.Storage.Entities.Surface
|
|||||||
|
|
||||||
public List<DeviceInputIdentifierEntity> InputIdentifiers { get; set; }
|
public List<DeviceInputIdentifierEntity> InputIdentifiers { get; set; }
|
||||||
public List<InputMappingEntity> InputMappings { get; set; }
|
public List<InputMappingEntity> InputMappings { get; set; }
|
||||||
|
public List<int> Categories { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InputMappingEntity
|
public class InputMappingEntity
|
||||||
|
|||||||
@ -12,6 +12,8 @@ using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBi
|
|||||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects;
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects;
|
||||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
|
||||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree;
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints;
|
||||||
using Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem;
|
using Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem;
|
||||||
using Artemis.UI.Screens.ProfileEditor.Visualization;
|
using Artemis.UI.Screens.ProfileEditor.Visualization;
|
||||||
using Artemis.UI.Screens.ProfileEditor.Visualization.Tools;
|
using Artemis.UI.Screens.ProfileEditor.Visualization.Tools;
|
||||||
@ -59,6 +61,14 @@ namespace Artemis.UI.Ninject.Factories
|
|||||||
LayerViewModel LayerViewModel(ProfileElement layer);
|
LayerViewModel LayerViewModel(ProfileElement layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ILayerHintVmFactory : IVmFactory
|
||||||
|
{
|
||||||
|
LayerHintsDialogViewModel LayerHintsDialogViewModel(Layer layer);
|
||||||
|
CategoryAdaptionHintViewModel CategoryAdaptionHintViewModel(CategoryAdaptionHint adaptionHint);
|
||||||
|
DeviceAdaptionHintViewModel DeviceAdaptionHintViewModel(DeviceAdaptionHint adaptionHint);
|
||||||
|
KeyboardSectionAdaptionHintViewModel KeyboardSectionAdaptionHintViewModel(KeyboardSectionAdaptionHint adaptionHint);
|
||||||
|
}
|
||||||
|
|
||||||
public interface IProfileLayerVmFactory : IVmFactory
|
public interface IProfileLayerVmFactory : IVmFactory
|
||||||
{
|
{
|
||||||
ProfileLayerViewModel Create(Layer layer, PanZoomViewModel panZoomViewModel);
|
ProfileLayerViewModel Create(Layer layer, PanZoomViewModel panZoomViewModel);
|
||||||
|
|||||||
@ -169,6 +169,12 @@
|
|||||||
</Button>
|
</Button>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|
||||||
|
<Button Command="{s:Action AdaptActiveProfile}" ToolTip="Adapt the profile to the current surface">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<materialDesign:PackIcon Kind="AutoFix" Margin="0 0 15 0" />
|
||||||
|
<TextBlock>Adapt profile</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
<Button Command="{s:Action ExportActiveProfile}">
|
<Button Command="{s:Action ExportActiveProfile}">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon Kind="Upload" Margin="0 0 15 0" />
|
<materialDesign:PackIcon Kind="Upload" Margin="0 0 15 0" />
|
||||||
|
|||||||
@ -209,6 +209,20 @@ namespace Artemis.UI.Screens.ProfileEditor
|
|||||||
SelectedProfile = copy;
|
SelectedProfile = copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task AdaptActiveProfile()
|
||||||
|
{
|
||||||
|
if (_profileEditorService.SelectedProfile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!await DialogService.ShowConfirmDialog(
|
||||||
|
"Adapt profile",
|
||||||
|
"Are you sure you want to adapt the profile to your current surface? Layer assignments may change."
|
||||||
|
))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_profileService.AdaptProfile(_profileEditorService.SelectedProfile);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ExportActiveProfile()
|
public async Task ExportActiveProfile()
|
||||||
{
|
{
|
||||||
await DialogService.ShowDialog<ProfileExportViewModel>(new Dictionary<string, object>
|
await DialogService.ShowDialog<ProfileExportViewModel>(new Dictionary<string, object>
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints
|
||||||
|
{
|
||||||
|
public abstract class AdaptionHintViewModel : Screen
|
||||||
|
{
|
||||||
|
protected AdaptionHintViewModel(IAdaptionHint adaptionHint)
|
||||||
|
{
|
||||||
|
AdaptionHint = adaptionHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAdaptionHint AdaptionHint { get; }
|
||||||
|
|
||||||
|
public void Remove()
|
||||||
|
{
|
||||||
|
((LayerHintsDialogViewModel) Parent).RemoveAdaptionHint(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints.CategoryAdaptionHintView"
|
||||||
|
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.ProfileEditor.ProfileTree.Dialogs.AdaptionHints"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:Converters="clr-namespace:Artemis.UI.Converters"
|
||||||
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance local:CategoryAdaptionHintViewModel}">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<Converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||||
|
</UserControl.Resources>
|
||||||
|
<materialDesign:Card Margin="0 5" Padding="10">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Grid.ColumnSpan="3" Margin="0 0 0 5">
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Text="Category hint" />
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignBody2TextBlock}" Text="Applies the layer to devices of a certain category" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Button Grid.Row="0"
|
||||||
|
Grid.Column="3"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||||
|
ToolTip="Remove hint"
|
||||||
|
Command="{s:Action Remove}">
|
||||||
|
<materialDesign:PackIcon Kind="Delete" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<ComboBox Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Style="{StaticResource MaterialDesignFilledComboBox}"
|
||||||
|
materialDesign:HintAssist.Hint="Category"
|
||||||
|
Margin="0 0 5 0"
|
||||||
|
SelectedValue="{Binding CategoryAdaptionHint.Category}"
|
||||||
|
ItemsSource="{Binding Categories}"
|
||||||
|
SelectedValuePath="Value"
|
||||||
|
DisplayMemberPath="Description" />
|
||||||
|
|
||||||
|
<TextBox Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Style="{StaticResource MaterialDesignFilledTextBox}"
|
||||||
|
materialDesign:HintAssist.Hint="Skip"
|
||||||
|
materialDesign:TextFieldAssist.SuffixText="device(s)"
|
||||||
|
Margin="5 0"
|
||||||
|
Text="{Binding CategoryAdaptionHint.Skip}" />
|
||||||
|
|
||||||
|
<TextBox Grid.Row="1"
|
||||||
|
Grid.Column="2"
|
||||||
|
Style="{StaticResource MaterialDesignFilledTextBox}"
|
||||||
|
materialDesign:HintAssist.Hint="Take"
|
||||||
|
materialDesign:TextFieldAssist.SuffixText="device(s)"
|
||||||
|
IsEnabled="{Binding TakeAllDevices, Converter={StaticResource InverseBooleanConverter}}"
|
||||||
|
Margin="5 0"
|
||||||
|
Text="{Binding CategoryAdaptionHint.Amount}" />
|
||||||
|
|
||||||
|
<CheckBox Grid.Row="1"
|
||||||
|
Grid.Column="3"
|
||||||
|
Content="Take all devices"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0 18 0 0"
|
||||||
|
IsChecked="{Binding TakeAllDevices}" />
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints
|
||||||
|
{
|
||||||
|
public class CategoryAdaptionHintViewModel : AdaptionHintViewModel
|
||||||
|
{
|
||||||
|
private bool _takeAllDevices;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public CategoryAdaptionHintViewModel(CategoryAdaptionHint adaptionHint) : base(adaptionHint)
|
||||||
|
{
|
||||||
|
CategoryAdaptionHint = adaptionHint;
|
||||||
|
Categories = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(DeviceCategory)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryAdaptionHint CategoryAdaptionHint { get; }
|
||||||
|
public BindableCollection<ValueDescription> Categories { get; }
|
||||||
|
|
||||||
|
public bool TakeAllDevices
|
||||||
|
{
|
||||||
|
get => _takeAllDevices;
|
||||||
|
set => SetAndNotify(ref _takeAllDevices, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Screen
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
TakeAllDevices = !CategoryAdaptionHint.LimitAmount;
|
||||||
|
base.OnInitialActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnClose()
|
||||||
|
{
|
||||||
|
CategoryAdaptionHint.LimitAmount = !TakeAllDevices;
|
||||||
|
base.OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints.DeviceAdaptionHintView"
|
||||||
|
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.ProfileEditor.ProfileTree.Dialogs.AdaptionHints"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||||
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance local:DeviceAdaptionHintViewModel}">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||||
|
</UserControl.Resources>
|
||||||
|
<materialDesign:Card Margin="0 5" Padding="10">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Grid.ColumnSpan="3" Margin="0 0 0 5">
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Text="Device type hint" />
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignBody2TextBlock}" Text="Applies the layer to devices of a certain type" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Button Grid.Row="0"
|
||||||
|
Grid.Column="3"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||||
|
ToolTip="Remove hint"
|
||||||
|
Command="{s:Action Remove}">
|
||||||
|
<materialDesign:PackIcon Kind="Delete" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<ComboBox Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Style="{StaticResource MaterialDesignFilledComboBox}"
|
||||||
|
materialDesign:HintAssist.Hint="Device type"
|
||||||
|
Margin="0 0 5 0"
|
||||||
|
SelectedValue="{Binding DeviceAdaptionHint.DeviceType}"
|
||||||
|
ItemsSource="{Binding DeviceTypes}"
|
||||||
|
SelectedValuePath="Value"
|
||||||
|
DisplayMemberPath="Description">
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
|
<TextBox Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Style="{StaticResource MaterialDesignFilledTextBox}"
|
||||||
|
materialDesign:HintAssist.Hint="Skip"
|
||||||
|
materialDesign:TextFieldAssist.SuffixText="device(s)"
|
||||||
|
Margin="5 0"
|
||||||
|
Text="{Binding DeviceAdaptionHint.Skip}"/>
|
||||||
|
|
||||||
|
<TextBox Grid.Row="1"
|
||||||
|
Grid.Column="2"
|
||||||
|
Style="{StaticResource MaterialDesignFilledTextBox}"
|
||||||
|
materialDesign:HintAssist.Hint="Take"
|
||||||
|
materialDesign:TextFieldAssist.SuffixText="device(s)"
|
||||||
|
IsEnabled="{Binding TakeAllDevices, Converter={StaticResource InverseBooleanConverter}}"
|
||||||
|
Margin="5 0"
|
||||||
|
Text="{Binding DeviceAdaptionHint.Amount}"/>
|
||||||
|
|
||||||
|
<CheckBox Grid.Row="1"
|
||||||
|
Grid.Column="3"
|
||||||
|
Content="Take all devices"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0 18 0 0"
|
||||||
|
IsChecked="{Binding TakeAllDevices}" />
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints
|
||||||
|
{
|
||||||
|
public class DeviceAdaptionHintViewModel : AdaptionHintViewModel
|
||||||
|
{
|
||||||
|
private bool _takeAllDevices;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DeviceAdaptionHintViewModel(DeviceAdaptionHint adaptionHint) : base(adaptionHint)
|
||||||
|
{
|
||||||
|
DeviceAdaptionHint = adaptionHint;
|
||||||
|
DeviceTypes = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(RGBDeviceType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceAdaptionHint DeviceAdaptionHint { get; }
|
||||||
|
public BindableCollection<ValueDescription> DeviceTypes { get; }
|
||||||
|
|
||||||
|
public bool TakeAllDevices
|
||||||
|
{
|
||||||
|
get => _takeAllDevices;
|
||||||
|
set => SetAndNotify(ref _takeAllDevices, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Screen
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
TakeAllDevices = !DeviceAdaptionHint.LimitAmount;
|
||||||
|
base.OnInitialActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnClose()
|
||||||
|
{
|
||||||
|
DeviceAdaptionHint.LimitAmount = !TakeAllDevices;
|
||||||
|
base.OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints.KeyboardSectionAdaptionHintView"
|
||||||
|
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.ProfileEditor.ProfileTree.Dialogs.AdaptionHints"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance local:KeyboardSectionAdaptionHintViewModel}">
|
||||||
|
<materialDesign:Card Margin="0 5" Padding="10">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Grid.ColumnSpan="3" Margin="0 0 0 5">
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Text="Keyboard section hint" />
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignBody2TextBlock}" Text="Applies the layer to a section of all keyboards" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Button Grid.Row="0"
|
||||||
|
Grid.Column="3"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||||
|
ToolTip="Remove hint"
|
||||||
|
Command="{s:Action Remove}">
|
||||||
|
<materialDesign:PackIcon Kind="Delete" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<ComboBox Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Style="{StaticResource MaterialDesignFilledComboBox}"
|
||||||
|
materialDesign:HintAssist.Hint="Section"
|
||||||
|
Margin="0 0 5 0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Width="209"
|
||||||
|
SelectedValue="{Binding KeyboardSectionAdaptionHint.Section}"
|
||||||
|
ItemsSource="{Binding Sections}"
|
||||||
|
SelectedValuePath="Value"
|
||||||
|
DisplayMemberPath="Description">
|
||||||
|
</ComboBox>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints
|
||||||
|
{
|
||||||
|
public class KeyboardSectionAdaptionHintViewModel : AdaptionHintViewModel
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public KeyboardSectionAdaptionHintViewModel(KeyboardSectionAdaptionHint adaptionHint) : base(adaptionHint)
|
||||||
|
{
|
||||||
|
KeyboardSectionAdaptionHint = adaptionHint;
|
||||||
|
Sections = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(KeyboardSection)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardSectionAdaptionHint KeyboardSectionAdaptionHint { get; }
|
||||||
|
public BindableCollection<ValueDescription> Sections { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
<mde:MaterialWindow x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.LayerHintsDialogView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
xmlns:mde="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||||
|
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||||
|
xmlns:dialogs="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="{Binding DisplayName}"
|
||||||
|
TitleBarIcon="{svgc:SvgImage Source=/Resources/Images/Logo/bow-white.svg}"
|
||||||
|
Foreground="{DynamicResource MaterialDesignBody}"
|
||||||
|
Background="{DynamicResource MaterialDesignPaper}"
|
||||||
|
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
|
||||||
|
UseLayoutRounding="True"
|
||||||
|
FadeContentIfInactive="False"
|
||||||
|
Width="800"
|
||||||
|
Height="800"
|
||||||
|
d:DesignHeight="800" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance dialogs:LayerHintsDialogViewModel}"
|
||||||
|
Icon="/Resources/Images/Logo/bow.ico">
|
||||||
|
<mde:MaterialWindow.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
</mde:MaterialWindow.Resources>
|
||||||
|
|
||||||
|
<materialDesign:DialogHost IsTabStop="False"
|
||||||
|
Focusable="False"
|
||||||
|
Identifier="DeviceDialog"
|
||||||
|
DialogTheme="Inherit"
|
||||||
|
SnackbarMessageQueue="{Binding LayerHintsMessageQueue}">
|
||||||
|
<DockPanel>
|
||||||
|
<mde:AppBar Type="Dense"
|
||||||
|
Title="{Binding Layer.Name}"
|
||||||
|
ShowShadow="True"
|
||||||
|
DockPanel.Dock="Top"
|
||||||
|
Margin="-18 0 0 0">
|
||||||
|
<mde:AppBar.AppIcon>
|
||||||
|
<materialDesign:PackIcon Kind="AutoFix" Width="20" Height="28" />
|
||||||
|
</mde:AppBar.AppIcon>
|
||||||
|
</mde:AppBar>
|
||||||
|
|
||||||
|
<Grid Margin="15">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock Grid.Row="0" Style="{StaticResource MaterialDesignHeadline6TextBlock}">
|
||||||
|
Introduction
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock Grid.Row="1" Style="{StaticResource MaterialDesignTextBlock}" TextWrapping="Wrap">
|
||||||
|
In this window you can tell Artemis how this layer should be adapted when the profile is applied to a different set of devices by providing so-called adaption hints.
|
||||||
|
<LineBreak />
|
||||||
|
When sharing your profile with other people good hints help them import your profile without the need for manual adjustments.
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="2" Style="{StaticResource MaterialDesignHeadline6TextBlock}" Margin="0 25 0 0">
|
||||||
|
Adaption hints
|
||||||
|
</TextBlock>
|
||||||
|
<ScrollViewer Grid.Row="3">
|
||||||
|
<ItemsControl ItemsSource="{Binding Items}" Margin="0 0 10 0">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<materialDesign:TransitioningContent OpeningEffect="{materialDesign:TransitionEffect SlideInFromLeft}"
|
||||||
|
OpeningEffectsOffset="{materialDesign:IndexedItemOffsetMultiplier 0:0:0.05}">
|
||||||
|
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||||
|
</materialDesign:TransitioningContent>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ScrollViewer>
|
||||||
|
|
||||||
|
<!-- Buttons -->
|
||||||
|
<Grid Grid.Row="4">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Button Grid.Column="0"
|
||||||
|
Style="{StaticResource MaterialDesignOutlinedButton}"
|
||||||
|
Margin="0 8 8 0"
|
||||||
|
Command="{s:Action AutoDetermineHints}"
|
||||||
|
ToolTip="Attempt to automatically determine relevant hint(s) for this layer">
|
||||||
|
AUTO-DETERMINE HINTS
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<materialDesign:PopupBox Grid.Column="1"
|
||||||
|
Style="{StaticResource MaterialDesignMultiFloatingActionAccentPopupBox}"
|
||||||
|
ToolTip="Add a new hint"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Margin="0 5 0 0">
|
||||||
|
<StackPanel>
|
||||||
|
<Button ToolTip="Add a category hint" Content="{materialDesign:PackIcon Kind=Desk, Size=20}" Command="{s:Action AddCategoryHint}" />
|
||||||
|
<Button ToolTip="Add a device type hint" Content="{materialDesign:PackIcon Kind=Devices, Size=20}" Command="{s:Action AddDeviceHint}" />
|
||||||
|
<Button ToolTip="Add a keyboard-section hint" Content="{materialDesign:PackIcon Kind=Keyboard, Size=20}" Command="{s:Action AddKeyboardSectionHint}" />
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:PopupBox>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</DockPanel>
|
||||||
|
</materialDesign:DialogHost>
|
||||||
|
</mde:MaterialWindow>
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Ninject.Factories;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs
|
||||||
|
{
|
||||||
|
public class LayerHintsDialogViewModel : Conductor<AdaptionHintViewModel>.Collection.AllActive
|
||||||
|
{
|
||||||
|
private readonly IRgbService _rgbService;
|
||||||
|
private readonly ILayerHintVmFactory _vmFactory;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
private SnackbarMessageQueue _layerHintsMessageQueue;
|
||||||
|
|
||||||
|
public LayerHintsDialogViewModel(Layer layer, IRgbService rgbService, ILayerHintVmFactory vmFactory, IProfileEditorService profileEditorService)
|
||||||
|
{
|
||||||
|
_rgbService = rgbService;
|
||||||
|
_vmFactory = vmFactory;
|
||||||
|
_profileEditorService = profileEditorService;
|
||||||
|
|
||||||
|
Layer = layer;
|
||||||
|
DisplayName = "Layer hints | Artemis";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Layer Layer { get; }
|
||||||
|
|
||||||
|
public SnackbarMessageQueue LayerHintsMessageQueue
|
||||||
|
{
|
||||||
|
get => _layerHintsMessageQueue;
|
||||||
|
set => SetAndNotify(ref _layerHintsMessageQueue, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AutoDetermineHints()
|
||||||
|
{
|
||||||
|
List<IAdaptionHint> newHints = Layer.Adapter.DetermineHints(_rgbService.EnabledDevices);
|
||||||
|
CreateHintViewModels(newHints);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCategoryHint()
|
||||||
|
{
|
||||||
|
CategoryAdaptionHint hint = new();
|
||||||
|
Layer.Adapter.AdaptionHints.Add(hint);
|
||||||
|
Items.Add(_vmFactory.CategoryAdaptionHintViewModel(hint));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddDeviceHint()
|
||||||
|
{
|
||||||
|
DeviceAdaptionHint hint = new();
|
||||||
|
Layer.Adapter.AdaptionHints.Add(hint);
|
||||||
|
Items.Add(_vmFactory.DeviceAdaptionHintViewModel(hint));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddKeyboardSectionHint()
|
||||||
|
{
|
||||||
|
KeyboardSectionAdaptionHint hint = new();
|
||||||
|
Layer.Adapter.AdaptionHints.Add(hint);
|
||||||
|
Items.Add(_vmFactory.KeyboardSectionAdaptionHintViewModel(hint));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveAdaptionHint(AdaptionHintViewModel adaptionHintViewModel)
|
||||||
|
{
|
||||||
|
Layer.Adapter.AdaptionHints.Remove(adaptionHintViewModel.AdaptionHint);
|
||||||
|
Items.Remove(adaptionHintViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Screen
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
LayerHintsMessageQueue = new SnackbarMessageQueue(TimeSpan.FromSeconds(5));
|
||||||
|
CreateHintViewModels(Layer.Adapter.AdaptionHints);
|
||||||
|
|
||||||
|
base.OnInitialActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of AllActive
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnClose()
|
||||||
|
{
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
base.OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void CreateHintViewModels(List<IAdaptionHint> hints)
|
||||||
|
{
|
||||||
|
foreach (IAdaptionHint adapterAdaptionHint in hints)
|
||||||
|
{
|
||||||
|
switch (adapterAdaptionHint)
|
||||||
|
{
|
||||||
|
case CategoryAdaptionHint categoryAdaptionHint:
|
||||||
|
Items.Add(_vmFactory.CategoryAdaptionHintViewModel(categoryAdaptionHint));
|
||||||
|
break;
|
||||||
|
case DeviceAdaptionHint deviceAdaptionHint:
|
||||||
|
Items.Add(_vmFactory.DeviceAdaptionHintViewModel(deviceAdaptionHint));
|
||||||
|
break;
|
||||||
|
case KeyboardSectionAdaptionHint keyboardSectionAdaptionHint:
|
||||||
|
Items.Add(_vmFactory.KeyboardSectionAdaptionHintViewModel(keyboardSectionAdaptionHint));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -35,6 +35,12 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
<MenuItem Header="View adaption hints" Command="{s:Action OpenAdaptionHints}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="AutoFix" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<Separator />
|
||||||
<MenuItem Header="Rename" Command="{s:Action RenameElement}" InputGestureText="F2">
|
<MenuItem Header="Rename" Command="{s:Action RenameElement}" InputGestureText="F2">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<materialDesign:PackIcon Kind="RenameBox" />
|
<materialDesign:PackIcon Kind="RenameBox" />
|
||||||
|
|||||||
@ -2,19 +2,32 @@
|
|||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
||||||
{
|
{
|
||||||
public class LayerViewModel : TreeItemViewModel
|
public class LayerViewModel : TreeItemViewModel
|
||||||
{
|
{
|
||||||
|
private readonly IWindowManager _windowManager;
|
||||||
|
private ILayerHintVmFactory _vmFactory;
|
||||||
|
|
||||||
public LayerViewModel(ProfileElement layer,
|
public LayerViewModel(ProfileElement layer,
|
||||||
IRgbService rgbService,
|
IRgbService rgbService,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
IDialogService dialogService,
|
IDialogService dialogService,
|
||||||
IProfileTreeVmFactory profileTreeVmFactory,
|
IProfileTreeVmFactory profileTreeVmFactory,
|
||||||
ILayerBrushService layerBrushService) :
|
ILayerBrushService layerBrushService,
|
||||||
|
IWindowManager windowManager,
|
||||||
|
ILayerHintVmFactory vmFactory) :
|
||||||
base(layer, rgbService, profileEditorService, dialogService, profileTreeVmFactory, layerBrushService)
|
base(layer, rgbService, profileEditorService, dialogService, profileTreeVmFactory, layerBrushService)
|
||||||
{
|
{
|
||||||
|
_windowManager = windowManager;
|
||||||
|
_vmFactory = vmFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenAdaptionHints()
|
||||||
|
{
|
||||||
|
_windowManager.ShowDialog(_vmFactory.LayerHintsDialogViewModel(Layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Layer Layer => ProfileElement as Layer;
|
public Layer Layer => ProfileElement as Layer;
|
||||||
|
|||||||
@ -21,7 +21,41 @@
|
|||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<StackPanel Grid.Row="0">
|
<StackPanel Grid.Row="0">
|
||||||
<Grid>
|
<!-- Layout -->
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}">
|
||||||
|
Categories
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}"
|
||||||
|
Foreground="{DynamicResource MaterialDesignBodyLight}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
TextAlignment="Justify">
|
||||||
|
Artemis uses categories to determine where the layers of imported profiles are applied to. <LineBreak/>
|
||||||
|
You can hover over a category for a more detailed description.
|
||||||
|
</TextBlock>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
|
||||||
|
IsChecked="{Binding HasDeskCategory}"
|
||||||
|
ToolTip="A device acting as desk ornamentation such as a LED strip"
|
||||||
|
Content="Desk" />
|
||||||
|
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
|
||||||
|
IsChecked="{Binding HasMonitorCategory}"
|
||||||
|
ToolTip="A device attached to the monitor such as ambilight LEDs"
|
||||||
|
Content="Monitor" />
|
||||||
|
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
|
||||||
|
ToolTip="A device inside your computer case"
|
||||||
|
IsChecked="{Binding HasCaseCategory}"
|
||||||
|
Content="Case" />
|
||||||
|
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
|
||||||
|
IsChecked="{Binding HasRoomCategory}"
|
||||||
|
ToolTip="A device elsewhere in the room"
|
||||||
|
Content="Room" />
|
||||||
|
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
|
||||||
|
IsChecked="{Binding HasPeripheralsCategory}"
|
||||||
|
ToolTip="A peripheral such as a mouse or keyboard"
|
||||||
|
Content="Peripheral" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Grid Margin="0 25">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
<ColumnDefinition Width="40" />
|
<ColumnDefinition Width="40" />
|
||||||
@ -157,7 +191,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Layout -->
|
<!-- Layout -->
|
||||||
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Margin="0 25 0 0">
|
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}">
|
||||||
Custom layout
|
Custom layout
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}"
|
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}"
|
||||||
|
|||||||
@ -22,6 +22,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
|||||||
private SKColor _currentColor;
|
private SKColor _currentColor;
|
||||||
private bool _displayOnDevices;
|
private bool _displayOnDevices;
|
||||||
private float _greenScale;
|
private float _greenScale;
|
||||||
|
private List<DeviceCategory> _categories;
|
||||||
private float _initialBlueScale;
|
private float _initialBlueScale;
|
||||||
private float _initialGreenScale;
|
private float _initialGreenScale;
|
||||||
private float _initialRedScale;
|
private float _initialRedScale;
|
||||||
@ -100,13 +101,45 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
|||||||
get => _displayOnDevices;
|
get => _displayOnDevices;
|
||||||
set => SetAndNotify(ref _displayOnDevices, value);
|
set => SetAndNotify(ref _displayOnDevices, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This solution won't scale well but I don't expect there to be many more categories.
|
||||||
|
// If for some reason there will be, dynamically creating a view model per category may be more appropriate
|
||||||
|
public bool HasDeskCategory
|
||||||
|
{
|
||||||
|
get => GetCategory(DeviceCategory.Desk);
|
||||||
|
set => SetCategory(DeviceCategory.Desk, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasMonitorCategory
|
||||||
|
{
|
||||||
|
get => GetCategory(DeviceCategory.Monitor);
|
||||||
|
set => SetCategory(DeviceCategory.Monitor, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasCaseCategory
|
||||||
|
{
|
||||||
|
get => GetCategory(DeviceCategory.Case);
|
||||||
|
set => SetCategory(DeviceCategory.Case, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasRoomCategory
|
||||||
|
{
|
||||||
|
get => GetCategory(DeviceCategory.Room);
|
||||||
|
set => SetCategory(DeviceCategory.Room, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasPeripheralsCategory
|
||||||
|
{
|
||||||
|
get => GetCategory(DeviceCategory.Peripherals);
|
||||||
|
set => SetCategory(DeviceCategory.Peripherals, value);
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyScaling()
|
public void ApplyScaling()
|
||||||
{
|
{
|
||||||
Device.RedScale = RedScale / 100f;
|
Device.RedScale = RedScale / 100f;
|
||||||
Device.GreenScale = GreenScale / 100f;
|
Device.GreenScale = GreenScale / 100f;
|
||||||
Device.BlueScale = BlueScale / 100f;
|
Device.BlueScale = BlueScale / 100f;
|
||||||
|
|
||||||
_rgbService.Surface.Update(true);
|
_rgbService.Surface.Update(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +184,10 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
|||||||
Device.RedScale = RedScale / 100f;
|
Device.RedScale = RedScale / 100f;
|
||||||
Device.GreenScale = GreenScale / 100f;
|
Device.GreenScale = GreenScale / 100f;
|
||||||
Device.BlueScale = BlueScale / 100f;
|
Device.BlueScale = BlueScale / 100f;
|
||||||
|
Device.Categories.Clear();
|
||||||
|
foreach (DeviceCategory deviceCategory in _categories)
|
||||||
|
Device.Categories.Add(deviceCategory);
|
||||||
|
|
||||||
_rgbService.SaveDevice(Device);
|
_rgbService.SaveDevice(Device);
|
||||||
|
|
||||||
_coreService.ModuleRenderingDisabled = false;
|
_coreService.ModuleRenderingDisabled = false;
|
||||||
@ -158,6 +195,12 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
|||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
|
HasDeskCategory = Device.Categories.Contains(DeviceCategory.Desk);
|
||||||
|
HasMonitorCategory = Device.Categories.Contains(DeviceCategory.Monitor);
|
||||||
|
HasCaseCategory = Device.Categories.Contains(DeviceCategory.Case);
|
||||||
|
HasRoomCategory = Device.Categories.Contains(DeviceCategory.Room);
|
||||||
|
HasPeripheralsCategory = Device.Categories.Contains(DeviceCategory.Peripherals);
|
||||||
|
|
||||||
Device.RedScale = _initialRedScale;
|
Device.RedScale = _initialRedScale;
|
||||||
Device.GreenScale = _initialGreenScale;
|
Device.GreenScale = _initialGreenScale;
|
||||||
Device.BlueScale = _initialBlueScale;
|
Device.BlueScale = _initialBlueScale;
|
||||||
@ -176,6 +219,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
|||||||
_initialRedScale = Device.RedScale;
|
_initialRedScale = Device.RedScale;
|
||||||
_initialGreenScale = Device.GreenScale;
|
_initialGreenScale = Device.GreenScale;
|
||||||
_initialBlueScale = Device.BlueScale;
|
_initialBlueScale = Device.BlueScale;
|
||||||
|
_categories = new List<DeviceCategory>(Device.Categories);
|
||||||
CurrentColor = SKColors.White;
|
CurrentColor = SKColors.White;
|
||||||
|
|
||||||
_coreService.FrameRendering += OnFrameRendering;
|
_coreService.FrameRendering += OnFrameRendering;
|
||||||
@ -192,6 +236,21 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
|||||||
base.OnDeactivate();
|
base.OnDeactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool GetCategory(DeviceCategory category)
|
||||||
|
{
|
||||||
|
return _categories.Contains(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCategory(DeviceCategory category, bool value)
|
||||||
|
{
|
||||||
|
if (value && !_categories.Contains(category))
|
||||||
|
_categories.Add(category);
|
||||||
|
else
|
||||||
|
_categories.Remove(category);
|
||||||
|
|
||||||
|
NotifyOfPropertyChange($"Has{category}Category");
|
||||||
|
}
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user