1
0
mirror of https://github.com/DarthAffe/RGB.NET.git synced 2025-12-13 10:08:31 +00:00

Compare commits

...

11 Commits

Author SHA1 Message Date
5592fd9923
Merge pull request #358 from DarthAffe/bugfix/layout-saving
Fix custom LED data type not being determined correctly
2023-11-01 21:14:44 +01:00
Robert
08fbb0e526 Fix custom LED data type not being determined correctly 2023-11-01 20:37:12 +01:00
99225f04fc
Merge pull request #357 from DarthAffe/LayoutFixes
Layout fixes/improvements
2023-11-01 20:16:23 +01:00
fda89e74c2
Merge pull request #355 from DarthAffe/feature/wooting-uwu
Wooting - Add uwu support
2023-11-01 20:15:50 +01:00
be252790d4 Added extension to save layouts 2023-10-31 22:14:05 +01:00
188de3c558 Fixed an error when parsing custom layout data if the xml-element contains an attribute 2023-10-31 21:54:58 +01:00
883d6cbea4 Added ToString to Scale 2023-10-31 21:51:40 +01:00
Diogo Trindade
fcf86ff9da Fix analog key coords 2023-10-18 14:11:44 +01:00
Diogo Trindade
7ad1e595a9 Added Missing LEDs 2023-10-17 19:29:40 +01:00
Diogo Trindade
69d320fca3 Ignore UwU non-RGB 2023-10-17 17:49:09 +01:00
Diogo Trindade
736d58c7a3 Wooting - Add uwu support 2023-10-17 14:20:04 +01:00
13 changed files with 209 additions and 75 deletions

View File

@ -50,6 +50,12 @@ public readonly struct Scale : IEquatable<Scale>
#region Methods
/// <summary>
/// Converts the <see cref="Horizontal"/> and <see cref="Vertical"/> value of this <see cref="Scale"/> to a human-readable string.
/// </summary>
/// <returns>A string that contains the <see cref="Horizontal"/> and <see cref="Vertical"/> value of this <see cref="Scale"/>. For example "[Horizontal: 1, Vertical: 0.5]".</returns>
public override string ToString() => $"[Horizontal: {Horizontal}, Vertical: {Vertical}]\"";
/// <summary>
/// Tests whether the specified <see cref="Scale"/> is equivalent to this <see cref="Scale" />.
/// </summary>

View File

@ -1,24 +1,29 @@
// ReSharper disable InconsistentNaming
namespace RGB.NET.Devices.Wooting.Enum;
/// <summary>
/// Represents the type of a wooting device
/// </summary>
public enum WootingDeviceType
{
/// <summary>
/// 10 Keyless Keyboard. E.g. Wooting One
/// </summary>
KeyboardTKL = 1,
/// <summary>
/// Full Size keyboard. E.g. Wooting Two
/// </summary>
// ReSharper disable InconsistentNaming
namespace RGB.NET.Devices.Wooting.Enum;
/// <summary>
/// Represents the type of a wooting device
/// </summary>
public enum WootingDeviceType
{
/// <summary>
/// 10 Keyless Keyboard. E.g. Wooting One
/// </summary>
KeyboardTKL = 1,
/// <summary>
/// Full Size keyboard. E.g. Wooting Two
/// </summary>
Keyboard = 2,
/// <summary>
/// Full Size keyboard. E.g. Wooting Two
/// </summary>
KeyboardSixtyPercent = 3
/// <summary>
/// 60 percent keyboard, E.g. Wooting 60HE
/// </summary>
KeyboardSixtyPercent = 3,
/// <summary>
/// Three key keypad. E.g. Wooting Uwu
/// </summary>
Keypad3Keys = 4,
}

View File

@ -13,6 +13,7 @@ namespace RGB.NET.Devices.Wooting.Enum;
/// </remarks>
public enum WootingLayoutType
{
Unknown = -1,
ANSI = 0,
ISO = 1
}

View File

@ -1,15 +1,15 @@
// ReSharper disable InconsistentNaming
// ReSharper disable InconsistentNaming
using System.Collections.Generic;
using RGB.NET.Core;
using RGB.NET.Devices.Wooting.Enum;
using System.Collections.Generic;
namespace RGB.NET.Devices.Wooting.Keyboard;
namespace RGB.NET.Devices.Wooting.Generic;
/// <summary>
/// Contains all the hardware-id mappings for Wooting devices.
/// </summary>
internal static class WootingKeyboardLedMappings
internal static class WootingLedMappings
{
#region Properties & Fields
@ -305,6 +305,36 @@ internal static class WootingKeyboardLedMappings
{ LedId.Keyboard_Function, (5, 13) }
};
private static readonly Dictionary<LedId, (int row, int column)> ThreeKeyKeypad = new()
{
//left (from top to bottom)
[LedId.LedStripe1] = (1, 0),
[LedId.LedStripe2] = (2, 0),
[LedId.LedStripe3] = (3, 0),
//bottom (from left to right)
[LedId.LedStripe4] = (4, 1),
[LedId.LedStripe5] = (4, 2),
[LedId.LedStripe6] = (4, 4),
[LedId.LedStripe7] = (4, 5),
//right (from bottom to top)
[LedId.LedStripe8] = (3, 6),
[LedId.LedStripe9] = (2, 6),
[LedId.LedStripe10] = (1, 6),
//top (from right to left)
[LedId.LedStripe11] = (0, 6),
[LedId.LedStripe12] = (0, 4),
[LedId.LedStripe13] = (0, 2),
[LedId.LedStripe14] = (0, 0),
//analog keys
[LedId.Keypad1] = (2, 1),
[LedId.Keypad2] = (2, 3),
[LedId.Keypad3] = (2, 5),
};
/// <summary>
/// Contains all the hardware-id mappings for Wooting devices.
/// </summary>
@ -312,8 +342,9 @@ internal static class WootingKeyboardLedMappings
{
[WootingDeviceType.Keyboard] = Fullsize,
[WootingDeviceType.KeyboardTKL] = TKL,
[WootingDeviceType.KeyboardSixtyPercent] = SixtyPercent
[WootingDeviceType.KeyboardSixtyPercent] = SixtyPercent,
[WootingDeviceType.Keypad3Keys] = ThreeKeyKeypad
};
#endregion
}
}

View File

@ -1,4 +1,5 @@
using RGB.NET.Core;
using RGB.NET.Devices.Wooting.Native;
namespace RGB.NET.Devices.Wooting.Generic;
@ -23,4 +24,17 @@ public abstract class WootingRGBDevice<TDeviceInfo> : AbstractRGBDevice<TDeviceI
}
#endregion
#region Methods
public override void Dispose()
{
_WootingSDK.SelectDevice(DeviceInfo.WootingDeviceIndex);
_WootingSDK.Reset();
base.Dispose();
}
#endregion
}

View File

@ -1,34 +0,0 @@
using System;
using System.ComponentModel;
using System.Reflection;
namespace RGB.NET.Devices.Wooting.Helper;
/// <summary>
/// Offers some extensions and helper-methods for enum related things.
/// </summary>
internal static class EnumExtension
{
/// <summary>
/// Gets the value of the <see cref="DescriptionAttribute"/>.
/// </summary>
/// <param name="source">The enum value to get the description from.</param>
/// <returns>The value of the <see cref="DescriptionAttribute"/> or the <see cref="System.Enum.ToString()" /> result of the source.</returns>
internal static string GetDescription(this System.Enum source)
=> source.GetAttribute<DescriptionAttribute>()?.Description ?? source.ToString();
/// <summary>
/// Gets the attribute of type T.
/// </summary>
/// <param name="source">The enum value to get the attribute from</param>
/// <typeparam name="T">The generic attribute type</typeparam>
/// <returns>The <see cref="Attribute"/>.</returns>
private static T? GetAttribute<T>(this System.Enum source)
where T : Attribute
{
FieldInfo? fi = source.GetType().GetField(source.ToString());
if (fi == null) return null;
T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false);
return attributes.Length > 0 ? attributes[0] : null;
}
}

View File

@ -37,22 +37,14 @@ public sealed class WootingKeyboardRGBDevice : WootingRGBDevice<WootingKeyboardR
private void InitializeLayout()
{
Dictionary<LedId, (int row, int column)> mapping = WootingKeyboardLedMappings.Mapping[DeviceInfo.WootingDeviceType];
Dictionary<LedId, (int row, int column)> mapping = WootingLedMappings.Mapping[DeviceInfo.WootingDeviceType];
foreach (KeyValuePair<LedId, (int row, int column)> led in mapping)
AddLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19, 19));
}
/// <inheritdoc />
protected override object GetLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.WootingDeviceType][ledId];
public override void Dispose()
{
_WootingSDK.SelectDevice(DeviceInfo.WootingDeviceIndex);
_WootingSDK.Reset();
base.Dispose();
}
protected override object GetLedCustomData(LedId ledId) => WootingLedMappings.Mapping[DeviceInfo.WootingDeviceType][ledId];
#endregion
}

View File

@ -0,0 +1,44 @@
using System.Collections.Generic;
using RGB.NET.Core;
using RGB.NET.Devices.Wooting.Generic;
using RGB.NET.Devices.Wooting.Keyboard;
namespace RGB.NET.Devices.Wooting.Keypad;
/// <inheritdoc cref="WootingRGBDevice{TDeviceInfo}" />
/// <summary>
/// Represents a Wooting keyboard.
/// </summary>
public sealed class WootingKeypadRGBDevice : WootingRGBDevice<WootingKeypadRGBDeviceInfo>, IKeypad
{
#region Constructors
/// <inheritdoc />
/// <summary>
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Wooting.Keyboard.WootingKeypadRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Wooting for the keyboard</param>
/// <param name="updateQueue">The update queue used to update this device.</param>
internal WootingKeypadRGBDevice(WootingKeypadRGBDeviceInfo info, IUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
private void InitializeLayout()
{
Dictionary<LedId, (int row, int column)> mapping = WootingLedMappings.Mapping[DeviceInfo.WootingDeviceType];
foreach (KeyValuePair<LedId, (int row, int column)> led in mapping)
AddLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19, 19));
}
/// <inheritdoc />
protected override object GetLedCustomData(LedId ledId) => WootingLedMappings.Mapping[DeviceInfo.WootingDeviceType][ledId];
#endregion
}

View File

@ -0,0 +1,17 @@
using RGB.NET.Core;
using RGB.NET.Devices.Wooting.Generic;
using RGB.NET.Devices.Wooting.Native;
namespace RGB.NET.Devices.Wooting.Keypad;
/// <summary>
/// Represents a generic information for a <see cref="T:RGB.NET.Devices.Wooting.Keypad.WootingKeypadRGBDevice" />.
/// </summary>
public sealed class WootingKeypadRGBDeviceInfo : WootingRGBDeviceInfo
{
internal WootingKeypadRGBDeviceInfo(_WootingDeviceInfo deviceInfo, byte deviceIndex)
: base(RGBDeviceType.Keypad, deviceInfo, deviceIndex)
{
}
}

View File

@ -17,11 +17,13 @@ internal struct _WootingDeviceInfo
internal byte MaxColumns { get; private set; }
internal byte KeycodeLimit { get; private set; }
internal byte MaxLedIndex { get; private set; }
internal WootingDeviceType DeviceType { get; private set; }
internal bool V2Interface { get; set; }
internal bool V2Interface { get; private set; }
internal WootingLayoutType LayoutType { get; private set; }
internal bool UsesSmallPackets { get; private set; }
}

View File

@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Wooting.Enum;
using RGB.NET.Devices.Wooting.Generic;
using RGB.NET.Devices.Wooting.Keyboard;
using RGB.NET.Devices.Wooting.Keypad;
using RGB.NET.Devices.Wooting.Native;
namespace RGB.NET.Devices.Wooting;
@ -99,8 +101,16 @@ public sealed class WootingDeviceProvider : AbstractRGBDeviceProvider
WootingUpdateQueue updateQueue = new(GetUpdateTrigger(), i);
_WootingSDK.SelectDevice(i);
_WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!;
//Uwu non-rgb returns zero here.
if (nativeDeviceInfo.MaxLedIndex == 0)
continue;
yield return new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(nativeDeviceInfo, i), updateQueue);
yield return nativeDeviceInfo.DeviceType switch
{
WootingDeviceType.Keypad3Keys => new WootingKeypadRGBDevice(new WootingKeypadRGBDeviceInfo(nativeDeviceInfo, i), updateQueue),
_ => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(nativeDeviceInfo, i), updateQueue),
};
}
}
}

View File

@ -174,7 +174,7 @@ public class DeviceLayout : IDeviceLayout
/// <returns>The deserialized custom data object.</returns>
protected virtual object? GetCustomData(object? customData, Type? type)
{
XmlNode? node = (customData as XmlNode) ?? (customData as IEnumerable<XmlNode>)?.FirstOrDefault()?.ParentNode; //HACK DarthAffe 16.01.2021: This gives us the CustomData-Node
XmlNode? node = (customData as XmlNode) ?? (customData as IEnumerable<XmlNode>)?.FirstOrDefault(x => x.ParentNode != null)?.ParentNode; //HACK DarthAffe 16.01.2021: This gives us the CustomData-Node
if ((node == null) || (type == null)) return null;
using MemoryStream ms = new();

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using RGB.NET.Core;
namespace RGB.NET.Layout;
@ -51,4 +53,48 @@ public static class LayoutExtension
device.RemoveLed(led);
}
}
/// <summary>
/// Saves the specified layout to the given location.
/// </summary>
/// <param name="layout">The layout to save.</param>
/// <param name="targetFile">The location to save to.</param>
public static void Save(this IDeviceLayout layout, string targetFile)
{
using FileStream fs = new(targetFile, FileMode.Create);
layout.Save(fs);
}
/// <summary>
/// Saves the specified layout to the given stream.
/// </summary>
/// <param name="layout">The layout to save.</param>
/// <param name="stream">The stream to save to.</param>
public static void Save(this IDeviceLayout layout, Stream stream)
{
Type? customDataType = layout.CustomData?.GetType();
Type? customLedDataType = layout.Leds.FirstOrDefault(x => x.CustomData != null)?.CustomData?.GetType();
Type[] customTypes;
if ((customDataType != null) && (customLedDataType != null))
customTypes = new[] { customDataType, customLedDataType };
else if (customDataType != null)
customTypes = new[] { customDataType };
else if (customLedDataType != null)
customTypes = new[] { customLedDataType };
else
customTypes = Array.Empty<Type>();
if (layout is DeviceLayout deviceLayout)
{
deviceLayout.InternalCustomData = deviceLayout.CustomData;
foreach (ILedLayout led in deviceLayout.Leds)
if (led is LedLayout ledLayout)
ledLayout.InternalCustomData = ledLayout.CustomData;
}
XmlSerializer serializer = new(typeof(DeviceLayout), null, customTypes, null, null);
serializer.Serialize(stream, layout);
}
}