1
0
mirror of https://github.com/DarthAffe/CUE.NET.git synced 2025-12-12 16:58:29 +00:00

Changed color-control to brushes, improved keygroups

This commit is contained in:
Darth Affe 2015-09-22 21:34:36 +02:00
parent 02aaf24c41
commit 0a47642c38
11 changed files with 106 additions and 73 deletions

View File

@ -72,7 +72,7 @@
<Compile Include="Devices\Keyboard\Keys\BaseKeyGroup.cs" /> <Compile Include="Devices\Keyboard\Keys\BaseKeyGroup.cs" />
<Compile Include="Devices\Keyboard\Keys\IKeyGroup.cs" /> <Compile Include="Devices\Keyboard\Keys\IKeyGroup.cs" />
<Compile Include="Devices\Keyboard\Keys\RectangleKeyGroup.cs" /> <Compile Include="Devices\Keyboard\Keys\RectangleKeyGroup.cs" />
<Compile Include="Devices\Keyboard\Keys\SimpleKeyGroup.cs" /> <Compile Include="Devices\Keyboard\Keys\ListKeyGroup.cs" />
<Compile Include="Devices\Mouse\Enums\CorsairMouseButtonId.cs" /> <Compile Include="Devices\Mouse\Enums\CorsairMouseButtonId.cs" />
<Compile Include="Devices\Mouse\Enums\CorsairPhysicalMouseLayout.cs" /> <Compile Include="Devices\Mouse\Enums\CorsairPhysicalMouseLayout.cs" />
<Compile Include="Exceptions\CUEException.cs" /> <Compile Include="Exceptions\CUEException.cs" />

View File

@ -4,6 +4,6 @@ namespace CUE.NET.Devices.Keyboard.ColorBrushes
{ {
public interface IBrush public interface IBrush
{ {
Color GetColorAtPoint(Point point); Color GetColorAtPoint(RectangleF rectangle, PointF point);
} }
} }

View File

@ -21,7 +21,7 @@ namespace CUE.NET.Devices.Keyboard.ColorBrushes
#region Methods #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 return Color; // A solid color brush returns the same color no matter the point
} }

View File

@ -6,6 +6,7 @@ using System.Drawing;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using CUE.NET.Devices.Generic; using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Keyboard.ColorBrushes;
using CUE.NET.Devices.Keyboard.Enums; using CUE.NET.Devices.Keyboard.Enums;
using CUE.NET.Devices.Keyboard.Keys; using CUE.NET.Devices.Keyboard.Keys;
using CUE.NET.Helper; using CUE.NET.Helper;
@ -52,7 +53,7 @@ namespace CUE.NET.Devices.Keyboard
public IEnumerable<CorsairKey> Keys => new ReadOnlyCollection<CorsairKey>(_keys.Values.ToList()); public IEnumerable<CorsairKey> Keys => new ReadOnlyCollection<CorsairKey>(_keys.Values.ToList());
public Color Color { get; set; } = Color.Transparent; public IBrush Brush { get; set; }
private readonly IList<IKeyGroup> _keyGroups = new List<IKeyGroup>(); private readonly IList<IKeyGroup> _keyGroups = new List<IKeyGroup>();
@ -66,7 +67,7 @@ namespace CUE.NET.Devices.Keyboard
this.KeyboardDeviceInfo = info; this.KeyboardDeviceInfo = info;
InitializeKeys(); InitializeKeys();
CalculateKeyboardRectangle(); KeyboardRectangle = RectangleHelper.CreateRectangleFromRectangles(this.Select(x => x.KeyRectangle));
} }
#endregion #endregion
@ -75,23 +76,26 @@ namespace CUE.NET.Devices.Keyboard
public override void UpdateLeds(bool forceUpdate = false) public override void UpdateLeds(bool forceUpdate = false)
{ {
// Apply all KeyGroups first // Apply all KeyGroups
// Update only 'clean' leds, manual set should always override groups
IEnumerable<CorsairKey> cleanKeys = this.Where(x => !x.Led.IsUpdated).ToList();
if (Color != Color.Transparent) if (Brush != null)
foreach (CorsairKey key in cleanKeys) ApplyBrush(this.ToList(), Brush);
key.Led.Color = Color;
//TODO DarthAffe 20.09.2015: Add some sort of priority //TODO DarthAffe 20.09.2015: Add some sort of priority
foreach (IKeyGroup keyGroup in _keyGroups) foreach (IKeyGroup keyGroup in _keyGroups)
foreach (CorsairKey key in keyGroup.Keys.Where(key => cleanKeys.Contains(key))) ApplyBrush(keyGroup.Keys.ToList(), keyGroup.Brush);
key.Led.Color = keyGroup.Color;
// Perform 'real' update // Perform 'real' update
base.UpdateLeds(forceUpdate); base.UpdateLeds(forceUpdate);
} }
private void ApplyBrush(ICollection<CorsairKey> 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) public bool AttachKeyGroup(IKeyGroup keyGroup)
{ {
if (keyGroup == null || _keyGroups.Contains(keyGroup)) return false; 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 #region IEnumerable
public IEnumerator<CorsairKey> GetEnumerator() public IEnumerator<CorsairKey> GetEnumerator()

View File

@ -6,28 +6,28 @@ namespace CUE.NET.Devices.Keyboard.Extensions
{ {
public static class KeyGroupExtension 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) if (simpleKeyGroup == null)
{ {
bool wasAttached = keyGroup.Detach(); 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; 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) foreach (CorsairKeyboardKeyId keyId in keyIds)
simpleKeyGroup.RemoveKey(keyId); simpleKeyGroup.RemoveKey(keyId);
return simpleKeyGroup; 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) foreach (CorsairKey key in keyIds)
simpleKeyGroup.RemoveKey(key); simpleKeyGroup.RemoveKey(key);
return simpleKeyGroup; return simpleKeyGroup;

View File

@ -1,20 +1,19 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Drawing; using CUE.NET.Devices.Keyboard.ColorBrushes;
using CUE.NET.Devices.Keyboard.Extensions; using CUE.NET.Devices.Keyboard.Extensions;
namespace CUE.NET.Devices.Keyboard.Keys namespace CUE.NET.Devices.Keyboard.Keys
{ {
public class BaseKeyGroup : IKeyGroup public abstract class BaseKeyGroup : IKeyGroup
{ {
#region Properties & Fields #region Properties & Fields
internal CorsairKeyboard Keyboard { get; } internal CorsairKeyboard Keyboard { get; }
public IEnumerable<CorsairKey> Keys => new ReadOnlyCollection<CorsairKey>(GroupKeys); public IEnumerable<CorsairKey> Keys => new ReadOnlyCollection<CorsairKey>(GetGroupKeys());
protected IList<CorsairKey> GroupKeys { get; } = new List<CorsairKey>();
public Color Color { get; set; } = Color.Transparent; public IBrush Brush { get; set; }
#endregion #endregion
@ -28,6 +27,8 @@ namespace CUE.NET.Devices.Keyboard.Keys
this.Attach(); this.Attach();
} }
protected abstract IList<CorsairKey> GetGroupKeys();
#endregion #endregion
} }
} }

View File

@ -1,5 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using CUE.NET.Devices.Keyboard.ColorBrushes;
namespace CUE.NET.Devices.Keyboard.Keys namespace CUE.NET.Devices.Keyboard.Keys
{ {
@ -7,6 +7,6 @@ namespace CUE.NET.Devices.Keyboard.Keys
{ {
IEnumerable<CorsairKey> Keys { get; } IEnumerable<CorsairKey> Keys { get; }
Color Color { get; set; } IBrush Brush { get; set; }
} }
} }

View File

@ -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 namespace CUE.NET.Devices.Keyboard.Keys
{ {
public class SimpleKeyGroup : BaseKeyGroup public class ListKeyGroup : BaseKeyGroup
{ {
#region Properties & Fields
protected IList<CorsairKey> GroupKeys { get; } = new List<CorsairKey>();
#endregion
#region Constructors #region Constructors
public SimpleKeyGroup(CorsairKeyboard keyboard, bool autoAttach = true) public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach = true)
: base(keyboard, autoAttach) : base(keyboard, autoAttach)
{ } { }
public SimpleKeyGroup(CorsairKeyboard keyboard, params CorsairKey[] keys) public ListKeyGroup(CorsairKeyboard keyboard, params CorsairKey[] keys)
: this(keyboard, true, 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) : base(keyboard, autoAttach)
{ {
AddKey(keys); AddKey(keys);
} }
public SimpleKeyGroup(CorsairKeyboard keyboard, params CorsairKeyboardKeyId[] keys) public ListKeyGroup(CorsairKeyboard keyboard, params CorsairKeyboardKeyId[] keys)
: this(keyboard, true, 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) : base(keyboard, autoAttach)
{ {
AddKey(keys); AddKey(keys);
@ -82,6 +89,12 @@ namespace CUE.NET.Devices.Keyboard.Keys
GroupKeys.Add(key); GroupKeys.Add(key);
} }
protected override IList<CorsairKey> GetGroupKeys()
{
return GroupKeys;
}
#endregion #endregion
} }
} }

View File

@ -1,4 +1,5 @@
using System.Drawing; using System.Collections.Generic;
using System.Drawing;
using System.Linq; using System.Linq;
using CUE.NET.Devices.Keyboard.Enums; using CUE.NET.Devices.Keyboard.Enums;
using CUE.NET.Helper; using CUE.NET.Helper;
@ -9,8 +10,8 @@ namespace CUE.NET.Devices.Keyboard.Keys
{ {
#region Properties & Fields #region Properties & Fields
public RectangleF RequestedRectangle { get; } public RectangleF Rectangle { get; set; }
public float MinOverlayPercentage { get; } public float MinOverlayPercentage { get; set; }
#endregion #endregion
@ -28,20 +29,22 @@ namespace CUE.NET.Devices.Keyboard.Keys
: this(keyboard, RectangleHelper.CreateRectangleFromPoints(fromPoint, toPoint), minOverlayPercentage, autoAttach) : 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) : base(keyboard, autoAttach)
{ {
this.RequestedRectangle = requestedRectangle; this.Rectangle = rectangle;
this.MinOverlayPercentage = minOverlayPercentage; this.MinOverlayPercentage = minOverlayPercentage;
foreach (CorsairKey key in Keyboard.Where(x => RectangleHelper.CalculateIntersectPercentage(x.KeyRectangle, requestedRectangle) >= minOverlayPercentage))
GroupKeys.Add(key);
} }
#endregion #endregion
#region Methods #region Methods
protected override IList<CorsairKey> GetGroupKeys()
{
return Keyboard.Where(x => RectangleHelper.CalculateIntersectPercentage(x.KeyRectangle, Rectangle) >= MinOverlayPercentage).ToList();
}
#endregion #endregion
} }
} }

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using CUE.NET; using CUE.NET;
using CUE.NET.Devices.Generic.Enums; using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Keyboard; using CUE.NET.Devices.Keyboard;
using CUE.NET.Devices.Keyboard.ColorBrushes;
using CUE.NET.Devices.Keyboard.Enums; using CUE.NET.Devices.Keyboard.Enums;
using CUE.NET.Devices.Keyboard.Extensions; using CUE.NET.Devices.Keyboard.Extensions;
using CUE.NET.Devices.Keyboard.Keys; using CUE.NET.Devices.Keyboard.Keys;
@ -36,13 +37,13 @@ namespace SimpleDevTest
throw new WrapperException("No keyboard found"); throw new WrapperException("No keyboard found");
// Ink all numbers on the keypad except the '5' purple, we want that to be gray // 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) ListKeyGroup purpleGroup = new RectangleKeyGroup(keyboard, CorsairKeyboardKeyId.Keypad7, CorsairKeyboardKeyId.Keypad3)
{ Color = Color.Purple } { Brush = new SolidColorBrush(Color.Purple) }
.Exclude(CorsairKeyboardKeyId.Keypad5); .Exclude(CorsairKeyboardKeyId.Keypad5);
keyboard[CorsairKeyboardKeyId.Keypad5].Led.Color = Color.Gray; keyboard[CorsairKeyboardKeyId.Keypad5].Led.Color = Color.Gray;
// Ink the Keys 'r', 'g', 'b' in their respective color // 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['R'].Led.Color = Color.Red;
keyboard[CorsairKeyboardKeyId.G].Led.Color = Color.Green; keyboard[CorsairKeyboardKeyId.G].Led.Color = Color.Green;
keyboard['B'].Led.Color = Color.Blue; keyboard['B'].Led.Color = Color.Blue;
@ -53,12 +54,12 @@ namespace SimpleDevTest
keyboard['B'].Led.IsLocked = true; keyboard['B'].Led.IsLocked = true;
// Ink the letters of 'white' white // Ink the letters of 'white' white
SimpleKeyGroup whiteGroup = new SimpleKeyGroup(keyboard, CorsairKeyboardKeyId.W, CorsairKeyboardKeyId.H, CorsairKeyboardKeyId.I, CorsairKeyboardKeyId.T, CorsairKeyboardKeyId.E) ListKeyGroup whiteGroup = new ListKeyGroup(keyboard, CorsairKeyboardKeyId.W, CorsairKeyboardKeyId.H, CorsairKeyboardKeyId.I, CorsairKeyboardKeyId.T, CorsairKeyboardKeyId.E)
{ Color = Color.White }; { Brush = new SolidColorBrush(Color.White) };
// Ink the keys '1' to '0' yellow // Ink the keys '1' to '0' yellow
RectangleKeyGroup yellowGroup = new RectangleKeyGroup(keyboard, CorsairKeyboardKeyId.D1, CorsairKeyboardKeyId.D0) 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) // Update the keyboard to show the configured colors, (your CUE settings defines the rest)
keyboard.UpdateLeds(); keyboard.UpdateLeds();
@ -87,19 +88,24 @@ namespace SimpleDevTest
// Flash whole keyboard three times to ... well ... just to make it happen // Flash whole keyboard three times to ... well ... just to make it happen
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
keyboard.Color = Color.Aquamarine; keyboard.Brush = new SolidColorBrush(Color.Aquamarine);
keyboard.UpdateLeds(); keyboard.UpdateLeds();
Thread.Sleep(160); Thread.Sleep(160);
keyboard.Color = Color.Black; keyboard.Brush = new SolidColorBrush(Color.Black);
keyboard.UpdateLeds(); keyboard.UpdateLeds();
Thread.Sleep(200); Thread.Sleep(200);
} }
// Set keyboard 'background' to something fancy // 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) // 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); 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 // Target of our movement
PointF target = new PointF(point.X, point.Y); PointF target = new PointF(point.X, point.Y);
while (true) while (true)
@ -109,13 +115,13 @@ namespace SimpleDevTest
target = new PointF((float)(keyboard.KeyboardRectangle.X + (random.NextDouble() * keyboard.KeyboardRectangle.Width)), target = new PointF((float)(keyboard.KeyboardRectangle.X + (random.NextDouble() * keyboard.KeyboardRectangle.Width)),
(float)(keyboard.KeyboardRectangle.Y + (random.NextDouble() * keyboard.KeyboardRectangle.Height))); (float)(keyboard.KeyboardRectangle.Y + (random.NextDouble() * keyboard.KeyboardRectangle.Height)));
else 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 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<CorsairKey> keys = keyboard[point, 0.1f]; // Move our rectangle to the new position
if (keys != null) pointGroup.Rectangle = point;
foreach (CorsairKey key in keys)
key.Led.Color = Color.Orange;
// Update changed leds
keyboard.UpdateLeds(); keyboard.UpdateLeds();
// 20 updates per sec should be enought for this // 20 updates per sec should be enought for this

View File

@ -1,10 +1,16 @@
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
namespace CUE.NET.Helper namespace CUE.NET.Helper
{ {
public static class RectangleHelper 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) public static RectangleF CreateRectangleFromPoints(PointF point1, PointF point2)
{ {
float posX = Math.Min(point1.X, point2.X); float posX = Math.Min(point1.X, point2.X);
@ -25,6 +31,24 @@ namespace CUE.NET.Helper
return new RectangleF(posX, posY, width, height); return new RectangleF(posX, posY, width, height);
} }
public static RectangleF CreateRectangleFromRectangles(IEnumerable<RectangleF> 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) public static float CalculateIntersectPercentage(RectangleF rect, RectangleF referenceRect)
{ {
if (rect.IsEmpty || referenceRect.IsEmpty) return 0; if (rect.IsEmpty || referenceRect.IsEmpty) return 0;