Initial Commit

This commit is contained in:
vextrixes committed 2026-05-31 12:20:48 +02:00
commit 1ab3ddf273
13 files changed
+1267

No files matched your search

+7
View File
@@ -0,0 +1,7 @@
extern crate hidapi;
mod constants;
pub mod error;
pub mod wrapper;
pub use error::HidWrapperError;
pub use wrapper::HidWrapper;
+4
View File
@@ -0,0 +1,4 @@
pub const VENDOR_ID: u16 = 0x0c45;
pub const PRODUCT_ID: u16 = 0x8006;
pub const MAX_SEND_REPORT_LEN: usize = 65;
pub const GET_REPORT_REPORT: [u8; MAX_SEND_REPORT_LEN] = [0u8; MAX_SEND_REPORT_LEN];
+40
View File
@@ -0,0 +1,40 @@
use hidapi::HidError;
use std::error::Error;
use std::fmt::Display;
#[derive(Debug)]
pub enum HidWrapperError {
#[allow(dead_code)]
HidApiError(HidError),
NoHidDeviceError,
}
impl Display for HidWrapperError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
HidWrapperError::HidApiError(err) => {
write!(f, "Hid Api Error: {err}")
}
HidWrapperError::NoHidDeviceError => {
write!(f, "No Hid Device Found")
}
}
}
}
impl Error for HidWrapperError {}
impl From<HidError> for HidWrapperError {
fn from(error: HidError) -> Self {
match error {
HidError::HidApiError { ref message } => {
if message == "No HID devices with requested VID/PID found in the system." {
HidWrapperError::NoHidDeviceError
} else {
HidWrapperError::HidApiError(error)
}
}
_ => HidWrapperError::HidApiError(error),
}
}
}
+108
View File
@@ -0,0 +1,108 @@
use crate::hid_wrapper::constants::{
GET_REPORT_REPORT, MAX_SEND_REPORT_LEN, PRODUCT_ID, VENDOR_ID,
};
use crate::hid_wrapper::error::HidWrapperError;
use hidapi::{HidApi, HidDevice};
pub struct HidWrapper {
hid_api: HidApi,
hid_device: Option<HidDevice>,
}
impl Default for HidWrapper {
/// Makes a new instance of HidWrapper (No shit Sherlock)
///
/// # Panics
/// If ```HidWrapperError::HidApiError``` is returned from new()
fn default() -> Self {
match Self::new() {
Ok(hid_wrapper) => hid_wrapper,
Err(err) => panic!("hid wrapper Default() failed to create new HidWrapper: {err}"),
}
}
}
impl HidWrapper {
/// Makes a new instance of HidWrapper (No shit Sherlock)
///
/// # Errors
/// ```HidWrapperError::HidApiError```
pub fn new() -> Result<HidWrapper, HidWrapperError> {
Ok(HidWrapper {
hid_api: match HidApi::new() {
Ok(hidapi) => hidapi,
Err(err) => return Err(HidWrapperError::from(err)),
},
hid_device: None,
})
}
pub fn is_device_connected(&mut self) -> Result<bool, HidWrapperError> {
match self.hid_api.reset_devices() {
Ok(_) => {}
Err(err) => return Err(HidWrapperError::from(err)),
};
match self.hid_api.add_devices(VENDOR_ID, PRODUCT_ID) {
Ok(_) => {}
Err(err) => return Err(HidWrapperError::from(err)),
};
Ok(self.hid_api.device_list().count() >= 1)
}
/// Opens a device
///
/// # Errors
/// ```HidWrapperError::HidApiError```
/// ```HidWrapperError::NoHidDeviceError```
pub fn open_device(&mut self) -> Result<(), HidWrapperError> {
self.hid_device = match self.hid_api.open(VENDOR_ID, PRODUCT_ID) {
Ok(hid_device) => Some(hid_device),
Err(err) => return Err(HidWrapperError::from(err)),
};
Ok(())
}
/// Drops the device
///
pub fn close_device(&mut self) {
self.hid_device = None;
}
/// Sends a set report (65 bytes len)
///
/// # Errors
/// ```HidWrapperError::HidApiError```
/// ```HidWrapperError::NoHidDeviceError```
pub fn send_report(&mut self, data: &[u8]) -> Result<(), HidWrapperError> {
match &self.hid_device {
Some(hid_device) => {
let mut out = [0; MAX_SEND_REPORT_LEN];
out[1..1 + data.len()].copy_from_slice(data);
match hid_device.send_feature_report(&out) {
Ok(_) => Ok(()),
Err(err) => Err(HidWrapperError::from(err)),
}
}
None => Err(HidWrapperError::NoHidDeviceError),
}
}
/// Sends a get report (64 bytes len)
///
/// # Errors
/// ```HidWrapperError::HidApiError```
/// ```HidWrapperError::NoHidDeviceError```
pub fn get_report(&mut self) -> Result<usize, HidWrapperError> {
match &self.hid_device {
Some(hid_device) => {
let mut request = GET_REPORT_REPORT;
request[1] = 64;
match hid_device.get_feature_report(&mut request) {
Ok(usize) => Ok(usize),
Err(err) => Err(HidWrapperError::from(err)),
}
}
None => Err(HidWrapperError::NoHidDeviceError),
}
}
}
+6
View File
@@ -0,0 +1,6 @@
mod hid_wrapper;
mod rgb_controller;
pub use hid_wrapper::HidWrapperError;
pub use rgb_controller::controller::RGBController;
pub use rgb_controller::effects::Effects;
+3
View File
@@ -0,0 +1,3 @@
pub mod controller;
pub mod effect_info;
pub mod effects;
+695
View File
@@ -0,0 +1,695 @@
use crate::Effects;
use crate::HidWrapperError;
use crate::hid_wrapper::HidWrapper;
pub struct RGBController {
hid_wrapper: HidWrapper,
}
impl Default for RGBController {
/// Makes a new instance of HidWrapper (No shit Sherlock)
///
/// # Panics
/// if ```HidWrapperError::HidApiError``` is returned from new()
fn default() -> Self {
match Self::new() {
Ok(hid_wrapper) => hid_wrapper,
Err(err) => panic!("RGBController Default() failed to create new RGBController: {err}"),
}
}
}
impl RGBController {
/// Makes a new instance of HidWrapper (No shit Sherlock)
///
/// # Errors
/// ```HidWrapperError::HidApiError```
pub fn new() -> Result<RGBController, HidWrapperError> {
Ok(RGBController {
hid_wrapper: HidWrapper::new()?,
})
}
pub fn is_device_connected(&mut self) -> Result<bool, HidWrapperError> {
self.hid_wrapper.is_device_connected()
}
/// Starts the RGB conversation
///
/// # Errors
/// ```HidWrapperError::HidApiError```
/// ```HidWrapperError::NoHidDeviceError```
fn prepare_device(&mut self) -> Result<(), HidWrapperError> {
self.hid_wrapper.send_report(&[0x04, 0xab])?;
self.hid_wrapper.get_report()?;
self.hid_wrapper.send_report(&[
0x26, 0x36, 0xf2, 0x27, 0xb7, 0x2a, 0x56, 0x77, 0x98, 0x59, 0x9c, 0x6d, 0x9f, 0xc6,
0xb, 0x44, 0xec, 0xa8, 0x47, 0x21, 0xe2, 0x65, 0x76, 0xa3, 0x70, 0xbe, 0xa2, 0xbb,
0x95, 0x47, 0x5e, 0xbe, 0x23, 0x1b, 0xad, 0xb8, 0xc3, 0xcd, 0x1f, 0x4, 0x39, 0xa2,
0x3d, 0x19, 0xe9, 0xfd, 0x27, 0xa7, 0x9a, 0x1a, 0x7c, 0xe3, 0x7b, 0xff, 0x7a, 0x1e,
0x63, 0xb0, 0x67, 0x9d, 0x5d, 0xa3, 0x2f, 0xa5,
])?;
self.hid_wrapper.send_report(&[0x04, 0x02])?;
self.hid_wrapper.get_report()?;
self.hid_wrapper
.send_report(&[0x04, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12])?;
self.hid_wrapper.get_report()?;
Ok(())
}
/// Some middle bytes IDK what to name ts
/// Is a required part of the RGB conversation
///
/// # Errors
/// ```HidWrapperError::HidApiError```
/// ```HidWrapperError::NoHidDeviceError```
fn mid(&mut self) -> Result<(), HidWrapperError> {
//TODO: Rename func and possibly change packets depending on mode
self.hid_wrapper.send_report(&[
0x1, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x2, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x3, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x4, 0x5a, 0xff, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
])?;
self.hid_wrapper.send_report(&[
0x5, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x6, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x7, 0x5a, 0xff, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x8, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
])?;
self.hid_wrapper.send_report(&[
0x9, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0xa, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0xb, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0xc, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
])?;
self.hid_wrapper.send_report(&[
0xd, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0xe, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0xf, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x10, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
])?;
self.hid_wrapper.send_report(&[
0x11, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x12, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x13, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
0x80, 0xff, 0xff, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x55,
])?;
Ok(())
}
/// Sets colors for each key (only if StaticPerKey effect is set) base on a 2d array
/// Is a required part of the RGB conversation
///
/// # Errors
/// ```HidWrapperError::HidApiError```
/// ```HidWrapperError::NoHidDeviceError```
fn custom_keys(&mut self, keymap: &[[u8; 3]; 144]) -> Result<(), HidWrapperError> {
for i in 0..9 {
//Magic num 9 == len of keymap / 16
self.hid_wrapper.send_report(&[
0x80,
keymap[i * 16][0],
keymap[i * 16][1],
keymap[i * 16][2],
0x80,
keymap[i * 16 + 1][0],
keymap[i * 16 + 1][1],
keymap[i * 16 + 1][2],
0x80,
keymap[i * 16 + 2][0],
keymap[i * 16 + 2][1],
keymap[i * 16 + 2][2],
0x80,
keymap[i * 16 + 3][0],
keymap[i * 16 + 3][1],
keymap[i * 16 + 3][2],
0x80,
keymap[i * 16 + 4][0],
keymap[i * 16 + 4][1],
keymap[i * 16 + 4][2],
0x80,
keymap[i * 16 + 5][0],
keymap[i * 16 + 5][1],
keymap[i * 16 + 5][2],
0x80,
keymap[i * 16 + 6][0],
keymap[i * 16 + 6][1],
keymap[i * 16 + 6][2],
0x80,
keymap[i * 16 + 7][0],
keymap[i * 16 + 7][1],
keymap[i * 16 + 7][2],
0x80,
keymap[i * 16 + 8][0],
keymap[i * 16 + 8][1],
keymap[i * 16 + 8][2],
0x80,
keymap[i * 16 + 9][0],
keymap[i * 16 + 9][1],
keymap[i * 16 + 9][2],
0x80,
keymap[i * 16 + 10][0],
keymap[i * 16 + 10][1],
keymap[i * 16 + 10][2],
0x80,
keymap[i * 16 + 11][0],
keymap[i * 16 + 11][1],
keymap[i * 16 + 11][2],
0x80,
keymap[i * 16 + 12][0],
keymap[i * 16 + 12][1],
keymap[i * 16 + 12][2],
0x80,
keymap[i * 16 + 13][0],
keymap[i * 16 + 13][1],
keymap[i * 16 + 13][2],
0x80,
keymap[i * 16 + 14][0],
keymap[i * 16 + 14][1],
keymap[i * 16 + 14][2],
0x80,
keymap[i * 16 + 15][0],
keymap[i * 16 + 15][1],
keymap[i * 16 + 15][2],
])?;
}
Ok(())
}
/// Applies an effect to the device
/// Is a required part of the RGB conversation
///
/// # Errors
/// ```HidWrapperError::HidApiError```
/// ```HidWrapperError::NoHidDeviceError```
fn apply_to_device(&mut self) -> Result<(), HidWrapperError> {
self.hid_wrapper.send_report(&[0x04, 0x02])?;
self.hid_wrapper.get_report()?;
self.hid_wrapper.send_report(&[0x04, 0xf0])?;
Ok(())
}
/// Sets an effect
///
/// # Errors
/// ```HidWrapperError::HidApiError```
/// ```HidWrapperError::NoHidDeviceError```
#[allow(clippy::too_many_arguments)]
pub fn set_effect(
&mut self,
effect: Effects,
red: u8,
green: u8,
blue: u8,
full_color: bool,
brightness: u8,
speed: u8,
direction: u8,
keymap: Option<[[u8; 3]; 144]>,
) -> Result<(), HidWrapperError> {
self.hid_wrapper.open_device()?;
self.prepare_device()?;
self.mid()?;
self.hid_wrapper.send_report(&[])?;
self.hid_wrapper.send_report(&[])?;
self.hid_wrapper.send_report(&[])?;
match keymap {
Some(map) => self.custom_keys(&map)?,
None => self.custom_keys(&[[0, 255, 0]; 144])?,
}
self.hid_wrapper.send_report(&[
effect.to_u8(),
red,
green,
blue,
0,
0,
0,
0,
u8::from(full_color),
brightness.clamp(0, 16),
speed.clamp(1, 16),
direction.clamp(0, 3),
0,
0,
0xaa,
0x55,
])?;
self.apply_to_device()?;
self.hid_wrapper.close_device();
Ok(())
}
pub fn set_static_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Static,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
1,
0,
None,
)
}
pub fn set_single_off_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::SingleOff,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_single_on_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::SingleOn,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_glittering_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Glittering,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_rain_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Rain,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_colorful_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Colorful,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_breath_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Breath,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_spectrum_effect(
&mut self,
brightness: u8,
speed: u8,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Spectrum,
0,
0,
0,
false,
brightness,
speed,
0,
None,
)
}
pub fn set_centrifugal_wave_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::CentrifugalWave,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
#[allow(clippy::too_many_arguments)]
pub fn set_vertical_wave_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
direction: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::VerticalWave,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
direction.clamp(2, 3),
None,
)
}
#[allow(clippy::too_many_arguments)]
pub fn set_horizontal_wave_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
direction: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::HorizontalWave,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
direction.clamp(0, 1),
None,
)
}
pub fn set_rotating_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Rotating,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_explosion_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Explosion,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_launch_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Launch,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_ripples_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Ripples,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_snake_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Snake,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_pulse_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Pulse,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_tilt_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Tilt,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_shuttle_effect(
&mut self,
red: u8,
green: u8,
blue: u8,
brightness: u8,
speed: u8,
full_color: Option<bool>,
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::Shuttle,
red,
green,
blue,
full_color.unwrap_or(false),
brightness,
speed,
0,
None,
)
}
pub fn set_static_per_key_effect(
&mut self,
brightness: u8,
keymap: [[u8; 3]; 144],
) -> Result<(), HidWrapperError> {
self.set_effect(
Effects::StaticPerKey,
0,
0,
0,
false,
brightness,
1,
0,
Some(keymap),
)
}
}
+182
View File
@@ -0,0 +1,182 @@
use crate::Effects;
#[allow(dead_code)]
pub struct EffectInfo<'a> {
name: &'a str,
effect: Effects,
can_set_color: bool,
can_set_speed: bool,
can_set_direction: DirectionPolicy,
can_set_full_color: bool,
}
#[allow(dead_code)]
pub enum DirectionPolicy {
None,
Horizontal01,
Vertical23,
}
#[allow(dead_code)]
pub const EFFECTS: [EffectInfo; 20] = [
EffectInfo {
name: "Static",
effect: Effects::Static,
can_set_color: true,
can_set_speed: false,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "SingleOn",
effect: Effects::SingleOn,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "SingleOff",
effect: Effects::SingleOff,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Glittering",
effect: Effects::Glittering,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Rain",
effect: Effects::Rain,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Colorful",
effect: Effects::Colorful,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Breath",
effect: Effects::Breath,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Spectrum",
effect: Effects::Spectrum,
can_set_color: false,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: false,
},
EffectInfo {
name: "CentrifugalWave",
effect: Effects::CentrifugalWave,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "VerticalWave",
effect: Effects::VerticalWave,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::Vertical23,
can_set_full_color: true,
},
EffectInfo {
name: "HorizontalWave",
effect: Effects::HorizontalWave,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::Horizontal01,
can_set_full_color: true,
},
EffectInfo {
name: "Rotating",
effect: Effects::Rotating,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Explosion",
effect: Effects::Explosion,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Launch",
effect: Effects::Launch,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Ripples",
effect: Effects::Ripples,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Snake",
effect: Effects::Snake,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Pulse",
effect: Effects::Pulse,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Tilt",
effect: Effects::Tilt,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "Shuttle",
effect: Effects::Shuttle,
can_set_color: true,
can_set_speed: true,
can_set_direction: DirectionPolicy::None,
can_set_full_color: true,
},
EffectInfo {
name: "StaticPerKey",
effect: Effects::StaticPerKey,
can_set_color: false,
can_set_speed: false,
can_set_direction: DirectionPolicy::None,
can_set_full_color: false,
},
];
+57
View File
@@ -0,0 +1,57 @@
use Effects::{
Breath, CentrifugalWave, Colorful, Explosion, Glittering, HorizontalWave, Launch, Pulse, Rain,
Ripples, Rotating, Shuttle, SingleOff, SingleOn, Snake, Spectrum, Static, StaticPerKey, Tilt,
VerticalWave,
};
/// Effects of the keyboard
pub enum Effects {
Static,
SingleOn,
SingleOff,
Glittering,
Rain,
Colorful,
Breath,
Spectrum,
CentrifugalWave,
VerticalWave,
HorizontalWave,
Rotating,
Explosion,
Launch,
Ripples,
Snake,
Pulse,
Tilt,
Shuttle,
StaticPerKey,
}
impl Effects {
/// Returns an u8 of the effect used for communication with the device
pub fn to_u8(&self) -> u8 {
match self {
Static => 1,
SingleOn => 2,
SingleOff => 3,
Glittering => 4,
Rain => 5,
Colorful => 6,
Breath => 7,
Spectrum => 8,
CentrifugalWave => 9,
VerticalWave => 10,
HorizontalWave => 11,
Rotating => 12,
Explosion => 13,
Launch => 14,
Ripples => 15,
Snake => 16,
Pulse => 17,
Tilt => 18,
Shuttle => 19,
StaticPerKey => 20,
}
}
}