diff --git a/CUE.NET.csproj b/CUE.NET.csproj
index b7c90ac..3932d0e 100644
--- a/CUE.NET.csproj
+++ b/CUE.NET.csproj
@@ -55,10 +55,15 @@
+
+
+
+
+
diff --git a/Devices/Generic/AbstractCueDevice.cs b/Devices/Generic/AbstractCueDevice.cs
index 138cb3f..40e522a 100644
--- a/Devices/Generic/AbstractCueDevice.cs
+++ b/Devices/Generic/AbstractCueDevice.cs
@@ -3,18 +3,40 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Native;
namespace CUE.NET.Devices.Generic
{
public abstract class AbstractCueDevice : ICueDevice
{
+ private UpdateMode _updateMode = UpdateMode.AutoOnEffect;
+
#region Properties & Fields
public IDeviceInfo DeviceInfo { get; }
+ public UpdateMode UpdateMode
+ {
+ get { return _updateMode; }
+ set
+ {
+ _updateMode = value;
+ CheckUpdateLoop();
+ }
+ }
+ public float UpdateFrequency { get; set; } = 1f / 30f;
+
private Dictionary Leds { get; } = new Dictionary();
+ protected abstract bool HasEffect { get; }
+
+ private CancellationTokenSource _updateTokenSource;
+ private CancellationToken _updateToken;
+ private Task _updateTask;
+
#endregion
#region Constructors
@@ -22,6 +44,8 @@ namespace CUE.NET.Devices.Generic
protected AbstractCueDevice(IDeviceInfo info)
{
this.DeviceInfo = info;
+
+ CheckUpdateLoop();
}
#endregion
@@ -36,16 +60,61 @@ namespace CUE.NET.Devices.Generic
return Leds[ledId];
}
- public virtual void UpdateLeds(bool forceUpdate = false)
+ protected async void CheckUpdateLoop()
{
- IList> ledsToUpdate = (forceUpdate ? Leds : Leds.Where(x => x.Value.IsDirty)).ToList();
+ bool shouldRun;
+ switch (UpdateMode)
+ {
+ case UpdateMode.Manual:
+ shouldRun = false;
+ break;
+ case UpdateMode.AutoOnEffect:
+ shouldRun = HasEffect;
+ break;
+ case UpdateMode.Continuous:
+ shouldRun = true;
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if (shouldRun && _updateTask == null) // Start task
+ {
+ _updateTokenSource?.Dispose();
+ _updateTokenSource = new CancellationTokenSource();
+ _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token));
+ }
+ else if (!shouldRun && _updateTask != null) // Stop task
+ {
+ _updateTokenSource.Cancel();
+ await _updateTask;
+ _updateTask.Dispose();
+ _updateTask = null;
+ }
+ }
+
+ private void UpdateLoop()
+ {
+ while (!_updateToken.IsCancellationRequested)
+ {
+ long preUpdateTicks = DateTime.Now.Ticks;
+ Update();
+ int sleep = (int)((UpdateFrequency * 1000f) - ((DateTime.Now.Ticks - preUpdateTicks) / 10000f));
+ if (sleep > 0)
+ Thread.Sleep(sleep);
+ }
+ }
+
+ public virtual void Update(bool flushLeds = false)
+ {
+ IList> ledsToUpdate = (flushLeds ? Leds : Leds.Where(x => x.Value.IsDirty)).ToList();
foreach (CorsairLed led in Leds.Values)
led.Update();
UpdateLeds(ledsToUpdate);
}
-
+
private static void UpdateLeds(ICollection> ledsToUpdate)
{
ledsToUpdate = ledsToUpdate.Where(x => x.Value.Color != Color.Transparent).ToList();
diff --git a/Devices/Generic/CorsairLed.cs b/Devices/Generic/CorsairLed.cs
index 930862d..c07dc18 100644
--- a/Devices/Generic/CorsairLed.cs
+++ b/Devices/Generic/CorsairLed.cs
@@ -1,4 +1,8 @@
-using System.Drawing;
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+
+using System.Drawing;
using CUE.NET.Helper;
namespace CUE.NET.Devices.Generic
@@ -28,8 +32,6 @@ namespace CUE.NET.Devices.Generic
public bool IsLocked { get; set; } = false;
- //TODO DarthAffe 19.09.2015: Add effects and stuff
-
#endregion
#region Constructors
diff --git a/Devices/Generic/Enums/UpdateMode.cs b/Devices/Generic/Enums/UpdateMode.cs
new file mode 100644
index 0000000..8ce44ab
--- /dev/null
+++ b/Devices/Generic/Enums/UpdateMode.cs
@@ -0,0 +1,9 @@
+namespace CUE.NET.Devices.Generic.Enums
+{
+ public enum UpdateMode
+ {
+ Manual,
+ AutoOnEffect,
+ Continuous
+ }
+}
diff --git a/Devices/Headset/CorsairHeadset.cs b/Devices/Headset/CorsairHeadset.cs
index c754b24..a976a64 100644
--- a/Devices/Headset/CorsairHeadset.cs
+++ b/Devices/Headset/CorsairHeadset.cs
@@ -7,6 +7,8 @@ namespace CUE.NET.Devices.Headset
{
#region Properties & Fields
+ protected override bool HasEffect => false;
+
#endregion
#region Constructors
diff --git a/Devices/ICueDevice.cs b/Devices/ICueDevice.cs
index c1bab11..4a6d654 100644
--- a/Devices/ICueDevice.cs
+++ b/Devices/ICueDevice.cs
@@ -1,9 +1,15 @@
-namespace CUE.NET.Devices
+using CUE.NET.Devices.Generic.Enums;
+
+namespace CUE.NET.Devices
{
public interface ICueDevice
{
IDeviceInfo DeviceInfo { get; }
- void UpdateLeds(bool forceUpdate = false);
+ UpdateMode UpdateMode { get; set; }
+
+ float UpdateFrequency { get; set; }
+
+ void Update(bool flushLeds = false);
}
}
diff --git a/Devices/Keyboard/Brushes/Gradient/AbstractGradient.cs b/Devices/Keyboard/Brushes/Gradient/AbstractGradient.cs
index dfe056b..cb1bd64 100644
--- a/Devices/Keyboard/Brushes/Gradient/AbstractGradient.cs
+++ b/Devices/Keyboard/Brushes/Gradient/AbstractGradient.cs
@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+// ReSharper disable MemberCanBeProtected.Global
+
+using System.Collections.Generic;
using System.Drawing;
using System.Linq;
@@ -14,10 +16,10 @@ namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
#region Constructors
- public AbstractGradient()
+ protected AbstractGradient()
{ }
- public AbstractGradient(params GradientStop[] gradientStops)
+ protected AbstractGradient(params GradientStop[] gradientStops)
{
foreach (GradientStop gradientStop in gradientStops)
GradientStops.Add(gradientStop);
diff --git a/Devices/Keyboard/Brushes/Gradient/GradientStop.cs b/Devices/Keyboard/Brushes/Gradient/GradientStop.cs
index 89bd03a..8ddd9db 100644
--- a/Devices/Keyboard/Brushes/Gradient/GradientStop.cs
+++ b/Devices/Keyboard/Brushes/Gradient/GradientStop.cs
@@ -1,4 +1,7 @@
-using System.Drawing;
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+// ReSharper disable MemberCanBePrivate.Global
+
+using System.Drawing;
namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
{
diff --git a/Devices/Keyboard/Brushes/LinearGradientBrush.cs b/Devices/Keyboard/Brushes/LinearGradientBrush.cs
index 729d969..741d4e6 100644
--- a/Devices/Keyboard/Brushes/LinearGradientBrush.cs
+++ b/Devices/Keyboard/Brushes/LinearGradientBrush.cs
@@ -1,6 +1,7 @@
// ReSharper disable CollectionNeverUpdated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable ReturnTypeCanBeEnumerable.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
using System.Drawing;
using CUE.NET.Devices.Keyboard.Brushes.Gradient;
diff --git a/Devices/Keyboard/Brushes/RadialGradientBrush.cs b/Devices/Keyboard/Brushes/RadialGradientBrush.cs
index 57cca44..c284d0a 100644
--- a/Devices/Keyboard/Brushes/RadialGradientBrush.cs
+++ b/Devices/Keyboard/Brushes/RadialGradientBrush.cs
@@ -1,4 +1,7 @@
-using System;
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+
+using System;
using System.Drawing;
using CUE.NET.Devices.Keyboard.Brushes.Gradient;
using CUE.NET.Helper;
@@ -39,6 +42,7 @@ namespace CUE.NET.Devices.Keyboard.Brushes
PointF centerPoint = new PointF(rectangle.X + rectangle.Width * Center.X, rectangle.Y + rectangle.Height * Center.Y);
// Calculate the distance to the farthest point from the center as reference (this has to be a corner)
+ // ReSharper disable once RedundantCast - never trust this ...
float refDistance = (float)Math.Max(Math.Max(Math.Max(GradientHelper.CalculateDistance(rectangle.Location, centerPoint),
GradientHelper.CalculateDistance(new PointF(rectangle.X + rectangle.Width, rectangle.Y), centerPoint)),
GradientHelper.CalculateDistance(new PointF(rectangle.X, rectangle.Y + rectangle.Height), centerPoint)),
diff --git a/Devices/Keyboard/CorsairKeyboard.cs b/Devices/Keyboard/CorsairKeyboard.cs
index 27fa6a0..806b88d 100644
--- a/Devices/Keyboard/CorsairKeyboard.cs
+++ b/Devices/Keyboard/CorsairKeyboard.cs
@@ -1,4 +1,8 @@
-using System;
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+// ReSharper disable UnusedMember.Global
+
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -7,6 +11,7 @@ using System.Linq;
using System.Runtime.InteropServices;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Keyboard.Brushes;
+using CUE.NET.Devices.Keyboard.Effects;
using CUE.NET.Devices.Keyboard.Enums;
using CUE.NET.Devices.Keyboard.Keys;
using CUE.NET.Helper;
@@ -18,11 +23,8 @@ namespace CUE.NET.Devices.Keyboard
{
#region Properties & Fields
- public CorsairKeyboardDeviceInfo KeyboardDeviceInfo { get; }
+ #region Indexer
- public RectangleF KeyboardRectangle { get; private set; }
-
- private Dictionary _keys = new Dictionary();
public CorsairKey this[CorsairKeyboardKeyId keyId]
{
get
@@ -30,32 +32,34 @@ namespace CUE.NET.Devices.Keyboard
CorsairKey key;
return _keys.TryGetValue(keyId, out key) ? key : null;
}
- private set { throw new NotSupportedException(); }
}
- public CorsairKey this[char key]
- {
- get { return this[_CUESDK.CorsairGetLedIdForKeyName(key)]; }
- private set { throw new NotSupportedException(); }
- }
+ public CorsairKey this[char key] => this[_CUESDK.CorsairGetLedIdForKeyName(key)];
- public CorsairKey this[PointF location]
- {
- get { return _keys.Values.FirstOrDefault(x => x.KeyRectangle.Contains(location)); }
- private set { throw new NotSupportedException(); }
- }
+ public CorsairKey this[PointF location] => _keys.Values.FirstOrDefault(x => x.KeyRectangle.Contains(location));
- public IEnumerable this[RectangleF referenceRect, float minOverlayPercentage = 0.5f]
- {
- get { return _keys.Values.Where(x => RectangleHelper.CalculateIntersectPercentage(x.KeyRectangle, referenceRect) >= minOverlayPercentage); }
- private set { throw new NotSupportedException(); }
- }
+ public IEnumerable this[RectangleF referenceRect, float minOverlayPercentage = 0.5f] => _keys.Values.Where(x => RectangleHelper.CalculateIntersectPercentage(x.KeyRectangle, referenceRect) >= minOverlayPercentage);
+ #endregion
+
+ private readonly LinkedList _keyGroups = new LinkedList();
+ private readonly LinkedList _effects = new LinkedList();
+
+ private Dictionary _keys = new Dictionary();
public IEnumerable Keys => new ReadOnlyCollection(_keys.Values.ToList());
+ public CorsairKeyboardDeviceInfo KeyboardDeviceInfo { get; }
+ public RectangleF KeyboardRectangle { get; private set; }
public IBrush Brush { get; set; }
- private readonly IList _keyGroups = new List();
+ protected override bool HasEffect
+ {
+ get
+ {
+ lock (_effects)
+ return _effects.Any();
+ }
+ }
#endregion
@@ -74,21 +78,62 @@ namespace CUE.NET.Devices.Keyboard
#region Methods
- public override void UpdateLeds(bool forceUpdate = false)
- {
- // Apply all KeyGroups
+ #region Update
+ public override void Update(bool flushLeds = false)
+ {
+ UpdateKeyGroups();
+ UpdateEffects();
+
+ // Perform 'real' update
+ base.Update(flushLeds);
+ }
+
+ private void UpdateEffects()
+ {
+ List effectsToRemove = new List();
+ lock (_effects)
+ {
+ long currentTicks = DateTime.Now.Ticks;
+ foreach (EffectTimeContainer effect in _effects)
+ {
+ float deltaTime;
+ if (effect.TicksAtLastUpdate < 0)
+ {
+ effect.TicksAtLastUpdate = currentTicks;
+ deltaTime = 0f;
+ }
+ else
+ deltaTime = (currentTicks - effect.TicksAtLastUpdate) / 10000000f;
+
+ effect.TicksAtLastUpdate = currentTicks;
+ effect.Effect.Update(deltaTime);
+
+ ApplyBrush((effect.Effect.KeyList ?? this).ToList(), effect.Effect.EffectBrush);
+
+ if (effect.Effect.IsDone)
+ effectsToRemove.Add(effect.Effect);
+ }
+ }
+
+ foreach (IEffect effect in effectsToRemove)
+ DetachEffect(effect);
+ }
+
+ private void UpdateKeyGroups()
+ {
if (Brush != null)
ApplyBrush(this.ToList(), Brush);
- //TODO DarthAffe 20.09.2015: Add some sort of priority
- foreach (IKeyGroup keyGroup in _keyGroups)
- ApplyBrush(keyGroup.Keys.ToList(), keyGroup.Brush);
-
- // Perform 'real' update
- base.UpdateLeds(forceUpdate);
+ lock (_keyGroups)
+ {
+ //TODO DarthAffe 20.09.2015: Add some sort of priority
+ foreach (IKeyGroup keyGroup in _keyGroups)
+ ApplyBrush(keyGroup.Keys.ToList(), keyGroup.Brush);
+ }
}
+ // ReSharper disable once MemberCanBeMadeStatic.Local - idc
private void ApplyBrush(ICollection keys, IBrush brush)
{
RectangleF brushRectangle = RectangleHelper.CreateRectangleFromRectangles(keys.Select(x => x.KeyRectangle));
@@ -96,20 +141,68 @@ namespace CUE.NET.Devices.Keyboard
key.Led.Color = brush.GetColorAtPoint(brushRectangle, key.KeyRectangle.GetCenter());
}
+ #endregion
+
public bool AttachKeyGroup(IKeyGroup keyGroup)
{
- if (keyGroup == null || _keyGroups.Contains(keyGroup)) return false;
+ lock (_keyGroups)
+ {
+ if (keyGroup == null || _keyGroups.Contains(keyGroup)) return false;
- _keyGroups.Add(keyGroup);
- return true;
+ _keyGroups.AddLast(keyGroup);
+ return true;
+ }
}
public bool DetachKeyGroup(IKeyGroup keyGroup)
{
- if (keyGroup == null || !_keyGroups.Contains(keyGroup)) return false;
+ lock (_keyGroups)
+ {
+ if (keyGroup == null) return false;
- _keyGroups.Remove(keyGroup);
- return true;
+ LinkedListNode node = _keyGroups.Find(keyGroup);
+ if (node == null) return false;
+
+ _keyGroups.Remove(node);
+ return true;
+ }
+ }
+
+ public bool AttachEffect(IEffect effect)
+ {
+ bool retVal = false;
+ lock (_effects)
+ {
+ if (effect != null && _effects.All(x => x.Effect != effect))
+ {
+ effect.OnAttach();
+ _effects.AddLast(new EffectTimeContainer(effect, -1));
+ retVal = true;
+ }
+ }
+
+ CheckUpdateLoop();
+ return retVal;
+ }
+
+ public bool DetachEffect(IEffect effect)
+ {
+ bool retVal = false;
+ lock (_effects)
+ {
+ if (effect != null)
+ {
+ EffectTimeContainer val = _effects.FirstOrDefault(x => x.Effect == effect);
+ if (val != null)
+ {
+ effect.OnDetach();
+ _effects.Remove(val);
+ retVal = true;
+ }
+ }
+ }
+ CheckUpdateLoop();
+ return retVal;
}
private void InitializeKeys()
diff --git a/Devices/Keyboard/Effects/AbstractEffect.cs b/Devices/Keyboard/Effects/AbstractEffect.cs
new file mode 100644
index 0000000..25268b0
--- /dev/null
+++ b/Devices/Keyboard/Effects/AbstractEffect.cs
@@ -0,0 +1,39 @@
+// ReSharper disable MemberCanBePrivate.Global
+
+using System.Collections.Generic;
+using System.Linq;
+using CUE.NET.Devices.Keyboard.Brushes;
+using CUE.NET.Devices.Keyboard.Keys;
+
+namespace CUE.NET.Devices.Keyboard.Effects
+{
+ public abstract class AbstractEffect : IEffect
+ {
+ #region Properties & Fields
+
+ public abstract IBrush EffectBrush { get; }
+
+ public IEnumerable KeyList { get; protected set; }
+
+ public bool IsDone { get; protected set; }
+
+ #endregion
+
+ #region Methods
+
+ public void SetTarget(IKeyGroup keyGroup)
+ {
+ KeyList = keyGroup.Keys.ToList();
+ }
+
+ public abstract void Update(float deltaTime);
+
+ public virtual void OnAttach()
+ { }
+
+ public virtual void OnDetach()
+ { }
+
+ #endregion
+ }
+}
diff --git a/Devices/Keyboard/Effects/EffectTimeContainer.cs b/Devices/Keyboard/Effects/EffectTimeContainer.cs
new file mode 100644
index 0000000..ea32de4
--- /dev/null
+++ b/Devices/Keyboard/Effects/EffectTimeContainer.cs
@@ -0,0 +1,26 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+
+namespace CUE.NET.Devices.Keyboard.Effects
+{
+ internal class EffectTimeContainer
+ {
+ #region Properties & Fields
+
+ internal IEffect Effect { get; set; }
+
+ internal long TicksAtLastUpdate { get; set; }
+
+ #endregion
+
+ #region Constructors
+
+ internal EffectTimeContainer(IEffect effect, long ticksAtLastUpdate)
+ {
+ this.Effect = effect;
+ this.TicksAtLastUpdate = ticksAtLastUpdate;
+ }
+
+ #endregion
+ }
+}
diff --git a/Devices/Keyboard/Effects/FlashEffect.cs b/Devices/Keyboard/Effects/FlashEffect.cs
new file mode 100644
index 0000000..3a538db
--- /dev/null
+++ b/Devices/Keyboard/Effects/FlashEffect.cs
@@ -0,0 +1,126 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+
+using System;
+using System.Drawing;
+using CUE.NET.Devices.Keyboard.Brushes;
+
+namespace CUE.NET.Devices.Keyboard.Effects
+{
+ public class FlashEffect : AbstractEffect
+ {
+ #region Properties & Fields
+
+ public override IBrush EffectBrush { get; }
+
+ // Settings are close to a synthesizer envelope (sustain is different for consequent naming): https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope
+ public float Attack { get; set; } = 0.2f;
+ public float Decay { get; set; } = 0f;
+ public float Sustain { get; set; } = 0.3f;
+ public float Release { get; set; } = 0.2f;
+
+ public float SustainValue { get; set; } = 1f;
+ public float AttackValue { get; set; } = 1f;
+
+ public float Interval { get; set; } = 1f;
+
+ public int Repetitions { get; set; } = 0;
+
+ private ADSRPhase _currentPhase;
+ private float _currentPhaseValue;
+ private int _repetitionCount;
+
+ #endregion
+
+ #region Constructors
+
+ public FlashEffect(Color flashColor)
+ : this(new SolidColorBrush(flashColor))
+ { }
+
+ public FlashEffect(IBrush effectBrush)
+ {
+ this.EffectBrush = effectBrush;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void Update(float deltaTime)
+ {
+ _currentPhaseValue -= deltaTime;
+
+ // Using ifs instead of a switch allows to skip phases with time 0.
+
+ if (_currentPhase == ADSRPhase.Attack)
+ if (_currentPhaseValue > 0f)
+ EffectBrush.Opacity = Math.Min(1f, (Attack - _currentPhaseValue) / Attack) * AttackValue;
+ else
+ {
+ _currentPhaseValue = Decay;
+ _currentPhase = ADSRPhase.Decay;
+ }
+
+ if (_currentPhase == ADSRPhase.Decay)
+ if (_currentPhaseValue > 0f)
+ EffectBrush.Opacity = SustainValue + (Math.Min(1f, _currentPhaseValue / Decay) * (AttackValue - SustainValue));
+ else
+ {
+ _currentPhaseValue = Sustain;
+ _currentPhase = ADSRPhase.Sustain;
+ }
+
+ if (_currentPhase == ADSRPhase.Sustain)
+ if (_currentPhaseValue > 0f)
+ EffectBrush.Opacity = SustainValue;
+ else
+ {
+ _currentPhaseValue = Release;
+ _currentPhase = ADSRPhase.Release;
+ }
+
+ if (_currentPhase == ADSRPhase.Release)
+ if (_currentPhaseValue > 0f)
+ EffectBrush.Opacity = Math.Min(1f, _currentPhaseValue / Release) * SustainValue;
+ else
+ {
+ _currentPhaseValue = Interval;
+ _currentPhase = ADSRPhase.Pause;
+ }
+
+ if (_currentPhase == ADSRPhase.Pause)
+ if (_currentPhaseValue > 0f)
+ EffectBrush.Opacity = 0f;
+ else
+ {
+ if (++_repetitionCount >= Repetitions && Repetitions > 0)
+ IsDone = true;
+ _currentPhaseValue = Attack;
+ _currentPhase = ADSRPhase.Attack;
+ }
+ }
+
+ public override void OnAttach()
+ {
+ base.OnAttach();
+
+ _currentPhase = ADSRPhase.Attack;
+ _currentPhaseValue = Attack;
+ _repetitionCount = 0;
+ EffectBrush.Opacity = 0f;
+ }
+
+ #endregion
+
+ // ReSharper disable once InconsistentNaming
+ private enum ADSRPhase
+ {
+ Attack,
+ Decay,
+ Sustain,
+ Release,
+ Pause
+ }
+ }
+}
diff --git a/Devices/Keyboard/Effects/IEffect.cs b/Devices/Keyboard/Effects/IEffect.cs
new file mode 100644
index 0000000..9f166aa
--- /dev/null
+++ b/Devices/Keyboard/Effects/IEffect.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using CUE.NET.Devices.Keyboard.Brushes;
+using CUE.NET.Devices.Keyboard.Keys;
+
+namespace CUE.NET.Devices.Keyboard.Effects
+{
+ public interface IEffect
+ {
+ #region Properties & Fields
+
+ IBrush EffectBrush { get; }
+
+ IEnumerable KeyList { get; }
+
+ bool IsDone { get; }
+
+ #endregion
+
+ #region Methods
+
+ void Update(float deltaTime);
+
+ void OnAttach();
+
+ void OnDetach();
+
+ #endregion
+ }
+}
diff --git a/Devices/Keyboard/Extensions/KeyGroupExtension.cs b/Devices/Keyboard/Extensions/KeyGroupExtension.cs
index b68cc7d..73abff3 100644
--- a/Devices/Keyboard/Extensions/KeyGroupExtension.cs
+++ b/Devices/Keyboard/Extensions/KeyGroupExtension.cs
@@ -1,4 +1,6 @@
-using System.Linq;
+// ReSharper disable MemberCanBePrivate.Global
+
+using System.Linq;
using CUE.NET.Devices.Keyboard.Enums;
using CUE.NET.Devices.Keyboard.Keys;
@@ -33,6 +35,7 @@ namespace CUE.NET.Devices.Keyboard.Extensions
return simpleKeyGroup;
}
+ // ReSharper disable once UnusedMethodReturnValue.Global
public static bool Attach(this BaseKeyGroup keyGroup)
{
return keyGroup.Keyboard?.AttachKeyGroup(keyGroup) ?? false;
diff --git a/Devices/Keyboard/Keys/CorsairKey.cs b/Devices/Keyboard/Keys/CorsairKey.cs
index 7a05530..aaa6705 100644
--- a/Devices/Keyboard/Keys/CorsairKey.cs
+++ b/Devices/Keyboard/Keys/CorsairKey.cs
@@ -1,4 +1,7 @@
-using System.Drawing;
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+using System.Drawing;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Keyboard.Enums;
diff --git a/Devices/Keyboard/Keys/ListKeyGroup.cs b/Devices/Keyboard/Keys/ListKeyGroup.cs
index bf158a6..5d95aae 100644
--- a/Devices/Keyboard/Keys/ListKeyGroup.cs
+++ b/Devices/Keyboard/Keys/ListKeyGroup.cs
@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+// ReSharper disable MemberCanBePrivate.Global
+
+using System.Collections.Generic;
using CUE.NET.Devices.Keyboard.Enums;
namespace CUE.NET.Devices.Keyboard.Keys
diff --git a/Devices/Keyboard/Keys/RectangleKeyGroup.cs b/Devices/Keyboard/Keys/RectangleKeyGroup.cs
index 77db408..f29708f 100644
--- a/Devices/Keyboard/Keys/RectangleKeyGroup.cs
+++ b/Devices/Keyboard/Keys/RectangleKeyGroup.cs
@@ -1,4 +1,7 @@
-using System.Collections.Generic;
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+
+using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using CUE.NET.Devices.Keyboard.Enums;
diff --git a/Devices/Mouse/CorsairMouse.cs b/Devices/Mouse/CorsairMouse.cs
index e61cb05..e770e91 100644
--- a/Devices/Mouse/CorsairMouse.cs
+++ b/Devices/Mouse/CorsairMouse.cs
@@ -9,6 +9,8 @@ namespace CUE.NET.Devices.Mouse
public CorsairMouseDeviceInfo MouseDeviceInfo { get; }
+ protected override bool HasEffect => false;
+
#endregion
#region Constructors
diff --git a/Helper/ColorHelper.cs b/Helper/ColorHelper.cs
index 8f3df61..b4cbc7e 100644
--- a/Helper/ColorHelper.cs
+++ b/Helper/ColorHelper.cs
@@ -36,6 +36,7 @@ namespace CUE.NET.Helper
private static byte GetIntColorFromFloat(float f)
{
+ // ReSharper disable once RedundantCast - never trust this ...
float calcF = (float)Math.Max(0f, Math.Min(1f, f));
return (byte)(calcF.Equals(1f) ? 255 : calcF * 256f);
}
@@ -69,7 +70,9 @@ namespace CUE.NET.Helper
int max = Math.Max(color.R, Math.Max(color.G, color.B));
int min = Math.Min(color.R, Math.Min(color.G, color.B));
+ // ReSharper disable RedundantCast - never trust this ...
return (max == 0) ? 0 : 1f - ((float)min / (float)max);
+ // ReSharper restore RedundantCast
}
public static float GetHSVValue(this Color color)