mirror of
https://github.com/DarthAffe/CUE.NET.git
synced 2025-12-12 16:58:29 +00:00
Added LinearGradientBrush, improved example
This commit is contained in:
parent
6f05de450e
commit
f1daa4a766
@ -63,8 +63,10 @@
|
||||
<Compile Include="Devices\Generic\Enums\CorsairAccessMode.cs" />
|
||||
<Compile Include="Devices\Generic\Enums\CorsairDeviceCaps.cs" />
|
||||
<Compile Include="Devices\Generic\Enums\CorsairDeviceType.cs" />
|
||||
<Compile Include="Devices\Keyboard\ColorBrushes\IBrush.cs" />
|
||||
<Compile Include="Devices\Keyboard\ColorBrushes\SolidColorBrush.cs" />
|
||||
<Compile Include="Devices\Keyboard\Brushes\GradientStop.cs" />
|
||||
<Compile Include="Devices\Keyboard\Brushes\IBrush.cs" />
|
||||
<Compile Include="Devices\Keyboard\Brushes\LinearGradientBrush.cs" />
|
||||
<Compile Include="Devices\Keyboard\Brushes\SolidColorBrush.cs" />
|
||||
<Compile Include="Devices\Keyboard\Enums\CorsairLogicalKeyboardLayout.cs" />
|
||||
<Compile Include="Devices\Headset\Enums\CorsairHeadsetLedId.cs" />
|
||||
<Compile Include="Devices\Keyboard\Enums\CorsairKeyboardKeyId.cs" />
|
||||
|
||||
26
Devices/Keyboard/Brushes/GradientStop.cs
Normal file
26
Devices/Keyboard/Brushes/GradientStop.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
public class GradientStop
|
||||
{
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
public float Offset { get; set; }
|
||||
|
||||
public Color Color { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public GradientStop(float offset, Color color)
|
||||
{
|
||||
this.Offset = offset;
|
||||
this.Color = color;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.ColorBrushes
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
public interface IBrush
|
||||
{
|
||||
132
Devices/Keyboard/Brushes/LinearGradientBrush.cs
Normal file
132
Devices/Keyboard/Brushes/LinearGradientBrush.cs
Normal file
@ -0,0 +1,132 @@
|
||||
// ReSharper disable CollectionNeverUpdated.Global
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable ReturnTypeCanBeEnumerable.Global
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
public class LinearGradientBrush : IBrush
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public PointF StartPoint { get; set; } = new PointF(0f, 0.5f);
|
||||
public PointF EndPoint { get; set; } = new PointF(1f, 0.5f);
|
||||
public IList<GradientStop> GradientStops { get; } = new List<GradientStop>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public LinearGradientBrush()
|
||||
{ }
|
||||
|
||||
public LinearGradientBrush(PointF startPoint, PointF endPoint, params GradientStop[] gradientStops)
|
||||
{
|
||||
this.StartPoint = startPoint;
|
||||
this.EndPoint = endPoint;
|
||||
|
||||
foreach (GradientStop gradientStop in gradientStops)
|
||||
GradientStops.Add(gradientStop);
|
||||
}
|
||||
|
||||
public LinearGradientBrush(params GradientStop[] gradientStops)
|
||||
{
|
||||
foreach (GradientStop gradientStop in gradientStops)
|
||||
GradientStops.Add(gradientStop);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public Color GetColorAtPoint(RectangleF rectangle, PointF point)
|
||||
{
|
||||
if (!GradientStops.Any()) return Color.Transparent;
|
||||
if (GradientStops.Count == 1) return GradientStops.First().Color;
|
||||
|
||||
// Taken from https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/
|
||||
|
||||
float x3 = point.X;
|
||||
float y3 = point.Y;
|
||||
|
||||
float x1 = StartPoint.X * rectangle.Width;
|
||||
float y1 = StartPoint.Y * rectangle.Height;
|
||||
PointF p1 = new PointF(x1, y1); // Starting point
|
||||
|
||||
float x2 = EndPoint.X * rectangle.Width;
|
||||
float y2 = EndPoint.Y * rectangle.Height;
|
||||
PointF p2 = new PointF(x2, y2); //End point
|
||||
|
||||
// Calculate intersecting points
|
||||
PointF p4;
|
||||
|
||||
if (y1.Equals(y2)) // Horizontal case
|
||||
p4 = new PointF(x3, y1);
|
||||
|
||||
else if (x1.Equals(x2)) // Vertical case
|
||||
p4 = new PointF(x1, y3);
|
||||
|
||||
else // Diagnonal case
|
||||
{
|
||||
float m = (y2 - y1) / (x2 - x1);
|
||||
float m2 = -1 / m;
|
||||
float b = y1 - m * x1;
|
||||
float c = y3 - m2 * x3;
|
||||
|
||||
float x4 = (c - b) / (m - m2);
|
||||
float y4 = m * x4 + b;
|
||||
p4 = new PointF(x4, y4);
|
||||
}
|
||||
|
||||
// Calculate distances relative to the vector start
|
||||
float d4 = Dist(p4, p1, p2);
|
||||
float d2 = Dist(p2, p1, p2);
|
||||
|
||||
float x = d4 / d2;
|
||||
|
||||
// Clip the input if before or after the max/min offset values
|
||||
float max = GradientStops.Max(n => n.Offset);
|
||||
if (x > max)
|
||||
x = max;
|
||||
|
||||
float min = GradientStops.Min(n => n.Offset);
|
||||
if (x < min)
|
||||
x = min;
|
||||
|
||||
// Find gradient stops that surround the input value
|
||||
GradientStop gs0 = GradientStops.Where(n => n.Offset <= x).OrderBy(n => n.Offset).Last();
|
||||
GradientStop gs1 = GradientStops.Where(n => n.Offset >= x).OrderBy(n => n.Offset).First();
|
||||
|
||||
float y = 0f;
|
||||
if (!gs0.Offset.Equals(gs1.Offset))
|
||||
y = ((x - gs0.Offset) / (gs1.Offset - gs0.Offset));
|
||||
|
||||
byte colA = (byte)((gs1.Color.A - gs0.Color.A) * y + gs0.Color.A);
|
||||
byte colR = (byte)((gs1.Color.R - gs0.Color.R) * y + gs0.Color.R);
|
||||
byte colG = (byte)((gs1.Color.G - gs0.Color.G) * y + gs0.Color.G);
|
||||
byte colB = (byte)((gs1.Color.B - gs0.Color.B) * y + gs0.Color.B);
|
||||
return Color.FromArgb(colA, colR, colG, colB);
|
||||
}
|
||||
|
||||
// Taken from https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/
|
||||
/// <summary>
|
||||
/// Returns the signed magnitude of a point on a vector with origin po and pointing to pf
|
||||
/// </summary>
|
||||
private float Dist(PointF px, PointF po, PointF pf)
|
||||
{
|
||||
float d = (float)Math.Sqrt((px.Y - po.Y) * (px.Y - po.Y) + (px.X - po.X) * (px.X - po.X));
|
||||
|
||||
return (((px.Y < po.Y) && (pf.Y > po.Y)) ||
|
||||
((px.Y > po.Y) && (pf.Y < po.Y)) ||
|
||||
((px.Y.Equals(po.Y)) && (px.X < po.X) && (pf.X > po.X)) ||
|
||||
((px.Y.Equals(po.Y)) && (px.X > po.X) && (pf.X < po.X)))
|
||||
? -d : d;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.ColorBrushes
|
||||
namespace CUE.NET.Devices.Keyboard.Brushes
|
||||
{
|
||||
public class SolidColorBrush : IBrush
|
||||
{
|
||||
@ -6,7 +6,7 @@ using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using CUE.NET.Devices.Generic;
|
||||
using CUE.NET.Devices.Keyboard.ColorBrushes;
|
||||
using CUE.NET.Devices.Keyboard.Brushes;
|
||||
using CUE.NET.Devices.Keyboard.Enums;
|
||||
using CUE.NET.Devices.Keyboard.Keys;
|
||||
using CUE.NET.Helper;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using CUE.NET.Devices.Keyboard.ColorBrushes;
|
||||
using CUE.NET.Devices.Keyboard.Brushes;
|
||||
using CUE.NET.Devices.Keyboard.Extensions;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Keys
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using CUE.NET.Devices.Keyboard.ColorBrushes;
|
||||
using CUE.NET.Devices.Keyboard.Brushes;
|
||||
|
||||
namespace CUE.NET.Devices.Keyboard.Keys
|
||||
{
|
||||
|
||||
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
using CUE.NET;
|
||||
using CUE.NET.Devices.Generic.Enums;
|
||||
using CUE.NET.Devices.Keyboard;
|
||||
using CUE.NET.Devices.Keyboard.ColorBrushes;
|
||||
using CUE.NET.Devices.Keyboard.Brushes;
|
||||
using CUE.NET.Devices.Keyboard.Enums;
|
||||
using CUE.NET.Devices.Keyboard.Extensions;
|
||||
using CUE.NET.Devices.Keyboard.Keys;
|
||||
@ -18,6 +18,7 @@ namespace SimpleDevTest
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Press any key to exit ...");
|
||||
Console.WriteLine();
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
@ -35,6 +36,11 @@ namespace SimpleDevTest
|
||||
if (keyboard == null)
|
||||
throw new WrapperException("No keyboard found");
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// First we'll look at some basic coloring
|
||||
|
||||
Console.WriteLine("Basic color-test ...");
|
||||
// Ink all numbers on the keypad except the '5' purple, we want that to be gray
|
||||
ListKeyGroup purpleGroup = new RectangleKeyGroup(keyboard, CorsairKeyboardKeyId.Keypad7, CorsairKeyboardKeyId.Keypad3)
|
||||
{ Brush = new SolidColorBrush(Color.Purple) }
|
||||
@ -63,27 +69,68 @@ namespace SimpleDevTest
|
||||
// Update the keyboard to show the configured colors, (your CUE settings defines the rest)
|
||||
keyboard.UpdateLeds();
|
||||
|
||||
// Wait 5 sec
|
||||
for (int i = 5; i > 0; i--)
|
||||
Wait(3);
|
||||
|
||||
// Remove all the groups we created above to clear the keyboard
|
||||
purpleGroup.Detach();
|
||||
whiteGroup.Detach();
|
||||
yellowGroup.Detach();
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Next we add a nice linear gradient brush over the keyboard and play around with the offset of one stop
|
||||
|
||||
Console.WriteLine("gradient-brush-test");
|
||||
|
||||
// Create our gradient stop to play with
|
||||
GradientStop moveableStop = new GradientStop(0, Color.FromArgb(0, 255, 0));
|
||||
|
||||
//Create a basic (by default horizontal) brush ...
|
||||
LinearGradientBrush linearBrush = new LinearGradientBrush(new GradientStop(0, Color.Blue), moveableStop, new GradientStop(1f, Color.Red));
|
||||
|
||||
// ... and add it as the keyboard background
|
||||
keyboard.Brush = linearBrush;
|
||||
|
||||
// Move the brush from left to right
|
||||
for (float offset = 0; offset <= 1f; offset += 0.02f)
|
||||
{
|
||||
Console.WriteLine(i);
|
||||
Thread.Sleep(1000);
|
||||
moveableStop.Offset = offset;
|
||||
keyboard.UpdateLeds();
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
// And back to center
|
||||
for (float offset = 1f; offset >= 0.5f; offset -= 0.02f)
|
||||
{
|
||||
moveableStop.Offset = offset;
|
||||
keyboard.UpdateLeds();
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
// "Rotate" the brush (this is of course not the best implementation for this but you see the point)
|
||||
for (float rotateX = 0, rotateY = 0; rotateX <= 1f; rotateX += 0.02f, rotateY = 0.04f)
|
||||
{
|
||||
if (rotateY > 1f)
|
||||
rotateY = 1f - (rotateY - 1f);
|
||||
|
||||
linearBrush.StartPoint = new PointF(rotateX, rotateY);
|
||||
linearBrush.EndPoint = new PointF(1f - rotateX, 1f - rotateY);
|
||||
|
||||
keyboard.UpdateLeds();
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
Wait(2);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Now let us move some points random over the keyboard
|
||||
// Something like this could become some sort of effect
|
||||
|
||||
// Initialize needed stuff
|
||||
const float SPEED = 4f; // mm/tick
|
||||
const float SPEED = 6f; // mm/tick
|
||||
Random random = new Random();
|
||||
|
||||
// Remove all the groups we created above to clear the keyboard
|
||||
purpleGroup.Detach();
|
||||
whiteGroup.Detach();
|
||||
yellowGroup.Detach();
|
||||
|
||||
// Flash whole keyboard three times to ... well ... just to make it happen
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
@ -168,6 +215,15 @@ namespace SimpleDevTest
|
||||
Thread.Sleep(1000); // Don't exit after exception
|
||||
}
|
||||
|
||||
private static void Wait(int sec)
|
||||
{
|
||||
for (int i = sec; i > 0; i--)
|
||||
{
|
||||
Console.WriteLine(i);
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
private static PointF Interpolate(PointF p1, PointF p2, float length)
|
||||
{
|
||||
float distance = (float)(Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2)));
|
||||
|
||||
@ -49,8 +49,8 @@ namespace CUE.NET.Helper
|
||||
|
||||
private static byte GetIntColorFromFloat(float f)
|
||||
{
|
||||
float calcF = (float)Math.Max(0.0, Math.Min(1.0, f));
|
||||
return (byte)(calcF == 1.0 ? 255 : calcF * 256.0);
|
||||
float calcF = (float)Math.Max(0f, Math.Min(1f, f));
|
||||
return (byte)(calcF.Equals(1f) ? 255 : calcF * 256.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user