use embassy_time::Duration;
use heapless::Vec;
use rmk_types::fork::Fork;
use rmk_types::keycode::KeyCode;
use rmk_types::morse::{Morse, MorseMode, MorseProfile};
use crate::keyboard::combo::Combo;
use crate::{
AUTO_MOUSE_LAYER_MAX_NUM, COMBO_MAX_NUM, FORK_MAX_NUM, MACRO_SPACE_SIZE, MORSE_MAX_NUM, MORSE_PROFILE_MAX_NUM,
MOUSE_KEY_INTERVAL, MOUSE_WHEEL_INTERVAL,
};
#[derive(Debug, Default)]
pub struct BehaviorConfig {
pub default_layer: u8,
pub tri_layer: Option<[u8; 3]>,
pub tap: TapConfig,
pub one_shot: OneShotConfig,
pub one_shot_modifiers: OneShotModifiersConfig,
pub combo: CombosConfig,
pub fork: ForksConfig,
pub morse: MorsesConfig,
pub keyboard_macros: KeyboardMacrosConfig,
pub mouse_key: MouseKeyConfig,
pub auto_mouse_layer: Vec<AutoMouseLayerConfig, AUTO_MOUSE_LAYER_MAX_NUM>,
}
#[derive(Clone, Debug)]
pub struct AutoMouseLayerConfig {
pub device_id: Option<u8>,
pub target_layer: u8,
pub timeout: Duration,
pub threshold: u16,
pub deactivate_on_key: bool,
pub extra_mouse_keys: &'static [KeyCode],
pub reset_timeout_on_key: bool,
}
impl Default for AutoMouseLayerConfig {
fn default() -> Self {
Self {
device_id: None,
target_layer: 0,
timeout: Duration::from_millis(500),
threshold: 1,
deactivate_on_key: false,
extra_mouse_keys: &[],
reset_timeout_on_key: false,
}
}
}
impl AutoMouseLayerConfig {
pub fn new(device_id: Option<u8>, target_layer: u8, timeout: Duration, threshold: u16) -> Self {
assert!(threshold >= 1, "AutoMouseLayerConfig::new: threshold must be >= 1");
assert!(
timeout >= Duration::from_millis(1),
"AutoMouseLayerConfig::new: timeout must be at least 1ms"
);
Self {
device_id,
target_layer,
timeout,
threshold,
..Self::default()
}
}
pub fn with_deactivate_on_key(mut self, exceptions: &'static [KeyCode]) -> Self {
self.deactivate_on_key = true;
self.extra_mouse_keys = exceptions;
self
}
pub fn with_reset_timeout_on_key(mut self) -> Self {
self.reset_timeout_on_key = true;
self
}
}
#[derive(Clone, Copy, Debug)]
pub struct TapConfig {
pub tap_interval: u16,
pub tap_capslock_interval: u16,
}
impl Default for TapConfig {
fn default() -> Self {
Self {
tap_interval: 20,
tap_capslock_interval: 20,
}
}
}
#[derive(Clone, Debug)]
pub struct MorsesConfig {
pub enable_flow_tap: bool,
pub prior_idle_time: Duration, pub default_profile: MorseProfile,
pub profiles: Vec<MorseProfile, MORSE_PROFILE_MAX_NUM>,
pub morses: Vec<Morse, MORSE_MAX_NUM>,
}
impl Default for MorsesConfig {
fn default() -> Self {
Self {
enable_flow_tap: false,
prior_idle_time: Duration::from_millis(120),
default_profile: MorseProfile::new(Some(false), Some(MorseMode::Normal), Some(250u16), Some(250u16)),
profiles: Vec::new(),
morses: Vec::new(),
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct OneShotConfig {
pub timeout: Duration,
}
impl Default for OneShotConfig {
fn default() -> Self {
Self {
timeout: Duration::from_secs(1),
}
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct OneShotModifiersConfig {
pub activate_on_keypress: bool,
pub quick_release: bool,
}
#[derive(Clone, Debug)]
pub struct CombosConfig {
pub combos: [Option<Combo>; COMBO_MAX_NUM],
pub timeout: Duration,
pub prior_idle_time: Option<Duration>,
}
impl Default for CombosConfig {
fn default() -> Self {
Self {
timeout: Duration::from_millis(50),
combos: core::array::from_fn(|_| None),
prior_idle_time: None,
}
}
}
#[derive(Clone, Debug)]
pub struct ForksConfig {
pub forks: Vec<Fork, FORK_MAX_NUM>,
}
impl Default for ForksConfig {
fn default() -> Self {
Self { forks: Vec::new() }
}
}
#[derive(Debug)]
pub struct KeyboardMacrosConfig {
pub macro_sequences: [u8; MACRO_SPACE_SIZE],
}
impl Default for KeyboardMacrosConfig {
fn default() -> Self {
Self {
macro_sequences: [0; MACRO_SPACE_SIZE],
}
}
}
impl KeyboardMacrosConfig {
pub fn new(macro_sequences: [u8; MACRO_SPACE_SIZE]) -> Self {
Self { macro_sequences }
}
}
#[derive(Clone, Copy, Debug)]
pub struct MouseKeyConfig {
pub initial_delay_ms: u16,
pub repeat_interval_ms: u16,
pub move_delta: u8,
pub max_speed: u8,
pub ticks_to_max: u8,
pub wheel_initial_delay_ms: u16,
pub wheel_repeat_interval_ms: u16,
pub wheel_delta: u8,
pub wheel_max_speed: u8,
pub wheel_ticks_to_max: u8,
pub move_max: u8,
pub wheel_max: u8,
}
impl Default for MouseKeyConfig {
fn default() -> Self {
Self {
initial_delay_ms: 100, repeat_interval_ms: MOUSE_KEY_INTERVAL, move_delta: 5, max_speed: 3, ticks_to_max: 50, wheel_initial_delay_ms: 100, wheel_repeat_interval_ms: MOUSE_WHEEL_INTERVAL, wheel_delta: 1, wheel_max_speed: 2, wheel_ticks_to_max: 40, move_max: 25, wheel_max: 4, }
}
}
impl MouseKeyConfig {
pub fn get_movement_delay(&self, repeat_count: u8) -> u16 {
if repeat_count == 0 {
self.initial_delay_ms
} else {
self.repeat_interval_ms
}
}
pub fn get_wheel_delay(&self, repeat_count: u8) -> u16 {
if repeat_count == 0 {
self.wheel_initial_delay_ms
} else {
self.wheel_repeat_interval_ms
}
}
}