mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Devices - Reworking layout loading
This commit is contained in:
1 parent
9393bf2b68
commit
e8590abd61
57 files changed
+824
-349
No files matched your search
@@ -2,9 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Artemis.Core.DeviceProviders;
|
||||
using Artemis.Core.Providers;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.Storage.Entities.Surface;
|
||||
using RGB.NET.Core;
|
||||
@@ -46,6 +46,7 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
||||
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
||||
Categories = new HashSet<DeviceCategory>();
|
||||
LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LayoutType};
|
||||
|
||||
RgbDevice.ColorCorrections.Clear();
|
||||
RgbDevice.ColorCorrections.Add(new ScaleColorCorrection(this));
|
||||
@@ -74,6 +75,7 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
||||
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
||||
Categories = new HashSet<DeviceCategory>();
|
||||
LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LayoutType};
|
||||
|
||||
foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers)
|
||||
InputIdentifiers.Add(new ArtemisDeviceInputIdentifier(identifierEntity.InputProvider, identifierEntity.Identifier));
|
||||
@@ -153,6 +155,8 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
/// </summary>
|
||||
public HashSet<DeviceCategory> Categories { get; }
|
||||
|
||||
public LayoutSelection LayoutSelection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X-position of the device
|
||||
/// </summary>
|
||||
@@ -293,19 +297,6 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether falling back to default layouts is enabled or not
|
||||
/// </summary>
|
||||
public bool DisableDefaultLayout
|
||||
{
|
||||
get => DeviceEntity.DisableDefaultLayout;
|
||||
set
|
||||
{
|
||||
DeviceEntity.DisableDefaultLayout = value;
|
||||
OnPropertyChanged(nameof(DisableDefaultLayout));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logical layout of the device e.g. DE, UK or US.
|
||||
/// <para>Only applicable to keyboards</para>
|
||||
@@ -320,20 +311,6 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path of the custom layout to load when calling <see cref="GetBestDeviceLayout" />
|
||||
/// for this device
|
||||
/// </summary>
|
||||
public string? CustomLayoutPath
|
||||
{
|
||||
get => DeviceEntity.CustomLayoutPath;
|
||||
set
|
||||
{
|
||||
DeviceEntity.CustomLayoutPath = value;
|
||||
OnPropertyChanged(nameof(CustomLayoutPath));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the layout of the device expanded with Artemis-specific data
|
||||
/// </summary>
|
||||
@@ -381,40 +358,6 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
return artemisLed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the most preferred device layout for this device.
|
||||
/// </summary>
|
||||
/// <returns>The most preferred device layout for this device.</returns>
|
||||
public ArtemisLayout? GetBestDeviceLayout()
|
||||
{
|
||||
ArtemisLayout? layout;
|
||||
|
||||
// Configured layout path takes precedence over all other options
|
||||
if (CustomLayoutPath != null)
|
||||
{
|
||||
layout = new ArtemisLayout(CustomLayoutPath, LayoutSource.Configured);
|
||||
if (layout.IsValid)
|
||||
return layout;
|
||||
}
|
||||
|
||||
// Look for a layout provided by the user
|
||||
layout = DeviceProvider.LoadUserLayout(this);
|
||||
if (layout.IsValid)
|
||||
return layout;
|
||||
|
||||
if (DisableDefaultLayout)
|
||||
return null;
|
||||
|
||||
// Look for a layout provided by the plugin
|
||||
layout = DeviceProvider.LoadLayout(this);
|
||||
if (layout.IsValid)
|
||||
return layout;
|
||||
|
||||
// Finally fall back to a default layout
|
||||
layout = ArtemisLayout.GetDefaultLayout(this);
|
||||
return layout;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the underlying RGB.NET device was updated
|
||||
/// </summary>
|
||||
@@ -481,7 +424,7 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
throw new ArtemisCoreException($"Cannot apply layout with {nameof(createMissingLeds)} set to true because the device provider does not support it");
|
||||
if (layout != null && layout.IsValid && removeExcessiveLeds && !DeviceProvider.RemoveExcessiveLedsSupported)
|
||||
throw new ArtemisCoreException($"Cannot apply layout with {nameof(removeExcessiveLeds)} set to true because the device provider does not support it");
|
||||
|
||||
|
||||
// Always clear the current layout
|
||||
ClearLayout();
|
||||
|
||||
@@ -534,6 +477,9 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
DeviceEntity.Categories.Clear();
|
||||
foreach (DeviceCategory deviceCategory in Categories)
|
||||
DeviceEntity.Categories.Add((int) deviceCategory);
|
||||
|
||||
DeviceEntity.LayoutType = LayoutSelection.Type;
|
||||
DeviceEntity.LayoutParameter = LayoutSelection.Parameter;
|
||||
}
|
||||
|
||||
internal void Load()
|
||||
@@ -548,6 +494,9 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
if (!Categories.Any())
|
||||
ApplyDefaultCategories();
|
||||
|
||||
LayoutSelection.Type = DeviceEntity.LayoutType;
|
||||
LayoutSelection.Parameter = DeviceEntity.LayoutParameter;
|
||||
|
||||
LoadInputMappings();
|
||||
}
|
||||
|
||||
@@ -573,7 +522,7 @@ public class ArtemisDevice : CorePropertyChanged
|
||||
{
|
||||
Leds = RgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||
LedIds = new ReadOnlyDictionary<LedId, ArtemisLed>(Leds.ToDictionary(l => l.RgbLed.Id, l => l));
|
||||
|
||||
|
||||
if (loadInputMappings)
|
||||
LoadInputMappings();
|
||||
}
|
||||
|
||||
@@ -12,17 +12,18 @@ namespace Artemis.Core;
|
||||
/// </summary>
|
||||
public class ArtemisLayout
|
||||
{
|
||||
private static readonly string DefaultLayoutPath = Path.Combine(Constants.ApplicationFolder, "DefaultLayouts", "Artemis");
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ArtemisLayout" /> class
|
||||
/// </summary>
|
||||
/// <param name="filePath">The path of the layout XML file</param>
|
||||
/// <param name="source">The source from where this layout is being loaded</param>
|
||||
public ArtemisLayout(string filePath, LayoutSource source)
|
||||
public ArtemisLayout(string filePath)
|
||||
{
|
||||
FilePath = filePath;
|
||||
Source = source;
|
||||
Leds = new List<ArtemisLedLayout>();
|
||||
|
||||
IsDefaultLayout = filePath.StartsWith(DefaultLayoutPath);
|
||||
|
||||
LoadLayout();
|
||||
}
|
||||
|
||||
@@ -31,11 +32,6 @@ public class ArtemisLayout
|
||||
/// </summary>
|
||||
public string FilePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source from where this layout was loaded
|
||||
/// </summary>
|
||||
public LayoutSource Source { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether a valid layout was loaded
|
||||
/// </summary>
|
||||
@@ -61,6 +57,8 @@ public class ArtemisLayout
|
||||
/// </summary>
|
||||
public LayoutCustomDeviceData LayoutCustomDeviceData { get; private set; } = null!;
|
||||
|
||||
public bool IsDefaultLayout { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Applies the layout to the provided device
|
||||
/// </summary>
|
||||
@@ -121,29 +119,28 @@ public class ArtemisLayout
|
||||
|
||||
internal static ArtemisLayout? GetDefaultLayout(ArtemisDevice device)
|
||||
{
|
||||
string layoutFolder = Path.Combine(Constants.ApplicationFolder, "DefaultLayouts", "Artemis");
|
||||
if (device.DeviceType == RGBDeviceType.Keyboard)
|
||||
{
|
||||
// XL layout is defined by its programmable macro keys
|
||||
if (device.Leds.Any(l => l.RgbLed.Id >= LedId.Keyboard_Programmable1 && l.RgbLed.Id <= LedId.Keyboard_Programmable32))
|
||||
{
|
||||
if (device.PhysicalLayout == KeyboardLayoutType.ANSI)
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder, "Keyboard", "Artemis XL keyboard-ANSI.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder, "Keyboard", "Artemis XL keyboard-ISO.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Keyboard", "Artemis XL keyboard-ANSI.xml"));
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Keyboard", "Artemis XL keyboard-ISO.xml"));
|
||||
}
|
||||
|
||||
// L layout is defined by its numpad
|
||||
if (device.Leds.Any(l => l.RgbLed.Id >= LedId.Keyboard_NumLock && l.RgbLed.Id <= LedId.Keyboard_NumPeriodAndDelete))
|
||||
{
|
||||
if (device.PhysicalLayout == KeyboardLayoutType.ANSI)
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder + "Keyboard", "Artemis L keyboard-ANSI.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder + "Keyboard", "Artemis L keyboard-ISO.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Keyboard", "Artemis L keyboard-ANSI.xml"));
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Keyboard", "Artemis L keyboard-ISO.xml"));
|
||||
}
|
||||
|
||||
// No numpad will result in TKL
|
||||
if (device.PhysicalLayout == KeyboardLayoutType.ANSI)
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder + "Keyboard", "Artemis TKL keyboard-ANSI.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder + "Keyboard", "Artemis TKL keyboard-ISO.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Keyboard", "Artemis TKL keyboard-ANSI.xml"));
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Keyboard", "Artemis TKL keyboard-ISO.xml"));
|
||||
}
|
||||
|
||||
// if (device.DeviceType == RGBDeviceType.Mouse)
|
||||
@@ -151,21 +148,21 @@ public class ArtemisLayout
|
||||
// if (device.Leds.Count == 1)
|
||||
// {
|
||||
// if (device.Leds.Any(l => l.RgbLed.Id == LedId.Logo))
|
||||
// return new ArtemisLayout(Path.Combine(layoutFolder + "Mouse", "1 LED mouse logo.xml"), LayoutSource.Default);
|
||||
// return new ArtemisLayout(Path.Combine(layoutFolder + "Mouse", "1 LED mouse.xml"), LayoutSource.Default);
|
||||
// return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Mouse", "1 LED mouse logo.xml"), LayoutSource.Default);
|
||||
// return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Mouse", "1 LED mouse.xml"), LayoutSource.Default);
|
||||
// }
|
||||
// if (device.Leds.Any(l => l.RgbLed.Id == LedId.Logo))
|
||||
// return new ArtemisLayout(Path.Combine(layoutFolder + "Mouse", "4 LED mouse logo.xml"), LayoutSource.Default);
|
||||
// return new ArtemisLayout(Path.Combine(layoutFolder + "Mouse", "4 LED mouse.xml"), LayoutSource.Default);
|
||||
// return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Mouse", "4 LED mouse logo.xml"), LayoutSource.Default);
|
||||
// return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Mouse", "4 LED mouse.xml"), LayoutSource.Default);
|
||||
// }
|
||||
|
||||
if (device.DeviceType == RGBDeviceType.Headset)
|
||||
{
|
||||
if (device.Leds.Count == 1)
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder + "Headset", "Artemis 1 LED headset.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Headset", "Artemis 1 LED headset.xml"));
|
||||
if (device.Leds.Count == 2)
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder + "Headset", "Artemis 2 LED headset.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(layoutFolder + "Headset", "Artemis 4 LED headset.xml"), LayoutSource.Default);
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Headset", "Artemis 2 LED headset.xml"));
|
||||
return new ArtemisLayout(Path.Combine(DefaultLayoutPath, "Headset", "Artemis 4 LED headset.xml"));
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -206,30 +203,10 @@ public class ArtemisLayout
|
||||
else
|
||||
Image = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a source from where a layout came
|
||||
/// </summary>
|
||||
public enum LayoutSource
|
||||
{
|
||||
/// <summary>
|
||||
/// A layout loaded from config
|
||||
/// </summary>
|
||||
Configured,
|
||||
|
||||
/// <summary>
|
||||
/// A layout loaded from the user layout folder
|
||||
/// </summary>
|
||||
User,
|
||||
|
||||
/// <summary>
|
||||
/// A layout loaded from the plugin folder
|
||||
/// </summary>
|
||||
Plugin,
|
||||
|
||||
/// <summary>
|
||||
/// A default layout loaded as a fallback option
|
||||
/// </summary>
|
||||
Default
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return FilePath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace Artemis.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a reference to a layout for a device.
|
||||
/// </summary>
|
||||
public class LayoutSelection : CorePropertyChanged
|
||||
{
|
||||
private string? _type;
|
||||
private string? _parameter;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets what kind of layout reference this is.
|
||||
/// </summary>
|
||||
public string? Type
|
||||
{
|
||||
get => _type;
|
||||
set => SetAndNotify(ref _type, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter of the layout reference, such as a file path of workshop entry ID.
|
||||
/// </summary>
|
||||
public string? Parameter
|
||||
{
|
||||
get => _parameter;
|
||||
set => SetAndNotify(ref _parameter, value);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user