Refactored brushes, gradients, effects and the keyboard to uncouple them

This commit is contained in:
DarthAffe committed 2015-10-18 17:00:27 +02:00
1 parent 5fc7abc9db
commit 630090ac6f
20 files changed
+79 -62

No files matched your search

-68
View File
@@ -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);
}
}
}
-28
View File
@@ -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
}
}
+10 -3
View File
@@ -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;
@@ -188,7 +188,9 @@ namespace CUE.NET.Devices.Keyboard
effect.TicksAtLastUpdate = currentTicks;
effect.Effect.Update(deltaTime);
ApplyBrush((effect.Effect.KeyList ?? this).ToList(), effect.Effect.EffectBrush);
//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.Effect?.LedList?.Select(x => this.FirstOrDefault(y => y.Led == x));
ApplyBrush((keys ?? this).ToList(), effect.Effect.EffectBrush);
if (effect.Effect.IsDone)
effectsToRemove.Add(effect.Effect);
@@ -215,6 +217,11 @@ namespace CUE.NET.Devices.Keyboard
catch (Exception ex) { ManageException(ex); }
}
public IEnumerable<CorsairLed> GetLeds()
{
return this.Select(x => x.Led);
}
#endregion
/// <summary>
@@ -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
}
}
-179
View File
@@ -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
}
}
}
-56
View File
@@ -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
}
}
+12 -1
View File
@@ -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>
+8 -1
View File
@@ -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();
}
}