diff --git a/Brushes/BrushRenderTarget.cs b/Brushes/BrushRenderTarget.cs index b913c32..1ef5996 100644 --- a/Brushes/BrushRenderTarget.cs +++ b/Brushes/BrushRenderTarget.cs @@ -2,7 +2,7 @@ // ReSharper disable UnusedAutoPropertyAccessor.Global using System.Drawing; -using CUE.NET.Devices.Keyboard.Enums; +using CUE.NET.Devices.Generic.Enums; namespace CUE.NET.Brushes { @@ -14,12 +14,12 @@ namespace CUE.NET.Brushes #region Properties & Fields /// - /// Gets the id of the target-key. + /// Gets the ID of the target-LED. /// - public CorsairKeyboardKeyId Key { get; } + public CorsairLedId LedId { get; } /// - /// Gets the point representing the position to render the target-key. + /// Gets the point representing the position to render the target-LED. /// public PointF Point { get; } @@ -30,12 +30,12 @@ namespace CUE.NET.Brushes /// /// Initializes a new instance of the class. /// - /// The id of the target-key. - /// The point representing the position to render the target-key. - public BrushRenderTarget(CorsairKeyboardKeyId key, PointF point) + /// The ID of the target-LED. + /// The point representing the position to render the target-LED. + public BrushRenderTarget(CorsairLedId ledId, PointF point) { this.Point = point; - this.Key = key; + this.LedId = ledId; } #endregion diff --git a/Brushes/ProfileBrush.cs b/Brushes/ProfileBrush.cs index bc056f0..ce0a2fb 100644 --- a/Brushes/ProfileBrush.cs +++ b/Brushes/ProfileBrush.cs @@ -44,7 +44,7 @@ namespace CUE.NET.Brushes /// The color at the specified point. protected override Color GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget) { - CorsairKey key = CueSDK.KeyboardSDK[renderTarget.Key]; + CorsairKey key = CueSDK.KeyboardSDK[(CorsairKeyboardKeyId)renderTarget.LedId]; if (key == null) return Color.Transparent; Color color; diff --git a/CUE.NET.csproj b/CUE.NET.csproj index bb48f86..06bdcd3 100644 --- a/CUE.NET.csproj +++ b/CUE.NET.csproj @@ -84,10 +84,10 @@ - - - - + + + + @@ -102,7 +102,7 @@ - + diff --git a/Devices/Generic/AbstractCueDevice.cs b/Devices/Generic/AbstractCueDevice.cs index 3cd9340..34c7f2c 100644 --- a/Devices/Generic/AbstractCueDevice.cs +++ b/Devices/Generic/AbstractCueDevice.cs @@ -2,14 +2,21 @@ // ReSharper disable UnusedMethodReturnValue.Global using System; +using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using CUE.NET.Brushes; using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Generic.EventArgs; +using CUE.NET.Devices.Keyboard.Enums; +using CUE.NET.Effects; +using CUE.NET.Groups; +using CUE.NET.Helper; using CUE.NET.Native; namespace CUE.NET.Devices.Generic @@ -21,6 +28,16 @@ namespace CUE.NET.Devices.Generic { #region Properties & Fields + private CancellationTokenSource _updateTokenSource; + private CancellationToken _updateToken; + private Task _updateTask; + private DateTime _lastUpdate = DateTime.Now; + + /// + /// Gets a list of attached ledgroups. + /// + protected LinkedList LedGroups { get; } = new LinkedList(); + /// /// Gets generic information provided by CUE for the device. /// @@ -45,15 +62,65 @@ namespace CUE.NET.Devices.Generic /// public float UpdateFrequency { get; set; } = 1f / 30f; + /// + /// Gets the rectangle containing all LEDs of the device. + /// + public RectangleF DeviceRectangle { get; } + /// /// Gets a dictionary containing all LEDs of the device. /// - protected Dictionary Leds { get; } = new Dictionary(); + protected Dictionary LedMapping { get; } = new Dictionary(); - private CancellationTokenSource _updateTokenSource; - private CancellationToken _updateToken; - private Task _updateTask; - private DateTime _lastUpdate = DateTime.Now; + /// + /// Gets a read-only collection containing the LEDs of the device. + /// + public IEnumerable Leds => new ReadOnlyCollection(LedMapping.Values.ToList()); + + /// + /// Gets or sets the background brush of the keyboard. + /// + public IBrush Brush { get; set; } + + /// + /// Gets or sets the z-index of the background brush of the keyboard.
+ /// This value has absolutely no effect. + ///
+ public int ZIndex { get; set; } = 0; + + #region Indexers + + /// + /// Gets the with the specified ID. + /// + /// The ID of the LED to get. + /// The LED with the specified ID or null if no LED is found. + public CorsairLed this[CorsairLedId ledId] + { + get + { + CorsairLed key; + return LedMapping.TryGetValue(ledId, out key) ? key : null; + } + } + + /// + /// Gets the at the given physical location. + /// + /// The point to get the location from. + /// The LED at the given point or null if no location is found. + public CorsairLed this[PointF location] => LedMapping.Values.FirstOrDefault(x => x.LedRectangle.Contains(location)); + + /// + /// Gets a list of inside the given rectangle. + /// + /// The rectangle to check. + /// The minimal percentage overlay a location must have with the to be taken into the list. + /// + public IEnumerable this[RectangleF referenceRect, float minOverlayPercentage = 0.5f] => LedMapping.Values + .Where(x => RectangleHelper.CalculateIntersectPercentage(x.LedRectangle, referenceRect) >= minOverlayPercentage); + + #endregion #endregion @@ -96,6 +163,10 @@ namespace CUE.NET.Devices.Generic { this.DeviceInfo = info; + // ReSharper disable once VirtualMemberCallInConstructor - I know, but I need this ... + InitializeLeds(); + DeviceRectangle = RectangleHelper.CreateRectangleFromRectangles(((IEnumerable)this).Select(x => x.LedRectangle)); + CheckUpdateLoop(); } @@ -103,18 +174,20 @@ namespace CUE.NET.Devices.Generic #region Methods + protected abstract void InitializeLeds(); + /// /// Initializes the LED-Object with the specified id. /// /// The LED-Id to initialize. /// The rectangle representing the position of the LED to initialize. /// - protected CorsairLed InitializeLed(int ledId, RectangleF ledRectangle) + protected CorsairLed InitializeLed(CorsairLedId ledId, RectangleF ledRectangle) { - if (!Leds.ContainsKey(ledId)) + if (!LedMapping.ContainsKey(ledId)) { - CorsairLed led = new CorsairLed(ledRectangle); - Leds.Add(ledId, led); + CorsairLed led = new CorsairLed(ledId, ledRectangle); + LedMapping.Add(ledId, led); return led; } @@ -175,12 +248,22 @@ namespace CUE.NET.Devices.Generic { OnUpdating(); + // Update effects + foreach (ILedGroup ledGroup in LedGroups) + ledGroup.UpdateEffects(); + + // Render brushes + Render(this); + foreach (ILedGroup ledGroup in LedGroups.OrderBy(x => x.ZIndex)) + Render(ledGroup); + + // Device-specific updates DeviceUpdate(); - ICollection ledsToUpdate = (flushLeds ? Leds : Leds.Where(x => x.Value.IsDirty)).Select(x => new LedUpateRequest(x.Key, x.Value.RequestedColor)).ToList(); - - foreach (CorsairLed led in Leds.Values) - led.Update(); + // Send LEDs to SDK + ICollection ledsToUpdate = (flushLeds ? LedMapping : LedMapping.Where(x => x.Value.IsDirty)).Select(x => new LedUpateRequest(x.Key, x.Value.RequestedColor)).ToList(); + foreach (LedUpateRequest updateRequest in ledsToUpdate) + LedMapping[updateRequest.LedId].Update(); UpdateLeds(ledsToUpdate); @@ -190,7 +273,82 @@ namespace CUE.NET.Devices.Generic /// /// Performs device specific updates. /// - protected abstract void DeviceUpdate(); + protected virtual void DeviceUpdate() + { } + + /// + /// Attaches the given ledgroup. + /// + /// The ledgroup to attach. + /// true if the ledgroup could be attached; otherwise, false. + public bool AttachLedGroup(ILedGroup ledGroup) + { + lock (LedGroups) + { + if (ledGroup == null || LedGroups.Contains(ledGroup)) return false; + + LedGroups.AddLast(ledGroup); + return true; + } + } + + /// + /// Detaches the given ledgroup. + /// + /// The ledgroup to detached. + /// true if the ledgroup could be detached; otherwise, false. + public bool DetachLedGroup(ILedGroup ledGroup) + { + lock (LedGroups) + { + if (ledGroup == null) return false; + + LinkedListNode node = LedGroups.Find(ledGroup); + if (node == null) return false; + + LedGroups.Remove(node); + return true; + } + } + + /// + /// Renders a ledgroup. + /// + /// The led group to render. + // ReSharper disable once MemberCanBeMadeStatic.Local - idc + protected virtual void Render(ILedGroup ledGroup) + { + IList leds = ledGroup.GetLeds().ToList(); + IBrush brush = ledGroup.Brush; + + try + { + switch (brush.BrushCalculationMode) + { + case BrushCalculationMode.Relative: + RectangleF brushRectangle = RectangleHelper.CreateRectangleFromRectangles(leds.Select(x => x.LedRectangle)); + float offsetX = -brushRectangle.X; + float offsetY = -brushRectangle.Y; + brushRectangle.X = 0; + brushRectangle.Y = 0; + brush.PerformRender(brushRectangle, leds.Select(x => new BrushRenderTarget(x.Id, x.LedRectangle.GetCenter(offsetX, offsetY)))); + break; + case BrushCalculationMode.Absolute: + brush.PerformRender(DeviceRectangle, leds.Select(x => new BrushRenderTarget(x.Id, x.LedRectangle.GetCenter()))); + break; + default: + throw new ArgumentException(); + } + + brush.UpdateEffects(); + brush.PerformFinalize(); + + foreach (KeyValuePair renders in brush.RenderedTargets) + this[renders.Key.LedId].Color = renders.Value; + } + // ReSharper disable once CatchAllClause + catch (Exception ex) { OnException(ex); } + } private void UpdateLeds(ICollection updateRequests) { @@ -207,7 +365,7 @@ namespace CUE.NET.Devices.Generic { _CorsairLedColor color = new _CorsairLedColor { - ledId = ledUpdateRequest.LedId, + ledId = (int)ledUpdateRequest.LedId, r = ledUpdateRequest.Color.R, g = ledUpdateRequest.Color.G, b = ledUpdateRequest.Color.B @@ -228,10 +386,49 @@ namespace CUE.NET.Devices.Generic /// internal void ResetLeds() { - foreach (CorsairLed led in Leds.Values) + foreach (CorsairLed led in LedMapping.Values) led.Reset(); } + /// + /// Gets a list containing all LEDs of this group. + /// + /// The list containing all LEDs of this group. + public IEnumerable GetLeds() + { + return Leds; + } + + #region Effects + + /// + /// NOT IMPLEMENTED: Effects can't be applied directly to the device. Add it to the Brush or create a keygroup instead. + /// + public void UpdateEffects() + { + throw new NotSupportedException("Effects can't be applied directly to the device. Add it to the Brush or create a keygroup instead."); + } + + /// + /// NOT IMPLEMENTED: Effects can't be applied directly to the device. Add it to the Brush or create a keygroup instead. + /// + /// The effect to add. + public void AddEffect(IEffect effect) + { + throw new NotSupportedException("Effects can't be applied directly to the device. Add it to the Brush or create a keygroup instead."); + } + + /// + /// NOT IMPLEMENTED: Effects can't be applied directly to the device. Add it to the Brush or create a keygroup instead. + /// + /// The effect to remove. + public void RemoveEffect(IEffect effect) + { + throw new NotSupportedException("Effects can't be applied directly to the device. Add it to the Brush or create a keygroup instead."); + } + + #endregion + #region EventCaller /// @@ -313,6 +510,28 @@ namespace CUE.NET.Devices.Generic } #endregion + #region IEnumerable + + /// + /// Returns an enumerator that iterates over all LEDs of the device. + /// + /// An enumerator for all LEDs of the device. + public IEnumerator GetEnumerator() + { + return LedMapping.Values.GetEnumerator(); + } + + /// + /// Returns an enumerator that iterates over all LEDs of the device. + /// + /// An enumerator for all LEDs of the device. + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #endregion + #endregion } } diff --git a/Devices/Generic/CorsairLed.cs b/Devices/Generic/CorsairLed.cs index ceec886..ea1ec22 100644 --- a/Devices/Generic/CorsairLed.cs +++ b/Devices/Generic/CorsairLed.cs @@ -3,6 +3,7 @@ // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global using System.Drawing; +using CUE.NET.Devices.Generic.Enums; using CUE.NET.Helper; namespace CUE.NET.Devices.Generic @@ -13,7 +14,9 @@ namespace CUE.NET.Devices.Generic public class CorsairLed { #region Properties & Fields - + + public CorsairLedId Id { get; set; } + /// /// Gets a rectangle representing the physical location of the led. /// @@ -24,11 +27,6 @@ namespace CUE.NET.Devices.Generic /// public bool IsDirty => RequestedColor != _color; - /// - /// Indicate whether the Color of the LED was set since the last update. - /// - public bool IsUpdated { get; private set; } - /// /// Gets the Color the LED should be set to on the next update. /// @@ -36,7 +34,7 @@ namespace CUE.NET.Devices.Generic private Color _color = Color.Transparent; /// - /// Gets the current color of the LED. Sets the for the next update and mark the LED as . + /// Gets the current color of the LED. Sets the for the next update. />. /// public Color Color { @@ -44,10 +42,7 @@ namespace CUE.NET.Devices.Generic set { if (!IsLocked) - { RequestedColor = RequestedColor.Blend(value); - IsUpdated = true; - } } } @@ -63,9 +58,11 @@ namespace CUE.NET.Devices.Generic /// /// Initializes a new instance of the class. /// - /// The rectangle representing the physical location of the led. - internal CorsairLed(RectangleF ledRectangle) + /// The ID of the LED + /// The rectangle representing the physical location of the LED. + internal CorsairLed(CorsairLedId id, RectangleF ledRectangle) { + this.Id = id; this.LedRectangle = ledRectangle; } @@ -79,7 +76,6 @@ namespace CUE.NET.Devices.Generic internal void Update() { _color = RequestedColor; - IsUpdated = false; } /// @@ -89,7 +85,6 @@ namespace CUE.NET.Devices.Generic { _color = Color.Transparent; RequestedColor = Color.Transparent; - IsUpdated = false; IsLocked = false; } diff --git a/Devices/Generic/LedUpateRequest.cs b/Devices/Generic/LedUpateRequest.cs index 09c1060..e5fac1a 100644 --- a/Devices/Generic/LedUpateRequest.cs +++ b/Devices/Generic/LedUpateRequest.cs @@ -2,6 +2,7 @@ // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global using System.Drawing; +using CUE.NET.Devices.Generic.Enums; namespace CUE.NET.Devices.Generic { @@ -15,7 +16,7 @@ namespace CUE.NET.Devices.Generic /// /// Gets the id of the led to update. /// - public int LedId { get; } + public CorsairLedId LedId { get; } /// /// Gets the requested color of the led. @@ -31,7 +32,7 @@ namespace CUE.NET.Devices.Generic /// /// The id of the led to update. /// The requested color of the led. - public LedUpateRequest(int ledId, Color color) + public LedUpateRequest(CorsairLedId ledId, Color color) { this.LedId = ledId; this.Color = color; diff --git a/Devices/Headset/CorsairHeadset.cs b/Devices/Headset/CorsairHeadset.cs index b8bfa91..c65b89f 100644 --- a/Devices/Headset/CorsairHeadset.cs +++ b/Devices/Headset/CorsairHeadset.cs @@ -2,12 +2,9 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Drawing; -using System.Linq; using CUE.NET.Devices.Generic; +using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Headset.Enums; namespace CUE.NET.Devices.Headset @@ -15,38 +12,15 @@ namespace CUE.NET.Devices.Headset /// /// Represents the SDK for a corsair headset. /// - public class CorsairHeadset : AbstractCueDevice, IEnumerable + public class CorsairHeadset : AbstractCueDevice { #region Properties & Fields - #region Indexer - - /// - /// Gets the with the specified ID. - /// - /// The ID of the LED to get. - /// The LED with the specified ID. - public CorsairLed this[CorsairHeadsetLedId ledId] - { - get - { - CorsairLed led; - return base.Leds.TryGetValue((int)ledId, out led) ? led : null; - } - } - - #endregion - /// /// Gets specific information provided by CUE for the headset. /// public CorsairHeadsetDeviceInfo HeadsetDeviceInfo { get; } - /// - /// Gets a read-only collection containing all LEDs of the headset. - /// - public new IEnumerable Leds => new ReadOnlyCollection(base.Leds.Values.ToList()); - #endregion #region Constructors @@ -59,42 +33,18 @@ namespace CUE.NET.Devices.Headset : base(info) { this.HeadsetDeviceInfo = info; - InitializeLeds(); } #endregion #region Methods - private void InitializeLeds() + protected override void InitializeLeds() { - InitializeLed((int)CorsairHeadsetLedId.LeftLogo, new RectangleF(0, 0, 1, 1)); - InitializeLed((int)CorsairHeadsetLedId.RightLogo, new RectangleF(1, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairHeadsetLedId.LeftLogo, new RectangleF(0, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairHeadsetLedId.RightLogo, new RectangleF(1, 0, 1, 1)); } - protected override void DeviceUpdate() - { - //DarthAffe 21.08.2016: Headsets can't own brushes or groups - nothing to do here for now - } - - #region IEnumerable - - /// - /// Returns an enumerator that iterates over all LEDs of the headset. - /// - /// An enumerator for all LEDS of the headset. - public IEnumerator GetEnumerator() - { - return Leds.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - #endregion } } diff --git a/Devices/ICueDevice.cs b/Devices/ICueDevice.cs index 9914e3c..81dcd23 100644 --- a/Devices/ICueDevice.cs +++ b/Devices/ICueDevice.cs @@ -1,8 +1,12 @@ // ReSharper disable UnusedMemberInSuper.Global // ReSharper disable UnusedMember.Global +using System.Collections.Generic; +using System.Drawing; +using CUE.NET.Devices.Generic; using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Generic.EventArgs; +using CUE.NET.Groups; namespace CUE.NET.Devices { @@ -44,7 +48,7 @@ namespace CUE.NET.Devices /// /// Represents a generic cue device. /// - public interface ICueDevice + public interface ICueDevice : ILedGroup, IEnumerable { /// /// Gets generic information provided by CUE for the device. @@ -61,6 +65,38 @@ namespace CUE.NET.Devices /// float UpdateFrequency { get; set; } + /// + /// Gets the rectangle containing all LEDs of the device. + /// + RectangleF DeviceRectangle { get; } + + /// + /// Gets a read-only collection containing the LEDs of the device. + /// + IEnumerable Leds { get; } + + /// + /// Gets the with the specified ID. + /// + /// The ID of the LED to get. + /// The LED with the specified ID or null if no LED is found. + CorsairLed this[CorsairLedId ledId] { get; } + + /// + /// Gets the at the given physical location. + /// + /// The point to get the location from. + /// The LED at the given point or null if no location is found. + CorsairLed this[PointF location] { get; } + + /// + /// Gets a list of inside the given rectangle. + /// + /// The rectangle to check. + /// The minimal percentage overlay a location must have with the to be taken into the list. + /// + IEnumerable this[RectangleF referenceRect, float minOverlayPercentage = 0.5f] { get; } + // ReSharper disable EventNeverSubscribedTo.Global /// @@ -95,5 +131,14 @@ namespace CUE.NET.Devices /// /// Specifies whether all keys (including clean ones) should be updated. void Update(bool flushLeds = false); + + bool AttachLedGroup(ILedGroup ledGroup); + + /// + /// Detaches the given ledgroup. + /// + /// The ledgroup to detached. + /// true if the ledgroup could be detached; otherwise, false. + bool DetachLedGroup(ILedGroup ledGroup); } } diff --git a/Devices/Keyboard/CorsairKeyboard.cs b/Devices/Keyboard/CorsairKeyboard.cs index 1ad7ccb..a436443 100644 --- a/Devices/Keyboard/CorsairKeyboard.cs +++ b/Devices/Keyboard/CorsairKeyboard.cs @@ -15,6 +15,7 @@ using CUE.NET.Devices.Generic; using CUE.NET.Devices.Keyboard.Enums; using CUE.NET.Devices.Keyboard.Keys; using CUE.NET.Effects; +using CUE.NET.Groups; using CUE.NET.Helper; using CUE.NET.Native; @@ -23,7 +24,7 @@ namespace CUE.NET.Devices.Keyboard /// /// Represents the SDK for a corsair keyboard. /// - public class CorsairKeyboard : AbstractCueDevice, IEnumerable, IKeyGroup + public class CorsairKeyboard : AbstractCueDevice, IEnumerable { #region Properties & Fields @@ -64,7 +65,7 @@ namespace CUE.NET.Devices.Keyboard /// /// The point to get the key from. /// The key at the given point or null if no key is found. - public CorsairKey this[PointF location] => _keys.Values.FirstOrDefault(x => x.Led.LedRectangle.Contains(location)); + public new CorsairKey this[PointF location] => _keys.Values.FirstOrDefault(x => x.Led.LedRectangle.Contains(location)); /// /// Gets a list of inside the given rectangle. @@ -72,13 +73,11 @@ namespace CUE.NET.Devices.Keyboard /// The rectangle to check. /// The minimal percentage overlay a key must have with the to be taken into the list. /// - public IEnumerable this[RectangleF referenceRect, float minOverlayPercentage = 0.5f] => _keys.Values + public new IEnumerable this[RectangleF referenceRect, float minOverlayPercentage = 0.5f] => _keys.Values .Where(x => RectangleHelper.CalculateIntersectPercentage(x.Led.LedRectangle, referenceRect) >= minOverlayPercentage); #endregion - private readonly LinkedList _keyGroups = new LinkedList(); - private Dictionary _keys = new Dictionary(); /// @@ -91,22 +90,6 @@ namespace CUE.NET.Devices.Keyboard /// public CorsairKeyboardDeviceInfo KeyboardDeviceInfo { get; } - /// - /// Gets the rectangle containing all keys of the keyboard. - /// - public RectangleF KeyboardRectangle { get; } - - /// - /// Gets or sets the background brush of the keyboard. - /// - public IBrush Brush { get; set; } - - /// - /// Gets or sets the z-index of the background brush of the keyboard.
- /// This value has absolutely no effect. - ///
- public int ZIndex { get; set; } = 0; - #endregion #region Constructors @@ -119,117 +102,13 @@ namespace CUE.NET.Devices.Keyboard : base(info) { this.KeyboardDeviceInfo = info; - - InitializeKeys(); - KeyboardRectangle = RectangleHelper.CreateRectangleFromRectangles(this.Select(x => x.Led.LedRectangle)); } #endregion #region Methods - #region Update - - /// - /// Updates all brushes and groups on the keyboard. - /// - protected override void DeviceUpdate() - { - lock (_keyGroups) - { - foreach (IKeyGroup keyGroup in _keyGroups) - keyGroup.UpdateEffects(); - } - - if (Brush != null) - ApplyBrush(this.ToList(), Brush); - - lock (_keyGroups) - { - foreach (IKeyGroup keyGroup in _keyGroups.OrderBy(x => x.ZIndex)) - ApplyBrush(keyGroup.Keys.ToList(), keyGroup.Brush); - } - } - - // ReSharper disable once MemberCanBeMadeStatic.Local - idc - private void ApplyBrush(ICollection keys, IBrush brush) - { - try - { - switch (brush.BrushCalculationMode) - { - case BrushCalculationMode.Relative: - RectangleF brushRectangle = RectangleHelper.CreateRectangleFromRectangles(keys.Select(x => x.Led.LedRectangle)); - float offsetX = -brushRectangle.X; - float offsetY = -brushRectangle.Y; - brushRectangle.X = 0; - brushRectangle.Y = 0; - brush.PerformRender(brushRectangle, keys.Select(x => new BrushRenderTarget(x.KeyId, x.Led.LedRectangle.GetCenter(offsetX, offsetY)))); - break; - case BrushCalculationMode.Absolute: - brush.PerformRender(KeyboardRectangle, keys.Select(x => new BrushRenderTarget(x.KeyId, x.Led.LedRectangle.GetCenter()))); - break; - default: - throw new ArgumentException(); - } - - brush.UpdateEffects(); - brush.PerformFinalize(); - - foreach (KeyValuePair renders in brush.RenderedTargets) - _keys[renders.Key.Key].Led.Color = renders.Value; - } - // ReSharper disable once CatchAllClause - catch (Exception ex) { OnException(ex); } - } - - /// - /// Gets a list containing all LEDs of this group. - /// - /// The list containing all LEDs of this group. - public IEnumerable GetLeds() - { - return this.Select(x => x.Led); - } - - #endregion - - /// - /// Attaches the given keygroup. - /// - /// The keygroup to attach. - /// true if the keygroup could be attached; otherwise, false. - public bool AttachKeyGroup(IKeyGroup keyGroup) - { - lock (_keyGroups) - { - if (keyGroup == null || _keyGroups.Contains(keyGroup)) return false; - - _keyGroups.AddLast(keyGroup); - return true; - } - } - - /// - /// Detaches the given keygroup. - /// - /// The keygroup to detached. - /// true if the keygroup could be detached; otherwise, false. - public bool DetachKeyGroup(IKeyGroup keyGroup) - { - lock (_keyGroups) - { - if (keyGroup == null) return false; - - LinkedListNode node = _keyGroups.Find(keyGroup); - if (node == null) return false; - - _keyGroups.Remove(node); - return true; - } - } - - private void InitializeKeys() + protected override void InitializeLeds() { _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositions(), typeof(_CorsairLedPositions)); int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); @@ -237,50 +116,20 @@ namespace CUE.NET.Devices.Keyboard for (int i = 0; i < nativeLedPositions.numberOfLed; i++) { _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); - CorsairLed led = InitializeLed((int)ledPosition.ledId, new RectangleF((float)ledPosition.left, (float)ledPosition.top, (float)ledPosition.width, (float)ledPosition.height)); - _keys.Add(ledPosition.ledId, new CorsairKey(ledPosition.ledId, led)); + CorsairLed led = InitializeLed(ledPosition.ledId, new RectangleF((float)ledPosition.left, (float)ledPosition.top, (float)ledPosition.width, (float)ledPosition.height)); + _keys.Add((CorsairKeyboardKeyId)ledPosition.ledId, new CorsairKey((CorsairKeyboardKeyId)ledPosition.ledId, led)); ptr = new IntPtr(ptr.ToInt64() + structSize); } } - #region Effects - - /// - /// NOT IMPLEMENTED: Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead. - /// - public void UpdateEffects() - { - throw new NotSupportedException("Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead."); - } - - /// - /// NOT IMPLEMENTED: Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead. - /// - /// The effect to add. - public void AddEffect(IEffect effect) - { - throw new NotSupportedException("Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead."); - } - - /// - /// NOT IMPLEMENTED: Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead. - /// - /// The effect to remove. - public void RemoveEffect(IEffect effect) - { - throw new NotSupportedException("Effects can't be applied directly to the keyboard. Add it to the Brush or create a keygroup instead."); - } - - #endregion - #region IEnumerable /// /// Returns an enumerator that iterates over all keys of the keyboard. /// /// An enumerator for all keys of the keyboard. - public IEnumerator GetEnumerator() + public new IEnumerator GetEnumerator() { return _keys.Values.GetEnumerator(); } diff --git a/Devices/Keyboard/Extensions/KeyGroupExtension.cs b/Devices/Keyboard/Extensions/KeyGroupExtension.cs deleted file mode 100644 index 3114a5a..0000000 --- a/Devices/Keyboard/Extensions/KeyGroupExtension.cs +++ /dev/null @@ -1,80 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedMember.Global - -using System.Linq; -using CUE.NET.Devices.Keyboard.Enums; -using CUE.NET.Devices.Keyboard.Keys; - -namespace CUE.NET.Devices.Keyboard.Extensions -{ - /// - /// Offers some extensions and helper-methods for keygroup related things. - /// - public static class KeyGroupExtension - { - /// - /// Converts the given to a . - /// - /// The to convert. - /// The converted . - public static ListKeyGroup ToSimpleKeyGroup(this AbstractKeyGroup keyGroup) - { - ListKeyGroup simpleKeyGroup = keyGroup as ListKeyGroup; - if (simpleKeyGroup == null) - { - bool wasAttached = keyGroup.Detach(); - simpleKeyGroup = new ListKeyGroup(keyGroup.Keyboard, wasAttached, keyGroup.Keys.ToArray()) { Brush = keyGroup.Brush }; - } - return simpleKeyGroup; - } - - /// - /// Returns a new which contains all keys from the given keygroup excluding the specified ones. - /// - /// The base keygroup. - /// The ids of the keys to exclude. - /// The new . - public static ListKeyGroup Exclude(this AbstractKeyGroup keyGroup, params CorsairKeyboardKeyId[] keyIds) - { - ListKeyGroup simpleKeyGroup = keyGroup.ToSimpleKeyGroup(); - foreach (CorsairKeyboardKeyId keyId in keyIds) - simpleKeyGroup.RemoveKey(keyId); - return simpleKeyGroup; - } - - /// - /// Returns a new which contains all keys from the given keygroup excluding the specified ones. - /// - /// The base keygroup. - /// The keys to exclude. - /// The new . - public static ListKeyGroup Exclude(this AbstractKeyGroup keyGroup, params CorsairKey[] keyIds) - { - ListKeyGroup simpleKeyGroup = keyGroup.ToSimpleKeyGroup(); - foreach (CorsairKey key in keyIds) - simpleKeyGroup.RemoveKey(key); - return simpleKeyGroup; - } - - // ReSharper disable once UnusedMethodReturnValue.Global - /// - /// Attaches the given keygroup to the keyboard. - /// - /// The keygroup to attach. - /// true if the keygroup could be attached; otherwise, false. - public static bool Attach(this AbstractKeyGroup keyGroup) - { - return keyGroup.Keyboard?.AttachKeyGroup(keyGroup) ?? false; - } - - /// - /// Detaches the given keygroup from the keyboard. - /// - /// The keygroup to attach. - /// true if the keygroup could be detached; otherwise, false. - public static bool Detach(this AbstractKeyGroup keyGroup) - { - return keyGroup.Keyboard?.DetachKeyGroup(keyGroup) ?? false; - } - } -} diff --git a/Devices/Keyboard/Keys/CorsairKey.cs b/Devices/Keyboard/Keys/CorsairKey.cs index 3410fd1..34e7da4 100644 --- a/Devices/Keyboard/Keys/CorsairKey.cs +++ b/Devices/Keyboard/Keys/CorsairKey.cs @@ -1,7 +1,6 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedAutoPropertyAccessor.Global -using System.Drawing; using CUE.NET.Devices.Generic; using CUE.NET.Devices.Keyboard.Enums; @@ -40,5 +39,14 @@ namespace CUE.NET.Devices.Keyboard.Keys } #endregion + + #region Operators + + public static implicit operator CorsairLed(CorsairKey key) + { + return key.Led; + } + + #endregion } } diff --git a/Devices/Keyboard/Keys/ListKeyGroup.cs b/Devices/Keyboard/Keys/ListKeyGroup.cs deleted file mode 100644 index b5bb241..0000000 --- a/Devices/Keyboard/Keys/ListKeyGroup.cs +++ /dev/null @@ -1,248 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedMember.Global - -using System.Collections.Generic; -using CUE.NET.Devices.Keyboard.Enums; - -namespace CUE.NET.Devices.Keyboard.Keys -{ - /// - /// Represents a keygroup containing arbitrary keys. - /// - public class ListKeyGroup : AbstractKeyGroup - { - #region Properties & Fields - - protected override IKeyGroup EffectTarget => this; - - /// - /// Gets the list containing the keys of this keygroup. - /// - protected IList GroupKeys { get; } = new List(); - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// Specifies whether this keygroup should be automatically attached or not. - public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach = true) - : base(keyboard, autoAttach) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// The initial keys of this keygroup. - public ListKeyGroup(CorsairKeyboard keyboard, params CorsairKey[] keys) - : this(keyboard, true, keys) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// The initial keys of this keygroup. - public ListKeyGroup(CorsairKeyboard keyboard, IEnumerable keys) - : this(keyboard, true, keys) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// Specifies whether this keygroup should be automatically attached or not. - /// The initial keys of this keygroup. - public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach, IEnumerable keys) - : base(keyboard, autoAttach) - { - AddKeys(keys); - } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// Specifies whether this keygroup should be automatically attached or not. - /// The initial keys of this keygroup. - public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach, params CorsairKey[] keys) - : base(keyboard, autoAttach) - { - AddKeys(keys); - } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// The IDs of the initial keys of this keygroup. - public ListKeyGroup(CorsairKeyboard keyboard, params CorsairKeyboardKeyId[] keys) - : this(keyboard, true, keys) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// The IDs of the initial keys of this keygroup. - public ListKeyGroup(CorsairKeyboard keyboard, IEnumerable keys) - : this(keyboard, true, keys) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// Specifies whether this keygroup should be automatically attached or not. - /// The IDs of the initial keys of this keygroup. - public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach, params CorsairKeyboardKeyId[] keys) - : base(keyboard, autoAttach) - { - AddKeys(keys); - } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// Specifies whether this keygroup should be automatically attached or not. - /// The IDs of the initial keys of this keygroup. - public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach, IEnumerable keys) - : base(keyboard, autoAttach) - { - AddKeys(keys); - } - - #endregion - - #region Methods - - /// - /// Adds the given key(s) to the keygroup. - /// - /// The key(s) to add. - public void AddKey(params CorsairKey[] keys) - { - AddKeys(keys); - } - - /// - /// Adds the given key(s) to the keygroup. - /// - /// The ID(s) of the key(s) to add. - public void AddKey(params CorsairKeyboardKeyId[] keyIds) - { - AddKeys(keyIds); - } - - /// - /// Adds the given keys to the keygroup. - /// - /// The keys to add. - public void AddKeys(IEnumerable keys) - { - if (keys != null) - foreach (CorsairKey key in keys) - if (key != null && !ContainsKey(key)) - GroupKeys.Add(key); - } - - /// - /// Adds the given keys to the keygroup. - /// - /// The IDs of the keys to add. - public void AddKeys(IEnumerable keyIds) - { - if (keyIds != null) - foreach (CorsairKeyboardKeyId keyId in keyIds) - AddKey(Keyboard[keyId]); - } - - /// - /// Removes the given key(s) from the keygroup. - /// - /// The key(s) to remove. - public void RemoveKey(params CorsairKey[] keys) - { - RemoveKeys(keys); - } - - /// - /// Removes the given key(s) from the keygroup. - /// - /// The ID(s) of the key(s) to remove. - public void RemoveKey(params CorsairKeyboardKeyId[] keyIds) - { - RemoveKeys(keyIds); - } - - /// - /// Removes the given keys from the keygroup. - /// - /// The keys to remove. - public void RemoveKeys(IEnumerable keys) - { - if (keys != null) - foreach (CorsairKey key in keys) - if (key != null) - GroupKeys.Remove(key); - } - - /// - /// Removes the given keys from the keygroup. - /// - /// The IDs of the keys to remove. - public void RemoveKeys(IEnumerable keyIds) - { - if (keyIds != null) - foreach (CorsairKeyboardKeyId keyId in keyIds) - RemoveKey(Keyboard[keyId]); - } - - /// - /// Checks if a given key is contained by this keygroup. - /// - /// The key which should be checked. - /// true if the key is contained by this keygroup; otherwise, false. - public bool ContainsKey(CorsairKey key) - { - return key != null && GroupKeys.Contains(key); - } - - /// - /// Checks if a given key is contained by this keygroup. - /// - /// The ID of the key which should be checked. - /// true if the key is contained by this keygroup; otherwise, false. - public bool ContainsKey(CorsairKeyboardKeyId keyId) - { - return ContainsKey(Keyboard[keyId]); - } - - /// - /// Merges the keys from the given keygroup in this keygroup. - /// - /// The keygroup to merge. - public void MergeKeys(IKeyGroup groupToMerge) - { - foreach (CorsairKey key in groupToMerge.Keys) - if (!GroupKeys.Contains(key)) - GroupKeys.Add(key); - } - - /// - /// Gets a list containing the keys from this group. - /// - /// The list containing the keys. - protected override IList GetGroupKeys() - { - return GroupKeys; - } - - #endregion - } -} diff --git a/Devices/Keyboard/Keys/RectangleKeyGroup.cs b/Devices/Keyboard/Keys/RectangleKeyGroup.cs deleted file mode 100644 index 45015ba..0000000 --- a/Devices/Keyboard/Keys/RectangleKeyGroup.cs +++ /dev/null @@ -1,112 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -// ReSharper disable UnusedMember.Global - -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using CUE.NET.Devices.Keyboard.Enums; -using CUE.NET.Helper; - -namespace CUE.NET.Devices.Keyboard.Keys -{ - /// - /// Represents a keygroup containing keys which physically lay inside a rectangle. - /// - public class RectangleKeyGroup : AbstractKeyGroup - { - #region Properties & Fields - - protected override IKeyGroup EffectTarget => this; - - private IList _keyCache; - - private RectangleF _rectangle; - /// - /// Gets or sets the rectangle the keys should be taken from. - /// - public RectangleF Rectangle - { - get { return _rectangle; } - set - { - _rectangle = value; - _keyCache = null; - } - } - - /// - /// Gets or sets the minimal percentage overlay a key must have with the to be taken into the keygroup. - /// - public float MinOverlayPercentage { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// They ID of the first key to calculate the rectangle of this keygroup from. - /// They ID of the second key to calculate the rectangle of this keygroup from. - /// (optional) The minimal percentage overlay a key must have with the to be taken into the keygroup. (default: 0.5f) - /// (optional) Specifies whether this group should be automatically attached or not. (default: true) - public RectangleKeyGroup(CorsairKeyboard keyboard, CorsairKeyboardKeyId fromKey, CorsairKeyboardKeyId toKey, float minOverlayPercentage = 0.5f, bool autoAttach = true) - : this(keyboard, keyboard[fromKey], keyboard[toKey], minOverlayPercentage, autoAttach) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// They first key to calculate the rectangle of this keygroup from. - /// They second key to calculate the rectangle of this keygroup from. - /// (optional) The minimal percentage overlay a key must have with the to be taken into the keygroup. (default: 0.5f) - /// (optional) Specifies whether this group should be automatically attached or not. (default: true) - public RectangleKeyGroup(CorsairKeyboard keyboard, CorsairKey fromKey, CorsairKey toKey, float minOverlayPercentage = 0.5f, bool autoAttach = true) - : this(keyboard, RectangleHelper.CreateRectangleFromRectangles(fromKey.Led.LedRectangle, toKey.Led.LedRectangle), minOverlayPercentage, autoAttach) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// They first point to calculate the rectangle of this keygroup from. - /// They second point to calculate the rectangle of this keygroup from. - /// (optional) The minimal percentage overlay a key must have with the to be taken into the keygroup. (default: 0.5f) - /// (optional) Specifies whether this group should be automatically attached or not. (default: true) - public RectangleKeyGroup(CorsairKeyboard keyboard, PointF fromPoint, PointF toPoint, float minOverlayPercentage = 0.5f, bool autoAttach = true) - : this(keyboard, RectangleHelper.CreateRectangleFromPoints(fromPoint, toPoint), minOverlayPercentage, autoAttach) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The keyboard this keygroup belongs to. - /// The rectangle of this keygroup. - /// (optional) The minimal percentage overlay a key must have with the to be taken into the keygroup. (default: 0.5f) - /// (optional) Specifies whether this group should be automatically attached or not. (default: true) - public RectangleKeyGroup(CorsairKeyboard keyboard, RectangleF rectangle, float minOverlayPercentage = 0.5f, bool autoAttach = true) - : base(keyboard, autoAttach) - { - this.Rectangle = rectangle; - this.MinOverlayPercentage = minOverlayPercentage; - } - - #endregion - - #region Methods - - /// - /// Gets a list containing the keys from this group. - /// - /// The list containing the keys. - protected override IList GetGroupKeys() - { - return _keyCache ?? (_keyCache = Keyboard.Where(x => RectangleHelper.CalculateIntersectPercentage(x.Led.LedRectangle, Rectangle) >= MinOverlayPercentage).ToList()); - } - - #endregion - } -} diff --git a/Devices/Mouse/CorsairMouse.cs b/Devices/Mouse/CorsairMouse.cs index 46501b6..b48283f 100644 --- a/Devices/Mouse/CorsairMouse.cs +++ b/Devices/Mouse/CorsairMouse.cs @@ -2,12 +2,9 @@ // ReSharper disable UnusedAutoPropertyAccessor.Global // ReSharper disable UnusedMember.Global -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Drawing; -using System.Linq; using CUE.NET.Devices.Generic; +using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Mouse.Enums; using CUE.NET.Exceptions; @@ -16,38 +13,15 @@ namespace CUE.NET.Devices.Mouse /// /// Represents the SDK for a corsair mouse. /// - public class CorsairMouse : AbstractCueDevice, IEnumerable + public class CorsairMouse : AbstractCueDevice { #region Properties & Fields - #region Indexer - - /// - /// Gets the with the specified ID. - /// - /// The ID of the LED to get. - /// The LED with the specified ID. - public CorsairLed this[CorsairMouseLedId ledId] - { - get - { - CorsairLed led; - return base.Leds.TryGetValue((int)ledId, out led) ? led : null; - } - } - - #endregion - /// /// Gets specific information provided by CUE for the mouse. /// public CorsairMouseDeviceInfo MouseDeviceInfo { get; } - /// - /// Gets a read-only collection containing all LEDs of the mouse. - /// - public new IEnumerable Leds => new ReadOnlyCollection(base.Leds.Values.ToList()); - #endregion #region Constructors @@ -60,64 +34,39 @@ namespace CUE.NET.Devices.Mouse : base(info) { this.MouseDeviceInfo = info; - - InitializeLeds(); } #endregion #region Methods - private void InitializeLeds() + protected override void InitializeLeds() { switch (MouseDeviceInfo.PhysicalLayout) { case CorsairPhysicalMouseLayout.Zones1: - InitializeLed((int)CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); break; case CorsairPhysicalMouseLayout.Zones2: - InitializeLed((int)CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); - InitializeLed((int)CorsairMouseLedId.B2, new RectangleF(1, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B2, new RectangleF(1, 0, 1, 1)); break; case CorsairPhysicalMouseLayout.Zones3: - InitializeLed((int)CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); - InitializeLed((int)CorsairMouseLedId.B2, new RectangleF(1, 0, 1, 1)); - InitializeLed((int)CorsairMouseLedId.B3, new RectangleF(2, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B2, new RectangleF(1, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B3, new RectangleF(2, 0, 1, 1)); break; case CorsairPhysicalMouseLayout.Zones4: - InitializeLed((int)CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); - InitializeLed((int)CorsairMouseLedId.B2, new RectangleF(1, 0, 1, 1)); - InitializeLed((int)CorsairMouseLedId.B3, new RectangleF(2, 0, 1, 1)); - InitializeLed((int)CorsairMouseLedId.B4, new RectangleF(3, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B2, new RectangleF(1, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B3, new RectangleF(2, 0, 1, 1)); + InitializeLed((CorsairLedId)CorsairMouseLedId.B4, new RectangleF(3, 0, 1, 1)); break; default: throw new WrapperException($"Can't initial mouse with layout '{MouseDeviceInfo.PhysicalLayout}'"); } } - protected override void DeviceUpdate() - { - //DarthAffe 21.08.2016: Mice can't own brushes or groups - nothing to do here for now - } - - #region IEnumerable - - /// - /// Returns an enumerator that iterates over all LEDs of the mouse. - /// - /// An enumerator for all LDS of the mouse. - public IEnumerator GetEnumerator() - { - return Leds.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - #endregion } } diff --git a/Devices/Mousemat/CorsairMousemat.cs b/Devices/Mousemat/CorsairMousemat.cs index cf538ad..8d4c1f7 100644 --- a/Devices/Mousemat/CorsairMousemat.cs +++ b/Devices/Mousemat/CorsairMousemat.cs @@ -11,7 +11,6 @@ using System.Linq; using System.Runtime.InteropServices; using CUE.NET.Devices.Generic; using CUE.NET.Devices.Generic.Enums; -using CUE.NET.Devices.Mousemat.Enums; using CUE.NET.Exceptions; using CUE.NET.Native; @@ -20,38 +19,15 @@ namespace CUE.NET.Devices.Mousemat /// /// Represents the SDK for a corsair mousemat. /// - public class CorsairMousemat : AbstractCueDevice, IEnumerable + public class CorsairMousemat : AbstractCueDevice { #region Properties & Fields - #region Indexer - - /// - /// Gets the with the specified ID. - /// - /// The ID of the LED to get. - /// The LED with the specified ID. - public CorsairLed this[CorsairMousematLedId ledId] - { - get - { - CorsairLed led; - return base.Leds.TryGetValue((int)ledId, out led) ? led : null; - } - } - - #endregion - /// /// Gets specific information provided by CUE for the mousemat. /// public CorsairMousematDeviceInfo MousematDeviceInfo { get; } - /// - /// Gets a read-only collection containing all LEDs of the mousemat. - /// - public new IEnumerable Leds => new ReadOnlyCollection(base.Leds.Values.ToList()); - #endregion #region Constructors @@ -64,14 +40,13 @@ namespace CUE.NET.Devices.Mousemat : base(info) { this.MousematDeviceInfo = info; - InitializeLeds(); } #endregion #region Methods - private void InitializeLeds() + protected override void InitializeLeds() { int deviceCount = _CUESDK.CorsairGetDeviceCount(); @@ -105,32 +80,9 @@ namespace CUE.NET.Devices.Mousemat // Sort for easy iteration by clients foreach (_CorsairLedPosition ledPosition in positions.OrderBy(p => p.ledId)) - InitializeLed((int)ledPosition.ledId, new RectangleF((float)ledPosition.left, (float)ledPosition.top, (float)ledPosition.width, (float)ledPosition.height)); + InitializeLed(ledPosition.ledId, new RectangleF((float)ledPosition.left, (float)ledPosition.top, (float)ledPosition.width, (float)ledPosition.height)); } - protected override void DeviceUpdate() - { - //TODO DarthAffe 10.09.2016: Implement - } - - #region IEnumerable - - /// - /// Returns an enumerator that iterates over all LEDs of the mousemat. - /// - /// An enumerator for all LEDS of the mousemat. - public IEnumerator GetEnumerator() - { - return Leds.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - #endregion } -} \ No newline at end of file +} diff --git a/Effects/AbstractKeyGroupEffect.cs b/Effects/AbstractKeyGroupEffect.cs index c1526fb..e81baeb 100644 --- a/Effects/AbstractKeyGroupEffect.cs +++ b/Effects/AbstractKeyGroupEffect.cs @@ -2,13 +2,14 @@ // ReSharper disable UnusedAutoPropertyAccessor.Global using CUE.NET.Devices.Keyboard.Keys; +using CUE.NET.Groups; namespace CUE.NET.Effects { /// - /// Represents a basic effect targeting an . + /// Represents a basic effect targeting an . /// - public abstract class AbstractKeyGroupEffect : IEffect + public abstract class AbstractKeyGroupEffect : IEffect { #region Properties & Fields @@ -18,9 +19,9 @@ namespace CUE.NET.Effects public bool IsDone { get; protected set; } /// - /// Gets the this effect is targeting. + /// Gets the this effect is targeting. /// - protected IKeyGroup KeyGroup { get; private set; } + protected ILedGroup LedGroup { get; private set; } #endregion @@ -35,19 +36,19 @@ namespace CUE.NET.Effects /// /// Hook which is called when the effect is attached to a device. /// - /// The this effect is attached to. - public virtual void OnAttach(IKeyGroup target) + /// The this effect is attached to. + public virtual void OnAttach(ILedGroup target) { - KeyGroup = target; + LedGroup = target; } /// /// Hook which is called when the effect is detached from a device. /// - /// The this effect is detached from. - public virtual void OnDetach(IKeyGroup target) + /// The this effect is detached from. + public virtual void OnDetach(ILedGroup target) { - KeyGroup = null; + LedGroup = null; } #endregion diff --git a/Examples/AudioAnalyzer/Example_AudioAnalyzer_full/AudioAnalyzerExample.cs b/Examples/AudioAnalyzer/Example_AudioAnalyzer_full/AudioAnalyzerExample.cs index 2c4ca16..6d3fa65 100644 --- a/Examples/AudioAnalyzer/Example_AudioAnalyzer_full/AudioAnalyzerExample.cs +++ b/Examples/AudioAnalyzer/Example_AudioAnalyzer_full/AudioAnalyzerExample.cs @@ -8,6 +8,7 @@ using CUE.NET.Devices.Keyboard; using CUE.NET.Devices.Keyboard.Keys; using CUE.NET.Exceptions; using CUE.NET.Gradients; +using CUE.NET.Groups; using Example_AudioAnalyzer_full.TakeAsIs; namespace Example_AudioAnalyzer_full @@ -67,12 +68,12 @@ namespace Example_AudioAnalyzer_full // Note that this isn't a 'real effect' since it's update-rate dependent. A real effect would do always the same thing not mather how fast the keyboard updates. _keyboard.Brush = new SolidColorBrush(Color.FromArgb(96, 0, 0, 0)); // Add our song-beat-effect. Remember to uncomment the update in the spectrum effect if you want to remove this. - ListKeyGroup songBeatGroup = new ListKeyGroup(_keyboard, _keyboard); + ListLedGroup songBeatGroup = new ListLedGroup(_keyboard, _keyboard); songBeatGroup.Brush = new SolidColorBrush(Color.FromArgb(127, 164, 164, 164)); songBeatGroup.Brush.AddEffect(new SongBeatEffect(_soundDataProcessor)); // Add our spectrum-effect using the soundDataProcessor and a rainbow from purple to red as gradient - ListKeyGroup spectrumGroup = new ListKeyGroup(_keyboard, _keyboard); + ListLedGroup spectrumGroup = new ListLedGroup(_keyboard, _keyboard); spectrumGroup.Brush = new AudioSpectrumBrush(_soundDataProcessor, new RainbowGradient(300, -14)); // Hook onto the keyboard update and process data diff --git a/Examples/SimpleDevTest/Program.cs b/Examples/SimpleDevTest/Program.cs index 0372433..3e256b2 100644 --- a/Examples/SimpleDevTest/Program.cs +++ b/Examples/SimpleDevTest/Program.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Drawing; using System.Linq; using System.Threading; @@ -10,13 +9,11 @@ using CUE.NET.Brushes; using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Keyboard; using CUE.NET.Devices.Keyboard.Enums; -using CUE.NET.Devices.Keyboard.Extensions; -using CUE.NET.Devices.Keyboard.Keys; using CUE.NET.Devices.Mousemat; using CUE.NET.Devices.Mousemat.Enums; using CUE.NET.Exceptions; using CUE.NET.Gradients; -using CUE.NET.Profiles; +using CUE.NET.Groups; namespace SimpleDevTest { @@ -53,9 +50,9 @@ namespace SimpleDevTest keyboard.UpdateMode = UpdateMode.Continuous; keyboard.Brush = new SolidColorBrush(Color.Black); - RectangleF spot = new RectangleF(keyboard.KeyboardRectangle.Width / 2f, keyboard.KeyboardRectangle.Y / 2f, 160, 80); + RectangleF spot = new RectangleF(keyboard.DeviceRectangle.Width / 2f, keyboard.DeviceRectangle.Y / 2f, 160, 80); PointF target = new PointF(spot.X, spot.Y); - RectangleKeyGroup spotGroup = new RectangleKeyGroup(keyboard, spot) { Brush = new LinearGradientBrush(new RainbowGradient()) }; + RectangleLedGroup spotGroup = new RectangleLedGroup(keyboard, spot) { Brush = new LinearGradientBrush(new RainbowGradient()) }; float brushModeTimer = BRUSH_MODE_CHANGE_TIMER; keyboard.Updating += (sender, eventArgs) => @@ -69,8 +66,8 @@ namespace SimpleDevTest } if (spot.Contains(target)) - target = new PointF((float)(keyboard.KeyboardRectangle.X + (random.NextDouble() * keyboard.KeyboardRectangle.Width)), - (float)(keyboard.KeyboardRectangle.Y + (random.NextDouble() * keyboard.KeyboardRectangle.Height))); + target = new PointF((float)(keyboard.DeviceRectangle.X + (random.NextDouble() * keyboard.DeviceRectangle.Width)), + (float)(keyboard.DeviceRectangle.Y + (random.NextDouble() * keyboard.DeviceRectangle.Height))); else spot.Location = Interpolate(spot.Location, target, eventArgs.DeltaTime * SPEED); spotGroup.Rectangle = spot; @@ -80,23 +77,23 @@ namespace SimpleDevTest mousemat.UpdateMode = UpdateMode.Continuous; // Left - mousemat[CorsairMousematLedId.Zone1].Color = Color.Red; - mousemat[CorsairMousematLedId.Zone2].Color = Color.Red; - mousemat[CorsairMousematLedId.Zone3].Color = Color.Red; - mousemat[CorsairMousematLedId.Zone4].Color = Color.Red; - mousemat[CorsairMousematLedId.Zone5].Color = Color.Red; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone1].Color = Color.Red; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone2].Color = Color.Red; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone3].Color = Color.Red; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone4].Color = Color.Red; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone5].Color = Color.Red; // Bottom - mousemat[CorsairMousematLedId.Zone6].Color = Color.LawnGreen; - mousemat[CorsairMousematLedId.Zone7].Color = Color.LawnGreen; - mousemat[CorsairMousematLedId.Zone8].Color = Color.LawnGreen; - mousemat[CorsairMousematLedId.Zone9].Color = Color.LawnGreen; - mousemat[CorsairMousematLedId.Zone10].Color = Color.LawnGreen; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone6].Color = Color.LawnGreen; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone7].Color = Color.LawnGreen; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone8].Color = Color.LawnGreen; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone9].Color = Color.LawnGreen; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone10].Color = Color.LawnGreen; // Right - mousemat[CorsairMousematLedId.Zone11].Color = Color.Blue; - mousemat[CorsairMousematLedId.Zone12].Color = Color.Blue; - mousemat[CorsairMousematLedId.Zone13].Color = Color.Blue; - mousemat[CorsairMousematLedId.Zone14].Color = Color.Blue; - mousemat[CorsairMousematLedId.Zone15].Color = Color.Blue; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone11].Color = Color.Blue; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone12].Color = Color.Blue; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone13].Color = Color.Blue; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone14].Color = Color.Blue; + mousemat[(CorsairLedId)CorsairMousematLedId.Zone15].Color = Color.Blue; // Random colors to show update rate //foreach (var mousematLed in mousemat.Leds) @@ -111,7 +108,7 @@ namespace SimpleDevTest //}; //keyboard.Brush = new SolidColorBrush(Color.Black); - //IKeyGroup group = new RectangleKeyGroup(keyboard, CorsairKeyboardKeyId.F1, CorsairKeyboardKeyId.RightShift); + //ILedGroup group = new RectangleLedGroup(keyboard, CorsairKeyboardKeyId.F1, CorsairKeyboardKeyId.RightShift); //group.Brush = new LinearGradientBrush(new RainbowGradient()); //bool tmp = false; //while (true) @@ -126,7 +123,7 @@ namespace SimpleDevTest //keyboard.Brush = new SolidColorBrush(Color.Aqua); //keyboard.Update(); - //IKeyGroup specialKeyGroup = new ListKeyGroup(keyboard, CorsairKeyboardKeyId.Brightness, CorsairKeyboardKeyId.WinLock); + //ILedGroup specialKeyGroup = new ListLedGroup(keyboard, CorsairKeyboardKeyId.Brightness, CorsairKeyboardKeyId.WinLock); //specialKeyGroup.Brush = new SolidColorBrush(Color.Aqua); //keyboard.Update(); @@ -155,13 +152,13 @@ namespace SimpleDevTest //Wait(3); - //ListKeyGroup keyGroup = new ListKeyGroup(keyboard, keyboard['R'].KeyId); - //keyGroup.Brush = new SolidColorBrush(Color.White); + //ListLedGroup ledGroup = new ListLedGroup(keyboard, keyboard['R'].KeyId); + //ledGroup.Brush = new SolidColorBrush(Color.White); //keyboard.Update(); //Wait(2); - //keyGroup.RemoveKey(keyboard['R'].KeyId); + //ledGroup.RemoveKey(keyboard['R'].KeyId); //keyboard['R'].Led.Color = Color.Black; - //keyGroup.AddKey(keyboard['T'].KeyId); + //ledGroup.AddKey(keyboard['T'].KeyId); //keyboard.Update(); //Wait(10); @@ -173,7 +170,7 @@ namespace SimpleDevTest //Console.WriteLine("Basic color-test ..."); //// Ink all numbers on the keypad except the '5' purple, we want that to be gray - //ListKeyGroup purpleGroup = new RectangleKeyGroup(keyboard, CorsairKeyboardKeyId.Keypad7, CorsairKeyboardKeyId.Keypad3) + //ListLedGroup purpleGroup = new RectangleLedGroup(keyboard, CorsairKeyboardKeyId.Keypad7, CorsairKeyboardKeyId.Keypad3) //{ Brush = new SolidColorBrush(Color.Purple) } //.Exclude(CorsairKeyboardKeyId.Keypad5); //keyboard[CorsairKeyboardKeyId.Keypad5].Led.Color = Color.Gray; @@ -190,11 +187,11 @@ namespace SimpleDevTest ////keyboard['B'].Led.IsLocked = true; //// Ink the letters of 'white' white - //ListKeyGroup whiteGroup = new ListKeyGroup(keyboard, CorsairKeyboardKeyId.W, CorsairKeyboardKeyId.H, CorsairKeyboardKeyId.I, CorsairKeyboardKeyId.T, CorsairKeyboardKeyId.E) + //ListLedGroup whiteGroup = new ListLedGroup(keyboard, CorsairKeyboardKeyId.W, CorsairKeyboardKeyId.H, CorsairKeyboardKeyId.I, CorsairKeyboardKeyId.T, CorsairKeyboardKeyId.E) //{ Brush = new SolidColorBrush(Color.White) }; //// Ink the keys '1' to '0' yellow - //RectangleKeyGroup yellowGroup = new RectangleKeyGroup(keyboard, CorsairKeyboardKeyId.D1, CorsairKeyboardKeyId.D0) + //RectangleLedGroup yellowGroup = new RectangleLedGroup(keyboard, CorsairKeyboardKeyId.D1, CorsairKeyboardKeyId.D0) //{ Brush = new SolidColorBrush(Color.Yellow) }; //// Update the keyboard to show the configured colors, (your CUE settings defines the rest) @@ -306,7 +303,7 @@ namespace SimpleDevTest //RectangleF[] points = new RectangleF[NUM_POINTS]; //// KeyGroups which represents our point on the keyboard - //RectangleKeyGroup[] pointGroups = new RectangleKeyGroup[NUM_POINTS]; + //RectangleLedGroup[] pointGroups = new RectangleLedGroup[NUM_POINTS]; //// Target of our movement //PointF[] targets = new PointF[NUM_POINTS]; @@ -316,7 +313,7 @@ namespace SimpleDevTest //{ // // Spawn our point in the top-left corner (right over G1 or on ESC depending on your keyboard) // points[i] = new RectangleF(keyboard.KeyboardRectangle.X, keyboard.KeyboardRectangle.Y, 60, 60); - // pointGroups[i] = new RectangleKeyGroup(keyboard, points[i], 0.1f) { Brush = new SolidColorBrush(Color.White) }; + // pointGroups[i] = new RectangleLedGroup(keyboard, points[i], 0.1f) { Brush = new SolidColorBrush(Color.White) }; // targets[i] = new PointF(points[i].X, points[i].Y); //} diff --git a/Devices/Keyboard/Keys/AbstractKeyGroup.cs b/Groups/AbstractLedGroup.cs similarity index 52% rename from Devices/Keyboard/Keys/AbstractKeyGroup.cs rename to Groups/AbstractLedGroup.cs index 51927ca..6ce4091 100644 --- a/Devices/Keyboard/Keys/AbstractKeyGroup.cs +++ b/Groups/AbstractLedGroup.cs @@ -1,29 +1,28 @@ using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using CUE.NET.Brushes; +using CUE.NET.Devices; using CUE.NET.Devices.Generic; -using CUE.NET.Devices.Keyboard.Extensions; using CUE.NET.Effects; +using CUE.NET.Groups.Extensions; -namespace CUE.NET.Devices.Keyboard.Keys +namespace CUE.NET.Groups { /// /// Represents a basic keygroup. /// - public abstract class AbstractKeyGroup : AbstractEffectTarget, IKeyGroup + public abstract class AbstractLedGroup : AbstractEffectTarget, ILedGroup { #region Properties & Fields /// - /// Gets the keyboard this keygroup belongs to. + /// Gets the strongly-typed target used for the effect. /// - internal CorsairKeyboard Keyboard { get; } + protected override ILedGroup EffectTarget => this; /// - /// Gets a read-only collection containing the keys from this group. + /// Gets the device this ledgroup belongs to. /// - public IEnumerable Keys => new ReadOnlyCollection(GetGroupKeys()); + public ICueDevice Device { get; } /// /// Gets or sets the brush which should be drawn over this group. @@ -40,13 +39,13 @@ namespace CUE.NET.Devices.Keyboard.Keys #region Constructors /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The keyboard this keygroup belongs to. + /// The device this ledgroup belongs to. /// Specifies whether this group should be automatically attached or not. - protected AbstractKeyGroup(CorsairKeyboard keyboard, bool autoAttach = true) + protected AbstractLedGroup(ICueDevice device, bool autoAttach = true) { - this.Keyboard = keyboard; + this.Device = device; if (autoAttach) this.Attach(); @@ -56,16 +55,11 @@ namespace CUE.NET.Devices.Keyboard.Keys #region Methods - public IEnumerable GetLeds() - { - return GetGroupKeys().Select(x => x.Led); - } - /// - /// Gets a list containing the keys from this group. + /// Gets a list containing all LEDs of this group. /// - /// The list containing the keys. - protected abstract IList GetGroupKeys(); + /// The list containing all LEDs of this group. + public abstract IEnumerable GetLeds(); #endregion } diff --git a/Groups/Extensions/LedGroupExtension.cs b/Groups/Extensions/LedGroupExtension.cs new file mode 100644 index 0000000..56c3667 --- /dev/null +++ b/Groups/Extensions/LedGroupExtension.cs @@ -0,0 +1,79 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using CUE.NET.Devices.Generic; +using CUE.NET.Devices.Generic.Enums; + +namespace CUE.NET.Groups.Extensions +{ + /// + /// Offers some extensions and helper-methods for ledgroup related things. + /// + public static class LedGroupExtension + { + /// + /// Converts the given to a . + /// + /// The to convert. + /// The converted . + public static ListLedGroup ToSimpleKeyGroup(this AbstractLedGroup ledGroup) + { + ListLedGroup simpleLedGroup = ledGroup as ListLedGroup; + if (simpleLedGroup == null) + { + bool wasAttached = ledGroup.Detach(); + simpleLedGroup = new ListLedGroup(ledGroup.Device, wasAttached, ledGroup.GetLeds()) { Brush = ledGroup.Brush }; + } + return simpleLedGroup; + } + + /// + /// Returns a new which contains all LEDs from the given ledgroup excluding the specified ones. + /// + /// The base ledgroup. + /// The ids of the LEDs to exclude. + /// The new . + public static ListLedGroup Exclude(this AbstractLedGroup ledGroup, params CorsairLedId[] ledIds) + { + ListLedGroup simpleLedGroup = ledGroup.ToSimpleKeyGroup(); + foreach (CorsairLedId ledId in ledIds) + simpleLedGroup.RemoveLed(ledId); + return simpleLedGroup; + } + + /// + /// Returns a new which contains all LEDs from the given ledgroup excluding the specified ones. + /// + /// The base ledgroup. + /// The LEDs to exclude. + /// The new . + public static ListLedGroup Exclude(this AbstractLedGroup ledGroup, params CorsairLed[] ledIds) + { + ListLedGroup simpleLedGroup = ledGroup.ToSimpleKeyGroup(); + foreach (CorsairLed led in ledIds) + simpleLedGroup.RemoveLed(led); + return simpleLedGroup; + } + + // ReSharper disable once UnusedMethodReturnValue.Global + /// + /// Attaches the given ledgroup to the device. + /// + /// The ledgroup to attach. + /// true if the ledgroup could be attached; otherwise, false. + public static bool Attach(this AbstractLedGroup ledGroup) + { + return ledGroup.Device?.AttachLedGroup(ledGroup) ?? false; + } + + /// + /// Detaches the given ledgroup from the device. + /// + /// The ledgroup to attach. + /// true if the ledgroup could be detached; otherwise, false. + public static bool Detach(this AbstractLedGroup ledGroup) + { + return ledGroup.Device?.DetachLedGroup(ledGroup) ?? false; + } + } +} diff --git a/Devices/Keyboard/Keys/IKeyGroup.cs b/Groups/ILedGroup.cs similarity index 74% rename from Devices/Keyboard/Keys/IKeyGroup.cs rename to Groups/ILedGroup.cs index 0f60529..27d3528 100644 --- a/Devices/Keyboard/Keys/IKeyGroup.cs +++ b/Groups/ILedGroup.cs @@ -6,15 +6,10 @@ using CUE.NET.Brushes; using CUE.NET.Devices.Generic; using CUE.NET.Effects; -namespace CUE.NET.Devices.Keyboard.Keys +namespace CUE.NET.Groups { - public interface IKeyGroup : IEffectTarget + public interface ILedGroup : IEffectTarget { - /// - /// Gets a read-only collection containing the keys from this group. - /// - IEnumerable Keys { get; } - /// /// Gets or sets the brush which should be drawn over this group. /// diff --git a/Groups/ListLedGroup.cs b/Groups/ListLedGroup.cs new file mode 100644 index 0000000..1160dee --- /dev/null +++ b/Groups/ListLedGroup.cs @@ -0,0 +1,250 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using System.Collections.Generic; +using CUE.NET.Devices; +using CUE.NET.Devices.Generic; +using CUE.NET.Devices.Generic.Enums; + +namespace CUE.NET.Groups +{ + /// + /// Represents a ledgroup containing arbitrary LEDs. + /// + public class ListLedGroup : AbstractLedGroup + { + #region Properties & Fields + + protected override ILedGroup EffectTarget => this; + + /// + /// Gets the list containing the LEDs of this ledgroup. + /// + protected IList GroupLeds { get; } = new List(); + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// Specifies whether this ledgroup should be automatically attached or not. + public ListLedGroup(ICueDevice device, bool autoAttach = true) + : base(device, autoAttach) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// The initial LEDs of this ledgroup. + public ListLedGroup(ICueDevice device, params CorsairLed[] leds) + : this(device, true, leds) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// The initial LEDs of this ledgroup. + public ListLedGroup(ICueDevice device, IEnumerable leds) + : this(device, true, leds) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// Specifies whether this ledgroup should be automatically attached or not. + /// The initial LEDs of this ledgroup. + public ListLedGroup(ICueDevice device, bool autoAttach, IEnumerable leds) + : base(device, autoAttach) + { + AddLeds(leds); + } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// Specifies whether this ledgroup should be automatically attached or not. + /// The initial LEDs of this ledgroup. + public ListLedGroup(ICueDevice device, bool autoAttach, params CorsairLed[] leds) + : base(device, autoAttach) + { + AddLeds(leds); + } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// The IDs of the initial LEDs of this ledgroup. + public ListLedGroup(ICueDevice device, params CorsairLedId[] leds) + : this(device, true, leds) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// The IDs of the initial LEDs of this ledgroup. + public ListLedGroup(ICueDevice device, IEnumerable leds) + : this(device, true, leds) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// Specifies whether this ledgroup should be automatically attached or not. + /// The IDs of the initial LEDs of this ledgroup. + public ListLedGroup(ICueDevice device, bool autoAttach, params CorsairLedId[] leds) + : base(device, autoAttach) + { + AddLeds(leds); + } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// Specifies whether this ledgroup should be automatically attached or not. + /// The IDs of the initial LEDs of this ledgroup. + public ListLedGroup(ICueDevice device, bool autoAttach, IEnumerable leds) + : base(device, autoAttach) + { + AddLeds(leds); + } + + #endregion + + #region Methods + + /// + /// Adds the given LED(s) to the ledgroup. + /// + /// The LED(s) to add. + public void AddLed(params CorsairLed[] LEDs) + { + AddLeds(LEDs); + } + + /// + /// Adds the given LED(s) to the ledgroup. + /// + /// The ID(s) of the LED(s) to add. + public void AddLed(params CorsairLedId[] ledIds) + { + AddLeds(ledIds); + } + + /// + /// Adds the given LEDs to the ledgroup. + /// + /// The LEDs to add. + public void AddLeds(IEnumerable leds) + { + if (leds != null) + foreach (CorsairLed led in leds) + if (led != null && !ContainsLed(led)) + GroupLeds.Add(led); + } + + /// + /// Adds the given LEDs to the ledgroup. + /// + /// The IDs of the LEDs to add. + public void AddLeds(IEnumerable ledIds) + { + if (ledIds != null) + foreach (CorsairLedId ledId in ledIds) + AddLed(Device[ledId]); + } + + /// + /// Removes the given LED(s) from the ledgroup. + /// + /// The LED(s) to remove. + public void RemoveLed(params CorsairLed[] leds) + { + RemoveLeds(leds); + } + + /// + /// Removes the given LED(s) from the ledgroup. + /// + /// The ID(s) of the LED(s) to remove. + public void RemoveLed(params CorsairLedId[] ledIds) + { + RemoveLeds(ledIds); + } + + /// + /// Removes the given LEDs from the ledgroup. + /// + /// The LEDs to remove. + public void RemoveLeds(IEnumerable leds) + { + if (leds != null) + foreach (CorsairLed led in leds) + if (led != null) + GroupLeds.Remove(led); + } + + /// + /// Removes the given LEDs from the ledgroup. + /// + /// The IDs of the LEDs to remove. + public void RemoveLeds(IEnumerable ledIds) + { + if (ledIds != null) + foreach (CorsairLedId ledId in ledIds) + RemoveLed(Device[ledId]); + } + + /// + /// Checks if a given LED is contained by this ledgroup. + /// + /// The LED which should be checked. + /// true if the LED is contained by this ledgroup; otherwise, false. + public bool ContainsLed(CorsairLed led) + { + return led != null && GroupLeds.Contains(led); + } + + /// + /// Checks if a given LED is contained by this ledgroup. + /// + /// The ID of the LED which should be checked. + /// true if the LED is contained by this ledgroup; otherwise, false. + public bool ContainsLed(CorsairLedId ledId) + { + return ContainsLed(Device[ledId]); + } + + /// + /// Merges the LEDs from the given ledgroup in this ledgroup. + /// + /// The ledgroup to merge. + public void MergeLeds(ILedGroup groupToMerge) + { + foreach (CorsairLed led in groupToMerge.GetLeds()) + if (!GroupLeds.Contains(led)) + GroupLeds.Add(led); + } + + /// + /// Gets a list containing the LEDs from this group. + /// + /// The list containing the LEDs. + public override IEnumerable GetLeds() + { + return GroupLeds; + } + + #endregion + } +} diff --git a/Groups/RectangleLedGroup.cs b/Groups/RectangleLedGroup.cs new file mode 100644 index 0000000..624cdd2 --- /dev/null +++ b/Groups/RectangleLedGroup.cs @@ -0,0 +1,108 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable UnusedMember.Global + +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using CUE.NET.Devices; +using CUE.NET.Devices.Generic; +using CUE.NET.Devices.Generic.Enums; +using CUE.NET.Helper; + +namespace CUE.NET.Groups +{ + /// + /// Represents a ledgroup containing LEDs which physically lay inside a rectangle. + /// + public class RectangleLedGroup : AbstractLedGroup + { + #region Properties & Fields + + private IList _ledCache; + + private RectangleF _rectangle; + /// + /// Gets or sets the rectangle the LEDs should be taken from. + /// + public RectangleF Rectangle + { + get { return _rectangle; } + set + { + _rectangle = value; + _ledCache = null; + } + } + + /// + /// Gets or sets the minimal percentage overlay a LED must have with the to be taken into the ledgroup. + /// + public float MinOverlayPercentage { get; set; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// They ID of the first LED to calculate the rectangle of this ledgroup from. + /// They ID of the second LED to calculate the rectangle of this ledgroup from. + /// (optional) The minimal percentage overlay a LED must have with the to be taken into the ledgroup. (default: 0.5f) + /// (optional) Specifies whether this group should be automatically attached or not. (default: true) + public RectangleLedGroup(ICueDevice device, CorsairLedId fromLed, CorsairLedId toLed, float minOverlayPercentage = 0.5f, bool autoAttach = true) + : this(device, device[fromLed], device[toLed], minOverlayPercentage, autoAttach) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// They first LED to calculate the rectangle of this ledgroup from. + /// They second LED to calculate the rectangle of this ledgroup from. + /// (optional) The minimal percentage overlay a LED must have with the to be taken into the ledgroup. (default: 0.5f) + /// (optional) Specifies whether this group should be automatically attached or not. (default: true) + public RectangleLedGroup(ICueDevice device, CorsairLed fromLed, CorsairLed toLed, float minOverlayPercentage = 0.5f, bool autoAttach = true) + : this(device, RectangleHelper.CreateRectangleFromRectangles(fromLed.LedRectangle, toLed.LedRectangle), minOverlayPercentage, autoAttach) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// They first point to calculate the rectangle of this ledgroup from. + /// They second point to calculate the rectangle of this ledgroup from. + /// (optional) The minimal percentage overlay a LED must have with the to be taken into the ledgroup. (default: 0.5f) + /// (optional) Specifies whether this group should be automatically attached or not. (default: true) + public RectangleLedGroup(ICueDevice device, PointF fromPoint, PointF toPoint, float minOverlayPercentage = 0.5f, bool autoAttach = true) + : this(device, RectangleHelper.CreateRectangleFromPoints(fromPoint, toPoint), minOverlayPercentage, autoAttach) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The device this ledgroup belongs to. + /// The rectangle of this ledgroup. + /// (optional) The minimal percentage overlay a LED must have with the to be taken into the ledgroup. (default: 0.5f) + /// (optional) Specifies whether this group should be automatically attached or not. (default: true) + public RectangleLedGroup(ICueDevice device, RectangleF rectangle, float minOverlayPercentage = 0.5f, bool autoAttach = true) + : base(device, autoAttach) + { + this.Rectangle = rectangle; + this.MinOverlayPercentage = minOverlayPercentage; + } + + #endregion + + #region Methods + + public override IEnumerable GetLeds() + { + return _ledCache ?? (_ledCache = Device.Where(x => RectangleHelper.CalculateIntersectPercentage(x.LedRectangle, Rectangle) >= MinOverlayPercentage).ToList()); + } + + #endregion + } +} diff --git a/Native/_CorsairLedPosition.cs b/Native/_CorsairLedPosition.cs index bb0cc96..d24d8c1 100644 --- a/Native/_CorsairLedPosition.cs +++ b/Native/_CorsairLedPosition.cs @@ -3,7 +3,7 @@ #pragma warning disable 649 // Field 'x' is never assigned using System.Runtime.InteropServices; -using CUE.NET.Devices.Keyboard.Enums; +using CUE.NET.Devices.Generic.Enums; namespace CUE.NET.Native { @@ -18,7 +18,7 @@ namespace CUE.NET.Native /// /// CUE-SDK: identifier of led /// - internal CorsairKeyboardKeyId ledId; + internal CorsairLedId ledId; /// /// CUE-SDK: values in mm