164 lines
4.7 KiB
Rust
164 lines
4.7 KiB
Rust
use enum_ordinalize::Ordinalize;
|
|
use enumset::{enum_set, EnumSet, EnumSetType};
|
|
|
|
use crate::util::Endianness;
|
|
|
|
#[derive(Debug, Ordinalize, EnumSetType)]
|
|
#[repr(u8)]
|
|
pub enum LoupedeckKnob {
|
|
KnobLeftTop = 0x01,
|
|
KnobLeftMiddle = 0x02,
|
|
KnobLeftBottom = 0x03,
|
|
KnobRightTop = 0x04,
|
|
KnobRightMiddle = 0x05,
|
|
KnobRightBottom = 0x06,
|
|
}
|
|
|
|
#[derive(Debug, Ordinalize, EnumSetType)]
|
|
#[repr(u8)]
|
|
pub enum LoupedeckButton {
|
|
N0 = 0x07,
|
|
N1 = 0x08,
|
|
N2 = 0x09,
|
|
N3 = 0x0a,
|
|
N4 = 0x0b,
|
|
N5 = 0x0c,
|
|
N6 = 0x0d,
|
|
N7 = 0x0e,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
#[non_exhaustive]
|
|
pub struct LoupedeckDeviceDisplayConfiguration {
|
|
pub id: u8,
|
|
pub name: &'static str,
|
|
pub width: u16,
|
|
pub height: u16,
|
|
pub local_offset_x: u16,
|
|
pub local_offset_y: u16,
|
|
pub global_offset_x: u16,
|
|
pub global_offset_y: u16,
|
|
pub endianness: Endianness,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
#[non_exhaustive]
|
|
pub struct LoupedeckDeviceCharacteristics {
|
|
pub vendor_id: u16,
|
|
pub product_id: u16,
|
|
pub name: &'static str,
|
|
pub available_knobs: EnumSet<LoupedeckKnob>,
|
|
pub available_buttons: EnumSet<LoupedeckButton>,
|
|
pub key_grid_rows: u8,
|
|
pub key_grid_columns: u8,
|
|
pub key_grid_display: LoupedeckDeviceDisplayConfiguration,
|
|
pub additional_displays: &'static [LoupedeckDeviceDisplayConfiguration],
|
|
}
|
|
|
|
impl LoupedeckDeviceCharacteristics {
|
|
pub fn key_size(&self) -> (u16, u16) {
|
|
// Assuming the sizes are integers
|
|
(
|
|
self.key_grid_display.width / self.key_grid_columns as u16,
|
|
self.key_grid_display.height / self.key_grid_rows as u16,
|
|
)
|
|
}
|
|
|
|
pub fn get_display_at_coordinates(&self, x: u16, y: u16) -> Option<&LoupedeckDeviceDisplayConfiguration> {
|
|
let check = |display: &&LoupedeckDeviceDisplayConfiguration| {
|
|
x >= display.global_offset_x
|
|
&& x <= display.global_offset_x + display.width
|
|
&& y >= display.global_offset_y
|
|
&& y <= display.global_offset_y + display.height
|
|
};
|
|
|
|
if check(&&self.key_grid_display) {
|
|
Some(&self.key_grid_display)
|
|
} else {
|
|
self.additional_displays.iter().find(check)
|
|
}
|
|
}
|
|
|
|
pub fn get_key_at_coordinates(&self, x: u16, y: u16) -> Option<u8> {
|
|
let (column_width, row_height) = self.key_size();
|
|
|
|
if x < self.key_grid_display.global_offset_x || y < self.key_grid_display.global_offset_y {
|
|
return None;
|
|
}
|
|
|
|
let local_x = x - self.key_grid_display.global_offset_x;
|
|
let local_y = y - self.key_grid_display.global_offset_y;
|
|
|
|
if local_x >= self.key_grid_display.width || local_y >= self.key_grid_display.height {
|
|
return None;
|
|
}
|
|
|
|
let column = (local_x / column_width) as u8;
|
|
let row = (local_y / row_height) as u8;
|
|
|
|
Some(row * self.key_grid_columns + column)
|
|
}
|
|
}
|
|
|
|
static LOUPEDECK_LIVE_CHARACTERISTIC: LoupedeckDeviceCharacteristics = LoupedeckDeviceCharacteristics {
|
|
vendor_id: 0x2ec2,
|
|
product_id: 0x0004,
|
|
name: "Loupedeck Live",
|
|
available_knobs: enum_set!(
|
|
LoupedeckKnob::KnobLeftTop
|
|
| LoupedeckKnob::KnobLeftMiddle
|
|
| LoupedeckKnob::KnobLeftBottom
|
|
| LoupedeckKnob::KnobRightTop
|
|
| LoupedeckKnob::KnobRightMiddle
|
|
| LoupedeckKnob::KnobRightBottom
|
|
),
|
|
available_buttons: enum_set!(
|
|
LoupedeckButton::N0
|
|
| LoupedeckButton::N1
|
|
| LoupedeckButton::N2
|
|
| LoupedeckButton::N3
|
|
| LoupedeckButton::N4
|
|
| LoupedeckButton::N5
|
|
| LoupedeckButton::N6
|
|
| LoupedeckButton::N7
|
|
),
|
|
key_grid_rows: 3,
|
|
key_grid_columns: 4,
|
|
key_grid_display: LoupedeckDeviceDisplayConfiguration {
|
|
id: 0x4d,
|
|
name: "center",
|
|
width: 360,
|
|
height: 270,
|
|
local_offset_x: 60,
|
|
local_offset_y: 0,
|
|
global_offset_x: 60,
|
|
global_offset_y: 0,
|
|
endianness: Endianness::LittleEndian,
|
|
},
|
|
additional_displays: &[
|
|
LoupedeckDeviceDisplayConfiguration {
|
|
id: 0x4d,
|
|
name: "left",
|
|
width: 60,
|
|
height: 270,
|
|
local_offset_x: 0,
|
|
local_offset_y: 0,
|
|
global_offset_x: 0,
|
|
global_offset_y: 0,
|
|
endianness: Endianness::LittleEndian,
|
|
},
|
|
LoupedeckDeviceDisplayConfiguration {
|
|
id: 0x4d,
|
|
name: "right",
|
|
width: 60,
|
|
height: 270,
|
|
local_offset_x: 420,
|
|
local_offset_y: 0,
|
|
global_offset_x: 420,
|
|
global_offset_y: 0,
|
|
endianness: Endianness::LittleEndian,
|
|
},
|
|
],
|
|
};
|
|
|
|
pub static CHARACTERISTICS: [&LoupedeckDeviceCharacteristics; 1] = [&LOUPEDECK_LIVE_CHARACTERISTIC];
|