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

Compare commits

...

62 Commits

Author SHA1 Message Date
589bd12441
Update README.md 2021-08-05 23:27:28 +02:00
850eb66b3b
Merge pull request #70 from hmmwhatsthisdo/enablekeypresscallback_issue69
Add sanity-check to CueSDK.EnableKeypressHandler()
2018-04-22 16:45:09 +02:00
hmmwhatsthisdo
f3f7f498af Add sanity-check to CueSDK.EnableKeypressHandler() to ensure handlers are only enabled once. Resolves #69. 2018-04-22 06:27:10 -07:00
3b4649604f
Updated readme 2018-01-01 20:02:50 +01:00
83c67195fd Updated version number 2017-11-25 09:14:37 +01:00
811a296867 Added method to opt in to the keypress-callback since this prevents reinitializing 2017-11-25 09:12:57 +01:00
897162926a Updated changenotes and version number 2017-11-18 19:42:55 +01:00
8bcf64a9f9
Merge pull request #65 from DarthAffe/SdkUpdate
Sdk update
2017-11-18 18:27:27 +01:00
5091b33864 Added an event to get the key-change of special keys (G and M) 2017-11-18 12:29:03 +01:00
c4ac6f0e40 Added methods to use the new GetColor method 2017-11-18 11:17:25 +01:00
SpoinkyNL
6840813529 Updated SDK to 2.18.127
Added headset stand support
Added Glaive support
2017-11-13 21:59:33 +01:00
220953bfe7 Fixed an issue that prevents further reinitializing if an exception was thrown earlier 2017-08-13 08:22:18 +02:00
c786710b65 Correctly persisted update-rate in the ambilight example 2017-08-03 18:57:10 +02:00
63ef78f8fc Fixed missing LoadedArchitecture assignment 2017-07-16 12:11:57 +02:00
565e5ca1b2 Updated version number 2017-04-27 20:52:53 +02:00
86c9fb3860 Added an effect-list to the effect-target 2017-04-27 20:50:19 +02:00
33bd76ef0a Added two lists to modify the dative-dll-paths (#58) 2017-04-27 20:43:38 +02:00
5cc1748461 Fixed a bug in the SimpleDevTest and made it a bit more fancy 2017-04-27 20:42:38 +02:00
d17be4a976 Updated Ambilight-example version 2017-04-08 15:19:25 +02:00
0b92068fe6 Fixed DPI-scaling problem in the Ambilight-Example 2017-04-08 15:17:36 +02:00
295a56ca00 Updated CUE.NET package in ambilight example 2017-04-03 17:40:31 +02:00
34394caceb Updated version number 2017-03-18 09:50:51 +01:00
e6719c06a8 Updated SDK to 2.10.91 (this adds lightbar support) 2017-03-17 23:32:30 +01:00
7249da461f Updated version number 2017-02-01 19:47:26 +01:00
8781ce126e Added missing native-reload when calling IsSDKAvailable without initializing 2017-02-01 19:46:54 +01:00
0d5123aca1 Updated changenotes and version number 2017-01-28 14:19:05 +01:00
27562a4787 Added missing null-check while rendering groups 2017-01-28 12:16:46 +01:00
e0790cbc2a Added check for SDK-dll existance 2017-01-15 21:35:47 +01:00
28232a768b Improved performance of the LinearGradient 2017-01-15 14:30:41 +01:00
5e90779398 Fixed wrong region in RainbowGradient 2017-01-15 13:58:02 +01:00
7ef07ed99d Added ConicalGradientBrush 2017-01-15 13:57:44 +01:00
92fcbcff2a Fixed possible cache-issue in the RectangleKeyGroup 2017-01-08 10:51:10 +01:00
8a5581c660 Typo 2017-01-08 10:50:14 +01:00
8404985a55 Adjusted ambilight-example to take profit from the latest version 2017-01-05 20:21:02 +01:00
46c6fc62e3 Updated changenotes and version number 2017-01-05 17:23:33 +01:00
af754af27a Removed pdb from nuget.
Documentation states that this is bad practice.
2017-01-05 17:00:52 +01:00
619b389f7d Fixed some more code issues 2017-01-05 16:50:57 +01:00
d741318462 Added the associated device to CorsairLeds 2017-01-05 16:50:34 +01:00
925e02f146 Fixed some code-issues 2017-01-05 16:37:00 +01:00
8523a4ddb3 Cloned colors assigned to render-targets in the AbstractBrush to prevent reference-issues 2017-01-05 15:08:41 +01:00
1298f59d5a Fixed references in the ambilighte xample to prevent build-errors on the build-server 2017-01-05 15:00:39 +01:00
78dccd2603 Updated some comments and stuff 2017-01-03 22:43:10 +01:00
7fe3ece615 Marked profile-api as obsolete. Wontfix that to work with CUE 2. This closes #54. 2017-01-02 16:28:39 +01:00
74973df040 Updated test-project 2016-12-22 12:28:07 +01:00
9a9bf52fe9 Added new brush-effect to move gradients 2016-12-22 12:27:53 +01:00
55dff06380 Implemented Gradient-Wrapping 2016-12-22 12:03:38 +01:00
da15638817 Added color-corrections for brushes 2016-12-17 14:16:57 +01:00
c13d103566 Updated Ambilight Example to 1.0.1.1 2016-12-11 16:34:00 +01:00
947963a81c Updated Ambilight-Example to use the new gamma-correction 2016-12-11 16:28:28 +01:00
eb3f92d7b0 Fixed stupid bug in the order of applying gamma-correction and brightness/alpha-values 2016-12-11 16:27:54 +01:00
1b4af74b14 Added gamma-value to brushes to allow a simple color correction 2016-12-11 15:41:22 +01:00
17d05d9527 Updated ambilight-example version to 1.0.1 2016-11-12 13:46:53 +01:00
8373863f8c Added MinLightness-Setting to the Ambilight-example 2016-11-12 13:46:22 +01:00
633636efda Fixed wrong offset validation in the Ambilight-example 2016-11-12 13:46:02 +01:00
deb043b6b2 Added key-rectangle to BrushRenderTarget 2016-11-06 17:38:01 +01:00
74824e3363 Added Ambilight-Example-Project 2016-11-06 00:32:40 +01:00
662085a346 Enabled XML-Documentation for help-generation using sandcastle 2016-10-08 20:01:33 +02:00
288a5cf985 Updated version to 1.1.0.2 2016-10-06 20:13:39 +02:00
4a8f6c5928 Correctly implemented equality operators for CorsairColors
This fixes #52
2016-10-06 20:07:02 +02:00
77e4e86777 Updated version to 1.1.0.1 2016-09-11 19:42:48 +02:00
c611675355 Fixed wrong device-rectangle initialize 2016-09-11 19:39:15 +02:00
69a9a122d0 Added missing 'char' indexer for keyboards 2016-09-11 19:36:57 +02:00
101 changed files with 3167 additions and 151 deletions

View File

@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using CUE.NET.ColorCorrection;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Keyboard.Enums;
using CUE.NET.Effects;
@ -34,6 +35,11 @@ namespace CUE.NET.Brushes
/// </summary>
public float Opacity { get; set; }
/// <summary>
/// Gets a list of <see cref="IColorCorrection"/> used to correct the colors of the brush.
/// </summary>
public IList<IColorCorrection> ColorCorrections { get; } = new List<IColorCorrection>();
/// <summary>
/// Gets the Rectangle used in the last render pass.
/// </summary>
@ -79,7 +85,7 @@ namespace CUE.NET.Brushes
RenderedTargets.Clear();
foreach (BrushRenderTarget point in renderTargets)
RenderedTargets[point] = GetColorAtPoint(rectangle, point);
RenderedTargets[point] = new CorsairColor(GetColorAtPoint(rectangle, point)); // Clone the color, we don't want to have reference issues here and brushes might return the same color multiple times!
}
/// <summary>
@ -89,7 +95,7 @@ namespace CUE.NET.Brushes
{
List<BrushRenderTarget> renderTargets = RenderedTargets.Keys.ToList();
foreach (BrushRenderTarget renderTarget in renderTargets)
RenderedTargets[renderTarget] = FinalizeColor(RenderedTargets[renderTarget]);
RenderedTargets[renderTarget] = FinalizeColor(RenderedTargets[renderTarget]); // Cloning here again shouldn't be needed since we did this above.
}
/// <summary>
@ -103,16 +109,21 @@ namespace CUE.NET.Brushes
/// <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.
/// If you overwrite this method please make sure that you never return the same color-object twice to prevent reference-issues!
/// </summary>
/// <param name="color">The color to finalize.</param>
/// <returns>The finalized color.</returns>
protected virtual CorsairColor FinalizeColor(CorsairColor color)
{
foreach (IColorCorrection colorCorrection in ColorCorrections)
colorCorrection.ApplyTo(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.GetHSVHue(), color.GetHSVSaturation(), finalBrightness, finalAlpha);
}

View File

@ -3,6 +3,7 @@
using System.Drawing;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Helper;
namespace CUE.NET.Brushes
{
@ -18,6 +19,11 @@ namespace CUE.NET.Brushes
/// </summary>
public CorsairLedId LedId { get; }
/// <summary>
/// Gets the rectangle representing the area to render the target-LED.
/// </summary>
public RectangleF Rectangle { get; }
/// <summary>
/// Gets the point representing the position to render the target-LED.
/// </summary>
@ -31,11 +37,13 @@ namespace CUE.NET.Brushes
/// Initializes a new instance of the <see cref="BrushRenderTarget"/> class.
/// </summary>
/// <param name="ledId">The ID of the target-LED.</param>
/// <param name="point">The point representing the position to render the target-LED.</param>
public BrushRenderTarget(CorsairLedId ledId, PointF point)
/// <param name="rectangle">The rectangle representing the area to render the target-LED.</param>
public BrushRenderTarget(CorsairLedId ledId, RectangleF rectangle)
{
this.Point = point;
this.Rectangle = rectangle;
this.LedId = ledId;
Point = rectangle.GetCenter();
}
#endregion

View File

@ -0,0 +1,103 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable MemberCanBeProtected.Global
// ReSharper disable ReturnTypeCanBeEnumerable.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// ReSharper disable UnusedMember.Global
using System;
using System.Drawing;
using CUE.NET.Devices.Generic;
using CUE.NET.Gradients;
namespace CUE.NET.Brushes
{
/// <summary>
/// Represents a brush drawing a conical gradient.
/// </summary>
public class ConicalGradientBrush : AbstractBrush, IGradientBrush
{
#region Properties & Fields
/// <summary>
/// Gets or sets the origin (radian-angle) the brush is drawn to. (default: -π/2)
/// </summary>
public float Origin { get; set; } = (float)Math.Atan2(-1, 0);
/// <summary>
/// Gets or sets the center point (as percentage in the range [0..1]) of the gradient drawn by the brush. (default: 0.5f, 0.5f)
/// </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="ConicalGradientBrush"/> class.
/// </summary>
public ConicalGradientBrush()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ConicalGradientBrush"/> class.
/// </summary>
/// <param name="gradient">The gradient drawn by the brush.</param>
public ConicalGradientBrush(IGradient gradient)
{
this.Gradient = gradient;
}
/// <summary>
/// Initializes a new instance of the <see cref="ConicalGradientBrush"/> 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 ConicalGradientBrush(PointF center, IGradient gradient)
{
this.Center = center;
this.Gradient = gradient;
}
/// <summary>
/// Initializes a new instance of the <see cref="ConicalGradientBrush"/> class.
/// </summary>
/// <param name="center">The center point (as percentage in the range [0..1]).</param>
/// <param name="origin">The origin (radian-angle) the brush is drawn to.</param>
/// <param name="gradient">The gradient drawn by the brush.</param>
public ConicalGradientBrush(PointF center, float origin, IGradient gradient)
{
this.Center = center;
this.Origin = origin;
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="renderTarget">The target (key/point) from which the color should be taken.</param>
/// <returns>The color at the specified point.</returns>
protected override CorsairColor GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
{
float centerX = rectangle.Width * Center.X;
float centerY = rectangle.Height * Center.Y;
double angle = Math.Atan2(renderTarget.Point.Y - centerY, renderTarget.Point.X - centerX) - Origin;
if (angle < 0) angle += Math.PI * 2;
float offset = (float)(angle / (Math.PI * 2));
return Gradient.GetColor(offset);
}
#endregion
}
}

View File

@ -1,8 +1,10 @@
// ReSharper disable UnusedMemberInSuper.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable ReturnTypeCanBeEnumerable.Global
using System.Collections.Generic;
using System.Drawing;
using CUE.NET.ColorCorrection;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Keyboard.Enums;
using CUE.NET.Effects;
@ -29,6 +31,11 @@ namespace CUE.NET.Brushes
/// </summary>
float Opacity { get; set; }
/// <summary>
/// Gets a list of color-corrections used to correct the colors of the brush.
/// </summary>
IList<IColorCorrection> ColorCorrections { get; }
/// <summary>
/// Gets the Rectangle used in the last render pass.
/// </summary>

View File

@ -2,8 +2,14 @@
namespace CUE.NET.Brushes
{
/// <summary>
/// Represents a basic gradient-brush.
/// </summary>
public interface IGradientBrush : IBrush
{
/// <summary>
/// Gets the gradient used by this <see cref="IGradientBrush"/>.
/// </summary>
IGradient Gradient { get; }
}
}

View File

@ -50,21 +50,37 @@ namespace CUE.NET.Brushes
#region Operators
/// <summary>
/// Converts a <see cref="Color" /> to a <see cref="SolidColorBrush" />.
/// </summary>
/// <param name="color">The <see cref="Color"/> to convert.</param>
public static explicit operator SolidColorBrush(Color color)
{
return new SolidColorBrush(color);
}
/// <summary>
/// Converts a <see cref="SolidColorBrush" /> to a <see cref="Color" />.
/// </summary>
/// <param name="brush">The <see cref="Color"/> to convert.</param>
public static implicit operator Color(SolidColorBrush brush)
{
return brush.Color;
}
/// <summary>
/// Converts a <see cref="CorsairColor" /> to a <see cref="SolidColorBrush" />.
/// </summary>
/// <param name="color">The <see cref="Color"/> to convert.</param>
public static explicit operator SolidColorBrush(CorsairColor color)
{
return new SolidColorBrush(color);
}
/// <summary>
/// Converts a <see cref="SolidColorBrush" /> to a <see cref="CorsairColor" />.
/// </summary>
/// <param name="brush">The <see cref="Color"/> to convert.</param>
public static implicit operator CorsairColor(SolidColorBrush brush)
{
return brush.Color;

View File

@ -22,6 +22,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<DocumentationFile>bin\CUE.NET.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\</OutputPath>
@ -32,6 +33,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<DocumentationFile>bin\CUE.NET.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@ -45,15 +47,19 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Brushes\ConicalGradientBrush.cs" />
<Compile Include="Brushes\IGradientBrush.cs" />
<Compile Include="Brushes\ImageBrush.cs" />
<Compile Include="Brushes\ProfileBrush.cs" />
<Compile Include="Brushes\BrushRenderTarget.cs" />
<Compile Include="ColorCorrection\GammaCorrection.cs" />
<Compile Include="ColorCorrection\IColorCorrection.cs" />
<Compile Include="CueSDKAutoUpdate.cs" />
<Compile Include="Devices\Generic\CorsairColor.cs" />
<Compile Include="Devices\Generic\Enums\CorsairAccessMode.cs" />
<Compile Include="Devices\Generic\Enums\CorsairDeviceCaps.cs" />
<Compile Include="Devices\Generic\Enums\CorsairDeviceType.cs" />
<Compile Include="Devices\Generic\Enums\CorsairKeyId.cs" />
<Compile Include="Devices\Generic\Enums\CorsairLedId.cs" />
<Compile Include="Devices\Generic\EventArgs\ExceptionEventArgs.cs" />
<Compile Include="Brushes\AbstractBrush.cs" />
@ -62,7 +68,12 @@
<Compile Include="Devices\Generic\EventArgs\UpdatedEventArgs.cs" />
<Compile Include="Devices\Generic\EventArgs\UpdatingEventArgs.cs" />
<Compile Include="Devices\Generic\LedUpateRequest.cs" />
<Compile Include="Devices\HeadsetStand\CorsairHeadsetStand.cs" />
<Compile Include="Devices\HeadsetStand\CorsairHeadsetStandDeviceInfo.cs" />
<Compile Include="Devices\HeadsetStand\Enums\CorsairHeadsetStandLedId.cs" />
<Compile Include="Devices\Keyboard\Enums\BrushCalculationMode.cs" />
<Compile Include="Devices\Keyboard\Enums\CorsairKeyboardKeyId.cs" />
<Compile Include="Devices\Mouse\Enums\CorsairMouseKeyId.cs" />
<Compile Include="Effects\AbstractLedGroupEffect.cs" />
<Compile Include="Effects\AbstractBrushEffect.cs" />
<Compile Include="Effects\AbstractEffectTarget.cs" />
@ -70,6 +81,8 @@
<Compile Include="Devices\Mousemat\CorsairMousemat.cs" />
<Compile Include="Devices\Mousemat\CorsairMousematDeviceInfo.cs" />
<Compile Include="Devices\Mousemat\Enums\CorsairMousematLedId.cs" />
<Compile Include="Effects\MoveGradientEffect.cs" />
<Compile Include="EventArgs\KeyPressedEventArgs.cs" />
<Compile Include="Gradients\AbstractGradient.cs" />
<Compile Include="Gradients\GradientStop.cs" />
<Compile Include="Gradients\IGradient.cs" />

View File

@ -3,7 +3,7 @@
<metadata>
<id>CUE.NET</id>
<title>CUE.NET</title>
<version>1.1.0.0</version>
<version>1.2.0.1</version>
<authors>Darth Affe</authors>
<owners>Darth Affe</owners>
<projectUrl>https://github.com/DarthAffe/CUE.NET</projectUrl>
@ -11,20 +11,14 @@
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>Corsair HID SDK Wrapper</description>
<releaseNotes>
######### #########
### This release contains a lot of breaking changes and will most likely not work without changes to existing code! ###
######### #########
Updated SDK to 2.4.67,
Adde Corsair RGB Mous Mat support,
Rewrote brushes to perform two-pass-rendering,
Added own Color-Type to allow easier extension and modification (this type can be implicit converted to .NET-Colors)
Refactored everything to work based on LEDs - This will adapt the devices and reduces the importance of the "special case keyboard",
Added usable effect-system which allows to modify groups and brushes,
Refactored automatic updates to be SDK-wide (moved from device to CueSDK)
- Updated SDK to 2.18.127
- Added methods to use the new GetColor method
- Added an event to get the key-change of special keys (G and M)
- Fixed missing LoadedArchitecture assignment
- Fixed an issue that prevents further reinitializing if an exception was thrown earlier
</releaseNotes>
<summary>C# (.NET) Wrapper library around the Corsair CUE-SDK</summary>
<copyright>Copyright © Wyrez 2016</copyright>
<copyright>Copyright © Wyrez 2017</copyright>
<language>en-US</language>
</metadata>
<files>

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUE.NET", "CUE.NET.csproj", "{70A266B5-E9D4-4EAA-A91A-947C0039FFB6}"
EndProject
@ -32,6 +32,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AudioAnalyzer", "AudioAnaly
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example_AudioAnalyzer_full", "Examples\AudioAnalyzer\Example_AudioAnalyzer_full\Example_AudioAnalyzer_full.csproj", "{E06B4E1D-9735-4CB4-BC11-9ECDF27A0972}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ambilight", "Ambilight", "{1ABADCA4-AC96-4E9F-91C5-232EB824D6DE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example_Ambilight_full", "Examples\Ambilight\Example_Ambilight_full\Example_Ambilight_full.csproj", "{6D7BAF89-A705-4FFA-A3A2-AF93EC3A909C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -50,6 +54,10 @@ Global
{E06B4E1D-9735-4CB4-BC11-9ECDF27A0972}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E06B4E1D-9735-4CB4-BC11-9ECDF27A0972}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E06B4E1D-9735-4CB4-BC11-9ECDF27A0972}.Release|Any CPU.Build.0 = Release|Any CPU
{6D7BAF89-A705-4FFA-A3A2-AF93EC3A909C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6D7BAF89-A705-4FFA-A3A2-AF93EC3A909C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6D7BAF89-A705-4FFA-A3A2-AF93EC3A909C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D7BAF89-A705-4FFA-A3A2-AF93EC3A909C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -61,5 +69,7 @@ Global
{2F99124B-FAED-432D-B797-45566D373411} = {D69EF6D8-68FF-4C56-B5CB-253971B1DF91}
{BE16A0BF-6794-4718-AF27-F2A50078D880} = {1F52DDC9-E9D0-4A7B-8E78-930528203EE6}
{E06B4E1D-9735-4CB4-BC11-9ECDF27A0972} = {BE16A0BF-6794-4718-AF27-F2A50078D880}
{1ABADCA4-AC96-4E9F-91C5-232EB824D6DE} = {1F52DDC9-E9D0-4A7B-8E78-930528203EE6}
{6D7BAF89-A705-4FFA-A3A2-AF93EC3A909C} = {1ABADCA4-AC96-4E9F-91C5-232EB824D6DE}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,108 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
using System;
using CUE.NET.Devices.Generic;
using CUE.NET.Helper;
namespace CUE.NET.ColorCorrection
{
/// <summary>
/// Represents a gamma-color-correction.
/// </summary>
public class GammaCorrection : IColorCorrection
{
#region Properties & Fields
/// <summary>
/// Gets or sets the gamma-value of the color 'red' used for color-correction.
/// Values greater than one will make colors brighter, values less than one will make colors darker.
/// </summary>
public float R { get; set; }
/// <summary>
/// Gets or sets the gamma-value of the color 'green' used for color-correction.
/// Values greater than one will make colors brighter, values less than one will make colors darker.
/// </summary>
public float G { get; set; }
/// <summary>
/// Gets or sets the gamma-value of the color 'blue' used for color-correction.
/// Values greater than one will make colors brighter, values less than one will make colors darker.
/// </summary>
public float B { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="GammaCorrection"/> class using the default-value 1f (no correction) for all colors.
/// </summary>
public GammaCorrection() : this(1f) { }
/// <summary>
/// Initializes a new instance of the <see cref="GammaCorrection"/> class.
/// </summary>
/// <param name="gamma">The gamma-value for all colors used for color-correction.
/// Values greater than one will make colors brighter, values less than one will make colors darker.</param>
public GammaCorrection(float gamma)
{
this.R = gamma;
this.G = gamma;
this.B = gamma;
}
/// <summary>
/// Initializes a new instance of the <see cref="GammaCorrection"/> class.
/// </summary>
/// <param name="r">The gamma-value for the color 'red' used for color-correction.
/// Values greater than one will make colors brighter, values less than one will make colors darker.</param>
/// <param name="g">The gamma-value for the color 'green' used for color-correction. Values
/// greater than one will make colors brighter, values less than one will make colors darker.</param>
/// <param name="b">The gamma-value for the color 'blue' used for color-correction. Values
/// greater than one will make colors brighter, values less than one will make colors darker.</param>
public GammaCorrection(float r, float g, float b)
{
this.R = r;
this.G = g;
this.B = b;
}
#endregion
#region Methods
/// <summary>
/// Applies the gamma-correction to the given color.
/// </summary>
/// <param name="color">The color to correct.</param>
public void ApplyTo(CorsairColor color)
{
if (Math.Abs(R - 1f) > float.Epsilon)
color.R = ColorHelper.GetIntColorFromFloat((float)Math.Pow(color.GetFloatR(), 1.0 / R));
if (Math.Abs(G - 1f) > float.Epsilon)
color.G = ColorHelper.GetIntColorFromFloat((float)Math.Pow(color.GetFloatG(), 1.0 / G));
if (Math.Abs(B - 1f) > float.Epsilon)
color.B = ColorHelper.GetIntColorFromFloat((float)Math.Pow(color.GetFloatB(), 1.0 / B));
}
#endregion
#region Operators
/// <summary>
/// Converts a <see cref="float" /> to a <see cref="GammaCorrection" /> using the same value for all colors.
/// </summary>
/// <param name="gamma">The float-value to convert.</param>
public static implicit operator GammaCorrection(float gamma)
{
return new GammaCorrection(gamma);
}
#endregion
}
}

View File

@ -0,0 +1,16 @@
using CUE.NET.Devices.Generic;
namespace CUE.NET.ColorCorrection
{
/// <summary>
/// Represents generic color-correction.
/// </summary>
public interface IColorCorrection
{
/// <summary>
/// Applies the color-correction to the given color.
/// </summary>
/// <param name="color">The color to correct.</param>
void ApplyTo(CorsairColor color);
}
}

131
CueSDK.cs
View File

@ -1,6 +1,7 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
@ -8,20 +9,37 @@ using CUE.NET.Devices;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Headset;
using CUE.NET.Devices.HeadsetStand;
using CUE.NET.Devices.Keyboard;
using CUE.NET.Devices.Mouse;
using CUE.NET.Devices.Mousemat;
using CUE.NET.EventArgs;
using CUE.NET.Exceptions;
using CUE.NET.Native;
namespace CUE.NET
{
/// <summary>
/// Static entry point to work with the Corsair-SDK.
/// </summary>
public static partial class CueSDK
{
#region Properties & Fields
// ReSharper disable UnusedAutoPropertyAccessor.Global
/// <summary>
/// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications.
/// The first match will be used.
/// </summary>
public static List<string> PossibleX86NativePaths { get; } = new List<string> { "x86/CUESDK_2015.dll", "x86/CUESDK.dll" };
/// <summary>
/// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications.
/// The first match will be used.
/// </summary>
public static List<string> PossibleX64NativePaths { get; } = new List<string> { "x64/CUESDK_2015.dll", "x64/CUESDK.dll" };
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
@ -71,13 +89,35 @@ namespace CUE.NET
public static CorsairHeadset HeadsetSDK { get; private set; }
/// <summary>
/// Gets the managed representation of a moustmat managed by the CUE-SDK.
/// Gets the managed representation of a mousemat managed by the CUE-SDK.
/// Note that currently only one connected mousemat is supported.
/// </summary>
public static CorsairMousemat MousematSDK { get; private set; }
/// <summary>
/// Gets the managed representation of a headset stand managed by the CUE-SDK.
/// Note that currently only one connected headset stand is supported.
/// </summary>
public static CorsairHeadsetStand HeadsetStandSDK { get; private set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void OnKeyPressedDelegate(IntPtr context, CorsairKeyId keyId, [MarshalAs(UnmanagedType.I1)] bool pressed);
private static OnKeyPressedDelegate _onKeyPressedDelegate;
#endregion
#region Events
/// <summary>
/// Occurs when the SDK reports that a key is pressed.
/// Notice that right now only G- (keyboard) and M- (mouse) keys are supported.
///
/// To enable this event <see cref="EnableKeypressCallback"/> needs to be called.
/// </summary>
public static event EventHandler<KeyPressedEventArgs> KeyPressed;
#endregion
#region Methods
@ -85,12 +125,13 @@ namespace CUE.NET
/// <summary>
/// Checks if the SDK for the provided <see cref="CorsairDeviceType"/> is available or checks if CUE is installed and SDK supported enabled if null is provided.
/// </summary>
/// <param name="sdkType">The <see cref="CorsairDeviceType"/> to check or null to check for generall SDK availability.</param>
/// <param name="sdkType">The <see cref="CorsairDeviceType"/> to check or null to check for general SDK availability.</param>
/// <returns>The availability of the provided <see cref="CorsairDeviceType"/>.</returns>
public static bool IsSDKAvailable(CorsairDeviceType? sdkType = null)
{
try
{
// ReSharper disable once RedundantIfElseBlock
if (IsInitialized)
{
// ReSharper disable once SwitchStatementMissingSomeCases - everything else is true
@ -104,12 +145,15 @@ namespace CUE.NET
return HeadsetSDK != null;
case CorsairDeviceType.Mousemat:
return MousematSDK != null;
case CorsairDeviceType.HeadsetStand:
return HeadsetStandSDK != null;
default:
return true;
}
}
else
{
_CUESDK.Reload();
_CUESDK.CorsairPerformProtocolHandshake();
if (sdkType == null || sdkType == CorsairDeviceType.Unknown)
@ -143,11 +187,13 @@ namespace CUE.NET
if (IsInitialized)
throw new WrapperException("CueSDK is already initialized.");
_CUESDK.Reload();
ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake());
CorsairError error = LastError;
if (error != CorsairError.Success)
Throw(error);
Throw(error, true);
if (ProtocolDetails.BreakingChanges)
throw new WrapperException("The SDK currently used isn't compatible with the installed version of CUE.\r\n"
@ -157,7 +203,7 @@ namespace CUE.NET
if (exclusiveAccess)
{
if (!_CUESDK.CorsairRequestControl(CorsairAccessMode.ExclusiveLightingControl))
Throw(LastError);
Throw(LastError, true);
HasExclusiveAccess = true;
}
@ -186,6 +232,9 @@ namespace CUE.NET
case CorsairDeviceType.Mousemat:
device = MousematSDK = new CorsairMousemat(new CorsairMousematDeviceInfo(nativeDeviceInfo));
break;
case CorsairDeviceType.HeadsetStand:
device = HeadsetStandSDK = new CorsairHeadsetStand(new CorsairHeadsetStandDeviceInfo(nativeDeviceInfo));
break;
// ReSharper disable once RedundantCaseLabel
case CorsairDeviceType.Unknown:
default:
@ -197,14 +246,45 @@ namespace CUE.NET
error = LastError;
if (error != CorsairError.Success)
Throw(error);
Throw(error, true);
}
error = LastError;
if (error != CorsairError.Success)
Throw(error, false);
InitializedDevices = new ReadOnlyCollection<ICueDevice>(devices);
IsInitialized = true;
}
/// <summary>
/// Enables the keypress-callback.
/// This method needs to be called to enable the <see cref="KeyPressed"/>-event.
///
/// WARNING: AFTER THIS METHOD IS CALLED IT'S NO LONGER POSSIBLE TO REINITIALIZE THE SDK!
/// </summary>
public static void EnableKeypressCallback()
{
if (!IsInitialized)
throw new WrapperException("CueSDK isn't initialized.");
if (_onKeyPressedDelegate != null)
return;
_onKeyPressedDelegate = OnKeyPressed;
_CUESDK.CorsairRegisterKeypressCallback(Marshal.GetFunctionPointerForDelegate(_onKeyPressedDelegate), IntPtr.Zero);
}
/// <summary>
/// Resets the colors of all devices back to the last saved color-data. (If there wasn't a manual save, that's the data from the time the SDK was initialized.)
/// </summary>
public static void Reset()
{
foreach (ICueDevice device in InitializedDevices)
device.RestoreColors();
}
/// <summary>
/// Reinitialize the CUE-SDK and temporarily hand back full control to CUE.
/// </summary>
@ -222,10 +302,14 @@ namespace CUE.NET
if (!IsInitialized)
throw new WrapperException("CueSDK isn't initialized.");
if (_onKeyPressedDelegate != null)
throw new WrapperException("Keypress-Callback is enabled.");
KeyboardSDK?.ResetLeds();
MouseSDK?.ResetLeds();
HeadsetSDK?.ResetLeds();
MousematSDK?.ResetLeds();
HeadsetStandSDK?.ResetLeds();
_CUESDK.Reload();
@ -233,7 +317,7 @@ namespace CUE.NET
CorsairError error = LastError;
if (error != CorsairError.Success)
Throw(error);
Throw(error, false);
if (ProtocolDetails.BreakingChanges)
throw new WrapperException("The SDK currently used isn't compatible with the installed version of CUE.\r\n"
@ -242,7 +326,7 @@ namespace CUE.NET
if (exclusiveAccess)
if (!_CUESDK.CorsairRequestControl(CorsairAccessMode.ExclusiveLightingControl))
Throw(LastError);
Throw(LastError, false);
HasExclusiveAccess = exclusiveAccess;
int deviceCount = _CUESDK.CorsairGetDeviceCount();
@ -257,7 +341,7 @@ namespace CUE.NET
error = LastError;
if (error != CorsairError.Success)
Throw(error);
Throw(error, false);
}
if (KeyboardSDK != null)
@ -276,23 +360,38 @@ namespace CUE.NET
if (!reloadedDevices.ContainsKey(CorsairDeviceType.Mousemat)
|| MousematSDK.MousematDeviceInfo.Model != reloadedDevices[CorsairDeviceType.Mousemat].Model)
throw new WrapperException("The previously loaded Mousemat got disconnected.");
if (HeadsetStandSDK != null)
if (!reloadedDevices.ContainsKey(CorsairDeviceType.HeadsetStand)
|| HeadsetStandSDK.HeadsetStandDeviceInfo.Model != reloadedDevices[CorsairDeviceType.HeadsetStand].Model)
throw new WrapperException("The previously loaded Headset Stand got disconnected.");
error = LastError;
if (error != CorsairError.Success)
Throw(error, false);
IsInitialized = true;
}
private static void Throw(CorsairError error)
private static void Throw(CorsairError error, bool reset)
{
ProtocolDetails = null;
HasExclusiveAccess = false;
KeyboardSDK = null;
MouseSDK = null;
HeadsetSDK = null;
MousematSDK = null;
IsInitialized = false;
if (reset)
{
ProtocolDetails = null;
HasExclusiveAccess = false;
KeyboardSDK = null;
MouseSDK = null;
HeadsetSDK = null;
MousematSDK = null;
HeadsetStandSDK = null;
IsInitialized = false;
}
throw new CUEException(error);
}
private static void OnKeyPressed(IntPtr context, CorsairKeyId keyId, bool pressed)
=> KeyPressed?.Invoke(null, new KeyPressedEventArgs(keyId, pressed));
#endregion
}
}

View File

@ -9,6 +9,9 @@ using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET
{
/// <summary>
/// Static entry point to work with the Corsair-SDK.
/// </summary>
public static partial class CueSDK
{
#region Properties & Fields

View File

@ -29,6 +29,8 @@ namespace CUE.NET.Devices.Generic
private static DateTime _lastUpdate = DateTime.Now;
private Dictionary<CorsairLedId, CorsairColor> _colorDataSave;
/// <summary>
/// Gets generic information provided by CUE for the device.
/// </summary>
@ -37,7 +39,7 @@ namespace CUE.NET.Devices.Generic
/// <summary>
/// Gets the rectangle containing all LEDs of the device.
/// </summary>
public RectangleF DeviceRectangle { get; }
public RectangleF DeviceRectangle { get; protected set; }
/// <summary>
/// Gets a dictionary containing all LEDs of the device.
@ -56,6 +58,7 @@ namespace CUE.NET.Devices.Generic
/// <summary>
/// Gets or sets the background brush of the keyboard.
/// If this is null the last saved color-data is used as background.
/// </summary>
public IBrush Brush { get; set; }
@ -139,8 +142,6 @@ namespace CUE.NET.Devices.Generic
protected AbstractCueDevice(IDeviceInfo info)
{
this.DeviceInfo = info;
DeviceRectangle = RectangleHelper.CreateRectangleFromRectangles((this).Select(x => x.LedRectangle));
}
#endregion
@ -152,7 +153,11 @@ namespace CUE.NET.Devices.Generic
/// <summary>
/// Initializes the device.
/// </summary>
public abstract void Initialize();
public virtual void Initialize()
{
DeviceRectangle = RectangleHelper.CreateRectangleFromRectangles((this).Select(x => x.LedRectangle));
SaveColors();
}
/// <summary>
/// Initializes the LED-Object with the specified id.
@ -164,7 +169,7 @@ namespace CUE.NET.Devices.Generic
{
if (LedMapping.ContainsKey(ledId)) return null;
CorsairLed led = new CorsairLed(ledId, ledRectangle);
CorsairLed led = new CorsairLed(this, ledId, ledRectangle);
LedMapping.Add(ledId, led);
return led;
}
@ -186,19 +191,26 @@ namespace CUE.NET.Devices.Generic
/// Performs an update for all dirty keys, or all keys if flushLeds is set to true.
/// </summary>
/// <param name="flushLeds">Specifies whether all keys (including clean ones) should be updated.</param>
public void Update(bool flushLeds = false)
/// <param name="noRender">Only updates the hardware-leds skippin effects and the render-pass. Only use this if you know what that means!</param>
public void Update(bool flushLeds = false, bool noRender = false)
{
OnUpdating();
// Update effects
foreach (ILedGroup ledGroup in LedGroups)
ledGroup.UpdateEffects();
if (!noRender)
{
// Update effects
foreach (ILedGroup ledGroup in LedGroups)
ledGroup.UpdateEffects();
// Render brushes
Render(this);
foreach (ILedGroup ledGroup in LedGroups.OrderBy(x => x.ZIndex))
Render(ledGroup);
// Render brushes
if (Brush != null)
Render(this);
else
ApplyColorData(_colorDataSave);
foreach (ILedGroup ledGroup in LedGroups.OrderBy(x => x.ZIndex))
Render(ledGroup);
}
// Device-specific updates
DeviceUpdate();
@ -225,8 +237,12 @@ namespace CUE.NET.Devices.Generic
// ReSharper disable once MemberCanBeMadeStatic.Local - idc
protected virtual void Render(ILedGroup ledGroup)
{
if (ledGroup == null) return;
IList<CorsairLed> leds = ledGroup.GetLeds().ToList();
IBrush brush = ledGroup.Brush;
if (brush == null) return;
try
{
@ -238,10 +254,10 @@ namespace CUE.NET.Devices.Generic
float offsetY = -brushRectangle.Y;
brushRectangle.X = 0;
brushRectangle.Y = 0;
brush.PerformRender(brushRectangle, leds.Select(x => new BrushRenderTarget(x.Id, x.LedRectangle.GetCenter(offsetX, offsetY))));
brush.PerformRender(brushRectangle, leds.Select(x => new BrushRenderTarget(x.Id, x.LedRectangle.Move(offsetX, offsetY))));
break;
case BrushCalculationMode.Absolute:
brush.PerformRender(DeviceRectangle, leds.Select(x => new BrushRenderTarget(x.Id, x.LedRectangle.GetCenter())));
brush.PerformRender(DeviceRectangle, leds.Select(x => new BrushRenderTarget(x.Id, x.LedRectangle)));
break;
default:
throw new ArgumentException();
@ -288,6 +304,63 @@ namespace CUE.NET.Devices.Generic
OnLedsUpdated(updateRequests);
}
/// <inheritdoc />
public void SyncColors()
{
Dictionary<CorsairLedId, CorsairColor> colorData = GetColors();
ApplyColorData(colorData);
Update(true, true);
}
/// <inheritdoc />
public void SaveColors()
{
_colorDataSave = GetColors();
}
/// <inheritdoc />
public void RestoreColors()
{
ApplyColorData(_colorDataSave);
Update(true, true);
}
private void ApplyColorData(Dictionary<CorsairLedId, CorsairColor> colorData)
{
if (colorData == null) return;
foreach (KeyValuePair<CorsairLedId, CorsairColor> corsairColor in _colorDataSave)
LedMapping[corsairColor.Key].Color = corsairColor.Value;
}
private Dictionary<CorsairLedId, CorsairColor> GetColors()
{
int structSize = Marshal.SizeOf(typeof(_CorsairLedColor));
IntPtr ptr = Marshal.AllocHGlobal(structSize * LedMapping.Count);
IntPtr addPtr = new IntPtr(ptr.ToInt64());
foreach (KeyValuePair<CorsairLedId, CorsairLed> led in LedMapping)
{
_CorsairLedColor color = new _CorsairLedColor { ledId = (int)led.Value.Id };
Marshal.StructureToPtr(color, addPtr, false);
addPtr = new IntPtr(addPtr.ToInt64() + structSize);
}
_CUESDK.CorsairGetLedsColors(LedMapping.Count, ptr);
IntPtr readPtr = ptr;
Dictionary<CorsairLedId, CorsairColor> colorData = new Dictionary<CorsairLedId, CorsairColor>();
for (int i = 0; i < LedMapping.Count; i++)
{
_CorsairLedColor ledColor = (_CorsairLedColor)Marshal.PtrToStructure(readPtr, typeof(_CorsairLedColor));
colorData.Add((CorsairLedId)ledColor.ledId, new CorsairColor((byte)ledColor.r, (byte)ledColor.g, (byte)ledColor.b));
readPtr = new IntPtr(readPtr.ToInt64() + structSize);
}
Marshal.FreeHGlobal(ptr);
return colorData;
}
#endregion
#region LedGroup
@ -340,6 +413,12 @@ namespace CUE.NET.Devices.Generic
#region Effects
/// <summary>
/// Gets a list of all active effects of this target.
/// For this device this is always null.
/// </summary>
public IList<IEffect<ILedGroup>> Effects => null;
/// <summary>
/// NOT IMPLEMENTED: Effects can't be applied directly to the device. Add it to the Brush or create a ledgroup instead.
/// </summary>
@ -395,7 +474,7 @@ namespace CUE.NET.Devices.Generic
{
long lastUpdateTicks = _lastUpdate.Ticks;
_lastUpdate = DateTime.Now;
Updating?.Invoke(this, new UpdatingEventArgs((float)((DateTime.Now.Ticks - lastUpdateTicks) / 10000000f)));
Updating?.Invoke(this, new UpdatingEventArgs((DateTime.Now.Ticks - lastUpdateTicks) / 10000000f));
}
catch
{

View File

@ -2,35 +2,77 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// ReSharper disable UnusedMember.Global
using System.Diagnostics;
using System.Drawing;
namespace CUE.NET.Devices.Generic
{
/// <summary>
/// Represents an ARGB (alpha, red, green, blue) color used by CUE.NET.
/// </summary>
[DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")]
public class CorsairColor
{
#region Constants
/// <summary>
/// Gets an transparent color [A: 0, R: 0, G: 0, B: 0]
/// </summary>
public static CorsairColor Transparent => Color.Transparent;
#endregion
#region Properties & Fields
/// <summary>
/// Gets or sets the alpha component value of this <see cref="CorsairColor"/>.
/// </summary>
public byte A { get; set; }
/// <summary>
/// Gets or sets the red component value of this <see cref="CorsairColor"/>.
/// </summary>
public byte R { get; set; }
/// <summary>
/// Gets or sets the green component value of this <see cref="CorsairColor"/>.
/// </summary>
public byte G { get; set; }
/// <summary>
/// Gets or sets the blue component value of this <see cref="CorsairColor"/>.
/// </summary>
public byte B { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CorsairColor"/> class.
/// The class created by this constructor equals <see cref="Transparent"/>.
/// </summary>
public CorsairColor()
{ }
public CorsairColor(byte r, byte g, byte b) : this(255, r, g, b)
/// <summary>
/// Initializes a new instance of the <see cref="CorsairColor"/> class using only RGB-Values.
/// Alpha defaults to 255.
/// </summary>
/// <param name="r">The red component value of this <see cref="CorsairColor"/>.</param>
/// <param name="g">The green component value of this <see cref="CorsairColor"/>.</param>
/// <param name="b">The blue component value of this <see cref="CorsairColor"/>.</param>
public CorsairColor(byte r, byte g, byte b)
: this(255, r, g, b)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="CorsairColor"/> class using ARGB-values.
/// </summary>
/// <param name="a">The alpha component value of this <see cref="CorsairColor"/>.</param>
/// <param name="r">The red component value of this <see cref="CorsairColor"/>.</param>
/// <param name="g">The green component value of this <see cref="CorsairColor"/>.</param>
/// <param name="b">The blue component value of this <see cref="CorsairColor"/>.</param>
public CorsairColor(byte a, byte r, byte g, byte b)
{
this.A = a;
@ -39,15 +81,97 @@ namespace CUE.NET.Devices.Generic
this.B = b;
}
/// <summary>
/// Initializes a new instance of the <see cref="CorsairColor"/> class by cloning a existing <see cref="CorsairColor"/>.
/// </summary>
/// <param name="color">The <see cref="CorsairColor"/> the values are copied from.</param>
public CorsairColor(CorsairColor color)
: this(color.A, color.R, color.G, color.B)
{ }
#endregion
#region Operators
/// <summary>
/// Converts the individual byte-values of this <see cref="CorsairColor"/> to a human-readable string.
/// </summary>
/// <returns>A string that contains the individual byte-values of this <see cref="CorsairColor"/>. For example "[A: 255, R: 255, G: 0, B: 0]".</returns>
public override string ToString()
{
return $"[A: {A}, R: {R}, G: {G}, B: {B}]";
}
/// <summary>
/// Tests whether the specified object is a <see cref="CorsairColor" /> and is equivalent to this <see cref="CorsairColor" />.
/// </summary>
/// <param name="obj">The object to test.</param>
/// <returns>true if <paramref name="obj" /> is a <see cref="CorsairColor" /> equivalent to this <see cref="CorsairColor" /> ; otherwise, false.</returns>
public override bool Equals(object obj)
{
CorsairColor compareColor = obj as CorsairColor;
if (ReferenceEquals(compareColor, null))
return false;
if (ReferenceEquals(this, compareColor))
return true;
if (GetType() != compareColor.GetType())
return false;
return (compareColor.A == A) && (compareColor.R == R) && (compareColor.G == G) && (compareColor.B == B);
}
/// <summary>
/// Returns a hash code for this <see cref="CorsairColor" />.
/// </summary>
/// <returns>An integer value that specifies the hash code for this <see cref="CorsairColor" />.</returns>
public override int GetHashCode()
{
unchecked
{
int hashCode = A.GetHashCode();
hashCode = (hashCode * 397) ^ R.GetHashCode();
hashCode = (hashCode * 397) ^ G.GetHashCode();
hashCode = (hashCode * 397) ^ B.GetHashCode();
return hashCode;
}
}
/// <summary>
/// Returns a value that indicates whether two specified <see cref="CorsairColor" /> are equal.
/// </summary>
/// <param name="color1">The first <see cref="CorsairColor" /> color to compare.</param>
/// <param name="color2">The second <see cref="CorsairColor" /> color to compare.</param>
/// <returns>true if <paramref name="color1" /> and <paramref name="color2" /> are equal; otherwise, false.</returns>
public static bool operator ==(CorsairColor color1, CorsairColor color2)
{
return ReferenceEquals(color1, null) ? ReferenceEquals(color2, null) : color1.Equals(color2);
}
/// <summary>
/// Returns a value that indicates whether two specified <see cref="CorsairColor" /> are equal.
/// </summary>
/// <param name="color1">The first <see cref="CorsairColor" /> color to compare.</param>
/// <param name="color2">The second <see cref="CorsairColor" /> color to compare.</param>
/// <returns>true if <paramref name="color1" /> and <paramref name="color2" /> are not equal; otherwise, false.</returns>
public static bool operator !=(CorsairColor color1, CorsairColor color2)
{
return !(color1 == color2);
}
/// <summary>
/// Converts a <see cref="Color" /> to a <see cref="CorsairColor" />.
/// </summary>
/// <param name="color">The <see cref="Color"/> to convert.</param>
public static implicit operator CorsairColor(Color color)
{
return new CorsairColor(color.A, color.R, color.G, color.B);
}
/// <summary>
/// Converts a <see cref="CorsairColor" /> to a <see cref="Color" />.
/// </summary>
/// <param name="color">The <see cref="CorsairColor"/> to convert.</param>
public static implicit operator Color(CorsairColor color)
{
return Color.FromArgb(color.A, color.R, color.G, color.B);

View File

@ -2,6 +2,7 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
using System.Diagnostics;
using System.Drawing;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Helper;
@ -11,14 +12,20 @@ namespace CUE.NET.Devices.Generic
/// <summary>
/// Represents a single LED of a CUE-device.
/// </summary>
[DebuggerDisplay("{Id} {Color}")]
public class CorsairLed
{
#region Properties & Fields
/// <summary>
/// Gets the Device this <see cref="CorsairLed"/> is associated with.
/// </summary>
public ICueDevice Device { get; }
/// <summary>
/// Gets the key-ID of the Led.
/// </summary>
public CorsairLedId Id { get; set; }
public CorsairLedId Id { get; }
/// <summary>
/// Gets a rectangle representing the physical location of the led.
@ -52,7 +59,7 @@ 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;
public bool IsLocked { get; set; }
#endregion
@ -61,10 +68,12 @@ namespace CUE.NET.Devices.Generic
/// <summary>
/// Initializes a new instance of the <see cref="CorsairLed"/> class.
/// </summary>
/// <param name="id">The ID of the LED</param>
/// <param name="ledRectangle">The rectangle representing the physical location of the LED.</param>
internal CorsairLed(CorsairLedId id, RectangleF ledRectangle)
/// <param name="device">The <see cref="ICueDevice"/> the <see cref="CorsairLed"/> is associated with.</param>
/// <param name="id">The <see cref="CorsairLedId"/> of the <see cref="CorsairLed"/>.</param>
/// <param name="ledRectangle">The rectangle representing the physical location of the <see cref="CorsairLed"/>.</param>
internal CorsairLed(ICueDevice device, CorsairLedId id, RectangleF ledRectangle)
{
this.Device = device;
this.Id = id;
this.LedRectangle = ledRectangle;
}
@ -73,6 +82,15 @@ namespace CUE.NET.Devices.Generic
#region Methods
/// <summary>
/// Converts the Id and the <see cref="Color"/> of this <see cref="CorsairLed"/> to a human-readable string.
/// </summary>
/// <returns>A string that contains the Id and the <see cref="Color"/> of this <see cref="CorsairLed"/>. For example "Enter [A: 255, R: 255, G: 0, B: 0]".</returns>
public override string ToString()
{
return $"{Id} {Color}";
}
/// <summary>
/// Updates the LED to the requested color.
/// </summary>
@ -92,5 +110,27 @@ namespace CUE.NET.Devices.Generic
}
#endregion
#region Operators
/// <summary>
/// Converts a <see cref="CorsairLed" /> to a <see cref="CorsairLedId" />.
/// </summary>
/// <param name="led">The <see cref="CorsairLed"/> to convert.</param>
public static implicit operator CorsairLedId(CorsairLed led)
{
return led?.Id ?? CorsairLedId.Invalid;
}
/// <summary>
/// Converts a <see cref="CorsairLed" /> to a <see cref="CorsairColor" />.
/// </summary>
/// <param name="led">The <see cref="CorsairLed"/> to convert.</param>
public static implicit operator CorsairColor(CorsairLed led)
{
return led?.Color;
}
#endregion
}
}

View File

@ -1,6 +1,8 @@
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
namespace CUE.NET.Devices.Generic.Enums
{
/// <summary>

View File

@ -1,6 +1,8 @@
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
namespace CUE.NET.Devices.Generic.Enums
{
/// <summary>
@ -8,10 +10,12 @@ namespace CUE.NET.Devices.Generic.Enums
/// </summary>
public enum CorsairDeviceType
{
Unknown = 0,
Mouse = 1,
Keyboard = 2,
Headset = 3,
Mousemat = 4
Mousemat = 4,
HeadsetStand = 5
};
}

View File

@ -0,0 +1,46 @@
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
namespace CUE.NET.Devices.Generic.Enums
{
/// <summary>
/// Contains list of all KeyIds available for all corsair devices.
/// </summary>
public enum CorsairKeyId
{
Invalid = 0,
G1 = 1,
G2 = 2,
G3 = 3,
G4 = 4,
G5 = 5,
G6 = 6,
G7 = 7,
G8 = 8,
G9 = 9,
G10 = 10,
G11 = 11,
G12 = 12,
G13 = 13,
G14 = 14,
G15 = 15,
G16 = 16,
G17 = 17,
G18 = 18,
M1 = 19,
M2 = 20,
M3 = 21,
M4 = 22,
M5 = 23,
M6 = 24,
M7 = 25,
M8 = 26,
M9 = 27,
M10 = 28,
M11 = 29,
M12 = 30,
}
}

View File

@ -1,5 +1,7 @@
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
namespace CUE.NET.Devices.Generic.Enums
{
/// <summary>
@ -160,6 +162,8 @@ namespace CUE.NET.Devices.Generic.Enums
B2 = 149,
B3 = 150,
B4 = 151,
B5 = 189,
B6 = 190,
LeftLogo = 152,
RightLogo = 153,
@ -180,6 +184,36 @@ namespace CUE.NET.Devices.Generic.Enums
Zone12 = 166,
Zone13 = 167,
Zone14 = 168,
Zone15 = 169
Zone15 = 169,
Lightbar1 = 170,
Lightbar2 = 171,
Lightbar3 = 172,
Lightbar4 = 173,
Lightbar5 = 174,
Lightbar6 = 175,
Lightbar7 = 176,
Lightbar8 = 177,
Lightbar9 = 178,
Lightbar10 = 179,
Lightbar11 = 180,
Lightbar12 = 181,
Lightbar13 = 182,
Lightbar14 = 183,
Lightbar15 = 184,
Lightbar16 = 185,
Lightbar17 = 186,
Lightbar18 = 187,
Lightbar19 = 188,
HeadsetStandZone1 = 191,
HeadsetStandZone2 = 192,
HeadsetStandZone3 = 193,
HeadsetStandZone4 = 194,
HeadsetStandZone5 = 195,
HeadsetStandZone6 = 196,
HeadsetStandZone7 = 197,
HeadsetStandZone8 = 198,
HeadsetStandZone9 = 199,
}
}

View File

@ -6,7 +6,7 @@ using System;
namespace CUE.NET.Devices.Generic.EventArgs
{
/// <summary>
/// Represents the information supplied with an Exception-event.
/// Represents the information supplied with an <see cref="ICueDevice.Exception"/>-event.
/// </summary>
public class ExceptionEventArgs : System.EventArgs
{

View File

@ -5,16 +5,26 @@ using System.Collections.Generic;
namespace CUE.NET.Devices.Generic.EventArgs
{
/// <summary>
/// Represents the information supplied with an <see cref="ICueDevice.LedsUpdated"/>-event.
/// </summary>
public class LedsUpdatedEventArgs : System.EventArgs
{
#region Properties & Fields
/// <summary>
/// Gets a list of <see cref="LedUpateRequest"/> from the updated leds.
/// </summary>
public IEnumerable<LedUpateRequest> UpdatedLeds { get; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="LedsUpdatedEventArgs"/> class.
/// </summary>
/// <param name="updatedLeds">The updated leds.</param>
public LedsUpdatedEventArgs(IEnumerable<LedUpateRequest> updatedLeds)
{
this.UpdatedLeds = updatedLeds;

View File

@ -5,16 +5,26 @@ using System.Collections.Generic;
namespace CUE.NET.Devices.Generic.EventArgs
{
/// <summary>
/// Represents the information supplied with an <see cref="ICueDevice.LedsUpdating"/>-event.
/// </summary>
public class LedsUpdatingEventArgs : System.EventArgs
{
#region Properties & Fields
/// <summary>
/// Gets a list of <see cref="LedUpateRequest"/> from the updating leds.
/// </summary>
public ICollection<LedUpateRequest> UpdatingLeds { get; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="LedsUpdatingEventArgs"/> class.
/// </summary>
/// <param name="updatingLeds">The updating leds.</param>
public LedsUpdatingEventArgs(ICollection<LedUpateRequest> updatingLeds)
{
this.UpdatingLeds = updatingLeds;

View File

@ -1,5 +1,8 @@
namespace CUE.NET.Devices.Generic.EventArgs
{
/// <summary>
/// Represents the information supplied with an <see cref="ICueDevice.Updated"/>-event.
/// </summary>
public class UpdatedEventArgs : System.EventArgs
{ }
}

View File

@ -3,16 +3,26 @@
namespace CUE.NET.Devices.Generic.EventArgs
{
/// <summary>
/// Represents the information supplied with an <see cref="ICueDevice.Updating"/>-event.
/// </summary>
public class UpdatingEventArgs : System.EventArgs
{
#region Properties & Fields
/// <summary>
/// Gets the elapsed time (in seconds) sonce the last update.
/// </summary>
public float DeltaTime { get; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="UpdatingEventArgs"/> class.
/// </summary>
/// <param name="deltaTime">The elapsed time (in seconds) sonce the last update.</param>
public UpdatingEventArgs(float deltaTime)
{
this.DeltaTime = deltaTime;

View File

@ -45,6 +45,8 @@ namespace CUE.NET.Devices.Headset
{
InitializeLed(CorsairHeadsetLedId.LeftLogo, new RectangleF(0, 0, 1, 1));
InitializeLed(CorsairHeadsetLedId.RightLogo, new RectangleF(1, 0, 1, 1));
base.Initialize();
}
#endregion

View File

@ -1,6 +1,8 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Devices.Headset.Enums

View File

@ -0,0 +1,91 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Exceptions;
using CUE.NET.Native;
namespace CUE.NET.Devices.HeadsetStand
{
/// <summary>
/// Represents the SDK for a corsair headset stand.
/// </summary>
public class CorsairHeadsetStand : AbstractCueDevice
{
#region Properties & Fields
/// <summary>
/// Gets specific information provided by CUE for the headset stand.
/// </summary>
public CorsairHeadsetStandDeviceInfo HeadsetStandDeviceInfo { get; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CorsairHeadsetStand"/> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the headset stand</param>
internal CorsairHeadsetStand(CorsairHeadsetStandDeviceInfo info)
: base(info)
{
this.HeadsetStandDeviceInfo = info;
}
#endregion
#region Methods
/// <summary>
/// Initializes the headset stand.
/// </summary>
public override void Initialize()
{
int deviceCount = _CUESDK.CorsairGetDeviceCount();
// Get headset stand device index
int headsetStandIndex = -1;
for (int i = 0; i < deviceCount; i++)
{
_CorsairDeviceInfo nativeDeviceInfo = (_CorsairDeviceInfo)Marshal.PtrToStructure(_CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo));
GenericDeviceInfo info = new GenericDeviceInfo(nativeDeviceInfo);
if (info.Type != CorsairDeviceType.HeadsetStand)
continue;
headsetStandIndex = i;
break;
}
if (headsetStandIndex < 0)
throw new WrapperException("Can't determine headset stand device index");
_CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(headsetStandIndex), typeof(_CorsairLedPositions));
int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition));
IntPtr ptr = nativeLedPositions.pLedPosition;
// Put the positions in an array for sorting later on
List<_CorsairLedPosition> positions = new List<_CorsairLedPosition>();
for (int i = 0; i < nativeLedPositions.numberOfLed; i++)
{
_CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition));
ptr = new IntPtr(ptr.ToInt64() + structSize);
positions.Add(ledPosition);
}
// Sort for easy iteration by clients
foreach (_CorsairLedPosition ledPosition in positions.OrderBy(p => p.ledId))
InitializeLed(ledPosition.ledId, new RectangleF((float)ledPosition.left, (float)ledPosition.top, (float)ledPosition.width, (float)ledPosition.height));
base.Initialize();
}
#endregion
}
}

View File

@ -0,0 +1,26 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
using CUE.NET.Devices.Generic;
using CUE.NET.Native;
namespace CUE.NET.Devices.HeadsetStand
{
/// <summary>
/// Represents specific information for a CUE headset stand.
/// </summary>
public class CorsairHeadsetStandDeviceInfo : GenericDeviceInfo
{
#region Constructors
/// <summary>
/// Internal constructor of managed <see cref="CorsairHeadsetStandDeviceInfo" />.
/// </summary>
/// <param name="nativeInfo">The native <see cref="_CorsairDeviceInfo" />-struct</param>
internal CorsairHeadsetStandDeviceInfo(_CorsairDeviceInfo nativeInfo)
: base(nativeInfo)
{ }
#endregion
}
}

View File

@ -0,0 +1,26 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Devices.HeadsetStand.Enums
{
/// <summary>
/// Contains list of all LEDs available for corsair headset stands.
/// </summary>
public static class CorsairHeadsetStandLedId
{
public const CorsairLedId Invalid = CorsairLedId.Invalid;
public const CorsairLedId HeadsetStandZone1 = CorsairLedId.HeadsetStandZone1;
public const CorsairLedId HeadsetStandZone2 = CorsairLedId.HeadsetStandZone2;
public const CorsairLedId HeadsetStandZone3 = CorsairLedId.HeadsetStandZone3;
public const CorsairLedId HeadsetStandZone4 = CorsairLedId.HeadsetStandZone4;
public const CorsairLedId HeadsetStandZone5 = CorsairLedId.HeadsetStandZone5;
public const CorsairLedId HeadsetStandZone6 = CorsairLedId.HeadsetStandZone6;
public const CorsairLedId HeadsetStandZone7 = CorsairLedId.HeadsetStandZone7;
public const CorsairLedId HeadsetStandZone8 = CorsairLedId.HeadsetStandZone8;
public const CorsairLedId HeadsetStandZone9 = CorsairLedId.HeadsetStandZone9;
}
}

View File

@ -140,10 +140,26 @@ namespace CUE.NET.Devices
void Initialize();
/// <summary>
/// Perform an update for all dirty keys, or all keys if flushLeds is set to true.
/// Performs an update for all dirty keys, or all keys if flushLeds is set to true.
/// </summary>
/// <param name="flushLeds">Specifies whether all keys (including clean ones) should be updated.</param>
void Update(bool flushLeds = false);
/// <param name="noRender">Only updates the hardware-leds skippin effects and the render-pass. Only use this if you know what that means!</param>
void Update(bool flushLeds = false, bool noRender = false);
/// <summary>
/// Reads the currently active colors from the device and sync them with the internal state.
/// </summary>
void SyncColors();
/// <summary>
/// Saves the currently active colors from the device.
/// </summary>
void SaveColors();
/// <summary>
/// Restores the last saved colors.
/// </summary>
void RestoreColors();
/// <summary>
/// Attaches the given ledgroup.

View File

@ -7,6 +7,7 @@ using System;
using System.Drawing;
using System.Runtime.InteropServices;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Native;
namespace CUE.NET.Devices.Keyboard
@ -23,6 +24,26 @@ namespace CUE.NET.Devices.Keyboard
/// </summary>
public CorsairKeyboardDeviceInfo KeyboardDeviceInfo { get; }
#region Indexers
/// <summary>
/// Gets the <see cref="CorsairLed" /> 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 led representing the given character or null if no led is found.</returns>
public CorsairLed this[char key]
{
get
{
CorsairLedId ledId = _CUESDK.CorsairGetLedIdForKeyName(key);
CorsairLed led;
return LedMapping.TryGetValue(ledId, out led) ? led : null;
}
}
#endregion
#endregion
#region Constructors
@ -56,6 +77,8 @@ namespace CUE.NET.Devices.Keyboard
ptr = new IntPtr(ptr.ToInt64() + structSize);
}
base.Initialize();
}
#endregion

View File

@ -1,7 +1,7 @@
namespace CUE.NET.Devices.Keyboard.Enums
{
/// <summary>
/// Contains list of all brush calculation modes.
/// Contains a list of all brush calculation modes.
/// </summary>
public enum BrushCalculationMode
{

View File

@ -0,0 +1,36 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Devices.Keyboard.Enums
{
/// <summary>
/// Contains list of all LEDs available for corsair keyboards.
/// </summary>
public static class CorsairKeyboardKeyId
{
public const CorsairKeyId Invalid = CorsairKeyId.Invalid;
public const CorsairKeyId G1 = CorsairKeyId.G1;
public const CorsairKeyId G2 = CorsairKeyId.G2;
public const CorsairKeyId G3 = CorsairKeyId.G3;
public const CorsairKeyId G4 = CorsairKeyId.G4;
public const CorsairKeyId G5 = CorsairKeyId.G5;
public const CorsairKeyId G6 = CorsairKeyId.G6;
public const CorsairKeyId G7 = CorsairKeyId.G7;
public const CorsairKeyId G8 = CorsairKeyId.G8;
public const CorsairKeyId G9 = CorsairKeyId.G9;
public const CorsairKeyId G10 = CorsairKeyId.G10;
public const CorsairKeyId G11 = CorsairKeyId.G11;
public const CorsairKeyId G12 = CorsairKeyId.G12;
public const CorsairKeyId G13 = CorsairKeyId.G13;
public const CorsairKeyId G14 = CorsairKeyId.G14;
public const CorsairKeyId G15 = CorsairKeyId.G15;
public const CorsairKeyId G16 = CorsairKeyId.G16;
public const CorsairKeyId G17 = CorsairKeyId.G17;
public const CorsairKeyId G18 = CorsairKeyId.G18;
}
}

View File

@ -1,6 +1,8 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Devices.Keyboard.Enums
@ -159,5 +161,24 @@ namespace CUE.NET.Devices.Keyboard.Enums
public const CorsairLedId International4 = CorsairLedId.International4;
public const CorsairLedId Fn = CorsairLedId.Fn;
public const CorsairLedId Logo = CorsairLedId.Logo;
public const CorsairLedId Lightbar1 = CorsairLedId.Lightbar1;
public const CorsairLedId Lightbar2 = CorsairLedId.Lightbar2;
public const CorsairLedId Lightbar3 = CorsairLedId.Lightbar3;
public const CorsairLedId Lightbar4 = CorsairLedId.Lightbar4;
public const CorsairLedId Lightbar5 = CorsairLedId.Lightbar5;
public const CorsairLedId Lightbar6 = CorsairLedId.Lightbar6;
public const CorsairLedId Lightbar7 = CorsairLedId.Lightbar7;
public const CorsairLedId Lightbar8 = CorsairLedId.Lightbar8;
public const CorsairLedId Lightbar9 = CorsairLedId.Lightbar9;
public const CorsairLedId Lightbar10 = CorsairLedId.Lightbar10;
public const CorsairLedId Lightbar11 = CorsairLedId.Lightbar11;
public const CorsairLedId Lightbar12 = CorsairLedId.Lightbar12;
public const CorsairLedId Lightbar13 = CorsairLedId.Lightbar13;
public const CorsairLedId Lightbar14 = CorsairLedId.Lightbar14;
public const CorsairLedId Lightbar15 = CorsairLedId.Lightbar15;
public const CorsairLedId Lightbar16 = CorsairLedId.Lightbar16;
public const CorsairLedId Lightbar17 = CorsairLedId.Lightbar17;
public const CorsairLedId Lightbar18 = CorsairLedId.Lightbar18;
public const CorsairLedId Lightbar19 = CorsairLedId.Lightbar19;
}
}

View File

@ -1,6 +1,8 @@
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
namespace CUE.NET.Devices.Keyboard.Enums
{
/// <summary>

View File

@ -2,10 +2,16 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable UnusedMember.Global
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Mouse.Enums;
using CUE.NET.Exceptions;
using CUE.NET.Native;
namespace CUE.NET.Devices.Mouse
{
@ -44,6 +50,14 @@ namespace CUE.NET.Devices.Mouse
/// </summary>
public override void Initialize()
{
// Glaive is a special flake that doesn't follow the default layout
if (MouseDeviceInfo.Model == "GLAIVE RGB")
{
InitializeLed(CorsairMouseLedId.B1, new RectangleF(0, 0, 1, 1)); // Logo
InitializeLed(CorsairMouseLedId.B2, new RectangleF(2, 0, 1, 1)); // Front
InitializeLed(CorsairMouseLedId.B5, new RectangleF(3, 0, 1, 1)); // Sides
return;
}
switch (MouseDeviceInfo.PhysicalLayout)
{
case CorsairPhysicalMouseLayout.Zones1:
@ -67,6 +81,8 @@ namespace CUE.NET.Devices.Mouse
default:
throw new WrapperException($"Can't initial mouse with layout '{MouseDeviceInfo.PhysicalLayout}'");
}
base.Initialize();
}
#endregion

View File

@ -0,0 +1,30 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Devices.Mouse.Enums
{
/// <summary>
/// Contains list of all LEDs available for corsair mice.
/// </summary>
public static class CorsairMouseKeyId
{
public const CorsairKeyId Invalid = CorsairKeyId.Invalid;
public const CorsairKeyId M1 = CorsairKeyId.M1;
public const CorsairKeyId M2 = CorsairKeyId.M2;
public const CorsairKeyId M3 = CorsairKeyId.M3;
public const CorsairKeyId M4 = CorsairKeyId.M4;
public const CorsairKeyId M5 = CorsairKeyId.M5;
public const CorsairKeyId M6 = CorsairKeyId.M6;
public const CorsairKeyId M7 = CorsairKeyId.M7;
public const CorsairKeyId M8 = CorsairKeyId.M8;
public const CorsairKeyId M9 = CorsairKeyId.M9;
public const CorsairKeyId M10 = CorsairKeyId.M10;
public const CorsairKeyId M11 = CorsairKeyId.M11;
public const CorsairKeyId M12 = CorsairKeyId.M12;
}
}

View File

@ -1,6 +1,8 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Devices.Mouse.Enums
@ -15,5 +17,7 @@ namespace CUE.NET.Devices.Mouse.Enums
public const CorsairLedId B2 = CorsairLedId.B2;
public const CorsairLedId B3 = CorsairLedId.B3;
public const CorsairLedId B4 = CorsairLedId.B4;
public const CorsairLedId B5 = CorsairLedId.B5;
public const CorsairLedId B6 = CorsairLedId.B6;
}
}

View File

@ -82,6 +82,8 @@ namespace CUE.NET.Devices.Mousemat
// Sort for easy iteration by clients
foreach (_CorsairLedPosition ledPosition in positions.OrderBy(p => p.ledId))
InitializeLed(ledPosition.ledId, new RectangleF((float)ledPosition.left, (float)ledPosition.top, (float)ledPosition.width, (float)ledPosition.height));
base.Initialize();
}
#endregion

View File

@ -1,6 +1,8 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
#pragma warning disable 1591 // Missing XML comment for publicly visible type or member
using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.Devices.Mousemat.Enums

View File

@ -16,12 +16,15 @@ namespace CUE.NET.Effects
{
#region Properties & Fields
protected IList<EffectTimeContainer> EffectTimes = new List<EffectTimeContainer>();
/// <summary>
/// Gets a list of <see cref="EffectTimeContainer"/> storing the attached effects.
/// </summary>
protected IList<EffectTimeContainer> EffectTimes { get; } = new List<EffectTimeContainer>();
/// <summary>
/// Gets all <see cref="IEffect{T}" /> attached to this target.
/// </summary>
protected IList<IEffect<T>> Effects => EffectTimes.Select(x => x.Effect).Cast<IEffect<T>>().ToList();
public IList<IEffect<T>> Effects => EffectTimes.Select(x => x.Effect).Cast<IEffect<T>>().ToList();
/// <summary>
/// Gets the strongly-typed target used for the effect.

View File

@ -16,26 +16,26 @@ namespace CUE.NET.Effects
/// <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)
/// This is close to a synthesizer envelope. (See <see href="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)
/// This is close to a synthesizer envelope. (See <see href="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 />
/// This is close to a synthesizer envelope. (See <see href="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)
/// This is close to a synthesizer envelope. (See <see href="http://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope" /> as reference)
/// </summary>
public float Release { get; set; } = 0.2f;
@ -76,6 +76,7 @@ namespace CUE.NET.Effects
_currentPhaseValue -= deltaTime;
// Using ifs instead of a switch allows to skip phases with time 0.
// ReSharper disable InvertIf
if (_currentPhase == ADSRPhase.Attack)
if (_currentPhaseValue > 0f)
@ -123,6 +124,8 @@ namespace CUE.NET.Effects
_currentPhaseValue = Attack;
_currentPhase = ADSRPhase.Attack;
}
// ReSharper restore InvertIf
}
/// <summary>

View File

@ -1,14 +1,25 @@
// ReSharper disable UnusedMember.Global
using System.Collections.Generic;
namespace CUE.NET.Effects
{
/// <summary>
/// Represents a basic effect-target.
/// </summary>
/// <typeparam name="T">The type this target represents.</typeparam>
public interface IEffectTarget<out T>
public interface IEffectTarget<T>
where T : IEffectTarget<T>
{
#region Properties & Fields
/// <summary>
/// Gets a list of all active effects of this target.
/// </summary>
IList<IEffect<T>> Effects { get; }
#endregion
#region Methods
/// <summary>

View File

@ -0,0 +1,102 @@
using CUE.NET.Brushes;
using CUE.NET.Gradients;
namespace CUE.NET.Effects
{
/// <summary>
/// Represents an effect which allows to move an gradient by modifying his offset.
/// </summary>
public class MoveGradientEffect : AbstractBrushEffect<IGradientBrush>
{
#region Properties & Fields
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// ReSharper disable MemberCanBePrivate.Global
/// <summary>
/// Gets or sets the direction the gradient is moved.
/// True leads to an offset-increment (normaly moving to the right), false to an offset-decrement (normaly moving to the left).
/// </summary>
public bool Direction { get; set; }
/// <summary>
/// Gets or sets the speed of the movement in units per second.
/// The meaning of units differs for the different gradients, but 360 units will always be one complete cycle:
/// LinearGradient: 360 unit = 1 offset.
/// RainbowGradient: 1 unit = 1 degree.
/// </summary>
public float Speed { get; set; }
// ReSharper restore MemberCanBePrivate.Global
// ReSharper restore AutoPropertyCanBeMadeGetOnly.Global
#endregion
#region Constructors
/// <summary>
///
/// </summary>
/// <param name="speed"></param>
/// <param name="direction"></param>
public MoveGradientEffect(float speed = 180f, bool direction = true)
{
this.Speed = speed;
this.Direction = direction;
}
#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)
{
float movement = Speed * deltaTime;
if (!Direction)
movement = -movement;
// ReSharper disable once CanBeReplacedWithTryCastAndCheckForNull
if (Brush.Gradient is LinearGradient)
{
LinearGradient linearGradient = (LinearGradient)Brush.Gradient;
movement /= 360f;
foreach (GradientStop gradientStop in linearGradient.GradientStops)
{
gradientStop.Offset = gradientStop.Offset + movement;
if (gradientStop.Offset > 1f)
gradientStop.Offset -= 1f;
else if (gradientStop.Offset < 0)
gradientStop.Offset += 1f;
}
}
else if (Brush.Gradient is RainbowGradient)
{
RainbowGradient rainbowGradient = (RainbowGradient)Brush.Gradient;
// RainbowGradient is calculated inverse but the movement should be the same for all.
movement *= -1;
rainbowGradient.StartHue += movement;
rainbowGradient.EndHue += movement;
if (rainbowGradient.StartHue > 360f && rainbowGradient.EndHue > 360f)
{
rainbowGradient.StartHue -= 360f;
rainbowGradient.EndHue -= 360f;
}
else if (rainbowGradient.StartHue < -360f && rainbowGradient.EndHue < -360f)
{
rainbowGradient.StartHue += 360f;
rainbowGradient.EndHue += 360f;
}
}
}
#endregion
}
}

View File

@ -0,0 +1,41 @@
// ReSharper disable MemberCanBePrivate.Global
using CUE.NET.Devices.Generic.Enums;
namespace CUE.NET.EventArgs
{
/// <summary>
/// Represents the data provided by the <see cref="CueSDK.KeyPressed"/>-event.
/// </summary>
public class KeyPressedEventArgs : System.EventArgs
{
#region Properties & Fields
/// <summary>
/// Gets the id of the key.
/// </summary>
public CorsairKeyId KeyId { get; }
/// <summary>
/// Gets the current status of the key (true = pressed, flase = released).
/// </summary>
public bool IsPressed { get; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="KeyPressedEventArgs"/> class.
/// </summary>
/// <param name="keyId">The id of the key.</param>
/// <param name="isPressed">The current status of the key (true = pressed, flase = released).</param>
public KeyPressedEventArgs(CorsairKeyId keyId, bool isPressed)
{
this.KeyId = keyId;
this.IsPressed = isPressed;
}
#endregion
}
}

View File

@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using CUE.NET.Brushes;
using CUE.NET.ColorCorrection;
using CUE.NET.Devices.Generic;
using CUE.NET.Helper;
using Example_Ambilight_full.TakeAsIs;
using Example_Ambilight_full.TakeAsIs.Model;
using Example_Ambilight_full.TakeAsIs.Model.Extensions;
using Example_Ambilight_full.TakeAsIs.ScreenCapturing;
namespace Example_Ambilight_full
{
public abstract class AbstractAmbilightBrush : AbstractBrush
{
#region Properties & Fields
protected readonly IScreenCapture ScreenCapture;
protected readonly AmbilightSettings Settings;
protected byte[] ScreenPixelData;
protected int SourceWidth;
protected int SourceHeight;
protected int OffsetLeft;
protected int OffsetRight;
protected int OffsetTop;
protected int OffsetBottom;
protected int EffectiveSourceWidth;
protected int EffectiveSourceHeight;
protected int Increment;
protected float KeyWidthProportion;
protected float KeyHeightProportion;
#endregion
#region Constructors
public AbstractAmbilightBrush(IScreenCapture screenCapture, AmbilightSettings settings)
{
this.ScreenCapture = screenCapture;
this.Settings = settings;
}
#endregion
#region Methods
public override void PerformRender(RectangleF rectangle, IEnumerable<BrushRenderTarget> renderTargets)
{
ScreenPixelData = ScreenCapture.CaptureScreen();
SourceWidth = ScreenCapture.Width;
SourceHeight = ScreenCapture.Height;
OffsetLeft = Settings.OffsetLeft + (Settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Left)
? ScreenPixelData.DetectBlackBarLeft(SourceWidth, SourceHeight, Settings.OffsetLeft, Settings.OffsetRight, Settings.OffsetTop, Settings.OffsetBottom)
: 0);
OffsetRight = Settings.OffsetRight + (Settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Right)
? ScreenPixelData.DetectBlackBarRight(SourceWidth, SourceHeight, Settings.OffsetLeft, Settings.OffsetRight, Settings.OffsetTop, Settings.OffsetBottom)
: 0);
OffsetTop = Settings.OffsetTop + (Settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Top)
? ScreenPixelData.DetectBlackBarTop(SourceWidth, SourceHeight, Settings.OffsetLeft, Settings.OffsetRight, Settings.OffsetTop, Settings.OffsetBottom)
: 0);
OffsetBottom = Settings.OffsetBottom + (Settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Bottom)
? ScreenPixelData.DetectBlackBarBottom(SourceWidth, SourceHeight, Settings.OffsetLeft, Settings.OffsetRight, Settings.OffsetTop, Settings.OffsetBottom)
: 0);
EffectiveSourceWidth = SourceWidth - OffsetLeft - OffsetRight;
EffectiveSourceHeight = (int)Math.Round((SourceHeight - OffsetTop - OffsetBottom) * (Settings.MirroredAmount / 100.0));
Increment = Math.Max(1, Math.Min(20, Settings.Downsampling));
KeyWidthProportion = EffectiveSourceWidth / rectangle.Width;
KeyHeightProportion = EffectiveSourceHeight / rectangle.Height;
Opacity = Settings.SmoothMode == SmoothMode.Low ? 0.25f : (Settings.SmoothMode == SmoothMode.Medium ? 0.075f : (Settings.SmoothMode == SmoothMode.High ? 0.025f : 1f /*None*/));
base.PerformRender(rectangle, renderTargets);
}
protected override CorsairColor FinalizeColor(CorsairColor color)
{
// Apply our gamma-correction
((GammaCorrection)Settings.Gamma).ApplyTo(color);
float lightness = (float)Math.Max((Settings.MinLightness / 100.0), (color.GetHSVValue() * ((double)Brightness < 0.0 ? 0.0f : ((double)Brightness > 1.0 ? 1f : Brightness))));
byte alpha = (byte)((double)color.A * ((double)Opacity < 0.0 ? 0.0 : ((double)Opacity > 1.0 ? 1.0 : (double)Opacity)));
return ColorHelper.ColorFromHSV(color.GetHSVHue(), color.GetHSVSaturation(), lightness, alpha);
}
#endregion
}
}

View File

@ -0,0 +1,68 @@
using System.Drawing;
using CUE.NET;
using CUE.NET.Brushes;
using CUE.NET.Devices.Generic.Enums;
using Example_Ambilight_full.TakeAsIs;
using Example_Ambilight_full.TakeAsIs.Model;
using Example_Ambilight_full.TakeAsIs.ScreenCapturing;
namespace Example_Ambilight_full
{
public class Ambilight
{
#region Properties & Fields
private readonly IScreenCapture _screenCapture;
private readonly AmbilightSettings _settings;
#endregion
#region Constructors
public Ambilight(IScreenCapture screenCapture, AmbilightSettings settings)
{
this._screenCapture = screenCapture;
this._settings = settings;
}
#endregion
#region Methods
public bool Initialize()
{
try
{
CueSDK.Initialize();
CueSDK.UpdateMode = UpdateMode.Continuous;
CueSDK.UpdateFrequency = 1f / _settings.UpdateRate;
SetAmbilightBrush();
_settings.AmbienceCreatorTypeChanged += (sender, args) => SetAmbilightBrush();
}
catch { return false; }
return true;
}
private void SetAmbilightBrush()
{
IBrush ambilightBrush;
switch (_settings.AmbienceCreatorType)
{
case AmbienceCreatorType.Mirror:
ambilightBrush = new AmbilightMirrorBrush(_screenCapture, _settings);
break;
case AmbienceCreatorType.Extend:
ambilightBrush = new AmbilightExtendBrush(_screenCapture, _settings);
break;
default:
ambilightBrush = new SolidColorBrush(Color.Black);
break;
}
CueSDK.KeyboardSDK.Brush = ambilightBrush;
}
#endregion
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Drawing;
using CUE.NET.Brushes;
using CUE.NET.Devices.Generic;
using Example_Ambilight_full.TakeAsIs;
using Example_Ambilight_full.TakeAsIs.Model;
using Example_Ambilight_full.TakeAsIs.ScreenCapturing;
namespace Example_Ambilight_full
{
public class AmbilightExtendBrush : AbstractAmbilightBrush
{
#region Constructors
public AmbilightExtendBrush(IScreenCapture screenCapture, AmbilightSettings settings)
: base(screenCapture, settings)
{ }
#endregion
#region Methods
protected override CorsairColor GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
{
float keyWidth = renderTarget.Rectangle.Width;
int widthPixels = Math.Max(1, (int)(KeyWidthProportion * keyWidth));
int r = 0;
int g = 0;
int b = 0;
int counter = 0;
int widthOffset = Settings.FlipMode.HasFlag(FlipMode.Horizontal)
? (int)((SourceWidth - OffsetRight) - (KeyWidthProportion * (renderTarget.Point.X + (keyWidth / 2f))))
: (int)(OffsetLeft + (KeyWidthProportion * (renderTarget.Point.X - (keyWidth / 2f))));
int heightOffset = SourceHeight - OffsetBottom - EffectiveSourceHeight; // DarthAffe 05.11.2016: Vertical flipping doesn't mather in Extend-Mode
// DarthAffe 06.11.2016: Validate offsets - rounding errors might cause problems (heightOffset is safe calculated -> no need to validate)
widthOffset = Math.Max(0, Math.Min(SourceWidth - widthPixels, widthOffset));
for (int y = 0; y < EffectiveSourceHeight; y += Increment)
for (int x = 0; x < widthPixels; x += Increment)
{
int offset = ((((heightOffset + y) * SourceWidth) + widthOffset + x) * 4);
b += ScreenPixelData[offset];
g += ScreenPixelData[offset + 1];
r += ScreenPixelData[offset + 2];
counter++;
}
return new CorsairColor((byte)(r / counter), (byte)(g / counter), (byte)(b / counter));
}
#endregion
}
}

View File

@ -0,0 +1,63 @@
using System;
using System.Drawing;
using CUE.NET.Brushes;
using CUE.NET.Devices.Generic;
using Example_Ambilight_full.TakeAsIs;
using Example_Ambilight_full.TakeAsIs.Model;
using Example_Ambilight_full.TakeAsIs.ScreenCapturing;
namespace Example_Ambilight_full
{
public class AmbilightMirrorBrush : AbstractAmbilightBrush
{
#region Constructors
public AmbilightMirrorBrush(IScreenCapture screenCapture, AmbilightSettings settings)
: base(screenCapture, settings)
{ }
#endregion
#region Methods
protected override CorsairColor GetColorAtPoint(RectangleF rectangle, BrushRenderTarget renderTarget)
{
float keyWidth = renderTarget.Rectangle.Width;
float keyHeight = renderTarget.Rectangle.Height;
int widthPixels = Math.Max(1, (int)(KeyWidthProportion * keyWidth));
int heightPixels = Math.Max(1, (int)(KeyHeightProportion * keyHeight));
int r = 0;
int g = 0;
int b = 0;
int counter = 0;
int widthOffset = Settings.FlipMode.HasFlag(FlipMode.Horizontal)
? ((SourceWidth - OffsetRight) - (int)(KeyWidthProportion * (renderTarget.Point.X + (keyWidth / 2f))))
: (OffsetLeft + (int)(KeyWidthProportion * (renderTarget.Point.X - (keyWidth / 2f))));
int heightOffset = Settings.FlipMode.HasFlag(FlipMode.Vertical)
? ((SourceHeight - OffsetBottom) - (int)(KeyHeightProportion * (renderTarget.Point.Y + (keyHeight / 2f))))
: ((SourceHeight - OffsetBottom - EffectiveSourceHeight) + (int)(KeyHeightProportion * (renderTarget.Point.Y - (keyHeight / 2f))));
// DarthAffe 06.11.2016: Validate offsets - rounding errors might cause problems
widthOffset = Math.Max(0, Math.Min(SourceWidth - widthPixels, widthOffset));
heightOffset = Math.Max(0, Math.Min(SourceHeight - heightPixels, heightOffset));
for (int y = 0; y < heightPixels; y += Increment)
for (int x = 0; x < widthPixels; x += Increment)
{
int offset = ((((heightOffset + y) * SourceWidth) + widthOffset + x) * 4);
b += ScreenPixelData[offset];
g += ScreenPixelData[offset + 1];
r += ScreenPixelData[offset + 2];
counter++;
}
return new CorsairColor((byte)(r / counter), (byte)(g / counter), (byte)(b / counter));
}
#endregion
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>

View File

@ -0,0 +1,17 @@
<Application x:Class="Example_Ambilight_full.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="TakeAsIs/UI/Taskbar.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@ -0,0 +1,67 @@
using System;
using System.Windows;
using Example_Ambilight_full.TakeAsIs;
using Example_Ambilight_full.TakeAsIs.Helper;
using Example_Ambilight_full.TakeAsIs.ScreenCapturing;
using Example_Ambilight_full.TakeAsIs.UI;
using Hardcodet.Wpf.TaskbarNotification;
namespace Example_Ambilight_full
{
public partial class App : Application
{
#region Constants
private const string PATH_SETTINGS = "Settings.xaml";
#endregion
#region Properties & Fields
private TaskbarIcon _taskBar;
private AmbilightSettings _settings;
private Ambilight _ambilight;
#endregion
#region Methods
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
try
{
_settings = SerializationHelper.LoadObjectFromFile<AmbilightSettings>(PATH_SETTINGS) ??
new AmbilightSettings();
IScreenCapture screenCapture = new DX9ScreenCapture();
// DarthAffe 05.11.2016: This could be done way cleaner ...
_taskBar = FindResource("Taskbar") as TaskbarIcon;
FrameworkElement configView = _taskBar?.TrayPopup as ConfigView;
if (configView == null)
Shutdown();
else
configView.DataContext = new ConfigViewModel(_settings);
_ambilight = new Ambilight(screenCapture, _settings);
if (!_ambilight.Initialize())
throw new ApplicationException();
}
catch
{
MessageBox.Show("An error occured while starting the Keyboard-Ambilight.\r\nPlease double check if CUE is running and 'Enable SDK' is checked.", "Can't start Keyboard-Ambilight");
Shutdown();
}
}
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
SerializationHelper.SaveObjectToFile(_settings, PATH_SETTINGS);
}
#endregion
}
}

View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6D7BAF89-A705-4FFA-A3A2-AF93EC3A909C}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Example_Ambilight_full</RootNamespace>
<AssemblyName>Example_Ambilight_full</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\ambilight.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="CUE.NET, Version=1.1.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\CUE.NET.1.1.3.0\lib\net45\CUE.NET.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Hardcodet.Wpf.TaskbarNotification, Version=1.0.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Hardcodet.NotifyIcon.Wpf.1.0.8\lib\net45\Hardcodet.Wpf.TaskbarNotification.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MahApps.Metro, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\MahApps.Metro.1.4.0-ALPHA026\lib\net45\MahApps.Metro.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpDX, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\SharpDX.3.1.1\lib\net45\SharpDX.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpDX.Direct3D9, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\SharpDX.Direct3D9.3.1.1\lib\net45\SharpDX.Direct3D9.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\MahApps.Metro.1.4.0-ALPHA026\lib\net45\System.Windows.Interactivity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Ambilight.cs" />
<Compile Include="AbstractAmbilightBrush.cs" />
<Compile Include="AmbilightExtendBrush.cs" />
<Compile Include="AmbilightMirrorBrush.cs" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="TakeAsIs\AmbilightSettings.cs" />
<Compile Include="TakeAsIs\Helper\CheckboxEnumFlagHelper.cs" />
<Compile Include="TakeAsIs\Helper\SerializationHelper.cs" />
<Compile Include="TakeAsIs\Model\AmbienceCreatorType.cs" />
<Compile Include="TakeAsIs\Model\BlackBarDetectionMode.cs" />
<Compile Include="TakeAsIs\Model\Extensions\EnumExtension.cs" />
<Compile Include="TakeAsIs\Model\Extensions\PixelDataExtension.cs" />
<Compile Include="TakeAsIs\Model\FlipMode.cs" />
<Compile Include="TakeAsIs\Model\SmoothMode.cs" />
<Compile Include="TakeAsIs\ScreenCapturing\DX9ScreenCapture.cs" />
<Compile Include="TakeAsIs\ScreenCapturing\IScreenCapture.cs" />
<Compile Include="TakeAsIs\UI\ActionCommand.cs" />
<Compile Include="TakeAsIs\UI\ConfigViewModel.cs" />
<Compile Include="TakeAsIs\UI\ConfigView.xaml.cs">
<DependentUpon>ConfigView.xaml</DependentUpon>
</Compile>
<Compile Include="TakeAsIs\UI\EnumDescriptionConverter.cs" />
<Page Include="TakeAsIs\UI\ConfigView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="TakeAsIs\UI\Taskbar.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\ambilight.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\..\packages\CUE.NET.1.1.3.0\build\net45\CUE.NET.targets" Condition="Exists('..\..\..\packages\CUE.NET.1.1.3.0\build\net45\CUE.NET.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\CUE.NET.1.1.3.0\build\net45\CUE.NET.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\CUE.NET.1.1.3.0\build\net45\CUE.NET.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,53 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Example_Ambilight_full")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Example_Ambilight_full")]
[assembly: AssemblyCopyright("Copyright © Wyrez 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.3")]
[assembly: AssemblyFileVersion("1.0.1.3")]

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Example_Ambilight_full.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Example_Ambilight_full.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Example_Ambilight_full.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,50 @@
using System;
using Example_Ambilight_full.TakeAsIs.Model;
namespace Example_Ambilight_full.TakeAsIs
{
public class AmbilightSettings
{
private AmbienceCreatorType _ambienceCreatorType = AmbienceCreatorType.Mirror;
#region Properties & Fields
public AmbienceCreatorType AmbienceCreatorType
{
get { return _ambienceCreatorType; }
set
{
// ReSharper disable once InvertIf
if (_ambienceCreatorType != value)
{
_ambienceCreatorType = value;
AmbienceCreatorTypeChanged?.Invoke(this, new EventArgs());
}
}
}
public int UpdateRate { get; set; } = 20;
public int OffsetLeft { get; set; } = 0;
public int OffsetRight { get; set; } = 0;
public int OffsetTop { get; set; } = 0;
public int OffsetBottom { get; set; } = 0;
public int Downsampling { get; set; } = 2;
public double MirroredAmount { get; set; } = 10;
public SmoothMode SmoothMode { get; set; } = SmoothMode.Low;
public BlackBarDetectionMode BlackBarDetectionMode { get; set; } = BlackBarDetectionMode.Bottom;
public FlipMode FlipMode { get; set; } = FlipMode.Vertical;
public double MinLightness { get; set; } = 0;
public float Gamma { get; set; } = 1f;
#endregion
#region Events
public event EventHandler AmbienceCreatorTypeChanged;
#endregion
}
}

View File

@ -0,0 +1,93 @@
using System;
using System.Windows;
using System.Windows.Controls;
using Example_Ambilight_full.TakeAsIs.Model.Extensions;
namespace Example_Ambilight_full.TakeAsIs.Helper
{
public class CheckboxEnumFlagHelper
{
#region DependencyProperties
// ReSharper disable InconsistentNaming
public static readonly DependencyProperty FlagsProperty = DependencyProperty.RegisterAttached(
"Flags", typeof(Enum), typeof(CheckboxEnumFlagHelper), new FrameworkPropertyMetadata(default(Enum), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, FlagsChanged));
public static void SetFlags(DependencyObject element, Enum value)
{
element.SetValue(FlagsProperty, value);
}
public static Enum GetFlags(DependencyObject element)
{
return (Enum)element.GetValue(FlagsProperty);
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached(
"Value", typeof(Enum), typeof(CheckboxEnumFlagHelper), new PropertyMetadata(default(Enum), ValueChanged));
public static void SetValue(DependencyObject element, Enum value)
{
element.SetValue(ValueProperty, value);
}
public static Enum GetValue(DependencyObject element)
{
return (Enum)element.GetValue(ValueProperty);
}
// ReSharper restore InconsistentNaming
#endregion
#region Methods
private static void FlagsChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
UpdateTarget(dependencyObject as CheckBox, dependencyPropertyChangedEventArgs.NewValue as Enum);
}
private static void ValueChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
CheckBox checkbox = dependencyObject as CheckBox;
if (checkbox == null) return;
checkbox.Checked -= UpdateSource;
checkbox.Unchecked -= UpdateSource;
if (dependencyPropertyChangedEventArgs.NewValue != null)
{
checkbox.Checked += UpdateSource;
checkbox.Unchecked += UpdateSource;
}
UpdateTarget(checkbox, GetFlags(checkbox));
}
private static void UpdateTarget(CheckBox checkbox, Enum flags)
{
if (checkbox == null) return;
Enum value = GetValue(checkbox);
checkbox.IsChecked = value != null && (flags?.HasFlag(value) ?? false);
}
private static void UpdateSource(object sender, RoutedEventArgs routedEventArgs)
{
CheckBox checkbox = sender as CheckBox;
if (checkbox == null) return;
Enum flags = GetFlags(checkbox);
Enum value = GetValue(checkbox);
if (value == null) return;
if (checkbox.IsChecked ?? false)
SetFlags(checkbox, flags == null ? value : flags.SetFlag(value, true, flags.GetType()));
else
SetFlags(checkbox, flags?.SetFlag(value, false, flags.GetType()));
}
#endregion
}
}

View File

@ -0,0 +1,50 @@
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace Example_Ambilight_full.TakeAsIs.Helper
{
public static class SerializationHelper
{
public static void SaveObjectToFile<T>(T serializableObject, string path)
{
if (serializableObject == null) return;
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObject);
stream.Seek(0, SeekOrigin.Begin);
xmlDocument.Load(stream);
xmlDocument.Save(path);
}
}
catch {/* Catch'em all */}
}
public static T LoadObjectFromFile<T>(string fileName)
{
if (string.IsNullOrEmpty(fileName)) return default(T);
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(fileName);
string xmlString = xmlDocument.OuterXml;
using (StringReader sr = new StringReader(xmlString))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (XmlReader reader = new XmlTextReader(sr))
return (T)serializer.Deserialize(reader);
}
}
catch {/* Catch'em all */}
return default(T);
}
}
}

View File

@ -0,0 +1,13 @@
using System.ComponentModel;
namespace Example_Ambilight_full.TakeAsIs.Model
{
public enum AmbienceCreatorType
{
[Description("Mirror")]
Mirror,
[Description("Extend")]
Extend
}
}

View File

@ -0,0 +1,14 @@
using System;
namespace Example_Ambilight_full.TakeAsIs.Model
{
[Flags]
public enum BlackBarDetectionMode
{
None = 0,
Left = 1 << 0,
Right = 1 << 1,
Top = 1 << 2,
Bottom = 1 << 3,
}
}

View File

@ -0,0 +1,26 @@
using System;
namespace Example_Ambilight_full.TakeAsIs.Model.Extensions
{
public static class EnumExtension
{
#region Methods
public static Enum SetFlag(this Enum e, Enum value, bool set, Type t)
{
if (e == null || value == null || t == null) return e;
int eValue = Convert.ToInt32(e);
int valueValue = Convert.ToInt32(value);
if (set)
eValue |= valueValue;
else
eValue &= ~valueValue;
return (Enum)Enum.ToObject(t, eValue);
}
#endregion
}
}

View File

@ -0,0 +1,89 @@
namespace Example_Ambilight_full.TakeAsIs.Model.Extensions
{
public static class PixelDataExtension
{
#region Methods
public static int DetectBlackBarLeft(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom)
{
int bottomBorder = height - offsetBottom;
int rightBorder = width - offsetRight;
int blackBarWidth = 0;
for (int x = rightBorder - 1; x >= offsetLeft; x--)
{
for (int y = offsetTop; y < bottomBorder; y++)
{
int offset = ((y * width) + x) * 4;
if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15)
return blackBarWidth;
}
blackBarWidth++;
}
return width;
}
public static int DetectBlackBarRight(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom)
{
int bottomBorder = height - offsetBottom;
int rightBorder = width - offsetRight;
int blackBarWidth = 0;
for (int x = offsetLeft; x < rightBorder; x++)
{
for (int y = offsetTop; y < bottomBorder; y++)
{
int offset = ((y * width) + x) * 4;
if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15)
return blackBarWidth;
}
blackBarWidth++;
}
return width;
}
public static int DetectBlackBarTop(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom)
{
int bottomBorder = height - offsetBottom;
int rightBorder = width - offsetRight;
int blackBarHeight = 0;
for (int y = offsetTop; y < bottomBorder; y++)
{
for (int x = offsetLeft; x < rightBorder; x++)
{
int offset = ((y * width) + x) * 4;
if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15)
return blackBarHeight;
}
blackBarHeight++;
}
return height;
}
public static int DetectBlackBarBottom(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom)
{
int bottomBorder = height - offsetBottom;
int rightBorder = width - offsetRight;
int blackBarHeight = 0;
for (int y = bottomBorder - 1; y >= offsetTop; y--)
{
for (int x = offsetLeft; x < rightBorder; x++)
{
int offset = ((y * width) + x) * 4;
if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15)
return blackBarHeight;
}
blackBarHeight++;
}
return height;
}
#endregion
}
}

View File

@ -0,0 +1,12 @@
using System;
namespace Example_Ambilight_full.TakeAsIs.Model
{
[Flags]
public enum FlipMode
{
None = 0,
Vertical = 1 << 0,
Horizontal = 1 << 1
}
}

View File

@ -0,0 +1,19 @@
using System.ComponentModel;
namespace Example_Ambilight_full.TakeAsIs.Model
{
public enum SmoothMode
{
[Description("None")]
None,
[Description("Low")]
Low,
[Description("Medium")]
Medium,
[Description("High")]
High
}
}

View File

@ -0,0 +1,86 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Media;
using Microsoft.Win32;
using SharpDX;
using SharpDX.Direct3D9;
namespace Example_Ambilight_full.TakeAsIs.ScreenCapturing
{
public class DX9ScreenCapture : IScreenCapture
{
#region Properties & Fields
private Device _device;
private Surface _surface;
private byte[] _buffer;
public int Width { get; }
public int Height { get; }
public PixelFormat PixelFormat => PixelFormats.Bgr24;
#endregion
#region Constructors
public DX9ScreenCapture()
{
Width = (int)System.Windows.SystemParameters.PrimaryScreenWidth;
Height = (int)System.Windows.SystemParameters.PrimaryScreenHeight;
//DarthAffe 08.04.2017: Fix for system using windows-scaling. The primary screen size is reported 'wrong'.
double scaling = GetScaling();
if (Math.Abs(scaling - 1.0) > 0.01)
{
Width = (int)(Width / scaling);
Height = (int)(Height / scaling);
}
PresentParameters presentParams = new PresentParameters(Width, Height)
{
Windowed = true,
SwapEffect = SwapEffect.Discard
};
_device = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.SoftwareVertexProcessing, presentParams);
_surface = Surface.CreateOffscreenPlain(_device, Width, Height, Format.A8R8G8B8, Pool.Scratch);
_buffer = new byte[Width * Height * 4];
}
#endregion
#region Methods
private double GetScaling()
{
try
{
int currentDpi = (int)Registry.GetValue("HKEY_CURRENT_USER\\Control Panel\\Desktop", "LogPixels", 96);
return 96.0 / currentDpi;
}
catch
{
return 1.0;
}
}
public byte[] CaptureScreen()
{
_device.GetFrontBufferData(0, _surface);
DataRectangle dr = _surface.LockRectangle(LockFlags.None);
Marshal.Copy(dr.DataPointer, _buffer, 0, _buffer.Length);
_surface.UnlockRectangle();
return _buffer;
}
public void Dispose()
{
_device?.Dispose();
_surface?.Dispose();
}
#endregion
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Windows.Media;
namespace Example_Ambilight_full.TakeAsIs.ScreenCapturing
{
public interface IScreenCapture : IDisposable
{
int Width { get; }
int Height { get; }
PixelFormat PixelFormat { get; }
/// <summary>
/// As Pixel-Data BGRA
/// </summary>
/// <returns>The Pixel-Data</returns>
byte[] CaptureScreen();
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Windows.Input;
namespace Example_Ambilight_full.TakeAsIs.UI
{
public class ActionCommand : ICommand
{
#region Properties & Fields
private readonly Func<bool> _canExecute;
private readonly Action _command;
#endregion
#region Constructors
public ActionCommand(Action command, Func<bool> canExecute = null)
{
this._command = command;
this._canExecute = canExecute;
}
#endregion
#region Methods
public bool CanExecute(object parameter)
{
return _canExecute?.Invoke() ?? true;
}
public void Execute(object parameter)
{
_command?.Invoke();
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, new EventArgs());
}
#endregion
#region Events
public event EventHandler CanExecuteChanged;
#endregion
}
}

View File

@ -0,0 +1,179 @@
<UserControl x:Class="Example_Ambilight_full.TakeAsIs.UI.ConfigView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:helper="clr-namespace:Example_Ambilight_full.TakeAsIs.Helper"
xmlns:model="clr-namespace:Example_Ambilight_full.TakeAsIs.Model"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:ui="clr-namespace:Example_Ambilight_full.TakeAsIs.UI">
<!-- Quick'n'Dirty - you really shouldn't implement a View like this ... -->
<UserControl.Resources>
<ui:EnumDescriptionConverter x:Key="HEnumDescriptionConverter" />
<ObjectDataProvider x:Key="SmoothModeEnumValues" ObjectType="{x:Type system:Enum}" MethodName="GetValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="model:SmoothMode" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="AmbienceCreatorTypeValues" ObjectType="{x:Type system:Enum}" MethodName="GetValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="model:AmbienceCreatorType" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource HEnumDescriptionConverter}}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,4,0" />
</Style>
<Style TargetType="controls:NumericUpDown" BasedOn="{StaticResource {x:Type controls:NumericUpDown}}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</UserControl.Resources>
<Border Padding="16" Background="#CECECE" BorderBrush="#2E2E2E" BorderThickness="2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="160" />
<ColumnDefinition Width="32" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="160" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
<RowDefinition Height="32" />
</Grid.RowDefinitions>
<!-- Update-Rate-->
<TextBlock Grid.Row="0" Grid.Column="0" Text="Update-Rate (FPS):" />
<controls:NumericUpDown Grid.Row="0" Grid.Column="1"
Minimum="1" Maximum="60"
Value="{Binding Path=UpdateRate, Mode=TwoWay}" />
<!-- AmbienceCreatorType & Downsampling-->
<TextBlock Grid.Row="1" Grid.Column="0" Text="Ambilight-Mode:"/>
<ComboBox Grid.Row="1" Grid.Column="1"
ItemsSource="{Binding Source={StaticResource AmbienceCreatorTypeValues}}"
SelectedItem="{Binding Path=Settings.AmbienceCreatorType}" />
<TextBlock Grid.Row="1" Grid.Column="3" Text="Downsampling:" />
<controls:NumericUpDown Grid.Row="1" Grid.Column="4"
Minimum="1" Maximum="20"
Value="{Binding Path=Settings.Downsampling, Mode=TwoWay}" />
<!-- MirrorAmount & Gamma-->
<TextBlock Grid.Row="2" Grid.Column="0" Text="Mirrored Amount (%):" />
<controls:NumericUpDown Grid.Row="2" Grid.Column="1"
Minimum="0" Maximum="100"
Value="{Binding Path=Settings.MirroredAmount, Mode=TwoWay}" />
<TextBlock Grid.Row="2" Grid.Column="3" Text="Gamma:" />
<controls:NumericUpDown Grid.Row="2" Grid.Column="4"
Minimum="0.1" Maximum="10"
HasDecimals="True" Interval="0.1" StringFormat="F1"
Value="{Binding Path=Settings.Gamma, Mode=TwoWay}" />
<!-- SmoothMode -->
<TextBlock Grid.Row="3" Grid.Column="0" Text="Smoothing:" />
<ComboBox Grid.Row="3" Grid.Column="1"
ItemsSource="{Binding Source={StaticResource SmoothModeEnumValues}}"
SelectedItem="{Binding Path=Settings.SmoothMode}" />
<!-- Min Lightness -->
<TextBlock Grid.Row="3" Grid.Column="3" Text="Min Lightness (%):" />
<controls:NumericUpDown Grid.Row="3" Grid.Column="4"
Minimum="0" Maximum="100"
Value="{Binding Path=Settings.MinLightness, Mode=TwoWay}" />
<!-- FlipMode -->
<TextBlock Grid.Row="4" Grid.Column="0" Text="Flip Horizontal:" />
<CheckBox Grid.Row="4" Grid.Column="1"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:FlipMode.Horizontal}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.FlipMode}" />
<TextBlock Grid.Row="4" Grid.Column="3" Text="Flip Vertical:" />
<CheckBox Grid.Row="4" Grid.Column="4"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:FlipMode.Vertical}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.FlipMode}" />
<!-- Horizontal offsets -->
<TextBlock Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="4" FontWeight="Black" Text="Offset" />
<TextBlock Grid.Row="6" Grid.Column="0" Text="Left:" />
<controls:NumericUpDown Grid.Row="6" Grid.Column="1"
Minimum="0"
Value="{Binding Path=Settings.OffsetLeft, Mode=TwoWay}" />
<TextBlock Grid.Row="6" Grid.Column="3" Text="Right:" />
<controls:NumericUpDown Grid.Row="6" Grid.Column="4"
Minimum="0"
Value="{Binding Path=Settings.OffsetRight, Mode=TwoWay}" />
<!-- Vertical offsets -->
<TextBlock Grid.Row="7" Grid.Column="0" Text="Top:" />
<controls:NumericUpDown Grid.Row="7" Grid.Column="1" Minimum="0"
Value="{Binding Path=Settings.OffsetTop, Mode=TwoWay}" />
<TextBlock Grid.Row="7" Grid.Column="3" Text="Bottom:"/>
<controls:NumericUpDown Grid.Row="7" Grid.Column="4" Minimum="0"
Value="{Binding Path=Settings.OffsetBottom, Mode=TwoWay}" />
<!-- Horizontal BlackBar-detection -->
<TextBlock Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="4" FontWeight="Black" Text="Black-Bar detection" />
<TextBlock Grid.Row="9" Grid.Column="0" Text="Left:" />
<CheckBox Grid.Row="9" Grid.Column="1"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:BlackBarDetectionMode.Left}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.BlackBarDetectionMode}" />
<TextBlock Grid.Row="9" Grid.Column="3" Text="Right:" />
<CheckBox Grid.Row="9" Grid.Column="4"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:BlackBarDetectionMode.Right}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.BlackBarDetectionMode}" />
<!-- Vertical BlackBar-detection -->
<TextBlock Grid.Row="10" Grid.Column="0" Text="Top:" />
<CheckBox Grid.Row="10" Grid.Column="1"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:BlackBarDetectionMode.Top}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.BlackBarDetectionMode}" />
<TextBlock Grid.Row="10" Grid.Column="3" Text="Bottom:" />
<CheckBox Grid.Row="10" Grid.Column="4"
helper:CheckboxEnumFlagHelper.Value="{x:Static model:BlackBarDetectionMode.Bottom}"
helper:CheckboxEnumFlagHelper.Flags="{Binding Path=Settings.BlackBarDetectionMode}" />
<Button Grid.Row="12" Grid.Column="4" Command="{Binding ExitCommand}" Content="Exit" />
</Grid>
</Border>
</UserControl>

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Example_Ambilight_full.TakeAsIs.UI
{
/// <summary>
/// Interaction logic for ConfigView.xaml
/// </summary>
public partial class ConfigView : UserControl
{
public ConfigView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Windows;
using CUE.NET;
namespace Example_Ambilight_full.TakeAsIs.UI
{
public class ConfigViewModel
{
#region Properties & Fields
public AmbilightSettings Settings { get; }
public int UpdateRate
{
get => (int)Math.Round(1f / CueSDK.UpdateFrequency);
set
{
Settings.UpdateRate = value;
CueSDK.UpdateFrequency = 1f / value;
}
}
#endregion
#region Commands
private ActionCommand _exitCommand;
public ActionCommand ExitCommand => _exitCommand ?? (_exitCommand = new ActionCommand(Exit));
#endregion
#region Constructors
public ConfigViewModel(AmbilightSettings settings)
{
this.Settings = settings;
}
#endregion
#region Methods
private void Exit()
{
Application.Current.Shutdown();
}
#endregion
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Windows.Data;
namespace Example_Ambilight_full.TakeAsIs.UI
{
public class EnumDescriptionConverter : IValueConverter
{
#region Methods
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Enum myEnum = (Enum)value;
string description = GetEnumDescription(myEnum);
return description;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
private string GetEnumDescription(Enum enumObj)
{
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
return enumObj.ToString();
DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
return attrib?.Description;
}
#endregion
}
}

View File

@ -0,0 +1,16 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:ui="clr-namespace:Example_Ambilight_full.TakeAsIs.UI">
<tb:TaskbarIcon x:Key="Taskbar"
ToolTipText="Keyboard-Ambilight"
IconSource="../../Resources/ambilight.ico"
PopupActivation="All">
<tb:TaskbarIcon.TrayPopup>
<ui:ConfigView />
</tb:TaskbarIcon.TrayPopup>
</tb:TaskbarIcon>
</ResourceDictionary>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CUE.NET" version="1.1.3.0" targetFramework="net45" />
<package id="Hardcodet.NotifyIcon.Wpf" version="1.0.8" targetFramework="net45" />
<package id="MahApps.Metro" version="1.4.0-ALPHA026" targetFramework="net45" />
<package id="SharpDX" version="3.1.1" targetFramework="net45" />
<package id="SharpDX.Direct3D9" version="3.1.1" targetFramework="net45" />
</packages>

View File

@ -10,7 +10,7 @@ using System.Windows;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Wyrez")]
[assembly: AssemblyProduct("Example_AudioAnalyzer_full")]
[assembly: AssemblyCopyright("Copyright © Wyrez 2016")]
[assembly: AssemblyCopyright("Copyright © Wyrez 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -49,5 +49,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyVersion("1.1.0.1")]
[assembly: AssemblyFileVersion("1.1.0.1")]

View File

@ -1,37 +0,0 @@
using CUE.NET.Brushes;
using CUE.NET.Effects;
using CUE.NET.Gradients;
namespace SimpleDevTest
{
public class MoveRainbowEffect : AbstractBrushEffect<IGradientBrush>
{
#region Properties & Fields
public float DegreePerSecond { get; set; } = 30f;
#endregion
#region Constructors
#endregion
#region Methods
public override void Update(float deltaTime)
{
float value = DegreePerSecond * deltaTime;
//DarthAffe 11.09.2016: Only to test! This will overflow if run for a longer time!!!
((RainbowGradient)Brush.Gradient).StartHue += value;
((RainbowGradient)Brush.Gradient).EndHue += value;
}
public override bool CanBeAppliedTo(IBrush target)
{
return (target as IGradientBrush)?.Gradient is RainbowGradient;
}
#endregion
}
}

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using CUE.NET;
using CUE.NET.Brushes;
using CUE.NET.Devices;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Effects;
using CUE.NET.Exceptions;
@ -32,19 +33,69 @@ namespace SimpleDevTest
try
{
bool test = CueSDK.IsSDKAvailable();
// Initialize CUE-SDK
CueSDK.Initialize();
Console.WriteLine("Initialized with " + CueSDK.LoadedArchitecture + "-SDK");
CueSDK.EnableKeypressCallback();
CueSDK.KeyPressed += (sender, eventArgs) => Console.WriteLine($"Key {eventArgs.KeyId} {(eventArgs.IsPressed ? "pressed" : "released")}");
//CueSDK.KeyboardSDK.Brush = (SolidColorBrush)Color.Black;
//CueSDK.KeyboardSDK[CorsairLedId.Z].Color = Color.Red;
//CueSDK.KeyboardSDK[CorsairLedId.Z].IsLocked = true;
float thirdKeyboardWidth = CueSDK.KeyboardSDK.DeviceRectangle.Width / 3f;
ILedGroup left = new RectangleLedGroup(CueSDK.KeyboardSDK, new RectangleF(CueSDK.KeyboardSDK.DeviceRectangle.X, CueSDK.KeyboardSDK.DeviceRectangle.Y, thirdKeyboardWidth, CueSDK.KeyboardSDK.DeviceRectangle.Height));
ILedGroup mid = new RectangleLedGroup(CueSDK.KeyboardSDK, new RectangleF(CueSDK.KeyboardSDK.DeviceRectangle.X + thirdKeyboardWidth, CueSDK.KeyboardSDK.DeviceRectangle.Y, thirdKeyboardWidth, CueSDK.KeyboardSDK.DeviceRectangle.Height));
ILedGroup right = new RectangleLedGroup(CueSDK.KeyboardSDK, new RectangleF(CueSDK.KeyboardSDK.DeviceRectangle.X + thirdKeyboardWidth * 2, CueSDK.KeyboardSDK.DeviceRectangle.Y, thirdKeyboardWidth, CueSDK.KeyboardSDK.DeviceRectangle.Height));
//CueSDK.KeyboardSDK.Brush = new LinearGradientBrush(new LinearGradient(true, new GradientStop(0, Color.Blue), new GradientStop(0.5f, Color.Red)));
left.Brush = new ConicalGradientBrush(new PointF(0.6f, 0.7f), new RainbowGradient(360, 0));
left.Brush.AddEffect(new MoveGradientEffect());
left.Brush.AddEffect(new FlashEffect { Attack = 2, Sustain = 1f, Release = 2, Interval = 1f });
mid.Brush = new ConicalGradientBrush(new PointF(0.5f, 0.3f), new RainbowGradient());
mid.Brush.AddEffect(new MoveGradientEffect());
mid.Brush.AddEffect(new FlashEffect { Attack = 2, Sustain = 1f, Release = 2, Interval = 1f });
right.Brush = new ConicalGradientBrush(new PointF(0.4f, 0.7f), new RainbowGradient(360, 0));
right.Brush.AddEffect(new MoveGradientEffect());
right.Brush.AddEffect(new FlashEffect { Attack = 2, Sustain = 1f, Release = 2, Interval = 1f });
//float halfKeyboardWidth = CueSDK.KeyboardSDK.DeviceRectangle.Width / 2f;
//ILedGroup left = new RectangleLedGroup(CueSDK.KeyboardSDK, new RectangleF(CueSDK.KeyboardSDK.DeviceRectangle.X, CueSDK.KeyboardSDK.DeviceRectangle.Y, halfKeyboardWidth, CueSDK.KeyboardSDK.DeviceRectangle.Height));
//ILedGroup right = new RectangleLedGroup(CueSDK.KeyboardSDK, new RectangleF(CueSDK.KeyboardSDK.DeviceRectangle.X + halfKeyboardWidth, CueSDK.KeyboardSDK.DeviceRectangle.Y, halfKeyboardWidth, CueSDK.KeyboardSDK.DeviceRectangle.Height));
////CueSDK.KeyboardSDK.Brush = new LinearGradientBrush(new LinearGradient(true, new GradientStop(0, Color.Blue), new GradientStop(0.5f, Color.Red)));
//left.Brush = new ConicalGradientBrush(new PointF(0.6f, 0.6f), new RainbowGradient(360, 0));
//left.Brush.AddEffect(new MoveGradientEffect());
//right.Brush = new ConicalGradientBrush(new PointF(0.4f, 0.6f), new RainbowGradient());
//right.Brush.AddEffect(new MoveGradientEffect());
CueSDK.UpdateMode = UpdateMode.Continuous;
IBrush rainbowBrush = new LinearGradientBrush(new RainbowGradient());
rainbowBrush.AddEffect(new FlashEffect { Attack = 5f, Sustain = 1f, Decay = 0, Release = 5f, Interval = 1f });
rainbowBrush.AddEffect(new MoveRainbowEffect());
rainbowBrush.AddEffect(new RemoveRedEffect());
Wait(5);
CueSDK.UpdateMode = UpdateMode.Manual;
for (int i = 0; i < 100000; i++)
{
CueSDK.Reinitialize();
Console.WriteLine(i);
}
foreach (ICueDevice device in CueSDK.InitializedDevices)
AddTestBrush(device, rainbowBrush);
Console.WriteLine("done!");
Wait(5);
//IBrush rainbowBrush = new LinearGradientBrush(new RainbowGradient());
//rainbowBrush.AddEffect(new FlashEffect { Attack = 5f, Sustain = 1f, Decay = 0, Release = 5f, Interval = 1f });
//rainbowBrush.AddEffect(new MoveRainbowEffect());
//rainbowBrush.AddEffect(new RemoveRedEffect());
//foreach (ICueDevice device in CueSDK.InitializedDevices)
// AddTestBrush(device, rainbowBrush);
//// Get connected keyboard or throw exception if there is no light controllable keyboard connected
//CorsairKeyboard keyboard = CueSDK.KeyboardSDK;

View File

@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Wyrez")]
[assembly: AssemblyProduct("SimpleDevTest")]
[assembly: AssemblyCopyright("Copyright © Wyrez 2016")]
[assembly: AssemblyCopyright("Copyright © Wyrez 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyVersion("1.2.0.1")]
[assembly: AssemblyFileVersion("1.2.0.1")]

View File

@ -47,7 +47,6 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MoveRainbowEffect.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RemoveRedEffect.cs" />

View File

@ -1,4 +1,6 @@
// ReSharper disable MemberCanBeProtected.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
using System.Collections.Generic;
using System.Linq;
@ -18,6 +20,13 @@ namespace CUE.NET.Gradients
/// </summary>
public IList<GradientStop> GradientStops { get; } = new List<GradientStop>();
/// <summary>
/// Gets or sets if the Gradient wraps around if there isn't a second stop to take.
/// Example: There is a stop at offset 0f, 0.5f and 0.75f.
/// Without wrapping offset 1f will be calculated the same as 0.75f. With wrapping it would be the same as 0f.
/// </summary>
public bool WrapGradient { get; set; }
#endregion
#region Constructors
@ -38,6 +47,19 @@ namespace CUE.NET.Gradients
GradientStops.Add(gradientStop);
}
/// <summary>
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
/// </summary>
/// <param name="wrapGradient">Specifies whether the gradient should wrapp or not (see <see cref="WrapGradient"/> for an example of what this means).</param>
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
protected AbstractGradient(bool wrapGradient, params GradientStop[] gradientStops)
{
this.WrapGradient = wrapGradient;
foreach (GradientStop gradientStop in gradientStops)
GradientStops.Add(gradientStop);
}
#endregion
#region Methods
@ -54,10 +76,7 @@ namespace CUE.NET.Gradients
return max;
float min = GradientStops.Min(n => n.Offset);
if (offset < min)
return min;
return offset;
return offset < min ? min : offset;
}
/// <summary>

View File

@ -1,5 +1,6 @@
// ReSharper disable UnusedMember.Global
using System.Collections.Generic;
using System.Linq;
using CUE.NET.Devices.Generic;
@ -26,6 +27,15 @@ namespace CUE.NET.Gradients
: base(gradientStops)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="AbstractGradient"/> class.
/// </summary>
/// <param name="wrapGradient">Specifies whether the gradient should wrapp or not (see <see cref="AbstractGradient.WrapGradient"/> for an example of what this means).</param>
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
public LinearGradient(bool wrapGradient, params GradientStop[] gradientStops)
: base(wrapGradient, gradientStops)
{ }
#endregion
#region Methods
@ -37,13 +47,36 @@ namespace CUE.NET.Gradients
/// <returns>The color at the specific offset.</returns>
public override CorsairColor GetColor(float offset)
{
if (!GradientStops.Any()) return CorsairColor.Transparent;
if (GradientStops.Count == 0) return CorsairColor.Transparent;
if (GradientStops.Count == 1) return GradientStops.First().Color;
offset = ClipOffset(offset);
GradientStop gsBefore;
GradientStop gsAfter;
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();
IList<GradientStop> orderedStops = GradientStops.OrderBy(x => x.Offset).ToList();
if (WrapGradient)
{
gsBefore = orderedStops.LastOrDefault(n => n.Offset <= offset);
if (gsBefore == null)
{
GradientStop lastStop = orderedStops[orderedStops.Count - 1];
gsBefore = new GradientStop(lastStop.Offset - 1f, lastStop.Color);
}
gsAfter = orderedStops.FirstOrDefault(n => n.Offset >= offset);
if (gsAfter == null)
{
GradientStop firstStop = orderedStops[0];
gsAfter = new GradientStop(firstStop.Offset + 1f, firstStop.Color);
}
}
else
{
offset = ClipOffset(offset);
gsBefore = orderedStops.Last(n => n.Offset <= offset);
gsAfter = orderedStops.First(n => n.Offset >= offset);
}
float blendFactor = 0f;
if (!gsBefore.Offset.Equals(gsAfter.Offset))

View File

@ -8,7 +8,7 @@ namespace CUE.NET.Gradients
{
/// <summary>
/// Represents a rainbow gradient which circles through all colors of the HUE-color-space.<br />
/// See <see cref="http://upload.wikimedia.org/wikipedia/commons/a/ad/HueScale.svg" /> as reference
/// See <see href="http://upload.wikimedia.org/wikipedia/commons/a/ad/HueScale.svg" /> as reference.
/// </summary>
public class RainbowGradient : IGradient
{
@ -43,8 +43,6 @@ namespace CUE.NET.Gradients
#region Methods
#endregion
/// <summary>
/// Gets the color on the rainbow at the given offset.
/// </summary>
@ -58,5 +56,7 @@ namespace CUE.NET.Gradients
hue += 360;
return ColorHelper.ColorFromHSV(hue, 1f, 1f);
}
#endregion
}
}

View File

@ -19,6 +19,7 @@ namespace CUE.NET.Groups.Extensions
public static ListLedGroup ToListLedGroup(this AbstractLedGroup ledGroup)
{
ListLedGroup listLedGroup = ledGroup as ListLedGroup;
// ReSharper disable once InvertIf
if (listLedGroup == null)
{
bool wasAttached = ledGroup.Detach();

View File

@ -8,6 +8,9 @@ using CUE.NET.Effects;
namespace CUE.NET.Groups
{
/// <summary>
/// Represents a basic led-group.
/// </summary>
public interface ILedGroup : IEffectTarget<ILedGroup>
{
/// <summary>

View File

@ -15,6 +15,9 @@ namespace CUE.NET.Groups
{
#region Properties & Fields
/// <summary>
/// Gets the strongly-typed target used for the effect.
/// </summary>
protected override ILedGroup EffectTarget => this;
/// <summary>

View File

@ -18,7 +18,7 @@ namespace CUE.NET.Groups
public class RectangleLedGroup : AbstractLedGroup
{
#region Properties & Fields
private IList<CorsairLed> _ledCache;
private RectangleF _rectangle;
@ -35,10 +35,19 @@ namespace CUE.NET.Groups
}
}
private float _minOverlayPercentage;
/// <summary>
/// Gets or sets the minimal percentage overlay a LED must have with the <see cref="Rectangle" /> to be taken into the ledgroup.
/// </summary>
public float MinOverlayPercentage { get; set; }
public float MinOverlayPercentage
{
get { return _minOverlayPercentage; }
set
{
_minOverlayPercentage = value;
_ledCache = null;
}
}
#endregion
@ -98,6 +107,10 @@ namespace CUE.NET.Groups
#region Methods
/// <summary>
/// Gets a list containing all LEDs of this group.
/// </summary>
/// <returns>The list containing all LEDs of this group.</returns>
public override IEnumerable<CorsairLed> GetLeds()
{
return _ledCache ?? (_ledCache = Device.Where(x => RectangleHelper.CalculateIntersectPercentage(x.LedRectangle, Rectangle) >= MinOverlayPercentage).ToList());

View File

@ -13,7 +13,7 @@ namespace CUE.NET.Helper
#region byte/float conversion
/// <summary>
/// Converts the alpha-value of the <see cref="CorsairColor"/> to an float value int the range [0..1].
/// Converts the alpha-value of the <see cref="CorsairColor"/> to a float value in 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>
@ -23,7 +23,7 @@ namespace CUE.NET.Helper
}
/// <summary>
/// Converts the red-value of the <see cref="CorsairColor"/> to an float value int the range [0..1].
/// Converts the red-value of the <see cref="CorsairColor"/> to a float value in 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>
@ -33,7 +33,7 @@ namespace CUE.NET.Helper
}
/// <summary>
/// Converts the green-value of the <see cref="CorsairColor"/> to an float value int the range [0..1].
/// Converts the green-value of the <see cref="CorsairColor"/> to a float value in 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>
@ -43,7 +43,7 @@ namespace CUE.NET.Helper
}
/// <summary>
/// Converts the blue-value of the <see cref="CorsairColor"/> to an float value int the range [0..1].
/// Converts the blue-value of the <see cref="CorsairColor"/> to a float value in 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>
@ -65,7 +65,12 @@ namespace CUE.NET.Helper
return new CorsairColor(GetIntColorFromFloat(a), GetIntColorFromFloat(r), GetIntColorFromFloat(g), GetIntColorFromFloat(b));
}
private static byte GetIntColorFromFloat(float f)
/// <summary>
/// Converts the given float-value to a integer-color in the range [0..255].
/// </summary>
/// <param name="f">The float color-value</param>
/// <returns>The integer-value int the range [0..255].</returns>
public static byte GetIntColorFromFloat(float f)
{
// ReSharper disable once RedundantCast - never trust this ...
float calcF = (float)Math.Max(0f, Math.Min(1f, f));
@ -84,6 +89,7 @@ namespace CUE.NET.Helper
/// <returns>The resulting color.</returns>
public static CorsairColor Blend(this CorsairColor bg, CorsairColor fg)
{
// ReSharper disable once ConvertIfStatementToSwitchStatement
if (fg.A == 255)
return fg;
@ -114,7 +120,7 @@ namespace CUE.NET.Helper
float min = Math.Min(Math.Min(color.R, color.G), color.B);
float max = Math.Max(Math.Max(color.R, color.G), color.B);
float hue = 0f;
float hue;
if (Math.Abs(max - color.R) < float.Epsilon) // r is max
hue = (color.G - color.B) / (max - min);
else if (Math.Abs(max - color.G) < float.Epsilon) // g is max

View File

@ -10,7 +10,19 @@ namespace CUE.NET.Helper
public static class RectangleHelper
{
/// <summary>
/// Calculates the center-point of a rectangle adding a offset.
/// Moves a rectangle by a adding an offset.
/// </summary>
/// <param name="rectangle">The rectangle.</param>
/// <param name="offsetX">The offset for the x-value</param>
/// <param name="offsetY">The offset for the y-value</param>
/// <returns>The moved rectangle.</returns>
public static RectangleF Move(this RectangleF rectangle, float offsetX = 0f, float offsetY = 0f)
{
return new RectangleF(rectangle.X + offsetX, rectangle.Y + offsetY, rectangle.Width, rectangle.Height);
}
/// <summary>
/// Calculates the center-point of a rectangle adding an offset.
/// </summary>
/// <param name="rectangle">The rectangle.</param>
/// <param name="offsetX">The offset for the x-value</param>

View File

@ -2,8 +2,12 @@
// ReSharper disable UnusedMember.Global
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Exceptions;
namespace CUE.NET.Native
{
@ -19,11 +23,6 @@ namespace CUE.NET.Native
/// </summary>
internal static string LoadedArchitecture { get; private set; }
static _CUESDK()
{
LoadCUESDK();
}
/// <summary>
/// Reloads the SDK.
/// </summary>
@ -37,10 +36,24 @@ namespace CUE.NET.Native
{
if (_dllHandle != IntPtr.Zero) return;
LoadedArchitecture = LoadedArchitecture = Environment.Is64BitProcess ? "x64" : "x86";
// HACK: Load library at runtime to support both, x86 and x64 with one managed dll
_dllHandle = LoadLibrary((LoadedArchitecture = Environment.Is64BitProcess ? "x64" : "x86") + "/CUESDK_2015.dll");
List<string> possiblePathList = Environment.Is64BitProcess ? CueSDK.PossibleX64NativePaths : CueSDK.PossibleX86NativePaths;
string dllPath = null;
foreach (string path in possiblePathList)
if (File.Exists(path))
{
dllPath = path;
break;
}
if (dllPath == null) throw new WrapperException($"Can't find the CUE-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'");
_dllHandle = LoadLibrary(dllPath);
_corsairSetLedsColorsPointer = (CorsairSetLedsColorsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLedsColors"), typeof(CorsairSetLedsColorsPointer));
_corsairGetLedsColorsPointer = (CorsairGetLedsColorsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedsColors"), typeof(CorsairGetLedsColorsPointer));
_corsairGetDeviceCountPointer = (CorsairGetDeviceCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceCount"), typeof(CorsairGetDeviceCountPointer));
_corsairGetDeviceInfoPointer = (CorsairGetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceInfo"), typeof(CorsairGetDeviceInfoPointer));
_corsairGetLedPositionsPointer = (CorsairGetLedPositionsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedPositions"), typeof(CorsairGetLedPositionsPointer));
@ -50,6 +63,7 @@ namespace CUE.NET.Native
_corsairReleaseControlPointer = (CorsairReleaseControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairReleaseControl"), typeof(CorsairReleaseControlPointer));
_corsairPerformProtocolHandshakePointer = (CorsairPerformProtocolHandshakePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairPerformProtocolHandshake"), typeof(CorsairPerformProtocolHandshakePointer));
_corsairGetLastErrorPointer = (CorsairGetLastErrorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLastError"), typeof(CorsairGetLastErrorPointer));
_corsairRegisterKeypressCallbackPointer = (CorsairRegisterKeypressCallbackPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairRegisterKeypressCallback"), typeof(CorsairRegisterKeypressCallbackPointer));
}
private static void UnloadCUESDK()
@ -77,6 +91,7 @@ namespace CUE.NET.Native
#region Pointers
private static CorsairSetLedsColorsPointer _corsairSetLedsColorsPointer;
private static CorsairGetLedsColorsPointer _corsairGetLedsColorsPointer;
private static CorsairGetDeviceCountPointer _corsairGetDeviceCountPointer;
private static CorsairGetDeviceInfoPointer _corsairGetDeviceInfoPointer;
private static CorsairGetLedPositionsPointer _corsairGetLedPositionsPointer;
@ -86,6 +101,7 @@ namespace CUE.NET.Native
private static CorsairReleaseControlPointer _corsairReleaseControlPointer;
private static CorsairPerformProtocolHandshakePointer _corsairPerformProtocolHandshakePointer;
private static CorsairGetLastErrorPointer _corsairGetLastErrorPointer;
private static CorsairRegisterKeypressCallbackPointer _corsairRegisterKeypressCallbackPointer;
#endregion
@ -94,6 +110,9 @@ namespace CUE.NET.Native
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool CorsairSetLedsColorsPointer(int size, IntPtr ledsColors);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool CorsairGetLedsColorsPointer(int size, IntPtr ledsColors);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CorsairGetDeviceCountPointer();
@ -121,6 +140,9 @@ namespace CUE.NET.Native
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate CorsairError CorsairGetLastErrorPointer();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool CorsairRegisterKeypressCallbackPointer(IntPtr callback, IntPtr context);
#endregion
// ReSharper disable EventExceptionNotDocumented
@ -133,6 +155,14 @@ namespace CUE.NET.Native
return _corsairSetLedsColorsPointer(size, ledsColors);
}
/// <summary>
/// CUE-SDK: get current color for the list of requested LEDs.
/// </summary>
internal static bool CorsairGetLedsColors(int size, IntPtr ledsColors)
{
return _corsairGetLedsColorsPointer(size, ledsColors);
}
/// <summary>
/// CUE-SDK: returns number of connected Corsair devices that support lighting control.
/// </summary>
@ -206,6 +236,11 @@ namespace CUE.NET.Native
return _corsairGetLastErrorPointer();
}
internal static bool CorsairRegisterKeypressCallback(IntPtr callback, IntPtr context)
{
return _corsairRegisterKeypressCallbackPointer(callback, context);
}
// ReSharper restore EventExceptionNotDocumented
#endregion

View File

@ -2,6 +2,7 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable UnusedMember.Global
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -13,6 +14,7 @@ namespace CUE.NET.Profiles
/// <summary>
/// Represents a CUE profile.
/// </summary>
[Obsolete("Only works with CUE 1.")]
public class CueProfile
{
#region Properties & Fields

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using CUE.NET.Brushes;
@ -8,6 +9,7 @@ namespace CUE.NET.Profiles
/// <summary>
/// Represents a device of a CUE profile.
/// </summary>
[Obsolete("Only works with CUE 1.")]
internal class CueProfileDevice
{
#region Properties & Fields

View File

@ -12,6 +12,7 @@ namespace CUE.NET.Profiles
/// <summary>
/// Represents a mode of a CUE profile.
/// </summary>
[Obsolete("Only works with CUE 1.")]
internal class CueProfileMode
{
#region Properties & Fields

View File

@ -12,6 +12,7 @@ namespace CUE.NET.Profiles
/// <summary>
/// Represents the SDK for CUE profiles.
/// </summary>
[Obsolete("Only works with CUE 1.")]
public static class CueProfiles
{
#region Constants
@ -62,6 +63,7 @@ namespace CUE.NET.Profiles
public static CueProfile LoadProfileByName(string name = null)
{
string id = null;
// ReSharper disable once InvertIf
if (name != null && !_profileNameMapping.TryGetValue(name, out id))
{
LoadProfileNames(); // Reload and try again

View File

@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Wyrez")]
[assembly: AssemblyProduct("CUE.NET")]
[assembly: AssemblyCopyright("Copyright © Wyrez 2016")]
[assembly: AssemblyCopyright("Copyright © Wyrez 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyVersion("1.2.0.1")]
[assembly: AssemblyFileVersion("1.2.0.1")]

View File

@ -1,3 +1,6 @@
**CUE.NET is considered done now and will be no longer actively developed.
It is superseded by [RGB.NET](https://github.com/DarthAffe/RGB.NET). Feel free to join the [discord-channel](https://discord.gg/9kytURv) if you're interested what's happening there :)**
# CUE.NET
C# (.NET) Wrapper library around the Corsair CUE-SDK

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More