mirror of
https://github.com/DarthAffe/CUE.NET.git
synced 2026-11-10 20:46:24 +00:00
Merge pull request #27 from DarthAffe/Development
Merge refactoring to resolve #26
This commit is contained in:
commit
3f2c9f18aa
23 files changed
+205
-150
No files matched your search
@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CUE.NET.Devices.Generic.Enums;
|
||||
using CUE.NET.Effects;
|
||||
using CUE.NET.Native;
|
||||
|
||||
namespace CUE.NET.Devices.Generic
|
||||
@@ -51,6 +52,11 @@ namespace CUE.NET.Devices.Generic
|
||||
/// </summary>
|
||||
protected abstract bool HasEffect { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected LinkedList<EffectTimeContainer> Effects { get; } = new LinkedList<EffectTimeContainer>();
|
||||
|
||||
private CancellationTokenSource _updateTokenSource;
|
||||
private CancellationToken _updateToken;
|
||||
private Task _updateTask;
|
||||
@@ -146,11 +152,13 @@ namespace CUE.NET.Devices.Generic
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform an update for all dirty keys, or all keys if flushLeds is set to true.
|
||||
/// Performs an update for all dirty keys, or all keys if flushLeds is set to true.
|
||||
/// </summary>
|
||||
/// <param name="flushLeds">Specifies whether all keys (including clean ones) should be updated.</param>
|
||||
public virtual void Update(bool flushLeds = false)
|
||||
{
|
||||
UpdateEffects();
|
||||
|
||||
IList<KeyValuePair<int, CorsairLed>> ledsToUpdate = (flushLeds ? Leds : Leds.Where(x => x.Value.IsDirty)).ToList();
|
||||
|
||||
foreach (CorsairLed led in Leds.Values)
|
||||
@@ -159,6 +167,48 @@ namespace CUE.NET.Devices.Generic
|
||||
UpdateLeds(ledsToUpdate);
|
||||
}
|
||||
|
||||
private void UpdateEffects()
|
||||
{
|
||||
List<IEffect> effectsToRemove = new List<IEffect>();
|
||||
lock (Effects)
|
||||
{
|
||||
long currentTicks = DateTime.Now.Ticks;
|
||||
foreach (EffectTimeContainer effect in Effects.OrderBy(x => x.ZIndex))
|
||||
{
|
||||
try
|
||||
{
|
||||
float deltaTime;
|
||||
if (effect.TicksAtLastUpdate < 0)
|
||||
{
|
||||
effect.TicksAtLastUpdate = currentTicks;
|
||||
deltaTime = 0f;
|
||||
}
|
||||
else
|
||||
deltaTime = (currentTicks - effect.TicksAtLastUpdate) / 10000000f;
|
||||
|
||||
effect.TicksAtLastUpdate = currentTicks;
|
||||
effect.Effect.Update(deltaTime);
|
||||
|
||||
ApplyEffect(effect.Effect);
|
||||
|
||||
if (effect.Effect.IsDone)
|
||||
effectsToRemove.Add(effect.Effect);
|
||||
}
|
||||
// ReSharper disable once CatchAllClause
|
||||
catch (Exception ex) { ManageException(ex); }
|
||||
}
|
||||
}
|
||||
|
||||
foreach (IEffect effect in effectsToRemove)
|
||||
DetachEffect(effect);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the given effect to the device LEDs.
|
||||
/// </summary>
|
||||
/// <param name="effect">The effect to apply.</param>
|
||||
protected abstract void ApplyEffect(IEffect effect);
|
||||
|
||||
private static void UpdateLeds(ICollection<KeyValuePair<int, CorsairLed>> ledsToUpdate)
|
||||
{
|
||||
ledsToUpdate = ledsToUpdate.Where(x => x.Value.Color != Color.Transparent).ToList();
|
||||
@@ -186,6 +236,53 @@ namespace CUE.NET.Devices.Generic
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the given effect.
|
||||
/// </summary>
|
||||
/// <param name="effect">The effect to attach.</param>
|
||||
/// <returns><c>true</c> if the effect could be attached; otherwise, <c>false</c>.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detaches the given effect.
|
||||
/// </summary>
|
||||
/// <param name="effect">The effect to detached.</param>
|
||||
/// <returns><c>true</c> if the effect could be detached; otherwise, <c>false</c>.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the needed event-calls for an exception.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace CUE.NET.Devices.Generic.Enums
|
||||
using CUE.NET.Effects;
|
||||
|
||||
namespace CUE.NET.Devices.Generic.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains list of available update modes.
|
||||
@@ -12,7 +14,7 @@
|
||||
|
||||
/// <summary>
|
||||
/// The device will perform automatic updates at the rate set in <see cref="CUE.NET.Devices.ICueDevice.UpdateFrequency" />
|
||||
/// as long as an <see cref="CUE.NET.Devices.Keyboard.Effects.IEffect" /> is attached.
|
||||
/// as long as an <see cref="IEffect" /> is attached.
|
||||
/// </summary>
|
||||
AutoOnEffect,
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
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.Headset.Enums;
|
||||
using CUE.NET.Effects;
|
||||
|
||||
namespace CUE.NET.Devices.Headset
|
||||
{
|
||||
@@ -69,6 +71,13 @@ namespace CUE.NET.Devices.Headset
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void ApplyEffect(IEffect effect)
|
||||
{
|
||||
//TODO DarthAffe 18.10.2015: How should brushes be applied to headsets?
|
||||
foreach (CorsairLed led in effect.LedList)
|
||||
led.Color = effect.EffectBrush.GetColorAtPoint(new RectangleF(0, 0, 2, 2), new PointF(1, 1));
|
||||
}
|
||||
|
||||
private void InitializeLeds()
|
||||
{
|
||||
GetLed((int)CorsairHeadsetLedId.LeftLogo);
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
using System.Drawing;
|
||||
using CUE.NET.Helper;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a basic brush.
|
||||
/// </summary>
|
||||
public abstract class AbstractBrush : IBrush
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the overall percentage brightness of the brush.
|
||||
/// </summary>
|
||||
public float Brightness { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the overall percentage opacity of the brush.
|
||||
/// </summary>
|
||||
public float Opacity { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractBrush"/> class.
|
||||
/// </summary>
|
||||
/// <param name="brightness">The overall percentage brightness of the brush. (default: 1f)</param>
|
||||
/// <param name="opacity">The overall percentage opacity of the brush. (default: 1f)</param>
|
||||
protected AbstractBrush(float brightness = 1f, float opacity = 1f)
|
||||
{
|
||||
this.Brightness = brightness;
|
||||
this.Opacity = opacity;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
public abstract Color GetColorAtPoint(RectangleF rectangle, PointF point);
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes the color by appliing the overall brightness and opacity.<br/>
|
||||
/// This method should always be the last call of a <see cref="GetColorAtPoint" /> implementation.
|
||||
/// </summary>
|
||||
/// <param name="color">The color to finalize.</param>
|
||||
/// <returns>The finalized color.</returns>
|
||||
protected virtual Color FinalizeColor(Color color)
|
||||
{
|
||||
// Since we use HSV to calculate there is no way to make a color 'brighter' than 100%
|
||||
// Be carefull with the naming: Since we use HSV the correct term is 'value' but outside we call it 'brightness'
|
||||
// THIS IS NOT A HSB CALCULATION!!!
|
||||
float finalBrightness = color.GetHSVValue() * (Brightness < 0 ? 0 : (Brightness > 1f ? 1f : Brightness));
|
||||
byte finalAlpha = (byte)(color.A * (Opacity < 0 ? 0 : (Opacity > 1f ? 1f : Opacity)));
|
||||
return ColorHelper.ColorFromHSV(color.GetHue(), color.GetHSVSaturation(), finalBrightness, finalAlpha);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// ReSharper disable MemberCanBeProtected.Global
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a basic gradient.
|
||||
/// </summary>
|
||||
public abstract class AbstractGradient : IGradient
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of the stops used by this gradient.
|
||||
/// </summary>
|
||||
public IList<GradientStop> GradientStops { get; } = new List<GradientStop>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
|
||||
/// </summary>
|
||||
protected AbstractGradient()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
protected AbstractGradient(params GradientStop[] gradientStops)
|
||||
{
|
||||
foreach (GradientStop gradientStop in gradientStops)
|
||||
GradientStops.Add(gradientStop);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Clips the offset and ensures, that it is inside the bounds of the stop list.
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
protected float ClipOffset(float offset)
|
||||
{
|
||||
float max = GradientStops.Max(n => n.Offset);
|
||||
if (offset > max)
|
||||
return max;
|
||||
|
||||
float min = GradientStops.Min(n => n.Offset);
|
||||
if (offset < min)
|
||||
return min;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color of the gradient on the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the color from.</param>
|
||||
/// <returns>The color at the specific offset.</returns>
|
||||
public abstract Color GetColor(float offset);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a stop on a gradient.
|
||||
/// </summary>
|
||||
public class GradientStop
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the percentage offset to place this stop. This should be inside the range of [0..1] but it's not necessary.
|
||||
/// </summary>
|
||||
public float Offset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the stop.
|
||||
/// </summary>
|
||||
public Color Color { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GradientStop"/> class.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to place this stop.</param>
|
||||
/// <param name="color">The color of the stop.</param>
|
||||
public GradientStop(float offset, Color color)
|
||||
{
|
||||
this.Offset = offset;
|
||||
this.Color = color;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a basic gradient.
|
||||
/// </summary>
|
||||
public interface IGradient
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the color of the gradient on the specified offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the color from.</param>
|
||||
/// <returns>The color at the specific offset.</returns>
|
||||
Color GetColor(float offset);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a linear interpolated gradient with n stops.
|
||||
/// </summary>
|
||||
public class LinearGradient : AbstractGradient
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinearGradient"/> class.
|
||||
/// </summary>
|
||||
public LinearGradient()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinearGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||
public LinearGradient(params GradientStop[] gradientStops)
|
||||
: base(gradientStops)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the linear interpolated color at the given offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the color from.</param>
|
||||
/// <returns>The color at the specific offset.</returns>
|
||||
public override Color GetColor(float offset)
|
||||
{
|
||||
if (!GradientStops.Any()) return Color.Transparent;
|
||||
if (GradientStops.Count == 1) return GradientStops.First().Color;
|
||||
|
||||
offset = ClipOffset(offset);
|
||||
|
||||
GradientStop gsBefore = GradientStops.Where(n => n.Offset <= offset).OrderBy(n => n.Offset).Last();
|
||||
GradientStop gsAfter = GradientStops.Where(n => n.Offset >= offset).OrderBy(n => n.Offset).First();
|
||||
|
||||
float blendFactor = 0f;
|
||||
if (!gsBefore.Offset.Equals(gsAfter.Offset))
|
||||
blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset));
|
||||
|
||||
byte colA = (byte)((gsAfter.Color.A - gsBefore.Color.A) * blendFactor + gsBefore.Color.A);
|
||||
byte colR = (byte)((gsAfter.Color.R - gsBefore.Color.R) * blendFactor + gsBefore.Color.R);
|
||||
byte colG = (byte)((gsAfter.Color.G - gsBefore.Color.G) * blendFactor + gsBefore.Color.G);
|
||||
byte colB = (byte)((gsAfter.Color.B - gsBefore.Color.B) * blendFactor + gsBefore.Color.B);
|
||||
|
||||
return Color.FromArgb(colA, colR, colG, colB);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
|
||||
using System.Drawing;
|
||||
using CUE.NET.Helper;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a rainbow gradient which circles through all color colors of the HUE-color-space.<br />
|
||||
/// See <see cref="http://upload.wikimedia.org/wikipedia/commons/a/ad/HueScale.svg" /> as reference
|
||||
/// </summary>
|
||||
public class RainbowGradient : IGradient
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hue (in degrees) to start from.
|
||||
/// </summary>
|
||||
public float StartHue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hue (in degrees) to end the with.
|
||||
/// </summary>
|
||||
public float EndHue { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RainbowGradient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="startHue">The hue (in degrees) to start from (default: 0)</param>
|
||||
/// <param name="endHue">The hue (in degrees) to end with (default: 360)</param>
|
||||
public RainbowGradient(float startHue = 0f, float endHue = 360f)
|
||||
{
|
||||
this.StartHue = startHue;
|
||||
this.EndHue = endHue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color on the rainbow at the given offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The percentage offset to take the color from.</param>
|
||||
/// <returns>The color at the specific offset.</returns>
|
||||
public Color GetColor(float offset)
|
||||
{
|
||||
float range = EndHue - StartHue;
|
||||
float hue = (StartHue + (range * offset)) % 360f;
|
||||
if (hue < 0)
|
||||
hue += 360;
|
||||
return ColorHelper.ColorFromHSV(hue, 1f, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a basic brush.
|
||||
/// </summary>
|
||||
public interface IBrush
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the overall percentage brightness of the brush.
|
||||
/// </summary>
|
||||
float Brightness { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the overall percentage opacity of the brush.
|
||||
/// </summary>
|
||||
float Opacity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
Color GetColorAtPoint(RectangleF rectangle, PointF point);
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
// 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;
|
||||
using CUE.NET.Helper;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a brush drawing a linear gradient.
|
||||
/// </summary>
|
||||
public class LinearGradientBrush : AbstractBrush
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start point (as percentage in the range [0..1]) of the gradient drawn by the brush. (default: 0f, 0.5f)
|
||||
/// </summary>
|
||||
public PointF StartPoint { get; set; } = new PointF(0f, 0.5f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the end point (as percentage in the range [0..1]) of the gradient drawn by the brush. (default: 1f, 0.5f)
|
||||
/// </summary>
|
||||
public PointF EndPoint { get; set; } = new PointF(1f, 0.5f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the gradient drawn by the brush. If null it will default to full transparent.
|
||||
/// </summary>
|
||||
public IGradient Gradient { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinearGradientBrush"/> class.
|
||||
/// </summary>
|
||||
public LinearGradientBrush()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinearGradientBrush"/> class.
|
||||
/// </summary>
|
||||
/// <param name="gradient">The gradient drawn by the brush.</param>
|
||||
public LinearGradientBrush(IGradient gradient)
|
||||
{
|
||||
this.Gradient = gradient;
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinearGradientBrush"/> class.
|
||||
/// </summary>
|
||||
/// <param name="startPoint">The start point (as percentage in the range [0..1]).</param>
|
||||
/// <param name="endPoint">The end point (as percentage in the range [0..1]).</param>
|
||||
/// <param name="gradient">The gradient drawn by the brush.</param>
|
||||
public LinearGradientBrush(PointF startPoint, PointF endPoint, IGradient gradient)
|
||||
{
|
||||
this.StartPoint = startPoint;
|
||||
this.EndPoint = endPoint;
|
||||
this.Gradient = gradient;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
{
|
||||
if (Gradient == null) return Color.Transparent;
|
||||
|
||||
PointF startPoint = new PointF(StartPoint.X * rectangle.Width, StartPoint.Y * rectangle.Height);
|
||||
PointF endPoint = new PointF(EndPoint.X * rectangle.Width, EndPoint.Y * rectangle.Height);
|
||||
|
||||
float offset = GradientHelper.CalculateLinearGradientOffset(startPoint, endPoint, point);
|
||||
return FinalizeColor(Gradient.GetColor(offset));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using CUE.NET.Devices.Keyboard.Brushes.Gradient;
|
||||
using CUE.NET.Helper;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a brush drawing a radial gradient around a center point.
|
||||
/// </summary>
|
||||
public class RadialGradientBrush : AbstractBrush
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the center point (as percentage in the range [0..1]) around which the brush should be drawn.
|
||||
/// </summary>
|
||||
public PointF Center { get; set; } = new PointF(0.5f, 0.5f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the gradient drawn by the brush. If null it will default to full transparent.
|
||||
/// </summary>
|
||||
public IGradient Gradient { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RadialGradientBrush"/> class.
|
||||
/// </summary>
|
||||
public RadialGradientBrush()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RadialGradientBrush"/> class.
|
||||
/// </summary>
|
||||
/// <param name="gradient">The gradient drawn by the brush.</param>
|
||||
public RadialGradientBrush(IGradient gradient)
|
||||
{
|
||||
this.Gradient = gradient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RadialGradientBrush"/> class.
|
||||
/// </summary>
|
||||
/// <param name="center">The center point (as percentage in the range [0..1]).</param>
|
||||
/// <param name="gradient">The gradient drawn by the brush.</param>
|
||||
public RadialGradientBrush(PointF center, IGradient gradient)
|
||||
{
|
||||
this.Center = center;
|
||||
this.Gradient = gradient;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle in which the brush should be drawn.</param>
|
||||
/// <param name="point">The point from which the color should be taken.</param>
|
||||
/// <returns>The color at the specified point.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
{
|
||||
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)),
|
||||
GradientHelper.CalculateDistance(new PointF(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height), centerPoint));
|
||||
|
||||
float distance = GradientHelper.CalculateDistance(point, centerPoint);
|
||||
float offset = distance / refDistance;
|
||||
return FinalizeColor(Gradient.GetColor(offset));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using CUE.NET.Helper;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
//TODO DarthAffe 30.09.2015: Like this the brush seems kinda useless. Think about making it cool.
|
||||
|
||||
/// <summary>
|
||||
/// Represents a brush drawing random colors.
|
||||
/// </summary>
|
||||
public class RandomColorBrush : AbstractBrush
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private Random _random = new Random();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random color.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">This value isn't used.</param>
|
||||
/// <param name="point">This value isn't used.</param>
|
||||
/// <returns>A random color.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
{
|
||||
return FinalizeColor(ColorHelper.ColorFromHSV((float)_random.NextDouble() * 360f, 1, 1));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a brush drawing only a single color.
|
||||
/// </summary>
|
||||
public class SolidColorBrush : AbstractBrush
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color drawn by the brush.
|
||||
/// </summary>
|
||||
public Color Color { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SolidColorBrush"/> class.
|
||||
/// </summary>
|
||||
/// <param name="color">The color drawn by the brush.</param>
|
||||
public SolidColorBrush(Color color)
|
||||
{
|
||||
this.Color = color;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Color" /> of the brush.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">This value isn't used.</param>
|
||||
/// <param name="point">This value isn't used.</param>
|
||||
/// <returns>The <see cref="Color" /> of the brush.</returns>
|
||||
public override Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
{
|
||||
return FinalizeColor(Color);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,11 @@ using System.Collections.ObjectModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using CUE.NET.Brushes;
|
||||
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.Effects;
|
||||
using CUE.NET.Helper;
|
||||
using CUE.NET.Native;
|
||||
|
||||
@@ -76,7 +76,6 @@ namespace CUE.NET.Devices.Keyboard
|
||||
#endregion
|
||||
|
||||
private readonly LinkedList<IKeyGroup> _keyGroups = new LinkedList<IKeyGroup>();
|
||||
private readonly LinkedList<EffectTimeContainer> _effects = new LinkedList<EffectTimeContainer>();
|
||||
|
||||
private Dictionary<CorsairKeyboardKeyId, CorsairKey> _keys = new Dictionary<CorsairKeyboardKeyId, CorsairKey>();
|
||||
|
||||
@@ -113,8 +112,8 @@ namespace CUE.NET.Devices.Keyboard
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_effects)
|
||||
return _effects.Any();
|
||||
lock (Effects)
|
||||
return Effects.Any();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +147,6 @@ namespace CUE.NET.Devices.Keyboard
|
||||
public override void Update(bool flushLeds = false)
|
||||
{
|
||||
UpdateKeyGroups();
|
||||
UpdateEffects();
|
||||
|
||||
// Perform 'real' update
|
||||
base.Update(flushLeds);
|
||||
@@ -166,40 +164,13 @@ namespace CUE.NET.Devices.Keyboard
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateEffects()
|
||||
protected override void ApplyEffect(IEffect effect)
|
||||
{
|
||||
List<IEffect> effectsToRemove = new List<IEffect>();
|
||||
lock (_effects)
|
||||
{
|
||||
long currentTicks = DateTime.Now.Ticks;
|
||||
foreach (EffectTimeContainer effect in _effects.OrderBy(x => x.ZIndex))
|
||||
{
|
||||
try
|
||||
{
|
||||
float deltaTime;
|
||||
if (effect.TicksAtLastUpdate < 0)
|
||||
{
|
||||
effect.TicksAtLastUpdate = currentTicks;
|
||||
deltaTime = 0f;
|
||||
}
|
||||
else
|
||||
deltaTime = (currentTicks - effect.TicksAtLastUpdate) / 10000000f;
|
||||
if (effect == null) return;
|
||||
|
||||
effect.TicksAtLastUpdate = currentTicks;
|
||||
effect.Effect.Update(deltaTime);
|
||||
|
||||
ApplyBrush((effect.Effect.KeyList ?? this).ToList(), effect.Effect.EffectBrush);
|
||||
|
||||
if (effect.Effect.IsDone)
|
||||
effectsToRemove.Add(effect.Effect);
|
||||
}
|
||||
// ReSharper disable once CatchAllClause
|
||||
catch (Exception ex) { ManageException(ex); }
|
||||
}
|
||||
}
|
||||
|
||||
foreach (IEffect effect in effectsToRemove)
|
||||
DetachEffect(effect);
|
||||
//TODO DarthAffe 18.10.2015: This is really dirty and might have a really negative performance impact - find a better solution.
|
||||
IEnumerable<CorsairKey> keys = effect.LedList?.Select(x => this.FirstOrDefault(y => y.Led == x));
|
||||
ApplyBrush((keys ?? this).ToList(), effect.EffectBrush);
|
||||
}
|
||||
|
||||
// ReSharper disable once MemberCanBeMadeStatic.Local - idc
|
||||
@@ -215,6 +186,11 @@ namespace CUE.NET.Devices.Keyboard
|
||||
catch (Exception ex) { ManageException(ex); }
|
||||
}
|
||||
|
||||
public IEnumerable<CorsairLed> GetLeds()
|
||||
{
|
||||
return this.Select(x => x.Led);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -252,53 +228,6 @@ namespace CUE.NET.Devices.Keyboard
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the given effect.
|
||||
/// </summary>
|
||||
/// <param name="effect">The effect to attach.</param>
|
||||
/// <returns><c>true</c> if the effect could be attached; otherwise, <c>false</c>.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detaches the given effect.
|
||||
/// </summary>
|
||||
/// <param name="effect">The effect to detached.</param>
|
||||
/// <returns><c>true</c> if the effect could be detached; otherwise, <c>false</c>.</returns>
|
||||
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()
|
||||
{
|
||||
_CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositions(), typeof(_CorsairLedPositions));
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a basic effect.
|
||||
/// </summary>
|
||||
public abstract class AbstractEffect : IEffect
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of keys to which the effect applies.
|
||||
/// </summary>
|
||||
public IEnumerable<CorsairKey> KeyList { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the brush which is drawn by the effect.
|
||||
/// </summary>
|
||||
public abstract IBrush EffectBrush { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the z-index of the brush to allow ordering them before drawing. (lowest first) (default: 0)
|
||||
/// </summary>
|
||||
public int ZIndex { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if this effect has finished all of his work.
|
||||
/// </summary>
|
||||
public bool IsDone { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Sets the list of keys to which the effect applies.
|
||||
/// </summary>
|
||||
/// <param name="keyGroup"></param>
|
||||
public void SetTarget(IKeyGroup keyGroup)
|
||||
{
|
||||
KeyList = keyGroup.Keys.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the effect.
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">The elapsed time (in seconds) since the last update.</param>
|
||||
public abstract void Update(float deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// Hook which is called when the effect is attached to a keyboard.
|
||||
/// </summary>
|
||||
public virtual void OnAttach()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Hook which is called when the effect is detached from a keyboard.
|
||||
/// </summary>
|
||||
public virtual void OnDetach()
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Effects
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a wrapped effect with additional time information.
|
||||
/// </summary>
|
||||
internal class EffectTimeContainer
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the wrapped effect.
|
||||
/// </summary>
|
||||
internal IEffect Effect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the tick-count from the last time the effect was updated.
|
||||
/// </summary>
|
||||
internal long TicksAtLastUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the z-index of the effect.
|
||||
/// </summary>
|
||||
internal int ZIndex => Effect?.ZIndex ?? 0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EffectTimeContainer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="effect">The wrapped effect.</param>
|
||||
/// <param name="ticksAtLastUpdate">The tick-count from the last time the effect was updated.</param>
|
||||
internal EffectTimeContainer(IEffect effect, long ticksAtLastUpdate)
|
||||
{
|
||||
this.Effect = effect;
|
||||
this.TicksAtLastUpdate = ticksAtLastUpdate;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an effect which allows to flash an brush by modifying his opacity.
|
||||
/// </summary>
|
||||
public class FlashEffect : AbstractEffect
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets the brush which is drawn by the effect.
|
||||
/// </summary>
|
||||
public override IBrush EffectBrush { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attack-time (in seconds) of the effect. (default: 0.2f)<br />
|
||||
/// This is close to a synthesizer envelope. (See <see cref="http://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope" /> as reference)
|
||||
/// </summary>
|
||||
public float Attack { get; set; } = 0.2f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the decay-time (in seconds) of the effect. (default: 0f)<br />
|
||||
/// This is close to a synthesizer envelope. (See <see cref="http://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope" /> as reference)
|
||||
/// </summary>
|
||||
public float Decay { get; set; } = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sustain-time (in seconds) of the effect. (default: 0.3f)<br />
|
||||
/// This is close to a synthesizer envelope. (See <see cref="http://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope" /> as reference)<br />
|
||||
/// Note that this value for naming reasons represents the time NOT the level.
|
||||
/// </summary>
|
||||
public float Sustain { get; set; } = 0.3f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the release-time (in seconds) of the effect. (default: 0.2f)<br />
|
||||
/// This is close to a synthesizer envelope. (See <see cref="http://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope" /> as reference)
|
||||
/// </summary>
|
||||
public float Release { get; set; } = 0.2f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level to which the oppacity (percentage) should raise in the attack-cycle. (default: 1f);
|
||||
/// </summary>
|
||||
public float AttackValue { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level at which the oppacity (percentage) should stay in the sustain-cycle. (default: 1f);
|
||||
/// </summary>
|
||||
public float SustainValue { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the interval (in seconds) in which the effect should repeat (if repetition is enabled). (default: 1f)
|
||||
/// </summary>
|
||||
public float Interval { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of repetitions the effect should do until it's finished. Zero means infinite. (default: 0f)
|
||||
/// </summary>
|
||||
public int Repetitions { get; set; } = 0;
|
||||
|
||||
private ADSRPhase _currentPhase;
|
||||
private float _currentPhaseValue;
|
||||
private int _repetitionCount;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FlashEffect"/> class.
|
||||
/// </summary>
|
||||
/// <param name="flashColor">The color from which a <see cref="SolidColorBrush" /> should be created and used by this effect.</param>
|
||||
public FlashEffect(Color flashColor)
|
||||
: this(new SolidColorBrush(flashColor))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FlashEffect"/> class.
|
||||
/// </summary>
|
||||
/// <param name="effectBrush">The brush which should be used by this effect,</param>
|
||||
public FlashEffect(IBrush effectBrush)
|
||||
{
|
||||
this.EffectBrush = effectBrush;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Updates the effect.
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">The elapsed time (in seconds) since the last update.</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the effect.
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using CUE.NET.Devices.Keyboard.Brushes;
|
||||
using CUE.NET.Devices.Keyboard.Keys;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Effects
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a basic effect.
|
||||
/// </summary>
|
||||
public interface IEffect
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of keys to which the effect applies.
|
||||
/// </summary>
|
||||
IEnumerable<CorsairKey> KeyList { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the brush which is drawn by the effect.
|
||||
/// </summary>
|
||||
IBrush EffectBrush { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the z-index of the effect to allow ordering them before drawing. (lowest first) (default: 0)
|
||||
/// </summary>
|
||||
int ZIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if this effect has finished all of his work.
|
||||
/// </summary>
|
||||
bool IsDone { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Updates the effect.
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">The elapsed time (in seconds) since the last update.</param>
|
||||
void Update(float deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// Hook which is called when the effect is attached to a keyboard.
|
||||
/// </summary>
|
||||
void OnAttach();
|
||||
|
||||
/// <summary>
|
||||
/// Hook which is called when the effect is detached from a keyboard.
|
||||
/// </summary>
|
||||
void OnDetach();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using CUE.NET.Devices.Keyboard.Brushes;
|
||||
using System.Linq;
|
||||
using CUE.NET.Brushes;
|
||||
using CUE.NET.Devices.Generic;
|
||||
using CUE.NET.Devices.Keyboard.Extensions;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Keys
|
||||
@@ -49,6 +51,15 @@ namespace CUE.NET.Devices.Keyboard.Keys
|
||||
this.Attach();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public IEnumerable<CorsairLed> GetLeds()
|
||||
{
|
||||
return GetGroupKeys().Select(x => x.Led);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list containing the keys from this group.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using CUE.NET.Devices.Keyboard.Brushes;
|
||||
using CUE.NET.Brushes;
|
||||
using CUE.NET.Devices.Generic;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Keys
|
||||
{
|
||||
@@ -19,5 +20,11 @@ namespace CUE.NET.Devices.Keyboard.Keys
|
||||
/// Gets or sets the z-index of this keygroup to allow ordering them before drawing. (lowest first) (default: 0)
|
||||
/// </summary>
|
||||
int ZIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list containing all LEDs of this group.
|
||||
/// </summary>
|
||||
/// <returns>The list containing all LEDs of this group.</returns>
|
||||
IEnumerable<CorsairLed> GetLeds();
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,15 @@
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
using System;
|
||||
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.Mouse.Enums;
|
||||
using CUE.NET.Effects;
|
||||
using CUE.NET.Exceptions;
|
||||
|
||||
namespace CUE.NET.Devices.Mouse
|
||||
@@ -72,6 +75,13 @@ namespace CUE.NET.Devices.Mouse
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void ApplyEffect(IEffect effect)
|
||||
{
|
||||
//TODO DarthAffe 18.10.2015: How should brushes be applied to mice?
|
||||
foreach (CorsairLed led in effect.LedList)
|
||||
led.Color = effect.EffectBrush.GetColorAtPoint(new RectangleF(0, 0, 2, 2), new PointF(1, 1));
|
||||
}
|
||||
|
||||
private void InitializeLeds()
|
||||
{
|
||||
switch (MouseDeviceInfo.PhysicalLayout)
|
||||
|
||||
Reference in new issue
Block a user