From 0a47642c38810e09fbd8892853189de36c6f058f Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Tue, 22 Sep 2015 21:34:36 +0200 Subject: [PATCH] Changed color-control to brushes, improved keygroups --- CUE.NET.csproj | 2 +- Devices/Keyboard/ColorBrushes/IBrush.cs | 2 +- .../Keyboard/ColorBrushes/SolidColorBrush.cs | 2 +- Devices/Keyboard/CorsairKeyboard.cs | 42 +++++++------------ .../Keyboard/Extensions/KeyGroupExtension.cs | 14 +++---- Devices/Keyboard/Keys/BaseKeyGroup.cs | 11 ++--- Devices/Keyboard/Keys/IKeyGroup.cs | 4 +- .../{SimpleKeyGroup.cs => ListKeyGroup.cs} | 27 ++++++++---- Devices/Keyboard/Keys/RectangleKeyGroup.cs | 19 +++++---- Examples/SimpleDevTest/Program.cs | 32 ++++++++------ Helper/RectangleHelper.cs | 24 +++++++++++ 11 files changed, 106 insertions(+), 73 deletions(-) rename Devices/Keyboard/Keys/{SimpleKeyGroup.cs => ListKeyGroup.cs} (69%) diff --git a/CUE.NET.csproj b/CUE.NET.csproj index 57fee7a..6e6d9b8 100644 --- a/CUE.NET.csproj +++ b/CUE.NET.csproj @@ -72,7 +72,7 @@ - + diff --git a/Devices/Keyboard/ColorBrushes/IBrush.cs b/Devices/Keyboard/ColorBrushes/IBrush.cs index f89ab4d..e90c6dd 100644 --- a/Devices/Keyboard/ColorBrushes/IBrush.cs +++ b/Devices/Keyboard/ColorBrushes/IBrush.cs @@ -4,6 +4,6 @@ namespace CUE.NET.Devices.Keyboard.ColorBrushes { public interface IBrush { - Color GetColorAtPoint(Point point); + Color GetColorAtPoint(RectangleF rectangle, PointF point); } } \ No newline at end of file diff --git a/Devices/Keyboard/ColorBrushes/SolidColorBrush.cs b/Devices/Keyboard/ColorBrushes/SolidColorBrush.cs index 963dcca..66057cf 100644 --- a/Devices/Keyboard/ColorBrushes/SolidColorBrush.cs +++ b/Devices/Keyboard/ColorBrushes/SolidColorBrush.cs @@ -21,7 +21,7 @@ namespace CUE.NET.Devices.Keyboard.ColorBrushes #region Methods - public Color GetColorAtPoint(Point point) + public Color GetColorAtPoint(RectangleF rectangle, PointF point) { return Color; // A solid color brush returns the same color no matter the point } diff --git a/Devices/Keyboard/CorsairKeyboard.cs b/Devices/Keyboard/CorsairKeyboard.cs index 3153dea..b0be27b 100644 --- a/Devices/Keyboard/CorsairKeyboard.cs +++ b/Devices/Keyboard/CorsairKeyboard.cs @@ -6,6 +6,7 @@ using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using CUE.NET.Devices.Generic; +using CUE.NET.Devices.Keyboard.ColorBrushes; using CUE.NET.Devices.Keyboard.Enums; using CUE.NET.Devices.Keyboard.Keys; using CUE.NET.Helper; @@ -52,7 +53,7 @@ namespace CUE.NET.Devices.Keyboard public IEnumerable Keys => new ReadOnlyCollection(_keys.Values.ToList()); - public Color Color { get; set; } = Color.Transparent; + public IBrush Brush { get; set; } private readonly IList _keyGroups = new List(); @@ -66,7 +67,7 @@ namespace CUE.NET.Devices.Keyboard this.KeyboardDeviceInfo = info; InitializeKeys(); - CalculateKeyboardRectangle(); + KeyboardRectangle = RectangleHelper.CreateRectangleFromRectangles(this.Select(x => x.KeyRectangle)); } #endregion @@ -75,23 +76,26 @@ namespace CUE.NET.Devices.Keyboard public override void UpdateLeds(bool forceUpdate = false) { - // Apply all KeyGroups first - // Update only 'clean' leds, manual set should always override groups - IEnumerable cleanKeys = this.Where(x => !x.Led.IsUpdated).ToList(); + // Apply all KeyGroups - if (Color != Color.Transparent) - foreach (CorsairKey key in cleanKeys) - key.Led.Color = Color; + if (Brush != null) + ApplyBrush(this.ToList(), Brush); //TODO DarthAffe 20.09.2015: Add some sort of priority foreach (IKeyGroup keyGroup in _keyGroups) - foreach (CorsairKey key in keyGroup.Keys.Where(key => cleanKeys.Contains(key))) - key.Led.Color = keyGroup.Color; + ApplyBrush(keyGroup.Keys.ToList(), keyGroup.Brush); // Perform 'real' update base.UpdateLeds(forceUpdate); } + private void ApplyBrush(ICollection keys, IBrush brush) + { + RectangleF brushRectangle = RectangleHelper.CreateRectangleFromRectangles(keys.Select(x => x.KeyRectangle)); + foreach (CorsairKey key in keys) + key.Led.Color = brush.GetColorAtPoint(brushRectangle, key.KeyRectangle.GetCenter()); + } + public bool AttachKeyGroup(IKeyGroup keyGroup) { if (keyGroup == null || _keyGroups.Contains(keyGroup)) return false; @@ -124,24 +128,6 @@ namespace CUE.NET.Devices.Keyboard } } - private void CalculateKeyboardRectangle() - { - float posX = float.MaxValue; - float posY = float.MaxValue; - float posX2 = float.MinValue; - float posY2 = float.MinValue; - - foreach (CorsairKey key in this) - { - posX = Math.Min(posX, key.KeyRectangle.X); - posY = Math.Min(posY, key.KeyRectangle.Y); - posX2 = Math.Max(posX2, key.KeyRectangle.X + key.KeyRectangle.Width); - posY2 = Math.Max(posY2, key.KeyRectangle.Y + key.KeyRectangle.Height); - } - - KeyboardRectangle = RectangleHelper.CreateRectangleFromPoints(new PointF(posX, posY), new PointF(posX2, posY2)); - } - #region IEnumerable public IEnumerator GetEnumerator() diff --git a/Devices/Keyboard/Extensions/KeyGroupExtension.cs b/Devices/Keyboard/Extensions/KeyGroupExtension.cs index a8c1364..b68cc7d 100644 --- a/Devices/Keyboard/Extensions/KeyGroupExtension.cs +++ b/Devices/Keyboard/Extensions/KeyGroupExtension.cs @@ -6,28 +6,28 @@ namespace CUE.NET.Devices.Keyboard.Extensions { public static class KeyGroupExtension { - public static SimpleKeyGroup ToSimpleKeyGroup(this BaseKeyGroup keyGroup) + public static ListKeyGroup ToSimpleKeyGroup(this BaseKeyGroup keyGroup) { - SimpleKeyGroup simpleKeyGroup = keyGroup as SimpleKeyGroup; + ListKeyGroup simpleKeyGroup = keyGroup as ListKeyGroup; if (simpleKeyGroup == null) { bool wasAttached = keyGroup.Detach(); - simpleKeyGroup = new SimpleKeyGroup(keyGroup.Keyboard, wasAttached, keyGroup.Keys.ToArray()) { Color = keyGroup.Color }; + simpleKeyGroup = new ListKeyGroup(keyGroup.Keyboard, wasAttached, keyGroup.Keys.ToArray()) { Brush = keyGroup.Brush }; } return simpleKeyGroup; } - public static SimpleKeyGroup Exclude(this BaseKeyGroup keyGroup, params CorsairKeyboardKeyId[] keyIds) + public static ListKeyGroup Exclude(this BaseKeyGroup keyGroup, params CorsairKeyboardKeyId[] keyIds) { - SimpleKeyGroup simpleKeyGroup = keyGroup.ToSimpleKeyGroup(); + ListKeyGroup simpleKeyGroup = keyGroup.ToSimpleKeyGroup(); foreach (CorsairKeyboardKeyId keyId in keyIds) simpleKeyGroup.RemoveKey(keyId); return simpleKeyGroup; } - public static SimpleKeyGroup Exclude(this BaseKeyGroup keyGroup, params CorsairKey[] keyIds) + public static ListKeyGroup Exclude(this BaseKeyGroup keyGroup, params CorsairKey[] keyIds) { - SimpleKeyGroup simpleKeyGroup = keyGroup.ToSimpleKeyGroup(); + ListKeyGroup simpleKeyGroup = keyGroup.ToSimpleKeyGroup(); foreach (CorsairKey key in keyIds) simpleKeyGroup.RemoveKey(key); return simpleKeyGroup; diff --git a/Devices/Keyboard/Keys/BaseKeyGroup.cs b/Devices/Keyboard/Keys/BaseKeyGroup.cs index 42bd0d6..1eca0de 100644 --- a/Devices/Keyboard/Keys/BaseKeyGroup.cs +++ b/Devices/Keyboard/Keys/BaseKeyGroup.cs @@ -1,20 +1,19 @@ using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Drawing; +using CUE.NET.Devices.Keyboard.ColorBrushes; using CUE.NET.Devices.Keyboard.Extensions; namespace CUE.NET.Devices.Keyboard.Keys { - public class BaseKeyGroup : IKeyGroup + public abstract class BaseKeyGroup : IKeyGroup { #region Properties & Fields internal CorsairKeyboard Keyboard { get; } - public IEnumerable Keys => new ReadOnlyCollection(GroupKeys); - protected IList GroupKeys { get; } = new List(); + public IEnumerable Keys => new ReadOnlyCollection(GetGroupKeys()); - public Color Color { get; set; } = Color.Transparent; + public IBrush Brush { get; set; } #endregion @@ -28,6 +27,8 @@ namespace CUE.NET.Devices.Keyboard.Keys this.Attach(); } + protected abstract IList GetGroupKeys(); + #endregion } } diff --git a/Devices/Keyboard/Keys/IKeyGroup.cs b/Devices/Keyboard/Keys/IKeyGroup.cs index 07a5119..e962bee 100644 --- a/Devices/Keyboard/Keys/IKeyGroup.cs +++ b/Devices/Keyboard/Keys/IKeyGroup.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using System.Drawing; +using CUE.NET.Devices.Keyboard.ColorBrushes; namespace CUE.NET.Devices.Keyboard.Keys { @@ -7,6 +7,6 @@ namespace CUE.NET.Devices.Keyboard.Keys { IEnumerable Keys { get; } - Color Color { get; set; } + IBrush Brush { get; set; } } } diff --git a/Devices/Keyboard/Keys/SimpleKeyGroup.cs b/Devices/Keyboard/Keys/ListKeyGroup.cs similarity index 69% rename from Devices/Keyboard/Keys/SimpleKeyGroup.cs rename to Devices/Keyboard/Keys/ListKeyGroup.cs index aeed1ab..bf158a6 100644 --- a/Devices/Keyboard/Keys/SimpleKeyGroup.cs +++ b/Devices/Keyboard/Keys/ListKeyGroup.cs @@ -1,30 +1,37 @@ -using CUE.NET.Devices.Keyboard.Enums; +using System.Collections.Generic; +using CUE.NET.Devices.Keyboard.Enums; namespace CUE.NET.Devices.Keyboard.Keys { - public class SimpleKeyGroup : BaseKeyGroup + public class ListKeyGroup : BaseKeyGroup { + #region Properties & Fields + + protected IList GroupKeys { get; } = new List(); + + #endregion + #region Constructors - public SimpleKeyGroup(CorsairKeyboard keyboard, bool autoAttach = true) + public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach = true) : base(keyboard, autoAttach) { } - public SimpleKeyGroup(CorsairKeyboard keyboard, params CorsairKey[] keys) + public ListKeyGroup(CorsairKeyboard keyboard, params CorsairKey[] keys) : this(keyboard, true, keys) { } - public SimpleKeyGroup(CorsairKeyboard keyboard, bool autoAttach, params CorsairKey[] keys) + public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach, params CorsairKey[] keys) : base(keyboard, autoAttach) { AddKey(keys); } - public SimpleKeyGroup(CorsairKeyboard keyboard, params CorsairKeyboardKeyId[] keys) + public ListKeyGroup(CorsairKeyboard keyboard, params CorsairKeyboardKeyId[] keys) : this(keyboard, true, keys) { } - public SimpleKeyGroup(CorsairKeyboard keyboard, bool autoAttach, params CorsairKeyboardKeyId[] keys) + public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach, params CorsairKeyboardKeyId[] keys) : base(keyboard, autoAttach) { AddKey(keys); @@ -82,6 +89,12 @@ namespace CUE.NET.Devices.Keyboard.Keys GroupKeys.Add(key); } + + protected override IList GetGroupKeys() + { + return GroupKeys; + } + #endregion } } diff --git a/Devices/Keyboard/Keys/RectangleKeyGroup.cs b/Devices/Keyboard/Keys/RectangleKeyGroup.cs index 66bd4e4..77db408 100644 --- a/Devices/Keyboard/Keys/RectangleKeyGroup.cs +++ b/Devices/Keyboard/Keys/RectangleKeyGroup.cs @@ -1,4 +1,5 @@ -using System.Drawing; +using System.Collections.Generic; +using System.Drawing; using System.Linq; using CUE.NET.Devices.Keyboard.Enums; using CUE.NET.Helper; @@ -9,8 +10,8 @@ namespace CUE.NET.Devices.Keyboard.Keys { #region Properties & Fields - public RectangleF RequestedRectangle { get; } - public float MinOverlayPercentage { get; } + public RectangleF Rectangle { get; set; } + public float MinOverlayPercentage { get; set; } #endregion @@ -28,20 +29,22 @@ namespace CUE.NET.Devices.Keyboard.Keys : this(keyboard, RectangleHelper.CreateRectangleFromPoints(fromPoint, toPoint), minOverlayPercentage, autoAttach) { } - public RectangleKeyGroup(CorsairKeyboard keyboard, RectangleF requestedRectangle, float minOverlayPercentage = 0.5f, bool autoAttach = true) + public RectangleKeyGroup(CorsairKeyboard keyboard, RectangleF rectangle, float minOverlayPercentage = 0.5f, bool autoAttach = true) : base(keyboard, autoAttach) { - this.RequestedRectangle = requestedRectangle; + this.Rectangle = rectangle; this.MinOverlayPercentage = minOverlayPercentage; - - foreach (CorsairKey key in Keyboard.Where(x => RectangleHelper.CalculateIntersectPercentage(x.KeyRectangle, requestedRectangle) >= minOverlayPercentage)) - GroupKeys.Add(key); } #endregion #region Methods + protected override IList GetGroupKeys() + { + return Keyboard.Where(x => RectangleHelper.CalculateIntersectPercentage(x.KeyRectangle, Rectangle) >= MinOverlayPercentage).ToList(); + } + #endregion } } diff --git a/Examples/SimpleDevTest/Program.cs b/Examples/SimpleDevTest/Program.cs index 154b4da..68eb344 100644 --- a/Examples/SimpleDevTest/Program.cs +++ b/Examples/SimpleDevTest/Program.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using CUE.NET; using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Keyboard; +using CUE.NET.Devices.Keyboard.ColorBrushes; using CUE.NET.Devices.Keyboard.Enums; using CUE.NET.Devices.Keyboard.Extensions; using CUE.NET.Devices.Keyboard.Keys; @@ -36,13 +37,13 @@ namespace SimpleDevTest throw new WrapperException("No keyboard found"); // Ink all numbers on the keypad except the '5' purple, we want that to be gray - SimpleKeyGroup purpleGroup = new RectangleKeyGroup(keyboard, CorsairKeyboardKeyId.Keypad7, CorsairKeyboardKeyId.Keypad3) - { Color = Color.Purple } + ListKeyGroup purpleGroup = new RectangleKeyGroup(keyboard, CorsairKeyboardKeyId.Keypad7, CorsairKeyboardKeyId.Keypad3) + { Brush = new SolidColorBrush(Color.Purple) } .Exclude(CorsairKeyboardKeyId.Keypad5); keyboard[CorsairKeyboardKeyId.Keypad5].Led.Color = Color.Gray; // Ink the Keys 'r', 'g', 'b' in their respective color - // The char access seems to fail for everything except letters (SDK doesn't return a valid keyId) + // The char access fails for everything except letters (SDK doesn't return a valid keyId) keyboard['R'].Led.Color = Color.Red; keyboard[CorsairKeyboardKeyId.G].Led.Color = Color.Green; keyboard['B'].Led.Color = Color.Blue; @@ -53,12 +54,12 @@ namespace SimpleDevTest keyboard['B'].Led.IsLocked = true; // Ink the letters of 'white' white - SimpleKeyGroup whiteGroup = new SimpleKeyGroup(keyboard, CorsairKeyboardKeyId.W, CorsairKeyboardKeyId.H, CorsairKeyboardKeyId.I, CorsairKeyboardKeyId.T, CorsairKeyboardKeyId.E) - { Color = Color.White }; + ListKeyGroup whiteGroup = new ListKeyGroup(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) - { Color = Color.Yellow }; + { Brush = new SolidColorBrush(Color.Yellow) }; // Update the keyboard to show the configured colors, (your CUE settings defines the rest) keyboard.UpdateLeds(); @@ -87,19 +88,24 @@ namespace SimpleDevTest // Flash whole keyboard three times to ... well ... just to make it happen for (int i = 0; i < 3; i++) { - keyboard.Color = Color.Aquamarine; + keyboard.Brush = new SolidColorBrush(Color.Aquamarine); keyboard.UpdateLeds(); Thread.Sleep(160); - keyboard.Color = Color.Black; + keyboard.Brush = new SolidColorBrush(Color.Black); keyboard.UpdateLeds(); Thread.Sleep(200); } // Set keyboard 'background' to something fancy - keyboard.Color = Color.DarkSlateBlue; + keyboard.Brush = new SolidColorBrush(Color.DarkSlateBlue); // Spawn our point (rectangle since circles are too hard to calculate :p) in the top-left corner (right over G1 or on ESC depending on your keyboard) RectangleF point = new RectangleF(keyboard.KeyboardRectangle.X, keyboard.KeyboardRectangle.Y, 40, 40); + + // Create a new KeyGroup to represent our point on the keyboard + RectangleKeyGroup pointGroup = new RectangleKeyGroup(keyboard, point, 0.1f) + { Brush = new SolidColorBrush(Color.Orange) }; + // Target of our movement PointF target = new PointF(point.X, point.Y); while (true) @@ -109,13 +115,13 @@ namespace SimpleDevTest target = new PointF((float)(keyboard.KeyboardRectangle.X + (random.NextDouble() * keyboard.KeyboardRectangle.Width)), (float)(keyboard.KeyboardRectangle.Y + (random.NextDouble() * keyboard.KeyboardRectangle.Height))); else + // Calculate movement point.Location = Interpolate(point.Location, target, SPEED); // It would be better to calculate from the center of our rectangle but the easy way is enough here - IEnumerable keys = keyboard[point, 0.1f]; - if (keys != null) - foreach (CorsairKey key in keys) - key.Led.Color = Color.Orange; + // Move our rectangle to the new position + pointGroup.Rectangle = point; + // Update changed leds keyboard.UpdateLeds(); // 20 updates per sec should be enought for this diff --git a/Helper/RectangleHelper.cs b/Helper/RectangleHelper.cs index f7c0027..3082fbd 100644 --- a/Helper/RectangleHelper.cs +++ b/Helper/RectangleHelper.cs @@ -1,10 +1,16 @@ using System; +using System.Collections.Generic; using System.Drawing; namespace CUE.NET.Helper { public static class RectangleHelper { + public static PointF GetCenter(this RectangleF rectangle) + { + return new PointF(rectangle.Left + rectangle.Width / 2f, rectangle.Top + rectangle.Height / 2f); + } + public static RectangleF CreateRectangleFromPoints(PointF point1, PointF point2) { float posX = Math.Min(point1.X, point2.X); @@ -25,6 +31,24 @@ namespace CUE.NET.Helper return new RectangleF(posX, posY, width, height); } + public static RectangleF CreateRectangleFromRectangles(IEnumerable rectangles) + { + float posX = float.MaxValue; + float posY = float.MaxValue; + float posX2 = float.MinValue; + float posY2 = float.MinValue; + + foreach (RectangleF rectangle in rectangles) + { + posX = Math.Min(posX, rectangle.X); + posY = Math.Min(posY, rectangle.Y); + posX2 = Math.Max(posX2, rectangle.X + rectangle.Width); + posY2 = Math.Max(posY2, rectangle.Y + rectangle.Height); + } + + return CreateRectangleFromPoints(new PointF(posX, posY), new PointF(posX2, posY2)); + } + public static float CalculateIntersectPercentage(RectangleF rect, RectangleF referenceRect) { if (rect.IsEmpty || referenceRect.IsEmpty) return 0;