mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-01-01 02:03:32 +00:00
Devices - Add device layout loading
This commit is contained in:
parent
7792b662e0
commit
e1121afdf9
@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using Artemis.Core.DeviceProviders;
|
using Artemis.Core.DeviceProviders;
|
||||||
using Artemis.Storage.Entities.Surface;
|
using Artemis.Storage.Entities.Surface;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
|
using RGB.NET.Layout;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
@ -31,14 +32,13 @@ namespace Artemis.Core
|
|||||||
GreenScale = 1;
|
GreenScale = 1;
|
||||||
BlueScale = 1;
|
BlueScale = 1;
|
||||||
IsEnabled = true;
|
IsEnabled = true;
|
||||||
|
|
||||||
deviceProvider.DeviceLayoutPaths.TryGetValue(rgbDevice, out string? layoutPath);
|
|
||||||
LayoutPath = layoutPath;
|
|
||||||
|
|
||||||
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
||||||
|
|
||||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||||
LedIds = new ReadOnlyDictionary<LedId, ArtemisLed>(Leds.ToDictionary(l => l.RgbLed.Id, l => l));
|
LedIds = new ReadOnlyDictionary<LedId, ArtemisLed>(Leds.ToDictionary(l => l.RgbLed.Id, l => l));
|
||||||
|
|
||||||
|
LoadBestLayout();
|
||||||
ApplyToEntity();
|
ApplyToEntity();
|
||||||
CalculateRenderProperties();
|
CalculateRenderProperties();
|
||||||
}
|
}
|
||||||
@ -49,16 +49,14 @@ namespace Artemis.Core
|
|||||||
RgbDevice = rgbDevice;
|
RgbDevice = rgbDevice;
|
||||||
DeviceProvider = deviceProvider;
|
DeviceProvider = deviceProvider;
|
||||||
Surface = surface;
|
Surface = surface;
|
||||||
|
|
||||||
deviceProvider.DeviceLayoutPaths.TryGetValue(rgbDevice, out string? layoutPath);
|
|
||||||
LayoutPath = layoutPath;
|
|
||||||
|
|
||||||
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
||||||
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));
|
||||||
|
|
||||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||||
LedIds = new ReadOnlyDictionary<LedId, ArtemisLed>(Leds.ToDictionary(l => l.RgbLed.Id, l => l));
|
LedIds = new ReadOnlyDictionary<LedId, ArtemisLed>(Leds.ToDictionary(l => l.RgbLed.Id, l => l));
|
||||||
|
LoadBestLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -227,11 +225,6 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the path to where the layout of the device was (attempted to be) loaded from
|
|
||||||
/// </summary>
|
|
||||||
public string? LayoutPath { get; internal set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the layout of the device expanded with Artemis-specific data
|
/// Gets the layout of the device expanded with Artemis-specific data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -266,6 +259,15 @@ namespace Artemis.Core
|
|||||||
return artemisLed;
|
return artemisLed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadBestLayout()
|
||||||
|
{
|
||||||
|
ArtemisLayout artemisLayout = DeviceProvider.LoadLayout(RgbDevice);
|
||||||
|
if (artemisLayout.IsValid)
|
||||||
|
artemisLayout.DeviceLayout!.ApplyTo(RgbDevice);
|
||||||
|
|
||||||
|
Layout = artemisLayout;
|
||||||
|
}
|
||||||
|
|
||||||
internal void ApplyToEntity()
|
internal void ApplyToEntity()
|
||||||
{
|
{
|
||||||
// Other properties are computed
|
// Other properties are computed
|
||||||
|
|||||||
@ -1,10 +1,57 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using RGB.NET.Layout;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a device layout decorated with extra Artemis-specific data
|
||||||
|
/// </summary>
|
||||||
public class ArtemisLayout
|
public class ArtemisLayout
|
||||||
{
|
{
|
||||||
public ArtemisDevice Device { get; set; }
|
/// <summary>
|
||||||
public Uri Image { get; set; }
|
/// Creates a new instance of the <see cref="ArtemisLayout" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">The path of the layout XML file</param>
|
||||||
|
public ArtemisLayout(string filePath)
|
||||||
|
{
|
||||||
|
FilePath = filePath;
|
||||||
|
DeviceLayout = DeviceLayout.Load(FilePath);
|
||||||
|
IsValid = DeviceLayout != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the file path the layout was (attempted to be) loaded from
|
||||||
|
/// </summary>
|
||||||
|
public string FilePath { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the RGB.NET device layout
|
||||||
|
/// </summary>
|
||||||
|
public DeviceLayout? DeviceLayout { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a boolean indicating whether a valid layout was loaded
|
||||||
|
/// </summary>
|
||||||
|
public bool IsValid { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the device this image is applied to
|
||||||
|
/// </summary>
|
||||||
|
public ArtemisDevice? Device { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the physical layout of the device. Only applicable to keyboards
|
||||||
|
/// </summary>
|
||||||
|
public string? PhysicalLayout { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the logical layout of the device. Only applicable to keyboards
|
||||||
|
/// </summary>
|
||||||
|
public string? LogicalLayout { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the image of the device
|
||||||
|
/// </summary>
|
||||||
|
public Uri? Image { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
@ -34,7 +34,15 @@ namespace Artemis.Core.DeviceProviders
|
|||||||
[Inject]
|
[Inject]
|
||||||
public ILogger? Logger { get; set; }
|
public ILogger? Logger { get; set; }
|
||||||
|
|
||||||
internal Dictionary<IRGBDevice, string> DeviceLayoutPaths { get; set; } = new();
|
/// <summary>
|
||||||
|
/// A boolean indicating whether this device provider detects the physical layout of connected keyboards
|
||||||
|
/// </summary>
|
||||||
|
public bool CanDetectPhysicalLayout { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A boolean indicating whether this device provider detects the logical layout of connected keyboards
|
||||||
|
/// </summary>
|
||||||
|
public bool CanDetectLogicalLayout { get; protected set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Disable()
|
public override void Disable()
|
||||||
@ -43,31 +51,37 @@ namespace Artemis.Core.DeviceProviders
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Loads a layout for the specified device and wraps it in an <see cref="ArtemisLayout" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type"></param>
|
/// <param name="rgbDevice">The device to load the layout for</param>
|
||||||
/// <param name="sender"></param>
|
/// <returns>The resulting Artemis layout</returns>
|
||||||
/// <param name="e"></param>
|
public virtual ArtemisLayout LoadLayout(IRGBDevice rgbDevice)
|
||||||
protected void ResolveAbsolutePath(Type type, object sender, ResolvePathEventArgs e)
|
|
||||||
{
|
{
|
||||||
if (sender.GetType() == type || sender.GetType().IsGenericType(type))
|
// Take out invalid file name chars, may not be perfect but neither are you
|
||||||
{
|
string model = Path.GetInvalidFileNameChars().Aggregate(rgbDevice.DeviceInfo.Model, (current, c) => current.Replace(c, '-'));
|
||||||
// Start from the plugin directory
|
string layoutDir = Path.Combine(Plugin.Directory.FullName, "Layouts");
|
||||||
if (e.RelativePart != null && e.FileName != null)
|
string filePath;
|
||||||
e.FinalPath = Path.Combine(Plugin.Directory.FullName, e.RelativePart, e.FileName);
|
// if (rgbDevice.DeviceInfo is IPhysicalLayoutDeviceInfo)
|
||||||
else if (e.RelativePath != null)
|
// {
|
||||||
e.FinalPath = Path.Combine(Plugin.Directory.FullName, e.RelativePath);
|
// filePath = Path.Combine(
|
||||||
|
// layoutDir,
|
||||||
|
// rgbDevice.DeviceInfo.Manufacturer,
|
||||||
|
// rgbDevice.DeviceInfo.DeviceType.ToString(),
|
||||||
|
// model,
|
||||||
|
// keyboard.DeviceInfo.
|
||||||
|
// ) + ".xml";
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
filePath = Path.Combine(
|
||||||
|
layoutDir,
|
||||||
|
rgbDevice.DeviceInfo.Manufacturer,
|
||||||
|
rgbDevice.DeviceInfo.DeviceType.ToString(),
|
||||||
|
model
|
||||||
|
) + ".xml";
|
||||||
|
// }
|
||||||
|
|
||||||
IRGBDevice device = (IRGBDevice) sender;
|
return new ArtemisLayout(filePath);
|
||||||
IRGBDeviceInfo deviceInfo = device.DeviceInfo;
|
|
||||||
if (e.FileName != null && !File.Exists(e.FinalPath))
|
|
||||||
{
|
|
||||||
Logger?.Information("Couldn't find a layout for device {deviceName}, model {deviceModel} at {filePath}",
|
|
||||||
deviceInfo.DeviceName, deviceInfo.Model, e.FinalPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.FileName != null)
|
|
||||||
DeviceLayoutPaths[device] = e.FinalPath;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Artemis.Core.DeviceProviders;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
|
|
||||||
namespace Artemis.Core.Services
|
namespace Artemis.Core.Services
|
||||||
|
|||||||
@ -71,8 +71,7 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
foreach (IRGBDevice surfaceDevice in deviceProvider.Devices)
|
foreach (IRGBDevice surfaceDevice in deviceProvider.Devices)
|
||||||
{
|
{
|
||||||
_logger.Debug("Device provider {deviceProvider} added {deviceName}",
|
_logger.Debug("Device provider {deviceProvider} added {deviceName}", deviceProvider.GetType().Name, surfaceDevice.DeviceInfo?.DeviceName);
|
||||||
deviceProvider.GetType().Name, surfaceDevice.DeviceInfo?.DeviceName);
|
|
||||||
if (!_loadedDevices.Contains(surfaceDevice))
|
if (!_loadedDevices.Contains(surfaceDevice))
|
||||||
{
|
{
|
||||||
_loadedDevices.Add(surfaceDevice);
|
_loadedDevices.Add(surfaceDevice);
|
||||||
|
|||||||
@ -112,24 +112,6 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
|
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
|
||||||
|
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition />
|
|
||||||
<RowDefinition />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<StackPanel Grid.Column="0">
|
|
||||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Lighting support</TextBlock>
|
|
||||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
|
|
||||||
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
Text="{Binding Device.RgbDevice.DeviceInfo.Lighting}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
|
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition />
|
<RowDefinition />
|
||||||
@ -160,7 +142,7 @@
|
|||||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Device image</TextBlock>
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Device image</TextBlock>
|
||||||
<TextBox Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
<TextBox Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
Text="{Binding Device.RgbDevice.DeviceInfo.Image, Mode=OneWay}"
|
Text="{Binding Device.Layout.Image, Mode=OneWay}"
|
||||||
IsReadOnly="True" />
|
IsReadOnly="True" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -220,25 +202,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
|
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
|
||||||
|
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition />
|
|
||||||
<RowDefinition />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<StackPanel Grid.Column="0">
|
|
||||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Syncback supported</TextBlock>
|
|
||||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
|
|
||||||
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
Text="{Binding Device.RgbDevice.DeviceInfo.SupportsSyncBack}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
|
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition />
|
<RowDefinition />
|
||||||
@ -251,7 +215,7 @@
|
|||||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Layout file path</TextBlock>
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Layout file path</TextBlock>
|
||||||
<TextBox Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
<TextBox Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
Text="{Binding Device.LayoutPath, Mode=OneWay}"
|
Text="{Binding Device.Layout.FilePath, Mode=OneWay}"
|
||||||
IsReadOnly="True" />
|
IsReadOnly="True" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user