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

Merge pull request #25 from DarthAffe/Development

Merge xml-comments to resolve #18
This commit is contained in:
DarthAffe 2015-10-18 11:45:37 +02:00
commit d3405cb2cb
49 changed files with 1271 additions and 77 deletions

View File

@ -17,13 +17,42 @@ namespace CUE.NET
// ReSharper disable UnusedAutoPropertyAccessor.Global
/// <summary>
/// Gets the loaded architecture (x64/x86).
/// </summary>
public static string LoadedArchitecture => _CUESDK.LoadedArchitecture;
/// <summary>
/// Gets the protocol details for the current SDK-connection.
/// </summary>
public static CorsairProtocolDetails ProtocolDetails { get; private set; }
/// <summary>
/// Gets whether the application has exclusive access to the SDK or not.
/// </summary>
public static bool HasExclusiveAccess { get; private set; }
/// <summary>
/// Gets the last error documented by CUE.
/// </summary>
public static CorsairError LastError => _CUESDK.CorsairGetLastError();
/// <summary>
/// Gets the managed representation of a keyboard managed by the CUE-SDK.
/// Note that currently only one connected keyboard is supported.
/// </summary>
public static CorsairKeyboard KeyboardSDK { get; private set; }
/// <summary>
/// Gets the managed representation of a mouse managed by the CUE-SDK.
/// Note that currently only one connected mouse is supported.
/// </summary>
public static CorsairMouse MouseSDK { get; private set; }
/// <summary>
/// Gets the managed representation of a headset managed by the CUE-SDK.
/// Note that currently only one connected headset is supported.
/// </summary>
public static CorsairHeadset HeadsetSDK { get; private set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
@ -32,6 +61,11 @@ namespace CUE.NET
#region Methods
/// <summary>
/// Initializes the CUE-SDK. This method should be called exactly ONE time, before anything else is done.
/// </summary>
/// <param name="exclusiveAccess">Specifies whether the application should request exclusive access or not.</param>
/// <exception cref="WrapperException">Thrown if the SDK is already initialized, the SDK is not compatible to CUE or if CUE returns unknown devices.</exception>
public static void Initialize(bool exclusiveAccess = false)
{
if (ProtocolDetails != null)

View File

@ -10,14 +10,22 @@ using CUE.NET.Native;
namespace CUE.NET.Devices.Generic
{
/// <summary>
/// Represents a generic CUE-device. (keyboard, mouse, headset, ...)
/// </summary>
public abstract class AbstractCueDevice : ICueDevice
{
private UpdateMode _updateMode = UpdateMode.AutoOnEffect;
#region Properties & Fields
/// <summary>
/// Gets generic information provided by CUE for the device.
/// </summary>
public IDeviceInfo DeviceInfo { get; }
private UpdateMode _updateMode = UpdateMode.AutoOnEffect;
/// <summary>
/// Gets or sets the update-mode for the device.
/// </summary>
public UpdateMode UpdateMode
{
get { return _updateMode; }
@ -27,10 +35,20 @@ namespace CUE.NET.Devices.Generic
CheckUpdateLoop();
}
}
/// <summary>
/// Gets or sets the update-frequency in seconds. (Calculate by using '1f / updates per second')
/// </summary>
public float UpdateFrequency { get; set; } = 1f / 30f;
private Dictionary<int, CorsairLed> Leds { get; } = new Dictionary<int, CorsairLed>();
/// <summary>
/// Gets a dictionary containing all LEDs of the device.
/// </summary>
protected Dictionary<int, CorsairLed> Leds { get; } = new Dictionary<int, CorsairLed>();
/// <summary>
/// Indicates if the device has an active effect to deal with.
/// </summary>
protected abstract bool HasEffect { get; }
private CancellationTokenSource _updateTokenSource;
@ -41,12 +59,19 @@ namespace CUE.NET.Devices.Generic
#region Events
/// <summary>
/// Occurs when a catched exception is thrown inside the device.
/// </summary>
public event OnExceptionEventHandler OnException;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="AbstractCueDevice"/> class.
/// </summary>
/// <param name="info">The generic information provided by CUE for the device.</param>
protected AbstractCueDevice(IDeviceInfo info)
{
this.DeviceInfo = info;
@ -58,6 +83,11 @@ namespace CUE.NET.Devices.Generic
#region Methods
/// <summary>
/// Gets the LED-Object with the specified id.
/// </summary>
/// <param name="ledId">The LED-Id to look for.</param>
/// <returns></returns>
protected CorsairLed GetLed(int ledId)
{
if (!Leds.ContainsKey(ledId))
@ -66,6 +96,10 @@ namespace CUE.NET.Devices.Generic
return Leds[ledId];
}
/// <summary>
/// Checks if automatic updates should occur and starts/stops the update-loop if needed.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the requested update-mode is not available.</exception>
protected async void CheckUpdateLoop()
{
bool shouldRun;
@ -111,6 +145,10 @@ namespace CUE.NET.Devices.Generic
}
}
/// <summary>
/// Perform 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)
{
IList<KeyValuePair<int, CorsairLed>> ledsToUpdate = (flushLeds ? Leds : Leds.Where(x => x.Value.IsDirty)).ToList();
@ -148,6 +186,11 @@ namespace CUE.NET.Devices.Generic
Marshal.FreeHGlobal(ptr);
}
/// <summary>
/// Handles the needed event-calls for an exception.
/// </summary>
/// <param name="ex"></param>
/// <exception cref="Exception">A delegate callback throws an exception.</exception>
protected void ManageException(Exception ex)
{
OnException?.Invoke(this, new OnExceptionEventArgs(ex));

View File

@ -7,16 +7,32 @@ using CUE.NET.Helper;
namespace CUE.NET.Devices.Generic
{
/// <summary>
/// Represents a single LED of a CUE-device.
/// </summary>
public class CorsairLed
{
#region Properties & Fields
/// <summary>
/// Indicates whether the LED has changed an internal state.
/// </summary>
public bool IsDirty => RequestedColor != _color;
/// <summary>
/// Indicate whether the Color of the LED was set since the last update.
/// </summary>
public bool IsUpdated { get; private set; }
/// <summary>
/// Gets the Color the LED should be set to on the next update.
/// </summary>
public Color RequestedColor { get; private set; } = Color.Transparent;
private Color _color = Color.Transparent;
/// <summary>
/// Gets the current color of the LED. Sets the <see cref="RequestedColor" /> for the next update and mark the LED as <see cref="IsUpdated" />.
/// </summary>
public Color Color
{
get { return _color; }
@ -30,12 +46,15 @@ namespace CUE.NET.Devices.Generic
}
}
/// <summary>
/// Gets or sets if the color of this LED can be changed.
/// </summary>
public bool IsLocked { get; set; } = false;
#endregion
#region Constructors
internal CorsairLed() { }
#endregion

View File

@ -1,9 +1,24 @@
namespace CUE.NET.Devices.Generic.Enums
{
/// <summary>
/// Contains list of available update modes.
/// </summary>
public enum UpdateMode
{
/// <summary>
/// The device will not perform automatic updates. Updates will only occur if <see cref="CUE.NET.Devices.ICueDevice.Update" /> is called.
/// </summary>
Manual,
/// <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.
/// </summary>
AutoOnEffect,
/// <summary>
/// The device will perform automatic updates at the rate set in <see cref="CUE.NET.Devices.ICueDevice.UpdateFrequency" />.
/// </summary>
Continuous
}
}

View File

@ -5,22 +5,25 @@ using CUE.NET.Native;
namespace CUE.NET.Devices.Generic
{
/// <summary>
/// Represents generic information about a CUE device.
/// </summary>
public class GenericDeviceInfo : IDeviceInfo
{
#region Properties & Fields
/// <summary>
/// Device type.
/// Gets the device type. (<see cref="CUE.NET.Devices.Generic.Enums.CorsairDeviceType" />)
/// </summary>
public CorsairDeviceType Type { get; }
/// <summary>
/// Device model (like “K95RGB”).
/// Gets the device model (like “K95RGB”).
/// </summary>
public string Model { get; }
/// <summary>
/// Flags that describes device capabilities
/// Get a flag that describes device capabilities. (<see cref="CUE.NET.Devices.Generic.Enums.CorsairDeviceCaps" />)
/// </summary>
public CorsairDeviceCaps CapsMask { get; }
@ -29,9 +32,9 @@ namespace CUE.NET.Devices.Generic
#region Constructors
/// <summary>
/// Internal constructor of managed CorsairDeviceInfo.
/// Internal constructor of managed <see cref="GenericDeviceInfo"/>.
/// </summary>
/// <param name="nativeInfo">The native CorsairDeviceInfo-struct</param>
/// <param name="nativeInfo">The native <see cref="_CorsairDeviceInfo" />-struct</param>
internal GenericDeviceInfo(_CorsairDeviceInfo nativeInfo)
{
this.Type = nativeInfo.type;

View File

@ -1,17 +1,30 @@
using System;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
using System;
namespace CUE.NET.Devices.Generic
{
/// <summary>
/// Represents the information supplied with an OnException-event.
/// </summary>
public class OnExceptionEventArgs : EventArgs
{
#region Properties & Fields
/// <summary>
/// Gets the exception which is responsible for the event-call.
/// </summary>
public Exception Exception { get; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="OnExceptionEventArgs"/> class.
/// </summary>
/// <param name="exception">The exception which is responsible for the event-call.</param>
public OnExceptionEventArgs(Exception exception)
{
this.Exception = exception;

View File

@ -1,26 +1,98 @@
using CUE.NET.Devices.Generic;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable MemberCanBePrivate.Global
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Headset.Enums;
namespace CUE.NET.Devices.Headset
{
//TODO DarthAffe 20.09.2015: Find someone to test this
public class CorsairHeadset : AbstractCueDevice
/// <summary>
/// Represents the SDK for a corsair headset.
/// </summary>
public class CorsairHeadset : AbstractCueDevice, IEnumerable<CorsairLed>
{
#region Properties & Fields
#region Indexer
/// <summary>
/// Gets the <see cref="CorsairLed" /> with the specified ID.
/// </summary>
/// <param name="ledId">The ID of the LED to get.</param>
/// <returns>The LED with the specified ID.</returns>
public CorsairLed this[CorsairHeadsetLedId ledId]
{
get
{
CorsairLed led;
return base.Leds.TryGetValue((int)ledId, out led) ? led : null;
}
}
#endregion
/// <summary>
/// Gets specific information provided by CUE for the headset.
/// </summary>
public CorsairHeadsetDeviceInfo HeadsetDeviceInfo { get; }
/// <summary>
/// Gets a value indicating if the headset has an active effect to deal with or not.
/// </summary>
protected override bool HasEffect => false;
/// <summary>
/// Gets a read-only collection containing all LEDs of the headset.
/// </summary>
public new IEnumerable<CorsairLed> Leds => new ReadOnlyCollection<CorsairLed>(base.Leds.Values.ToList());
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CorsairHeadset"/> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the headset</param>
internal CorsairHeadset(CorsairHeadsetDeviceInfo info)
: base(info)
{ }
{
this.HeadsetDeviceInfo = info;
InitializeLeds();
}
#endregion
#region Methods
private void InitializeLeds()
{
GetLed((int)CorsairHeadsetLedId.LeftLogo);
GetLed((int)CorsairHeadsetLedId.RightLogo);
}
#region IEnumerable
/// <summary>
/// Returns an enumerator that iterates over all LEDs of the headset.
/// </summary>
/// <returns>An enumerator for all LDS of the headset.</returns>
public IEnumerator<CorsairLed> GetEnumerator()
{
return Leds.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#endregion
}
}

View File

@ -3,8 +3,15 @@ using CUE.NET.Native;
namespace CUE.NET.Devices.Headset
{
/// <summary>
/// Represents specific information for a CUE headset.
/// </summary>
public class CorsairHeadsetDeviceInfo : GenericDeviceInfo
{
/// <summary>
/// Internal constructor of managed <see cref="CorsairHeadsetDeviceInfo" />.
/// </summary>
/// <param name="nativeInfo">The native <see cref="_CorsairDeviceInfo" />-struct</param>
internal CorsairHeadsetDeviceInfo(_CorsairDeviceInfo nativeInfo)
: base(nativeInfo)
{ }

View File

@ -3,6 +3,9 @@
namespace CUE.NET.Devices.Headset.Enums
{
/// <summary>
/// Contains list of all LEDs available for corsair headsets.
/// </summary>
public enum CorsairHeadsetLedId
{
Invalid = 0,

View File

@ -3,19 +3,43 @@ using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Devices
{
/// <summary>
/// Represents the event-handler of the OnException-event.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="args">The arguments provided by the event.</param>
public delegate void OnExceptionEventHandler(object sender, OnExceptionEventArgs args);
/// <summary>
/// Represents a generic cue device.
/// </summary>
public interface ICueDevice
{
/// <summary>
/// Gets generic information provided by CUE for the device.
/// </summary>
IDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the update-mode for the device.
/// </summary>
UpdateMode UpdateMode { get; set; }
/// <summary>
/// Gets or sets the update-frequency in seconds. (Calculate by using '1f / updates per second')
/// </summary>
float UpdateFrequency { get; set; }
// ReSharper disable once EventNeverSubscribedTo.Global
/// <summary>
/// Occurs when a catched exception is thrown inside the device.
/// </summary>
event OnExceptionEventHandler OnException;
/// <summary>
/// Perform 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>
void Update(bool flushLeds = false);
}
}

View File

@ -2,20 +2,23 @@
namespace CUE.NET.Devices
{
/// <summary>
/// Represents generic device information.
/// </summary>
public interface IDeviceInfo
{
/// <summary>
/// Device type
/// Gets the device type.
/// </summary>
CorsairDeviceType Type { get; }
/// <summary>
/// Device model (like “K95RGB”).
/// Gets the device model (like “K95RGB”).
/// </summary>
string Model { get; }
/// <summary>
/// Flags that describes device capabilities
/// Gets flags, which describe device capabilities.
/// </summary>
CorsairDeviceCaps CapsMask { get; }
}

View File

@ -3,17 +3,32 @@ 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;
@ -24,8 +39,20 @@ namespace CUE.NET.Devices.Keyboard.Brushes
#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%

View File

@ -6,19 +6,32 @@ 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)
@ -29,6 +42,11 @@ namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
#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);
@ -42,6 +60,11 @@ namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
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

View File

@ -5,18 +5,32 @@ 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;

View File

@ -2,8 +2,16 @@
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);
}
}

View File

@ -3,13 +3,23 @@ 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)
{ }
@ -18,6 +28,11 @@ namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
#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;

View File

@ -5,17 +5,33 @@ 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;
@ -28,6 +44,11 @@ namespace CUE.NET.Devices.Keyboard.Brushes.Gradient
#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;

View File

@ -2,11 +2,27 @@ 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);
}
}

View File

@ -9,26 +9,52 @@ 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;
@ -40,6 +66,12 @@ namespace CUE.NET.Devices.Keyboard.Brushes
#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;

View File

@ -8,25 +8,47 @@ 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;
@ -37,6 +59,12 @@ namespace CUE.NET.Devices.Keyboard.Brushes
#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);

View File

@ -5,6 +5,10 @@ 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
@ -15,6 +19,12 @@ namespace CUE.NET.Devices.Keyboard.Brushes
#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));

View File

@ -1,19 +1,30 @@
// 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;
@ -23,6 +34,12 @@ namespace CUE.NET.Devices.Keyboard.Brushes
#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);

View File

@ -19,12 +19,20 @@ using CUE.NET.Native;
namespace CUE.NET.Devices.Keyboard
{
/// <summary>
/// Represents the SDK for a corsair keyboard.
/// </summary>
public class CorsairKeyboard : AbstractCueDevice, IEnumerable<CorsairKey>, IKeyGroup
{
#region Properties & Fields
#region Indexer
/// <summary>
/// Gets the <see cref="CorsairKey" /> with the specified ID.
/// </summary>
/// <param name="keyId">The ID of the key to get.</param>
/// <returns>The key with the specified ID or null if no key is found.</returns>
public CorsairKey this[CorsairKeyboardKeyId keyId]
{
get
@ -34,10 +42,35 @@ namespace CUE.NET.Devices.Keyboard
}
}
public CorsairKey this[char key] => this[_CUESDK.CorsairGetLedIdForKeyName(key)];
/// <summary>
/// Gets the <see cref="CorsairKey" /> representing the given character by calling the SDK-method 'CorsairGetLedIdForKeyName'.<br />
/// Note that this currently only works for letters.
/// </summary>
/// <param name="key">The character of the key.</param>
/// <returns>The key representing the given character or null if no key is found.</returns>
public CorsairKey this[char key]
{
get
{
CorsairKeyboardKeyId keyId = _CUESDK.CorsairGetLedIdForKeyName(key);
CorsairKey cKey;
return _keys.TryGetValue(keyId, out cKey) ? cKey : null;
}
}
/// <summary>
/// Gets the <see cref="CorsairKey" /> at the given physical location.
/// </summary>
/// <param name="location">The point to get the key from.</param>
/// <returns>The key at the given point or null if no key is found.</returns>
public CorsairKey this[PointF location] => _keys.Values.FirstOrDefault(x => x.KeyRectangle.Contains(location));
/// <summary>
/// Gets a list of <see cref="CorsairKey" /> inside the given rectangle.
/// </summary>
/// <param name="referenceRect">The rectangle to check.</param>
/// <param name="minOverlayPercentage">The minimal percentage overlay a key must have with the <see cref="Rectangle" /> to be taken into the list.</param>
/// <returns></returns>
public IEnumerable<CorsairKey> this[RectangleF referenceRect, float minOverlayPercentage = 0.5f] => _keys.Values.Where(x => RectangleHelper.CalculateIntersectPercentage(x.KeyRectangle, referenceRect) >= minOverlayPercentage);
#endregion
@ -46,13 +79,36 @@ namespace CUE.NET.Devices.Keyboard
private readonly LinkedList<EffectTimeContainer> _effects = new LinkedList<EffectTimeContainer>();
private Dictionary<CorsairKeyboardKeyId, CorsairKey> _keys = new Dictionary<CorsairKeyboardKeyId, CorsairKey>();
/// <summary>
/// Gets a read-only collection containing the keys of the keyboard.
/// </summary>
public IEnumerable<CorsairKey> Keys => new ReadOnlyCollection<CorsairKey>(_keys.Values.ToList());
/// <summary>
/// Gets specific information provided by CUE for the keyboard.
/// </summary>
public CorsairKeyboardDeviceInfo KeyboardDeviceInfo { get; }
/// <summary>
/// Gets the rectangle containing all keys of the keyboard.
/// </summary>
public RectangleF KeyboardRectangle { get; private set; }
/// <summary>
/// Gets or sets the background brush of the keyboard.
/// </summary>
public IBrush Brush { get; set; }
/// <summary>
/// Gets or sets the z-index of the background brush of the keyboard.<br />
/// This value has absolutely no effect.
/// </summary>
public int ZIndex { get; set; } = 0;
/// <summary>
/// Gets a value indicating if the keyboard has an active effect to deal with or not.
/// </summary>
protected override bool HasEffect
{
get
@ -66,6 +122,10 @@ namespace CUE.NET.Devices.Keyboard
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CorsairKeyboard"/> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the keyboard</param>
internal CorsairKeyboard(CorsairKeyboardDeviceInfo info)
: base(info)
{
@ -81,6 +141,10 @@ namespace CUE.NET.Devices.Keyboard
#region Update
/// <summary>
/// Updates all groups and effects and perform 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 override void Update(bool flushLeds = false)
{
UpdateKeyGroups();
@ -153,6 +217,11 @@ namespace CUE.NET.Devices.Keyboard
#endregion
/// <summary>
/// Attaches the given keygroup.
/// </summary>
/// <param name="keyGroup">The keygroup to attach.</param>
/// <returns><c>true</c> if the keygroup could be attached; otherwise, <c>false</c>.</returns>
public bool AttachKeyGroup(IKeyGroup keyGroup)
{
lock (_keyGroups)
@ -164,6 +233,11 @@ namespace CUE.NET.Devices.Keyboard
}
}
/// <summary>
/// Detaches the given keygroup.
/// </summary>
/// <param name="keyGroup">The keygroup to detached.</param>
/// <returns><c>true</c> if the keygroup could be detached; otherwise, <c>false</c>.</returns>
public bool DetachKeyGroup(IKeyGroup keyGroup)
{
lock (_keyGroups)
@ -178,6 +252,11 @@ 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;
@ -195,6 +274,11 @@ namespace CUE.NET.Devices.Keyboard
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;
@ -233,6 +317,10 @@ namespace CUE.NET.Devices.Keyboard
#region IEnumerable
/// <summary>
/// Returns an enumerator that iterates over all keys of the keyboard.
/// </summary>
/// <returns>An enumerator for all keys of the keyboard.</returns>
public IEnumerator<CorsairKey> GetEnumerator()
{
return _keys.Values.GetEnumerator();

View File

@ -7,17 +7,20 @@ using CUE.NET.Native;
namespace CUE.NET.Devices.Keyboard
{
/// <summary>
/// Represents specific information for a CUE keyboard.
/// </summary>
public class CorsairKeyboardDeviceInfo : GenericDeviceInfo
{
#region Properties & Fields
/// <summary>
/// Physical layout of the keyboard.
/// Gets the physical layout of the keyboard.
/// </summary>
public CorsairPhysicalKeyboardLayout PhysicalLayout { get; private set; }
/// <summary>
/// Logical layout of the keyboard as set in CUE settings.
/// Gets the logical layout of the keyboard as set in CUE settings.
/// </summary>
public CorsairLogicalKeyboardLayout LogicalLayout { get; private set; }

View File

@ -7,32 +7,61 @@ 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()
{ }

View File

@ -3,20 +3,37 @@
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;

View File

@ -7,23 +7,61 @@ 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; }
// Settings are close to a synthesizer envelope (sustain is different for consequent naming): https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope
/// <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;
public float SustainValue { get; set; } = 1f;
/// <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;
@ -34,10 +72,18 @@ namespace CUE.NET.Devices.Keyboard.Effects
#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;
@ -47,6 +93,10 @@ namespace CUE.NET.Devices.Keyboard.Effects
#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;
@ -101,6 +151,9 @@ namespace CUE.NET.Devices.Keyboard.Effects
}
}
/// <summary>
/// Resets the effect.
/// </summary>
public override void OnAttach()
{
base.OnAttach();

View File

@ -4,26 +4,51 @@ 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

View File

@ -3,6 +3,9 @@
namespace CUE.NET.Devices.Keyboard.Enums
{
/// <summary>
/// Contains list of all LEDs available for corsair keyboards.
/// </summary>
public enum CorsairKeyboardKeyId
{
Invalid = 0,

View File

@ -6,8 +6,16 @@ using CUE.NET.Devices.Keyboard.Keys;
namespace CUE.NET.Devices.Keyboard.Extensions
{
/// <summary>
/// Offers some extensions and helper-methods for keygroup related things.
/// </summary>
public static class KeyGroupExtension
{
/// <summary>
/// Converts the given <see cref="BaseKeyGroup" /> to a <see cref="ListKeyGroup" />.
/// </summary>
/// <param name="keyGroup">The <see cref="BaseKeyGroup" /> to convert.</param>
/// <returns>The converted <see cref="ListKeyGroup" />.</returns>
public static ListKeyGroup ToSimpleKeyGroup(this BaseKeyGroup keyGroup)
{
ListKeyGroup simpleKeyGroup = keyGroup as ListKeyGroup;
@ -19,6 +27,12 @@ namespace CUE.NET.Devices.Keyboard.Extensions
return simpleKeyGroup;
}
/// <summary>
/// Returns a new <see cref="ListKeyGroup" /> which contains all keys from the given keygroup excluding the specified ones.
/// </summary>
/// <param name="keyGroup">The base keygroup.</param>
/// <param name="keyIds">The ids of the keys to exclude.</param>
/// <returns>The new <see cref="ListKeyGroup" />.</returns>
public static ListKeyGroup Exclude(this BaseKeyGroup keyGroup, params CorsairKeyboardKeyId[] keyIds)
{
ListKeyGroup simpleKeyGroup = keyGroup.ToSimpleKeyGroup();
@ -27,6 +41,12 @@ namespace CUE.NET.Devices.Keyboard.Extensions
return simpleKeyGroup;
}
/// <summary>
/// Returns a new <see cref="ListKeyGroup" /> which contains all keys from the given keygroup excluding the specified ones.
/// </summary>
/// <param name="keyGroup">The base keygroup.</param>
/// <param name="keyIds">The keys to exclude.</param>
/// <returns>The new <see cref="ListKeyGroup" />.</returns>
public static ListKeyGroup Exclude(this BaseKeyGroup keyGroup, params CorsairKey[] keyIds)
{
ListKeyGroup simpleKeyGroup = keyGroup.ToSimpleKeyGroup();
@ -36,11 +56,21 @@ namespace CUE.NET.Devices.Keyboard.Extensions
}
// ReSharper disable once UnusedMethodReturnValue.Global
/// <summary>
/// Attaches the given keygroup to the keyboard.
/// </summary>
/// <param name="keyGroup">The keygroup to attach.</param>
/// <returns><c>true</c> if the keygroup could be attached; otherwise, <c>false</c>.</returns>
public static bool Attach(this BaseKeyGroup keyGroup)
{
return keyGroup.Keyboard?.AttachKeyGroup(keyGroup) ?? false;
}
/// <summary>
/// Detaches the given keygroup from the keyboard.
/// </summary>
/// <param name="keyGroup">The keygroup to attach.</param>
/// <returns><c>true</c> if the keygroup could be detached; otherwise, <c>false</c>.</returns>
public static bool Detach(this BaseKeyGroup keyGroup)
{
return keyGroup.Keyboard?.DetachKeyGroup(keyGroup) ?? false;

View File

@ -5,22 +5,42 @@ using CUE.NET.Devices.Keyboard.Extensions;
namespace CUE.NET.Devices.Keyboard.Keys
{
/// <summary>
/// Represents a basic keygroup.
/// </summary>
public abstract class BaseKeyGroup : IKeyGroup
{
#region Properties & Fields
/// <summary>
/// Gets the keyboard this keygroup belongs to.
/// </summary>
internal CorsairKeyboard Keyboard { get; }
/// <summary>
/// Gets a read-only collection containing the keys from this group.
/// </summary>
public IEnumerable<CorsairKey> Keys => new ReadOnlyCollection<CorsairKey>(GetGroupKeys());
/// <summary>
/// Gets or sets the brush which should be drawn over this group.
/// </summary>
public IBrush Brush { get; set; }
/// <summary>
/// Gets or sets the z-index of this keygroup to allow ordering them before drawing. (lowest first) (default: 0)
/// </summary>
public int ZIndex { get; set; } = 0;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="BaseKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="autoAttach">Specifies whether this group should be automatically attached or not.</param>
protected BaseKeyGroup(CorsairKeyboard keyboard, bool autoAttach = true)
{
this.Keyboard = keyboard;
@ -29,6 +49,10 @@ namespace CUE.NET.Devices.Keyboard.Keys
this.Attach();
}
/// <summary>
/// Gets a list containing the keys from this group.
/// </summary>
/// <returns>The list containing the keys.</returns>
protected abstract IList<CorsairKey> GetGroupKeys();
#endregion

View File

@ -7,18 +7,38 @@ using CUE.NET.Devices.Keyboard.Enums;
namespace CUE.NET.Devices.Keyboard.Keys
{
/// <summary>
/// Represents a key of a corsair keyboard.
/// </summary>
public class CorsairKey
{
#region Properties & Fields
/// <summary>
/// Gets the key-ID of the key.
/// </summary>
public CorsairKeyboardKeyId KeyId { get; }
/// <summary>
/// Gets the LED of the key.
/// </summary>
public CorsairLed Led { get; }
/// <summary>
/// Gets a rectangle representing the physical location of the key.
/// </summary>
public RectangleF KeyRectangle { get; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CorsairKey"/> class.
/// </summary>
/// <param name="keyId">The key-ID of the key.</param>
/// <param name="led">The LED of the key.</param>
/// <param name="keyRectangle">The rectangle representing the physical location of the key.</param>
internal CorsairKey(CorsairKeyboardKeyId keyId, CorsairLed led, RectangleF keyRectangle)
{
this.KeyId = keyId;
@ -27,9 +47,5 @@ namespace CUE.NET.Devices.Keyboard.Keys
}
#endregion
#region Methods
#endregion
}
}

View File

@ -5,10 +5,19 @@ namespace CUE.NET.Devices.Keyboard.Keys
{
public interface IKeyGroup
{
/// <summary>
/// Gets a read-only collection containing the keys from this group.
/// </summary>
IEnumerable<CorsairKey> Keys { get; }
/// <summary>
/// Gets or sets the brush which should be drawn over this group.
/// </summary>
IBrush Brush { get; set; }
/// <summary>
/// Gets or sets the z-index of this keygroup to allow ordering them before drawing. (lowest first) (default: 0)
/// </summary>
int ZIndex { get; set; }
}
}

View File

@ -5,34 +5,67 @@ using CUE.NET.Devices.Keyboard.Enums;
namespace CUE.NET.Devices.Keyboard.Keys
{
/// <summary>
/// Represents a keygroup containing arbitrary keys.
/// </summary>
public class ListKeyGroup : BaseKeyGroup
{
#region Properties & Fields
/// <summary>
/// Gets the list containing the keys of this keygroup.
/// </summary>
protected IList<CorsairKey> GroupKeys { get; } = new List<CorsairKey>();
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ListKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="autoAttach">Specifies whether this keygroup should be automatically attached or not.</param>
public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach = true)
: base(keyboard, autoAttach)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ListKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="keys">The initial keys of this keygroup.</param>
public ListKeyGroup(CorsairKeyboard keyboard, params CorsairKey[] keys)
: this(keyboard, true, keys)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ListKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="autoAttach">Specifies whether this keygroup should be automatically attached or not.</param>
/// <param name="keys">The initial keys of this keygroup.</param>
public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach, params CorsairKey[] keys)
: base(keyboard, autoAttach)
{
AddKey(keys);
}
/// <summary>
/// Initializes a new instance of the <see cref="ListKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="keys">The IDs of the initial keys of this keygroup.</param>
public ListKeyGroup(CorsairKeyboard keyboard, params CorsairKeyboardKeyId[] keys)
: this(keyboard, true, keys)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ListKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="autoAttach">Specifies whether this keygroup should be automatically attached or not.</param>
/// <param name="keys">The IDs of the initial keys of this keygroup.</param>
public ListKeyGroup(CorsairKeyboard keyboard, bool autoAttach, params CorsairKeyboardKeyId[] keys)
: base(keyboard, autoAttach)
{
@ -43,6 +76,10 @@ namespace CUE.NET.Devices.Keyboard.Keys
#region Methods
/// <summary>
/// Adds the given key(s) to the keygroup.
/// </summary>
/// <param name="keys">The key(s) to add.</param>
public void AddKey(params CorsairKey[] keys)
{
if (keys != null)
@ -52,6 +89,10 @@ namespace CUE.NET.Devices.Keyboard.Keys
}
/// <summary>
/// Adds the given key(s) to the keygroup.
/// </summary>
/// <param name="keyIds">The ID(s) of the key(s) to add.</param>
public void AddKey(params CorsairKeyboardKeyId[] keyIds)
{
if (keyIds != null)
@ -59,6 +100,10 @@ namespace CUE.NET.Devices.Keyboard.Keys
AddKey(Keyboard[keyId]);
}
/// <summary>
/// Removes the given key(s) from the keygroup.
/// </summary>
/// <param name="keys">The key(s) to remove.</param>
public void RemoveKey(params CorsairKey[] keys)
{
if (keys != null)
@ -67,6 +112,10 @@ namespace CUE.NET.Devices.Keyboard.Keys
GroupKeys.Remove(key);
}
/// <summary>
/// Removes the given key(s) from the keygroup.
/// </summary>
/// <param name="keyIds">The ID(s) of the key(s) to remove.</param>
public void RemoveKey(params CorsairKeyboardKeyId[] keyIds)
{
if (keyIds != null)
@ -74,16 +123,30 @@ namespace CUE.NET.Devices.Keyboard.Keys
RemoveKey(Keyboard[keyId]);
}
/// <summary>
/// Checks if a given key is contained by this keygroup.
/// </summary>
/// <param name="key">The key which should be checked.</param>
/// <returns><c>true</c> if the key is contained by this keygroup; otherwise, <c>false</c>.</returns>
public bool ContainsKey(CorsairKey key)
{
return key != null && GroupKeys.Contains(key);
}
/// <summary>
/// Checks if a given key is contained by this keygroup.
/// </summary>
/// <param name="keyId">The ID of the key which should be checked.</param>
/// <returns><c>true</c> if the key is contained by this keygroup; otherwise, <c>false</c>.</returns>
public bool ContainsKey(CorsairKeyboardKeyId keyId)
{
return ContainsKey(Keyboard[keyId]);
}
/// <summary>
/// Merges the keys from the given keygroup in this keygroup.
/// </summary>
/// <param name="groupToMerge">The keygroup to merge.</param>
public void MergeKeys(IKeyGroup groupToMerge)
{
foreach (CorsairKey key in groupToMerge.Keys)
@ -91,7 +154,10 @@ namespace CUE.NET.Devices.Keyboard.Keys
GroupKeys.Add(key);
}
/// <summary>
/// Gets a list containing the keys from this group.
/// </summary>
/// <returns>The list containing the keys.</returns>
protected override IList<CorsairKey> GetGroupKeys()
{
return GroupKeys;

View File

@ -9,29 +9,70 @@ using CUE.NET.Helper;
namespace CUE.NET.Devices.Keyboard.Keys
{
/// <summary>
/// Represents a keygroup containing keys which physically lay inside a rectangle.
/// </summary>
public class RectangleKeyGroup : BaseKeyGroup
{
#region Properties & Fields
/// <summary>
/// Gets or sets the rectangle the keys should be taken from.
/// </summary>
public RectangleF Rectangle { get; set; }
/// <summary>
/// Gets or sets the minimal percentage overlay a key must have with the <see cref="Rectangle" /> to be taken into the keygroup.
/// </summary>
public float MinOverlayPercentage { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="RectangleKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="fromKey">They ID of the first key to calculate the rectangle of this keygroup from.</param>
/// <param name="toKey">They ID of the second key to calculate the rectangle of this keygroup from.</param>
/// <param name="minOverlayPercentage">(optional) The minimal percentage overlay a key must have with the <see cref="Rectangle" /> to be taken into the keygroup. (default: 0.5f)</param>
/// <param name="autoAttach">(optional) Specifies whether this group should be automatically attached or not. (default: true)</param>
public RectangleKeyGroup(CorsairKeyboard keyboard, CorsairKeyboardKeyId fromKey, CorsairKeyboardKeyId toKey, float minOverlayPercentage = 0.5f, bool autoAttach = true)
: this(keyboard, keyboard[fromKey], keyboard[toKey], minOverlayPercentage, autoAttach)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="RectangleKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="fromKey">They first key to calculate the rectangle of this keygroup from.</param>
/// <param name="toKey">They second key to calculate the rectangle of this keygroup from.</param>
/// <param name="minOverlayPercentage">(optional) The minimal percentage overlay a key must have with the <see cref="Rectangle" /> to be taken into the keygroup. (default: 0.5f)</param>
/// <param name="autoAttach">(optional) Specifies whether this group should be automatically attached or not. (default: true)</param>
public RectangleKeyGroup(CorsairKeyboard keyboard, CorsairKey fromKey, CorsairKey toKey, float minOverlayPercentage = 0.5f, bool autoAttach = true)
: this(keyboard, RectangleHelper.CreateRectangleFromRectangles(fromKey.KeyRectangle, toKey.KeyRectangle), minOverlayPercentage, autoAttach)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="RectangleKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="fromPoint">They first point to calculate the rectangle of this keygroup from.</param>
/// <param name="toPoint">They second point to calculate the rectangle of this keygroup from.</param>
/// <param name="minOverlayPercentage">(optional) The minimal percentage overlay a key must have with the <see cref="Rectangle" /> to be taken into the keygroup. (default: 0.5f)</param>
/// <param name="autoAttach">(optional) Specifies whether this group should be automatically attached or not. (default: true)</param>
public RectangleKeyGroup(CorsairKeyboard keyboard, PointF fromPoint, PointF toPoint, float minOverlayPercentage = 0.5f, bool autoAttach = true)
: this(keyboard, RectangleHelper.CreateRectangleFromPoints(fromPoint, toPoint), minOverlayPercentage, autoAttach)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="RectangleKeyGroup"/> class.
/// </summary>
/// <param name="keyboard">The keyboard this keygroup belongs to.</param>
/// <param name="rectangle">The rectangle of this keygroup.</param>
/// <param name="minOverlayPercentage">(optional) The minimal percentage overlay a key must have with the <see cref="Rectangle" /> to be taken into the keygroup. (default: 0.5f)</param>
/// <param name="autoAttach">(optional) Specifies whether this group should be automatically attached or not. (default: true)</param>
public RectangleKeyGroup(CorsairKeyboard keyboard, RectangleF rectangle, float minOverlayPercentage = 0.5f, bool autoAttach = true)
: base(keyboard, autoAttach)
{
@ -43,6 +84,10 @@ namespace CUE.NET.Devices.Keyboard.Keys
#region Methods
/// <summary>
/// Gets a list containing the keys from this group.
/// </summary>
/// <returns>The list containing the keys.</returns>
protected override IList<CorsairKey> GetGroupKeys()
{
return Keyboard.Where(x => RectangleHelper.CalculateIntersectPercentage(x.KeyRectangle, Rectangle) >= MinOverlayPercentage).ToList();

View File

@ -1,30 +1,122 @@
using CUE.NET.Devices.Generic;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable UnusedMember.Global
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Mouse.Enums;
using CUE.NET.Exceptions;
namespace CUE.NET.Devices.Mouse
{
//TODO DarthAffe 20.09.2015: Find someone to test this
public class CorsairMouse : AbstractCueDevice
/// <summary>
/// Represents the SDK for a corsair mouse.
/// </summary>
public class CorsairMouse : AbstractCueDevice, IEnumerable<CorsairLed>
{
#region Properties & Fields
#region Indexer
/// <summary>
/// Gets the <see cref="CorsairLed" /> with the specified ID.
/// </summary>
/// <param name="ledId">The ID of the LED to get.</param>
/// <returns>The LED with the specified ID.</returns>
public CorsairLed this[CorsairMouseLedId ledId]
{
get
{
CorsairLed led;
return base.Leds.TryGetValue((int)ledId, out led) ? led : null;
}
}
#endregion
/// <summary>
/// Gets specific information provided by CUE for the mouse.
/// </summary>
public CorsairMouseDeviceInfo MouseDeviceInfo { get; }
/// <summary>
/// Gets a value indicating if the mouse has an active effect to deal with or not.
/// </summary>
protected override bool HasEffect => false;
/// <summary>
/// Gets a read-only collection containing all LEDs of the mouse.
/// </summary>
public new IEnumerable<CorsairLed> Leds => new ReadOnlyCollection<CorsairLed>(base.Leds.Values.ToList());
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CorsairMouse"/> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the mouse</param>
internal CorsairMouse(CorsairMouseDeviceInfo info)
: base(info)
{
this.MouseDeviceInfo = info;
InitializeLeds();
}
#endregion
#region Methods
private void InitializeLeds()
{
switch (MouseDeviceInfo.PhysicalLayout)
{
case CorsairPhysicalMouseLayout.Zones1:
GetLed((int)CorsairMouseLedId.B1);
break;
case CorsairPhysicalMouseLayout.Zones2:
GetLed((int)CorsairMouseLedId.B1);
GetLed((int)CorsairMouseLedId.B2);
break;
case CorsairPhysicalMouseLayout.Zones3:
GetLed((int)CorsairMouseLedId.B1);
GetLed((int)CorsairMouseLedId.B2);
GetLed((int)CorsairMouseLedId.B3);
break;
case CorsairPhysicalMouseLayout.Zones4:
GetLed((int)CorsairMouseLedId.B1);
GetLed((int)CorsairMouseLedId.B2);
GetLed((int)CorsairMouseLedId.B3);
GetLed((int)CorsairMouseLedId.B4);
break;
default:
throw new WrapperException($"Can't initial mouse with layout '{MouseDeviceInfo.PhysicalLayout}'");
}
}
#region IEnumerable
/// <summary>
/// Returns an enumerator that iterates over all LEDs of the mouse.
/// </summary>
/// <returns>An enumerator for all LDS of the mouse.</returns>
public IEnumerator<CorsairLed> GetEnumerator()
{
return Leds.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#endregion
}
}

View File

@ -7,12 +7,15 @@ using CUE.NET.Native;
namespace CUE.NET.Devices.Mouse
{
/// <summary>
/// Represents specific information for a CUE mouse.
/// </summary>
public class CorsairMouseDeviceInfo : GenericDeviceInfo
{
#region Properties & Fields
/// <summary>
/// Physical layout of the mouse.
/// Gets the physical layout of the mouse.
/// </summary>
public CorsairPhysicalMouseLayout PhysicalLayout { get; private set; }
@ -21,9 +24,9 @@ namespace CUE.NET.Devices.Mouse
#region Constructors
/// <summary>
/// Internal constructor of managed CorsairDeviceInfo.
/// Internal constructor of managed <see cref="CorsairMouseDeviceInfo" />.
/// </summary>
/// <param name="nativeInfo">The native CorsairDeviceInfo-struct</param>
/// <param name="nativeInfo">The native <see cref="_CorsairDeviceInfo" />-struct</param>
internal CorsairMouseDeviceInfo(_CorsairDeviceInfo nativeInfo)
: base(nativeInfo)
{

View File

@ -3,6 +3,9 @@
namespace CUE.NET.Devices.Mouse.Enums
{
/// <summary>
/// Contains list of all LEDs available for corsair mice.
/// </summary>
public enum CorsairMouseLedId
{
Invalid = 0,

View File

@ -6,16 +6,26 @@ using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Exceptions
{
/// <summary>
/// Represents an exception thrown by the CUE.
/// </summary>
public class CUEException : ApplicationException
{
#region Properties & Fields
/// <summary>
/// Gets the <see cref="CorsairError" /> provided by CUE.
/// </summary>
public CorsairError Error { get; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CUEException"/> class.
/// </summary>
/// <param name="error">The <see cref="CorsairError" /> provided by CUE, which leads to this exception.</param>
public CUEException(CorsairError error)
{
this.Error = error;

View File

@ -2,10 +2,18 @@
namespace CUE.NET.Exceptions
{
/// <summary>
/// Represents an exception thrown by this SDK-Wrapper.
/// </summary>
public class WrapperException : ApplicationException
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="WrapperException"/> class.
/// </summary>
/// <param name="message">The message which describes the reason of throwing this exception.</param>
/// <param name="innerException">Optional inner exception, which lead to this exception.</param>
public WrapperException(string message, Exception innerException = null)
: base(message, innerException)
{ }

View File

@ -5,32 +5,64 @@ using System.Drawing;
namespace CUE.NET.Helper
{
/// <summary>
/// Offers some extensions and helper-methods for color related things.
/// </summary>
public static class ColorHelper
{
#region byte/float conversion
/// <summary>
/// Converts the alpha-value of the <see cref="Color"/> to an float value int the range [0..1].
/// </summary>
/// <param name="color">The color to take the alpha-value from.</param>
/// <returns>The float-value in the range of [0..1]</returns>
public static float GetFloatA(this Color color)
{
return color.A / 255f;
}
/// <summary>
/// Converts the red-value of the <see cref="Color"/> to an float value int the range [0..1].
/// </summary>
/// <param name="color">The color to take the red-value from.</param>
/// <returns>The float-value in the range of [0..1]</returns>
public static float GetFloatR(this Color color)
{
return color.R / 255f;
}
/// <summary>
/// Converts the green-value of the <see cref="Color"/> to an float value int the range [0..1].
/// </summary>
/// <param name="color">The color to take the green-value from.</param>
/// <returns>The float-value in the range of [0..1]</returns>
public static float GetFloatG(this Color color)
{
return color.G / 255f;
}
/// <summary>
/// Converts the blue-value of the <see cref="Color"/> to an float value int the range [0..1].
/// </summary>
/// <param name="color">The color to take the blue-value from.</param>
/// <returns>The float-value in the range of [0..1]</returns>
public static float GetFloatB(this Color color)
{
return color.B / 255f;
}
/// <summary>
/// Creates a <see cref="Color"/> object from the respective rgb-float-values in the range [0..1].
/// </summary>
/// <param name="a">The alpha-value in the range [0..1].</param>
/// <param name="r">The red-value in the range [0..1].</param>
/// <param name="g">The green-value in the range [0..1].</param>
/// <param name="b">The blue-value in the range [0..1].</param>
/// <returns>The color-object created representing the given values.</returns>
public static Color CreateColorFromFloat(float a, float r, float g, float b)
{
// ReSharper disable once ExceptionNotDocumentedOptional
return Color.FromArgb(GetIntColorFromFloat(a), GetIntColorFromFloat(r), GetIntColorFromFloat(g), GetIntColorFromFloat(b));
}
@ -45,6 +77,12 @@ namespace CUE.NET.Helper
#region Blending
/// <summary>
/// Blends two colors.
/// </summary>
/// <param name="bg">The background-color.</param>
/// <param name="fg">The foreground-color</param>
/// <returns>The resulting color.</returns>
public static Color Blend(this Color bg, Color fg)
{
if (fg.A == 255)
@ -65,6 +103,11 @@ namespace CUE.NET.Helper
#region RGB/HSV conversion
// https://en.wikipedia.org/wiki/HSL_and_HSV
/// <summary>
/// Gets the saturation-value (HSV-color space) of the color.
/// </summary>
/// <param name="color">The color to take the saturation from.</param>
/// <returns>The saturation-value (HSV-color space) of the color.</returns>
public static float GetHSVSaturation(this Color color)
{
int max = Math.Max(color.R, Math.Max(color.G, color.B));
@ -75,12 +118,25 @@ namespace CUE.NET.Helper
// ReSharper restore RedundantCast
}
/// <summary>
/// Gets the value-value (HSV-color space) of the color.
/// </summary>
/// <param name="color">The color to take the value from.</param>
/// <returns>The value-value (HSV-color space) of the color.</returns>
public static float GetHSVValue(this Color color)
{
return Math.Max(color.R, Math.Max(color.G, color.B)) / 255f;
}
// Based on http://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both/6930407#6930407 as of 27.09.2015
/// <summary>
/// Creates a <see cref="Color"/> object from the respective hsv-float-values in the range [0..1].
/// </summary>
/// <param name="hue">The hue of the color.</param>
/// <param name="saturation">The saturation of the color.</param>
/// <param name="value">The value of the color.</param>
/// <param name="alpha">The alpha of the color.</param>
/// <returns>The color-object created representing the given values.</returns>
public static Color ColorFromHSV(float hue, float saturation, float value, byte alpha = 255)
{
if (saturation <= 0.0)

View File

@ -5,9 +5,19 @@ using System.Drawing;
namespace CUE.NET.Helper
{
/// <summary>
/// Offers some extensions and helper-methods for gradient related things.
/// </summary>
public static class GradientHelper
{
// Based on https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/
/// <summary>
/// Calculates the offset of an given point on an gradient.
/// </summary>
/// <param name="startPoint">The start point of the gradient.</param>
/// <param name="endPoint">The end point of the gradient.</param>
/// <param name="point">The point on the gradient to which the offset is calculated.</param>
/// <returns>The offset of the point on the gradient.</returns>
public static float CalculateLinearGradientOffset(PointF startPoint, PointF endPoint, PointF point)
{
PointF intersectingPoint;
@ -17,7 +27,7 @@ namespace CUE.NET.Helper
else if (startPoint.X.Equals(endPoint.X)) // Vertical case
intersectingPoint = new PointF(startPoint.X, point.Y);
else // Diagnonal case
else // Diagonal case
{
float slope = (endPoint.Y - startPoint.Y) / (endPoint.X - startPoint.X);
float orthogonalSlope = -1 / slope;
@ -39,8 +49,12 @@ namespace CUE.NET.Helper
// Based on https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/
/// <summary>
/// Returns the signed magnitude of a point on a vector
/// Returns the signed magnitude of a point on a vector.
/// </summary>
/// <param name="point">The point on the vector of which the magnitude should be calculated.</param>
/// <param name="origin">The origin of the vector.</param>
/// <param name="direction">The direction of the vector.</param>
/// <returns>The signed magnitude of a point on a vector.</returns>
public static float CalculateDistance(PointF point, PointF origin, PointF direction)
{
float distance = CalculateDistance(point, origin);
@ -52,6 +66,12 @@ namespace CUE.NET.Helper
? -distance : distance;
}
/// <summary>
/// Calculated the distance between two points.
/// </summary>
/// <param name="point1">The first point.</param>
/// <param name="point2">The second point.</param>
/// <returns>The distance between the two points.</returns>
public static float CalculateDistance(PointF point1, PointF point2)
{
return (float)Math.Sqrt((point1.Y - point2.Y) * (point1.Y - point2.Y) + (point1.X - point2.X) * (point1.X - point2.X));

View File

@ -4,13 +4,27 @@ using System.Drawing;
namespace CUE.NET.Helper
{
/// <summary>
/// Offers some extensions and helper-methods for rectangle related things.
/// </summary>
public static class RectangleHelper
{
/// <summary>
/// Calculates the center-point of a rectangle.
/// </summary>
/// <param name="rectangle">The rectangle.</param>
/// <returns>The center point of the rectangle.</returns>
public static PointF GetCenter(this RectangleF rectangle)
{
return new PointF(rectangle.Left + rectangle.Width / 2f, rectangle.Top + rectangle.Height / 2f);
}
/// <summary>
/// Creates a rectangle from two corner points.
/// </summary>
/// <param name="point1">The first point.</param>
/// <param name="point2">The second points.</param>
/// <returns>The rectangle created from the two points.</returns>
public static RectangleF CreateRectangleFromPoints(PointF point1, PointF point2)
{
float posX = Math.Min(point1.X, point2.X);
@ -21,16 +35,27 @@ namespace CUE.NET.Helper
return new RectangleF(posX, posY, width, height);
}
public static RectangleF CreateRectangleFromRectangles(RectangleF point1, RectangleF point2)
/// <summary>
/// Creates a rectangle containing two other rectangles.
/// </summary>
/// <param name="rectangle1">The first rectangle.</param>
/// <param name="rectangle2">The second rectangle.</param>
/// <returns>The rectangle created from the two rectangles.</returns>
public static RectangleF CreateRectangleFromRectangles(RectangleF rectangle1, RectangleF rectangle2)
{
float posX = Math.Min(point1.X, point2.X);
float posY = Math.Min(point1.Y, point2.Y);
float width = Math.Max(point1.X + point1.Width, point2.X + point2.Width) - posX;
float height = Math.Max(point1.Y + point1.Height, point2.Y + point2.Height) - posY;
float posX = Math.Min(rectangle1.X, rectangle2.X);
float posY = Math.Min(rectangle1.Y, rectangle2.Y);
float width = Math.Max(rectangle1.X + rectangle1.Width, rectangle2.X + rectangle2.Width) - posX;
float height = Math.Max(rectangle1.Y + rectangle1.Height, rectangle2.Y + rectangle2.Height) - posY;
return new RectangleF(posX, posY, width, height);
}
/// <summary>
/// Creates a rectangle containing n other rectangles.
/// </summary>
/// <param name="rectangles">The list of rectangles.</param>
/// <returns>The rectangle created from the rectangles.</returns>
public static RectangleF CreateRectangleFromRectangles(IEnumerable<RectangleF> rectangles)
{
float posX = float.MaxValue;
@ -49,6 +74,12 @@ namespace CUE.NET.Helper
return CreateRectangleFromPoints(new PointF(posX, posY), new PointF(posX2, posY2));
}
/// <summary>
/// Calculates the percentage of the intersection of two rectangles.
/// </summary>
/// <param name="rect">The rectangle from which the percentage should be calculated.</param>
/// <param name="referenceRect">The intersecting rectangle.</param>
/// <returns>The percentage of the intersection.</returns>
public static float CalculateIntersectPercentage(RectangleF rect, RectangleF referenceRect)
{
if (rect.IsEmpty || referenceRect.IsEmpty) return 0;

View File

@ -10,6 +10,9 @@ namespace CUE.NET.Native
{
#region Libary Management
/// <summary>
/// Gets the loaded architecture (x64/x86).
/// </summary>
internal static string LoadedArchitecture { get; private set; }
static _CUESDK()
@ -25,8 +28,10 @@ namespace CUE.NET.Native
#region SDK-IMPORTS
/// <summary>
/// CUE-SDK: set specified leds to some colors. The color is retained until changed by successive calls. This function does not take logical layout into account
/// </summary>
[DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
// set specified leds to some colors. The color is retained until changed by successive calls. This function does not take logical layout into account
internal static extern bool CorsairSetLedsColors(int size, IntPtr ledsColors);
//#if WIN64
@ -36,32 +41,47 @@ namespace CUE.NET.Native
//#endif
//internal static extern bool CorsairSetLedsColorsAsync(int size, CorsairLedColor* ledsColors, void(*CallbackType)(void*, bool, CorsairError), void* context);
/// <summary>
/// CUE-SDK: returns number of connected Corsair devices that support lighting control.
/// </summary>
[DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
// returns number of connected Corsair devices that support lighting control.
internal static extern int CorsairGetDeviceCount();
/// <summary>
/// CUE-SDK: returns information about device at provided index
/// </summary>
[DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
// returns information about device at provided index
internal static extern IntPtr CorsairGetDeviceInfo(int deviceIndex);
/// <summary>
/// CUE-SDK: provides list of keyboard LEDs with their physical positions.
/// </summary>
[DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
// provides list of keyboard LEDs with their physical positions.
internal static extern IntPtr CorsairGetLedPositions();
/// <summary>
/// CUE-SDK: retrieves led id for key name taking logical layout into account.
/// </summary>
[DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
// retrieves led id for key name taking logical layout into account.
internal static extern CorsairKeyboardKeyId CorsairGetLedIdForKeyName(char keyName);
/// <summary>
/// CUE-SDK: requestes control using specified access mode.
/// By default client has shared control over lighting so there is no need to call CorsairRequestControl unless client requires exclusive control
/// </summary>
[DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
// requestes control using specified access mode. By default client has shared control over lighting so there is no need to call CorsairRequestControl unless client requires exclusive control
internal static extern bool CorsairRequestControl(CorsairAccessMode accessMode);
/// <summary>
/// CUE-SDK: checks file and protocol version of CUE to understand which of SDK functions can be used with this version of CUE
/// </summary>
[DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
// checks file and protocol version of CUE to understand which of SDK functions can be used with this version of CUE
internal static extern _CorsairProtocolDetails CorsairPerformProtocolHandshake();
/// <summary>
/// CUE-SDK: returns last error that occured while using any of Corsair* functions
/// </summary>
[DllImport("CUESDK_2013.dll", CallingConvention = CallingConvention.Cdecl)]
// returns last error that occured while using any of Corsair* functions
internal static extern CorsairError CorsairGetLastError();
#endregion

View File

@ -9,13 +9,35 @@ using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Native
{
// ReSharper disable once InconsistentNaming
/// <summary>
/// CUE-SDK: contains information about device
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal class _CorsairDeviceInfo // contains information about device
internal class _CorsairDeviceInfo
{
internal CorsairDeviceType type; // enum describing device type
internal IntPtr model; // null - terminated device model(like “K95RGB”)
internal int physicalLayout; // enum describing physical layout of the keyboard or mouse
internal int logicalLayout; // enum describing logical layout of the keyboard as set in CUE settings
internal int capsMask; // mask that describes device capabilities, formed as logical “or” of CorsairDeviceCaps enum values
/// <summary>
/// CUE-SDK: enum describing device type
/// </summary>
internal CorsairDeviceType type;
/// <summary>
/// CUE-SDK: null - terminated device model(like “K95RGB”)
/// </summary>
internal IntPtr model;
/// <summary>
/// CUE-SDK: enum describing physical layout of the keyboard or mouse
/// </summary>
internal int physicalLayout;
/// <summary>
/// CUE-SDK: enum describing logical layout of the keyboard as set in CUE settings
/// </summary>
internal int logicalLayout;
/// <summary>
/// CUE-SDK: mask that describes device capabilities, formed as logical “or” of CorsairDeviceCaps enum values
/// </summary>
internal int capsMask;
}
}

View File

@ -6,14 +6,31 @@ using System.Runtime.InteropServices;
namespace CUE.NET.Native
{
// ReSharper disable once InconsistentNaming
// ReSharper disable once InconsistentNaming
/// <summary>
/// CUE-SDK: contains information about led and its color
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal class _CorsairLedColor // contains information about led and its color
internal class _CorsairLedColor
{
/// <summary>
/// CUE-SDK: identifier of LED to set
/// </summary>
internal int ledId;
internal int ledId; // identifier of LED to set
internal int r; // red brightness[0..255]
internal int g; // green brightness[0..255]
internal int b; // blue brightness[0..255]
/// <summary>
/// CUE-SDK: red brightness[0..255]
/// </summary>
internal int r;
/// <summary>
/// CUE-SDK: green brightness[0..255]
/// </summary>
internal int g;
/// <summary>
/// CUE-SDK: blue brightness[0..255]
/// </summary>
internal int b;
};
}

View File

@ -8,13 +8,36 @@ using CUE.NET.Devices.Keyboard.Enums;
namespace CUE.NET.Native
{
// ReSharper disable once InconsistentNaming
/// <summary>
/// CUE-SDK: contains led id and position of led rectangle.Most of the keys are rectangular.
/// In case if key is not rectangular(like Enter in ISO / UK layout) it returns the smallest rectangle that fully contains the key
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal class _CorsairLedPosition // contains led id and position of led rectangle.Most of the keys are rectangular. In case if key is not rectangular(like Enter in ISO / UK layout) it returns the smallest rectangle that fully contains the key
internal class _CorsairLedPosition
{
internal CorsairKeyboardKeyId ledId; // identifier of led
/// <summary>
/// CUE-SDK: identifier of led
/// </summary>
internal CorsairKeyboardKeyId ledId;
/// <summary>
/// CUE-SDK: values in mm
/// </summary>
internal double top;
/// <summary>
/// CUE-SDK: values in mm
/// </summary>
internal double left;
/// <summary>
/// CUE-SDK: values in mm
/// </summary>
internal double height;
internal double width; // values in mm
/// <summary>
/// CUE-SDK: values in mm
/// </summary>
internal double width;
}
}

View File

@ -8,10 +8,20 @@ using System.Runtime.InteropServices;
namespace CUE.NET.Native
{
// ReSharper disable once InconsistentNaming
/// <summary>
/// CUE-SDK: contains number of leds and arrays with their positions
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal class _CorsairLedPositions // contains number of leds and arrays with their positions
internal class _CorsairLedPositions
{
internal int numberOfLed; // integer value.Number of elements in following array
internal IntPtr pLedPosition; // array of led positions
/// <summary>
/// CUE-SDK: integer value.Number of elements in following array
/// </summary>
internal int numberOfLed;
/// <summary>
/// CUE-SDK: array of led positions
/// </summary>
internal IntPtr pLedPosition;
}
}

View File

@ -8,13 +8,37 @@ using System.Runtime.InteropServices;
namespace CUE.NET.Native
{
// ReSharper disable once InconsistentNaming
/// <summary>
/// CUE-SDK: contains information about SDK and CUE versions
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct _CorsairProtocolDetails // contains information about SDK and CUE versions
internal struct _CorsairProtocolDetails
{
internal IntPtr sdkVersion; // null - terminated string containing version of SDK(like “1.0.0.1”). Always contains valid value even if there was no CUE found
internal IntPtr serverVersion; // null - terminated string containing version of CUE(like “1.0.0.1”) or NULL if CUE was not found.
internal int sdkProtocolVersion; // integer number that specifies version of protocol that is implemented by current SDK. Numbering starts from 1. Always contains valid value even if there was no CUE found
internal int serverProtocolVersion; // integer number that specifies version of protocol that is implemented by CUE. Numbering starts from 1. If CUE was not found then this value will be 0
internal byte breakingChanges; // boolean value that specifies if there were breaking changes between version of protocol implemented by server and client
/// <summary>
/// CUE-SDK: null - terminated string containing version of SDK(like “1.0.0.1”). Always contains valid value even if there was no CUE found
/// </summary>
internal IntPtr sdkVersion;
/// <summary>
/// CUE-SDK: null - terminated string containing version of CUE(like “1.0.0.1”) or NULL if CUE was not found.
/// </summary>
internal IntPtr serverVersion;
/// <summary>
/// CUE-SDK: integer number that specifies version of protocol that is implemented by current SDK.
/// Numbering starts from 1. Always contains valid value even if there was no CUE found
/// </summary>
internal int sdkProtocolVersion;
/// <summary>
/// CUE-SDK: integer number that specifies version of protocol that is implemented by CUE.
/// Numbering starts from 1. If CUE was not found then this value will be 0
/// </summary>
internal int serverProtocolVersion;
/// <summary>
/// CUE-SDK: boolean value that specifies if there were breaking changes between version of protocol implemented by server and client
/// </summary>
internal byte breakingChanges;
};
}