using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using AuraServiceLib; using RGB.NET.Core; namespace RGB.NET.Devices.Asus; /// /// Represents custom LED data for ASUS keyboard LEDs. /// public record AsusKeyboardLedCustomData(AsusLedType LedType, int Id); /// /// Represents a record containing regex that matches to an ASUS device model and a LED mapping mapping to Light indexes. /// public record AsusKeyboardExtraMapping(Regex Regex, LedMapping LedMapping); /// /// /// Represents a Asus keyboard. /// public sealed class AsusKeyboardRGBDevice : AsusRGBDevice, IKeyboard { #region Properties & Fields private readonly LedMapping? _ledMapping; private readonly Dictionary _ledAsusLed = []; private readonly Dictionary _ledAsusLights = []; IKeyboardDeviceInfo IKeyboard.DeviceInfo => DeviceInfo; /// /// Gets or sets a list of extra LED mappings to apply to modes that match the provided regex. /// Note: These LED mappings should be based on light indexes. /// // ReSharper disable once InconsistentNaming public static readonly List ExtraLedMappings = [ new(new Regex("(ROG Zephyrus Duo 15).*?"), LedMappings.ROGZephyrusDuo15), new(new Regex("(ROG Strix G513QM).*?"), LedMappings.ROGStrixG15) ]; #endregion #region Constructors /// /// /// Initializes a new instance of the class. /// /// The specific information provided by Asus for the keyboard. /// A mapping of leds this device is initialized with. /// The update trigger used to update this device. internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info, LedMapping? ledMapping, IDeviceUpdateTrigger updateTrigger) : base(info, updateTrigger) { this._ledMapping = ledMapping; InitializeLayout(); } #endregion #region Methods private void InitializeLayout() { if ((DeviceInfo.Device.Type != (uint)AsusDeviceType.NB_KB_4ZONE_RGB) && (DeviceInfo.Device.Type !=(uint)AsusDeviceType.KEYBOARD_5ZONE_RGB)) { int pos = 0; int unknownLed = (int)LedId.Unknown1; foreach (IAuraRgbKey key in ((IAuraSyncKeyboard)DeviceInfo.Device).Keys) { if ((_ledMapping != null) && _ledMapping.TryGetValue((AsusLedId)key.Code, out LedId ledId)) AddAsusLed((AsusLedId)key.Code, ledId, new Point(pos++ * 19, 0), new Size(19, 19)); else { AddAsusLed((AsusLedId)key.Code, (LedId)unknownLed, new Point(pos++ * 19, 0), new Size(19, 19)); unknownLed++; } } // Add extra LED mapping if required AsusKeyboardExtraMapping? extraMapping = ExtraLedMappings.FirstOrDefault(m => m.Regex.IsMatch(this.DeviceInfo.Model)); if (extraMapping != null) { foreach ((LedId ledId, int lightIndex) in extraMapping.LedMapping) AddAsusLed(lightIndex, ledId, new Point(pos++ * 19, 0), new Size(19, 19)); } } else { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) AddLed(LedId.Keyboard_Custom1 + i, new Point(i * 19, 0), new Size(19, 19)); } } /// protected override object? GetLedCustomData(LedId ledId) { if (this._ledAsusLed.TryGetValue(ledId, out AsusLedId asusLedId)) return new AsusKeyboardLedCustomData(AsusLedType.Key, (int)asusLedId); if (this._ledAsusLights.TryGetValue(ledId, out int lightIndex)) return new AsusKeyboardLedCustomData(AsusLedType.Light, lightIndex); return null; } /// /// Add an ASUS LED by its LED ID /// private void AddAsusLed(AsusLedId asusLedId, LedId ledId, Point position, Size size) { if (this._ledAsusLed.TryGetValue(ledId, out AsusLedId firstAsusLed)) throw new RGBDeviceException($"Got LED '{ledId}' twice, first ASUS LED '{firstAsusLed}' " + $"second ASUS LED '{asusLedId}' on device '{DeviceInfo.DeviceName}'"); this._ledAsusLed.Add(ledId, asusLedId); AddLed(ledId, position, size); } /// /// Add an ASUS LED by its light index /// private void AddAsusLed(int index, LedId ledId, Point position, Size size) { this._ledAsusLights.Add(ledId, index); AddLed(ledId, position, size); } #endregion }