use crate::effects::Effect;
use crate::effects::EffectValue;
use crate::kbd_out::KbdOut;
use crate::keys::KeyCode;
use crate::keys::KeyCode::*;
use crate::keys::KeyValue;
use crate::ktrl::Ktrl;
use crate::layers::LayerIndex;
#[cfg(feature = "sound")]
use crate::effects::KSnd;
use std::io::Error;
use std::vec::Vec;
lazy_static::lazy_static! {
static ref HYPER: Vec<KeyCode> = {
vec![
KEY_LEFTCTRL, KEY_LEFTALT, KEY_LEFTSHIFT, KEY_LEFTMETA
].iter()
.map(|evkey| KeyCode::from(evkey.clone()))
.collect()
};
}
lazy_static::lazy_static! {
static ref MEH: Vec<KeyCode> = {
vec![
KEY_LEFTCTRL, KEY_LEFTALT, KEY_LEFTSHIFT
].iter()
.map(|evkey| KeyCode::from(evkey.clone()))
.collect()
};
}
fn perform_multiple_effects(
ktrl: &mut Ktrl,
effects: Vec<Effect>,
value: KeyValue,
) -> Result<(), Error> {
for fx in effects {
let sub_fx_val = EffectValue::new(fx.clone(), value);
perform_effect(ktrl, sub_fx_val)?;
}
Ok(())
}
#[cfg(feature = "sound")]
fn perform_play_custom_sound(
ktrl: &mut Ktrl,
snd_path: String,
value: KeyValue,
) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.dj.play_custom(&snd_path)
}
Ok(())
}
#[cfg(feature = "sound")]
fn perform_play_sound(ktrl: &mut Ktrl, snd: KSnd, value: KeyValue) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.dj.play(snd)
}
Ok(())
}
fn perform_momentary_layer(ktrl: &mut Ktrl, idx: LayerIndex, value: KeyValue) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.l_mgr.turn_layer_on(idx)
} else if value == KeyValue::Release {
ktrl.l_mgr.turn_layer_off(idx)
}
Ok(())
}
fn perform_turn_on_layer(ktrl: &mut Ktrl, idx: LayerIndex, value: KeyValue) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.l_mgr.turn_layer_on(idx)
}
Ok(())
}
fn perform_turn_off_layer(ktrl: &mut Ktrl, idx: LayerIndex, value: KeyValue) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.l_mgr.turn_layer_off(idx)
}
Ok(())
}
fn perform_toggle_layer(ktrl: &mut Ktrl, idx: LayerIndex, value: KeyValue) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.l_mgr.toggle_layer(idx)
}
Ok(())
}
fn perform_turn_on_layer_alias(
ktrl: &mut Ktrl,
name: String,
value: KeyValue,
) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.l_mgr.turn_alias_on(name)
}
Ok(())
}
fn perform_turn_off_layer_alias(
ktrl: &mut Ktrl,
name: String,
value: KeyValue,
) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.l_mgr.turn_alias_off(name)
}
Ok(())
}
fn perform_toggle_layer_alias(ktrl: &mut Ktrl, name: String, value: KeyValue) -> Result<(), Error> {
if value == KeyValue::Press {
ktrl.l_mgr.toggle_layer_alias(name)
}
Ok(())
}
fn perform_toggle_profile(
ktrl: &mut Ktrl,
name: String,
value: KeyValue,
on: bool,
) -> Result<(), Error> {
if value == KeyValue::Press {
match perform_deactivate_all_profiles(ktrl, value) {
Ok(()) => ktrl.l_mgr.toggle_profile(name, on),
Err(e) => return Err(e),
}
}
Ok(())
}
fn perform_deactivate_all_profiles(ktrl: &mut Ktrl, value: KeyValue) -> Result<(), Error> {
if value == KeyValue::Press {
for name in ktrl.l_mgr.layer_profiles.clone().keys() {
ktrl.l_mgr.toggle_profile(name.clone(), false);
}
}
Ok(())
}
fn perform_key_sticky(ktrl: &mut Ktrl, code: KeyCode, value: KeyValue) -> Result<(), Error> {
if value == KeyValue::Release {
return Ok(());
}
if !ktrl.sticky.is_pressed(code) {
ktrl.sticky.update_pressed(&mut ktrl.l_mgr, code);
ktrl.kbd_out.press_key(code)
} else {
ktrl.sticky.update_released(&mut ktrl.l_mgr, code);
ktrl.kbd_out.release_key(code)
}
}
fn perform_keyseq(kbd_out: &mut KbdOut, seq: Vec<KeyCode>, value: KeyValue) -> Result<(), Error> {
for code in seq {
perform_key(kbd_out, code, value)?;
}
Ok(())
}
fn perform_key(kbd_out: &mut KbdOut, code: KeyCode, value: KeyValue) -> Result<(), Error> {
kbd_out.write_key(code, value)
}
pub fn perform_effect(ktrl: &mut Ktrl, fx_val: EffectValue) -> Result<(), Error> {
match fx_val.fx {
Effect::NoOp => Ok(()),
Effect::Key(code) => perform_key(&mut ktrl.kbd_out, code, fx_val.val),
Effect::KeySeq(seq) => perform_keyseq(&mut ktrl.kbd_out, seq, fx_val.val),
Effect::KeySticky(code) => perform_key_sticky(ktrl, code, fx_val.val),
Effect::Meh => perform_keyseq(&mut ktrl.kbd_out, MEH.to_vec(), fx_val.val),
Effect::Hyper => perform_keyseq(&mut ktrl.kbd_out, HYPER.to_vec(), fx_val.val),
Effect::ActivateProfile(name) => perform_toggle_profile(ktrl, name, fx_val.val, true),
Effect::DeactivateProfile(name) => perform_toggle_profile(ktrl, name, fx_val.val, false),
Effect::DeactivateAllProfiles => perform_deactivate_all_profiles(ktrl, fx_val.val),
Effect::TurnOnLayer(idx) => perform_turn_on_layer(ktrl, idx, fx_val.val),
Effect::TurnOffLayer(idx) => perform_turn_off_layer(ktrl, idx, fx_val.val),
Effect::ToggleLayer(idx) => perform_toggle_layer(ktrl, idx, fx_val.val),
Effect::TurnOnLayerAlias(name) => perform_turn_on_layer_alias(ktrl, name, fx_val.val),
Effect::TurnOffLayerAlias(name) => perform_turn_off_layer_alias(ktrl, name, fx_val.val),
Effect::ToggleLayerAlias(name) => perform_toggle_layer_alias(ktrl, name, fx_val.val),
Effect::MomentaryLayer(idx) => perform_momentary_layer(ktrl, idx, fx_val.val),
Effect::Multi(fxs) => perform_multiple_effects(ktrl, fxs, fx_val.val),
#[cfg(feature = "sound")]
Effect::Sound(snd) => perform_play_sound(ktrl, snd, fx_val.val),
#[cfg(feature = "sound")]
Effect::SoundEx(snd) => perform_play_custom_sound(ktrl, snd, fx_val.val),
}
}