The Corsair User Forums  

Go Back   The Corsair User Forums > Corsair Product Discussion > Corsair Utility Engine (CUE) 1.x and 2.x > CUE 1.x and 2.x SDK

 
 
Thread Tools Search this Thread Rate Thread Display Modes
  #16  
Old 12-23-2015, 11:57 AM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 827029
Darth Affe Reputation: 15
Default

I finally finished a V1.0.
Check the updates start-post (http://forum.corsair.com/v3/showpost...49&postcount=1)
or https://github.com/DarthAffe/CUE.NET/releases/tag/v1.0
  #17  
Old 02-07-2016, 06:55 AM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 835425
Darth Affe Reputation: 15
Default

I finished V1.0.1 with some basic CUE profile support (only colors so far)
https://github.com/DarthAffe/CUE.NET...ses/tag/v1.0.1
  #18  
Old 02-18-2016, 05:22 PM
dabates dabates is offline
Registered User
 
Join Date: Feb 2016
Posts: 2
POST ID # = 837859
dabates Reputation: 10
Default

Quick stupid question.. I'm writting an alert program that's going to run in the background.. I got everything working .. except this..

Basically what I do is flash lights (Brush color, Brush black.. etc) .. then at the end of that "flash" function I'd like the keyboard to revert back to the profile that's running before the flashing begain (like it does when you close the program) .. I am not opening it exclusive.. and I know the problem is that it's ujsing a black brush.

I've tried to use a transparent brush to see if that would work.. but no dice.. is there a way ( or do you know of a way ) that will release control of the keyboard back to CUE so the profile will continue to run as it did before, or a way to just "reset" the keyboard?
  #19  
Old 02-19-2016, 07:17 AM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 837959
Darth Affe Reputation: 15
Default

No, at the moment there is no way to get any kind of information about CUE through the SDK.
That's why currently (as far as I know) there are only two ways to release control of the keyboard back to CUE (and it seems that you know of both):
1. Close the application (this is quite obvious^^)
2. Run your application in shared access mode (this is default). CUE should regain access as soon as it updates something. (That's why a CUE-profile containing only background lights will never get control back.)

The profile loading option I introduced with the last update allows some kind of workaround to this problem, but you need to know to which profile you'd like to revert to (the default-profile is the only 'variable' thing, since it's possible to get this out of the CUE-config file).

EDIT: Just as I wrote this I came up with something that might work: Actually it should be possible to reset the connection to the SDK (to reset the keyboard to CUE settings) without losing internal states. I'll investigate this over the weekend - sometimes things are too easy to be recognized^^

Last edited by Darth Affe; 02-19-2016 at 07:19 AM.
  #20  
Old 02-20-2016, 05:39 AM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 838125
Darth Affe Reputation: 15
Thumbs up

I just added the possibility to reinitialize - this should solve your problem.
https://github.com/DarthAffe/CUE.NET...ses/tag/v1.0.2

Just update to the latest version (nuget-packages are updated too).
  #21  
Old 03-16-2016, 05:10 PM
dabates dabates is offline
Registered User
 
Join Date: Feb 2016
Posts: 2
POST ID # = 842749
dabates Reputation: 10
Default

Quote:
Originally Posted by Darth Affe View Post
I just added the possibility to reinitialize - this should solve your problem.
https://github.com/DarthAffe/CUE.NET...ses/tag/v1.0.2

Just update to the latest version (nuget-packages are updated too).
Sorry for the late response, I didn't get notified of a change.. .. I will need to fix that.. I will pull down the pre-release nuget and see if it works :) thanks for your help!

UPDATE: This works perfectly.. :) I'm using it for a monitoring program that flashes the keyboard when I have PRTG issues.. and this worked great! I appreciate it!

Last edited by dabates; 03-16-2016 at 05:13 PM.
  #22  
Old 06-04-2016, 12:43 PM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 856415
Darth Affe Reputation: 15
Default

I just published a new version (1.0.3) which contains quite a lot new stuff.
https://github.com/DarthAffe/CUE.NET...ses/tag/v1.0.3

Nuget-packages are of course up2date.
  #23  
Old 09-11-2016, 12:05 PM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 870924
Darth Affe Reputation: 15
Default

I just published a big release (1.1.0) [hotfixed to 1.1.0.1]
https://github.com/DarthAffe/CUE.NET...es/tag/1.1.0.1

Nuget-packages are of course up2date.

Last edited by Darth Affe; 09-11-2016 at 01:51 PM.
  #24  
Old 12-20-2016, 10:51 AM
goomonster3 goomonster3 is offline
Registered User
 
Join Date: Mar 2015
Posts: 44
POST ID # = 883166
goomonster3 Reputation: 10
Default

Hey,

Any chance you could give me a simple example of a rainbow wave flowing from left to right on the keyboard. I looked at your WIKI on git but I can't figure out how to make it flow, only static is working.

Thanks!
  #25  
Old 12-20-2016, 06:06 PM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 883218
Darth Affe Reputation: 15
Default

Hey, the wiki is currently really outdated - sorry for that but I'm just to lazy to work on it ...

I created a short example (consisting of two files) - whole project is attached too:

Program.cs
Code:
using System;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using CUE.NET;
using CUE.NET.Brushes;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Keyboard;
using CUE.NET.Exceptions;
using CUE.NET.Gradients;
using CUE.NET.Groups;

namespace FlowingRainbow
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                CueSDK.Initialize();

                CorsairKeyboard keyboard = CueSDK.KeyboardSDK;
                if (keyboard == null)
                {
                    Console.WriteLine("Can't initialize keyboard ...");
                    Console.ReadKey();
                    return;
                }

                // I prefer to always add a solid black background to prevent "bleeding" colors if transparency is used.
                keyboard.Brush = (SolidColorBrush)Color.Black;

                // Create a ledGroup containing all the leds you want to brush (in this case the whole keyboard).
                ILedGroup rainbowLedGroup = new ListLedGroup(keyboard, keyboard);

                // Prepare to brushes (we want to toggle them) and add one to the group.
                LinearGradientBrush linearRainbowBrush = new LinearGradientBrush(new RainbowGradient());
                RadialGradientBrush radialRainbowBrush = new RadialGradientBrush(new RainbowGradient());
                rainbowLedGroup.Brush = linearRainbowBrush;

                // Add our custom effect to the brush to animate the rainbow.
                MovingRainbowEffect movingRainbowEffect = new MovingRainbowEffect();
                rainbowLedGroup.Brush.AddEffect(movingRainbowEffect);

                // Enable automatic updates to allow the effect to work (you might want to tune 'CueSDK.UpdateFrequency' too)
                CueSDK.UpdateMode = UpdateMode.Continuous;


                // We want a really fancy console-application :p
                Console.WriteLine("Change speed with 'w' and 's'");
                Console.WriteLine("Change direction with 'd'");
                Console.WriteLine("Change brush with 'b'");
                Console.WriteLine("Press ESC to exit ...");
                Console.WriteLine();

                Task.Factory.StartNew(
                () =>
                {
                    ConsoleKey key;
                    do
                    {
                        key = Console.ReadKey().Key;
                        switch (key)
                        {
                            case ConsoleKey.W:
                                movingRainbowEffect.Speed += 10f;
                                Console.WriteLine($"\rIncreasing speed to {movingRainbowEffect.Speed}");
                                break;
                            case ConsoleKey.S:
                                movingRainbowEffect.Speed -= 10f;
                                Console.WriteLine($"\rDecreasing speed to {movingRainbowEffect.Speed}");
                                break;
                            case ConsoleKey.D:
                                movingRainbowEffect.Direction = !movingRainbowEffect.Direction;
                                Console.WriteLine($"\rChanging direction to {movingRainbowEffect.Direction}");
                                break;
                            case ConsoleKey.B:
                                // We want to reuse our effect for both brushes so we need to set it free first
                                rainbowLedGroup.Brush.RemoveEffect(movingRainbowEffect);
                                // Swap the brush (this isn't good code, but this is an example :p
                                rainbowLedGroup.Brush = (rainbowLedGroup.Brush is LinearGradientBrush) ? (IBrush)radialRainbowBrush : linearRainbowBrush;
                                // Apply the effect the the other brush
                                rainbowLedGroup.Brush.AddEffect(movingRainbowEffect);
                                Console.WriteLine($"\rChanging brush to {rainbowLedGroup.Brush.GetType()}");
                                break;
                        }
                    } while (key != ConsoleKey.Escape);
                    Environment.Exit(0);
                });
            }
            catch (CUEException ex)
            {
                Console.WriteLine("CUE Exception! ErrorCode: " + Enum.GetName(typeof(CorsairError), ex.Error));
            }
            catch (WrapperException ex)
            {
                Console.WriteLine("Wrapper Exception! Message:" + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception! Message:" + ex.Message);
            }
            while (true)
                Thread.Sleep(1000); // Don't exit after exception
        }
    }
}
MovingRainbowEffect.cs
Code:
using CUE.NET.Brushes;
using CUE.NET.Effects;
using CUE.NET.Gradients;

namespace FlowingRainbow
{
    public class MovingRainbowEffect : AbstractBrushEffect<IGradientBrush>
    {
        #region Properties & Fields

        public bool Direction { get; set; }
        public float Speed { get; set; } // 30 degree per second (see https://upload.wikimedia.org/wikipedia/commons/a/ad/HueScale.svg)

        #endregion

        #region Constructors

        public MovingRainbowEffect(float speed = 180f, bool direction = true)
        {
            this.Speed = speed;
            this.Direction = direction;
        }

        #endregion

        #region Methods

        public override void Update(float deltaTime)
        {
            // Our effect only works with rainbow-gradients
            RainbowGradient rainbowGradient = Brush.Gradient as RainbowGradient;
            if (rainbowGradient == null) return;

            // Calculate amount of movement we need to do considering the time since the last update, to be update-rate-independent.
            float movement = Speed * deltaTime;

            // Inverse our movement if we want move the rainbow in the other direction.
            if (!Direction)
                movement = -movement;

            // Move the whole gradient
            // Please notice, that this isn't good code since we're only increasing the value all the time. Like this we might get an overflow if the animation runs to long.
            // This should be prevented according to your specific use-case.
            rainbowGradient.StartHue += movement;
            rainbowGradient.EndHue += movement;
        }

        // Make sure that we only apply this effect if the brush has an rainbow gradient 
        public override bool CanBeAppliedTo(IBrush target)
        {
            return (target as IGradientBrush)?.Gradient is RainbowGradient;
        }

        #endregion
    }
}
Attached Files
File Type: zip FlowingRainbow.zip (6.4 KB, 124 views)

Last edited by Darth Affe; 12-20-2016 at 06:10 PM.
  #26  
Old 12-21-2016, 08:28 AM
goomonster3 goomonster3 is offline
Registered User
 
Join Date: Mar 2015
Posts: 44
POST ID # = 883295
goomonster3 Reputation: 10
Default

Quote:
Originally Posted by Darth Affe View Post
Hey, the wiki is currently really outdated - sorry for that but I'm just to lazy to work on it ...

I created a short example (consisting of two files) - whole project is attached too:

Program.cs
Code:
using System;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using CUE.NET;
using CUE.NET.Brushes;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Keyboard;
using CUE.NET.Exceptions;
using CUE.NET.Gradients;
using CUE.NET.Groups;

namespace FlowingRainbow
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                CueSDK.Initialize();

                CorsairKeyboard keyboard = CueSDK.KeyboardSDK;
                if (keyboard == null)
                {
                    Console.WriteLine("Can't initialize keyboard ...");
                    Console.ReadKey();
                    return;
                }

                // I prefer to always add a solid black background to prevent "bleeding" colors if transparency is used.
                keyboard.Brush = (SolidColorBrush)Color.Black;

                // Create a ledGroup containing all the leds you want to brush (in this case the whole keyboard).
                ILedGroup rainbowLedGroup = new ListLedGroup(keyboard, keyboard);

                // Prepare to brushes (we want to toggle them) and add one to the group.
                LinearGradientBrush linearRainbowBrush = new LinearGradientBrush(new RainbowGradient());
                RadialGradientBrush radialRainbowBrush = new RadialGradientBrush(new RainbowGradient());
                rainbowLedGroup.Brush = linearRainbowBrush;

                // Add our custom effect to the brush to animate the rainbow.
                MovingRainbowEffect movingRainbowEffect = new MovingRainbowEffect();
                rainbowLedGroup.Brush.AddEffect(movingRainbowEffect);

                // Enable automatic updates to allow the effect to work (you might want to tune 'CueSDK.UpdateFrequency' too)
                CueSDK.UpdateMode = UpdateMode.Continuous;


                // We want a really fancy console-application :p
                Console.WriteLine("Change speed with 'w' and 's'");
                Console.WriteLine("Change direction with 'd'");
                Console.WriteLine("Change brush with 'b'");
                Console.WriteLine("Press ESC to exit ...");
                Console.WriteLine();

                Task.Factory.StartNew(
                () =>
                {
                    ConsoleKey key;
                    do
                    {
                        key = Console.ReadKey().Key;
                        switch (key)
                        {
                            case ConsoleKey.W:
                                movingRainbowEffect.Speed += 10f;
                                Console.WriteLine($"\rIncreasing speed to {movingRainbowEffect.Speed}");
                                break;
                            case ConsoleKey.S:
                                movingRainbowEffect.Speed -= 10f;
                                Console.WriteLine($"\rDecreasing speed to {movingRainbowEffect.Speed}");
                                break;
                            case ConsoleKey.D:
                                movingRainbowEffect.Direction = !movingRainbowEffect.Direction;
                                Console.WriteLine($"\rChanging direction to {movingRainbowEffect.Direction}");
                                break;
                            case ConsoleKey.B:
                                // We want to reuse our effect for both brushes so we need to set it free first
                                rainbowLedGroup.Brush.RemoveEffect(movingRainbowEffect);
                                // Swap the brush (this isn't good code, but this is an example :p
                                rainbowLedGroup.Brush = (rainbowLedGroup.Brush is LinearGradientBrush) ? (IBrush)radialRainbowBrush : linearRainbowBrush;
                                // Apply the effect the the other brush
                                rainbowLedGroup.Brush.AddEffect(movingRainbowEffect);
                                Console.WriteLine($"\rChanging brush to {rainbowLedGroup.Brush.GetType()}");
                                break;
                        }
                    } while (key != ConsoleKey.Escape);
                    Environment.Exit(0);
                });
            }
            catch (CUEException ex)
            {
                Console.WriteLine("CUE Exception! ErrorCode: " + Enum.GetName(typeof(CorsairError), ex.Error));
            }
            catch (WrapperException ex)
            {
                Console.WriteLine("Wrapper Exception! Message:" + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception! Message:" + ex.Message);
            }
            while (true)
                Thread.Sleep(1000); // Don't exit after exception
        }
    }
}
MovingRainbowEffect.cs
Code:
using CUE.NET.Brushes;
using CUE.NET.Effects;
using CUE.NET.Gradients;

namespace FlowingRainbow
{
    public class MovingRainbowEffect : AbstractBrushEffect<IGradientBrush>
    {
        #region Properties & Fields

        public bool Direction { get; set; }
        public float Speed { get; set; } // 30 degree per second (see https://upload.wikimedia.org/wikipedia/commons/a/ad/HueScale.svg)

        #endregion

        #region Constructors

        public MovingRainbowEffect(float speed = 180f, bool direction = true)
        {
            this.Speed = speed;
            this.Direction = direction;
        }

        #endregion

        #region Methods

        public override void Update(float deltaTime)
        {
            // Our effect only works with rainbow-gradients
            RainbowGradient rainbowGradient = Brush.Gradient as RainbowGradient;
            if (rainbowGradient == null) return;

            // Calculate amount of movement we need to do considering the time since the last update, to be update-rate-independent.
            float movement = Speed * deltaTime;

            // Inverse our movement if we want move the rainbow in the other direction.
            if (!Direction)
                movement = -movement;

            // Move the whole gradient
            // Please notice, that this isn't good code since we're only increasing the value all the time. Like this we might get an overflow if the animation runs to long.
            // This should be prevented according to your specific use-case.
            rainbowGradient.StartHue += movement;
            rainbowGradient.EndHue += movement;
        }

        // Make sure that we only apply this effect if the brush has an rainbow gradient 
        public override bool CanBeAppliedTo(IBrush target)
        {
            return (target as IGradientBrush)?.Gradient is RainbowGradient;
        }

        #endregion
    }
}
Thanks so much! Don't worry about the wiki - having this C# wrapper alone is enough hard work for my liking! That example is amazing - it really helps me to understand how to make moving gradients (especially with the comments explaining each line).

Could you show me how to do the "ripple" effect from a key in a simple program now aswell?

Also, how can I make just an average lineargradient / radialgradient flow and not be static (essentially make it flow like the rainbowgradient)? I attempted this with no success as seen below:

Code:
CorsairKeyboardDeviceInfo dInfo = CueSDK.KeyboardSDK.KeyboardDeviceInfo;
                        Console.WriteLine("Corsair " + dInfo.Model.ToString() + " found! Application running...");
                        setKeysBlack(kBoard);
                        //kBoard[CorsairKeyboardLedId.W].Color = Color.Red; setting single led colour
                        CueSDK.UpdateMode = CUE.NET.Devices.Generic.Enums.UpdateMode.Continuous;
                        CueSDK.UpdateFrequency = 1f / 60f;

                        GradientStop[] gradientCode =
                        {
                            new GradientStop(0f, Color.Blue),
                            new GradientStop(1f, Color.Red)
                        };
                        #region lineargradient
                        LinearGradient blueToRed = new LinearGradient(gradientCode);
                        PointF startPoint = new PointF(0f, 1f); //bottom left corner
                        PointF endPoint = new PointF(1f, 0f); //top right corner
                        IBrush brushBlueRed = new LinearGradientBrush(startPoint, endPoint, blueToRed);
                        kBoard.Brush = brushBlueRed;
                        //kBoard.Brush.AddEffect(new MovingGradientEffect()); (I'm not sure how I should go about writing the MovingGradientEffect class)
                        #endregion
Sorry about the tab spacing - seems to have messed up :(


Cheers for your time again!

Last edited by goomonster3; 12-21-2016 at 08:59 AM.
  #27  
Old 12-21-2016, 11:37 AM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 883311
Darth Affe Reputation: 15
Default

Quote:
Could you show me how to do the "ripple" effect from a key in a simple program now aswell?
Well, this depends highly on what a "ripple" is for you.
You could create some sort of wave by adding a transparent-color-transparent gradient brush and setting his center above the key you want to ripple from and move it.
If you want something more fancy you'd need to come up with an own algorithm implemented in a brush/effect-pair.

Quote:
Also, how can I make just an average lineargradient / radialgradient flow and not be static (essentially make it flow like the rainbowgradient)? I attempted this with no success as seen below:
This is a good point - right now this isn't possible. I extended the previous example (code attached again) but I'll adopt this functionality into the next version of CUE.NET

Program.cs
Code:
using System;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using CUE.NET;
using CUE.NET.Brushes;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Keyboard;
using CUE.NET.Exceptions;
using CUE.NET.Gradients;
using CUE.NET.Groups;

namespace FlowingRainbow
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                CueSDK.Initialize();

                CorsairKeyboard keyboard = CueSDK.KeyboardSDK;
                if (keyboard == null)
                {
                    Console.WriteLine("Can't initialize keyboard ...");
                    Console.ReadKey();
                    return;
                }

                // I prefer to always add a solid black background to prevent "bleeding" colors if transparency is used.
                keyboard.Brush = (SolidColorBrush)Color.Black;

                // Create a ledGroup containing all the leds you want to brush (in this case the whole keyboard).
                ILedGroup ledGroup = new ListLedGroup(keyboard, keyboard);

                // Prepare the gradients and the brushes (we want to toggle them) and add one to the group.
                IGradient rainbowGradient = new RainbowGradient();
                IGradient linearGradient = new RotatingLinearGradient(new GradientStop(0f, Color.Red), new GradientStop(0.5f, Color.Blue));
                LinearGradientBrush linearBrush = new LinearGradientBrush(linearGradient);
                RadialGradientBrush radialBrush = new RadialGradientBrush(linearGradient);
                ledGroup.Brush = linearBrush;

                // Add our custom effect to the brush to animate the rainbow.
                MovingGradientEffect movingGradientEffect = new MovingGradientEffect();
                ledGroup.Brush.AddEffect(movingGradientEffect);

                // Enable automatic updates to allow the effect to work (you might want to tune 'CueSDK.UpdateFrequency' too)
                CueSDK.UpdateMode = UpdateMode.Continuous;


                // We want a really fancy console-application :p
                Console.WriteLine("Change speed with 'w' and 's'");
                Console.WriteLine("Change direction with 'd'");
                Console.WriteLine("Change brush with 'b'");
                Console.WriteLine("Change gradient with 'g'");
                Console.WriteLine("Press ESC to exit ...");
                Console.WriteLine();

                Task.Factory.StartNew(
                    () =>
                    {
                        ConsoleKey key;
                        do
                        {
                            key = Console.ReadKey().Key;
                            switch (key)
                            {
                                case ConsoleKey.W:
                                    movingGradientEffect.Speed += 10f;
                                    Console.WriteLine($"\rIncreasing speed to {movingGradientEffect.Speed}");
                                    break;
                                case ConsoleKey.S:
                                    movingGradientEffect.Speed -= 10f;
                                    Console.WriteLine($"\rDecreasing speed to {movingGradientEffect.Speed}");
                                    break;
                                case ConsoleKey.D:
                                    movingGradientEffect.Direction = !movingGradientEffect.Direction;
                                    Console.WriteLine($"\rChanging direction to {movingGradientEffect.Direction}");
                                    break;
                                case ConsoleKey.B:
                                    // We want to reuse our effect for both brushes so we need to set it free first
                                    ledGroup.Brush.RemoveEffect(movingGradientEffect);
                                    // Swap the brush (this isn't good code, but this is an example :p
                                    ledGroup.Brush = (ledGroup.Brush is LinearGradientBrush) ? (IBrush)radialBrush : linearBrush;
                                    // Apply the effect the the other brush
                                    ledGroup.Brush.AddEffect(movingGradientEffect);
                                    Console.WriteLine($"\rChanging brush to {ledGroup.Brush.GetType()}");
                                    break;
                                case ConsoleKey.G:
                                    if (linearBrush.Gradient is RainbowGradient)
                                    {
                                        linearBrush.Gradient = linearGradient;
                                        radialBrush.Gradient = linearGradient;
                                    }
                                    else
                                    {
                                        linearBrush.Gradient = rainbowGradient;
                                        radialBrush.Gradient = rainbowGradient;
                                    }
                                    Console.WriteLine($"\rChanging gradient to {(ledGroup.Brush as IGradientBrush)?.Gradient?.GetType().ToString() ?? "-"}");
                                    break;
                            }
                        } while (key != ConsoleKey.Escape);
                        Environment.Exit(0);
                    });
            }
            catch (CUEException ex)
            {
                Console.WriteLine("CUE Exception! ErrorCode: " + Enum.GetName(typeof(CorsairError), ex.Error));
            }
            catch (WrapperException ex)
            {
                Console.WriteLine("Wrapper Exception! Message:" + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception! Message:" + ex.Message);
            }
            while (true)
                Thread.Sleep(1000); // Don't exit after exception
        }
    }
}
RotatingLinearGradient.cs
Code:
using System.Linq;
using CUE.NET.Devices.Generic;
using CUE.NET.Gradients;

namespace FlowingRainbow
{
    public class RotatingLinearGradient : LinearGradient
    {
        #region Constructors

        public RotatingLinearGradient()
        { }

        public RotatingLinearGradient(params GradientStop[] gradientStops)
            : base(gradientStops)
        { }

        #endregion

        #region Methods

        public override CorsairColor GetColor(float offset)
        {
            if (!GradientStops.Any()) return CorsairColor.Transparent;
            if (GradientStops.Count == 1) return GradientStops.First().Color;

            GradientStop gsBefore = GradientStops.Where(n => n.Offset <= offset).OrderBy(n => n.Offset).LastOrDefault();
            if (gsBefore == null)
            {
                GradientStop lastStop = GradientStops.OrderBy(n => n.Offset).Last();
                gsBefore = new GradientStop(lastStop.Offset - 1f, lastStop.Color);
            }

            GradientStop gsAfter = GradientStops.Where(n => n.Offset >= offset).OrderBy(n => n.Offset).FirstOrDefault();
            if (gsAfter == null)
            {
                GradientStop firstStop = GradientStops.OrderBy(n => n.Offset).First();
                gsAfter = new GradientStop(firstStop.Offset + 1f, firstStop.Color);
            }

            float blendFactor = 0f;
            if (!gsBefore.Offset.Equals(gsAfter.Offset))
                blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset));

            byte colA = (byte)((gsAfter.Color.A - gsBefore.Color.A) * blendFactor + gsBefore.Color.A);
            byte colR = (byte)((gsAfter.Color.R - gsBefore.Color.R) * blendFactor + gsBefore.Color.R);
            byte colG = (byte)((gsAfter.Color.G - gsBefore.Color.G) * blendFactor + gsBefore.Color.G);
            byte colB = (byte)((gsAfter.Color.B - gsBefore.Color.B) * blendFactor + gsBefore.Color.B);

            return new CorsairColor(colA, colR, colG, colB);
        }

        #endregion
    }
}
MovingGradientEffect.cs
Code:
using CUE.NET.Brushes;
using CUE.NET.Effects;
using CUE.NET.Gradients;

namespace FlowingRainbow
{
    public class MovingGradientEffect : AbstractBrushEffect<IGradientBrush>
    {
        #region Properties & Fields

        public bool Direction { get; set; }
        public float Speed { get; set; }

        #endregion

        #region Constructors

        public MovingGradientEffect(float speed = 180f, bool direction = true)
        {
            this.Speed = speed;
            this.Direction = direction;
        }

        #endregion

        #region Methods

        public override void Update(float deltaTime)
        {
            // Calculate amount of movement we need to do considering the time since the last update, to be update-rate-independent.
            float movement = Speed * deltaTime;

            // Inverse our movement if we want move the rainbow in the other direction.
            if (!Direction)
                movement = -movement;

            if (Brush.Gradient is LinearGradient)
            {
                LinearGradient linearGradient = (LinearGradient)Brush.Gradient;

                // Speed is a bit different here
                movement /= 360f;

                // Move every gradient stop by the same amount and make sure the offset snaps back inside the range 0..1 after overflowing
                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;

                // We want both to move in the same direction, otherwise it might feel a bit odd.
                movement *= -1;

                rainbowGradient.StartHue += movement;
                rainbowGradient.EndHue += movement;
            }
        }

        #endregion
    }
}
Attached Files
File Type: zip FlowingRainbow.zip (7.4 KB, 106 views)
  #28  
Old 12-22-2016, 09:17 AM
goomonster3 goomonster3 is offline
Registered User
 
Join Date: Mar 2015
Posts: 44
POST ID # = 883420
goomonster3 Reputation: 10
Default

Quote:
Originally Posted by Darth Affe View Post
Well, this depends highly on what a "ripple" is for you.
You could create some sort of wave by adding a transparent-color-transparent gradient brush and setting his center above the key you want to ripple from and move it.
If you want something more fancy you'd need to come up with an own algorithm implemented in a brush/effect-pair.



This is a good point - right now this isn't possible. I extended the previous example (code attached again) but I'll adopt this functionality into the next version of CUE.NET

Program.cs
Code:
using System;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using CUE.NET;
using CUE.NET.Brushes;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Keyboard;
using CUE.NET.Exceptions;
using CUE.NET.Gradients;
using CUE.NET.Groups;

namespace FlowingRainbow
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                CueSDK.Initialize();

                CorsairKeyboard keyboard = CueSDK.KeyboardSDK;
                if (keyboard == null)
                {
                    Console.WriteLine("Can't initialize keyboard ...");
                    Console.ReadKey();
                    return;
                }

                // I prefer to always add a solid black background to prevent "bleeding" colors if transparency is used.
                keyboard.Brush = (SolidColorBrush)Color.Black;

                // Create a ledGroup containing all the leds you want to brush (in this case the whole keyboard).
                ILedGroup ledGroup = new ListLedGroup(keyboard, keyboard);

                // Prepare the gradients and the brushes (we want to toggle them) and add one to the group.
                IGradient rainbowGradient = new RainbowGradient();
                IGradient linearGradient = new RotatingLinearGradient(new GradientStop(0f, Color.Red), new GradientStop(0.5f, Color.Blue));
                LinearGradientBrush linearBrush = new LinearGradientBrush(linearGradient);
                RadialGradientBrush radialBrush = new RadialGradientBrush(linearGradient);
                ledGroup.Brush = linearBrush;

                // Add our custom effect to the brush to animate the rainbow.
                MovingGradientEffect movingGradientEffect = new MovingGradientEffect();
                ledGroup.Brush.AddEffect(movingGradientEffect);

                // Enable automatic updates to allow the effect to work (you might want to tune 'CueSDK.UpdateFrequency' too)
                CueSDK.UpdateMode = UpdateMode.Continuous;


                // We want a really fancy console-application :p
                Console.WriteLine("Change speed with 'w' and 's'");
                Console.WriteLine("Change direction with 'd'");
                Console.WriteLine("Change brush with 'b'");
                Console.WriteLine("Change gradient with 'g'");
                Console.WriteLine("Press ESC to exit ...");
                Console.WriteLine();

                Task.Factory.StartNew(
                    () =>
                    {
                        ConsoleKey key;
                        do
                        {
                            key = Console.ReadKey().Key;
                            switch (key)
                            {
                                case ConsoleKey.W:
                                    movingGradientEffect.Speed += 10f;
                                    Console.WriteLine($"\rIncreasing speed to {movingGradientEffect.Speed}");
                                    break;
                                case ConsoleKey.S:
                                    movingGradientEffect.Speed -= 10f;
                                    Console.WriteLine($"\rDecreasing speed to {movingGradientEffect.Speed}");
                                    break;
                                case ConsoleKey.D:
                                    movingGradientEffect.Direction = !movingGradientEffect.Direction;
                                    Console.WriteLine($"\rChanging direction to {movingGradientEffect.Direction}");
                                    break;
                                case ConsoleKey.B:
                                    // We want to reuse our effect for both brushes so we need to set it free first
                                    ledGroup.Brush.RemoveEffect(movingGradientEffect);
                                    // Swap the brush (this isn't good code, but this is an example :p
                                    ledGroup.Brush = (ledGroup.Brush is LinearGradientBrush) ? (IBrush)radialBrush : linearBrush;
                                    // Apply the effect the the other brush
                                    ledGroup.Brush.AddEffect(movingGradientEffect);
                                    Console.WriteLine($"\rChanging brush to {ledGroup.Brush.GetType()}");
                                    break;
                                case ConsoleKey.G:
                                    if (linearBrush.Gradient is RainbowGradient)
                                    {
                                        linearBrush.Gradient = linearGradient;
                                        radialBrush.Gradient = linearGradient;
                                    }
                                    else
                                    {
                                        linearBrush.Gradient = rainbowGradient;
                                        radialBrush.Gradient = rainbowGradient;
                                    }
                                    Console.WriteLine($"\rChanging gradient to {(ledGroup.Brush as IGradientBrush)?.Gradient?.GetType().ToString() ?? "-"}");
                                    break;
                            }
                        } while (key != ConsoleKey.Escape);
                        Environment.Exit(0);
                    });
            }
            catch (CUEException ex)
            {
                Console.WriteLine("CUE Exception! ErrorCode: " + Enum.GetName(typeof(CorsairError), ex.Error));
            }
            catch (WrapperException ex)
            {
                Console.WriteLine("Wrapper Exception! Message:" + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception! Message:" + ex.Message);
            }
            while (true)
                Thread.Sleep(1000); // Don't exit after exception
        }
    }
}
RotatingLinearGradient.cs
Code:
using System.Linq;
using CUE.NET.Devices.Generic;
using CUE.NET.Gradients;

namespace FlowingRainbow
{
    public class RotatingLinearGradient : LinearGradient
    {
        #region Constructors

        public RotatingLinearGradient()
        { }

        public RotatingLinearGradient(params GradientStop[] gradientStops)
            : base(gradientStops)
        { }

        #endregion

        #region Methods

        public override CorsairColor GetColor(float offset)
        {
            if (!GradientStops.Any()) return CorsairColor.Transparent;
            if (GradientStops.Count == 1) return GradientStops.First().Color;

            GradientStop gsBefore = GradientStops.Where(n => n.Offset <= offset).OrderBy(n => n.Offset).LastOrDefault();
            if (gsBefore == null)
            {
                GradientStop lastStop = GradientStops.OrderBy(n => n.Offset).Last();
                gsBefore = new GradientStop(lastStop.Offset - 1f, lastStop.Color);
            }

            GradientStop gsAfter = GradientStops.Where(n => n.Offset >= offset).OrderBy(n => n.Offset).FirstOrDefault();
            if (gsAfter == null)
            {
                GradientStop firstStop = GradientStops.OrderBy(n => n.Offset).First();
                gsAfter = new GradientStop(firstStop.Offset + 1f, firstStop.Color);
            }

            float blendFactor = 0f;
            if (!gsBefore.Offset.Equals(gsAfter.Offset))
                blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset));

            byte colA = (byte)((gsAfter.Color.A - gsBefore.Color.A) * blendFactor + gsBefore.Color.A);
            byte colR = (byte)((gsAfter.Color.R - gsBefore.Color.R) * blendFactor + gsBefore.Color.R);
            byte colG = (byte)((gsAfter.Color.G - gsBefore.Color.G) * blendFactor + gsBefore.Color.G);
            byte colB = (byte)((gsAfter.Color.B - gsBefore.Color.B) * blendFactor + gsBefore.Color.B);

            return new CorsairColor(colA, colR, colG, colB);
        }

        #endregion
    }
}
MovingGradientEffect.cs
Code:
using CUE.NET.Brushes;
using CUE.NET.Effects;
using CUE.NET.Gradients;

namespace FlowingRainbow
{
    public class MovingGradientEffect : AbstractBrushEffect<IGradientBrush>
    {
        #region Properties & Fields

        public bool Direction { get; set; }
        public float Speed { get; set; }

        #endregion

        #region Constructors

        public MovingGradientEffect(float speed = 180f, bool direction = true)
        {
            this.Speed = speed;
            this.Direction = direction;
        }

        #endregion

        #region Methods

        public override void Update(float deltaTime)
        {
            // Calculate amount of movement we need to do considering the time since the last update, to be update-rate-independent.
            float movement = Speed * deltaTime;

            // Inverse our movement if we want move the rainbow in the other direction.
            if (!Direction)
                movement = -movement;

            if (Brush.Gradient is LinearGradient)
            {
                LinearGradient linearGradient = (LinearGradient)Brush.Gradient;

                // Speed is a bit different here
                movement /= 360f;

                // Move every gradient stop by the same amount and make sure the offset snaps back inside the range 0..1 after overflowing
                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;

                // We want both to move in the same direction, otherwise it might feel a bit odd.
                movement *= -1;

                rainbowGradient.StartHue += movement;
                rainbowGradient.EndHue += movement;
            }
        }

        #endregion
    }
}
That's awesome! Keep up the good work with this wrapper - loving it! .

Theoretically I could make the ripple a radialbrush and use the movinggradienteffect class, setting the center to the location of the keypress using a method I could create - I think that'd do the job for what I am wanting to do.

Thanks a lot, can't wait to see what you can do in the future. Perhaps a simple effect class for spectrum lighting (IE every LED on the keyboard fades from one colour to another over x amount of time)? Is that possible to do right now?

Cheers.
  #29  
Old 12-22-2016, 10:01 AM
Darth Affe's Avatar
Darth Affe Darth Affe is offline
//TODO add user title
Darth Affe's PC Specs
 
Join Date: Sep 2015
Location: UTC+1
Posts: 125
POST ID # = 883422
Darth Affe Reputation: 15
Default

Quote:
Originally Posted by goomonster3 View Post
Perhaps a simple effect class for spectrum lighting (IE every LED on the keyboard fades from one colour to another over x amount of time)? Is that possible to do right now?
Sure, just create an effect and change the color of the brush.

For example like this:

Code:
using CUE.NET.Brushes;
using CUE.NET.Effects;
using CUE.NET.Helper;

namespace FlowingRainbow
{
    public class SpectrumEffect : AbstractBrushEffect<SolidColorBrush>
    {
        #region Properties & Fields

        public float Speed { get; set; }

        #endregion

        #region Constructors

        public SpectrumEffect(float speed = 30f)
        {
            this.Speed = speed;
        }

        #endregion

        #region Methods

        public override void Update(float deltaTime)
        {
            Brush.Color = ColorHelper.ColorFromHSV(((Brush.Color.GetHSVHue() + (Speed * deltaTime)) % 360),
                Brush.Color.GetHSVSaturation(),
                Brush.Color.GetHSVValue(),
                Brush.Color.A);
        }

        #endregion
    }
}

Last edited by Darth Affe; 12-23-2016 at 05:41 PM.
  #30  
Old 12-23-2016, 05:11 PM
goomonster3 goomonster3 is offline
Registered User
 
Join Date: Mar 2015
Posts: 44
POST ID # = 883602
goomonster3 Reputation: 10
Default

Quote:
Originally Posted by Darth Affe View Post
Sure, just create an effect and change the color of the brush.

For example like this:

Code:
using CUE.NET.Brushes;
using CUE.NET.Effects;
using CUE.NET.Helper;

namespace FlowingRainbow
{
    public class SpectrumEffect : AbstractBrushEffect<SolidColorBrush>
    {
        #region Properties & Fields

        public float Speed { get; set; }

        #endregion

        #region Constructors

        public SpectrumEffect(float speed = 30f)
        {
            this.Speed = speed;
        }

        #endregion

        #region Methods

        public override void Update(float deltaTime)
        {
            Brush.Color = ColorHelper.ColorFromHSV((Brush.Color.GetHSVHue() + (Speed * deltaTime) % 360),
                Brush.Color.GetHSVSaturation(),
                Brush.Color.GetHSVValue(),
                Brush.Color.A);
        }

        #endregion
    }
}
That's perfect - thanks for all the help!
 

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 04:36 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, vBulletin Solutions, Inc.