From 36b87022aa79034fd26cee6924ba0a93190a3833 Mon Sep 17 00:00:00 2001 From: Sawyer McLane Date: Fri, 27 Sep 2024 11:57:26 -0600 Subject: [PATCH] Added buffer for new shortcuts --- src/app.rs | 20 ++++++++++++++ src/listener.rs | 37 ++++++++++++++++++++++++++ src/shortcut.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 120 insertions(+), 6 deletions(-) diff --git a/src/app.rs b/src/app.rs index e0f5e03..ead8a93 100644 --- a/src/app.rs +++ b/src/app.rs @@ -423,6 +423,26 @@ impl MantleApp { ui.label(format!("{:?}", shortcut.callback_name)); }); } + // allow user to add new keyboard shortcuts + ui.horizontal(|ui| { + ui.label("Add Shortcut"); + ui.separator(); + ui.text_edit_singleline( + &mut self.shortcut_manager.new_shortcut.callback_name, + ); + ui.separator(); + ui.text_edit_singleline(&mut self.shortcut_manager.new_shortcut.shortcut); + ui.separator(); + // ui.text_edit_singleline(&mut self.shortcut_manager.new_shortcut.callback); + ui.label("TODO: Add callback"); + if ui.button("Add").clicked() { + self.shortcut_manager.add_shortcut( + self.shortcut_manager.new_shortcut.callback_name.clone(), + self.shortcut_manager.new_shortcut.shortcut.clone(), + |_keys_pressed| {}, + ); + } + }); }); } } diff --git a/src/listener.rs b/src/listener.rs index 1e96320..dc9c839 100644 --- a/src/listener.rs +++ b/src/listener.rs @@ -3,6 +3,7 @@ use rdev::{listen, Button, Event, EventType, Key}; use std::collections::BTreeSet; use std::fmt::{Display, Formatter, Result as FmtResult}; use std::hash::{Hash, Hasher}; +use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::thread::{spawn, JoinHandle}; use std::time::Instant; @@ -15,6 +16,42 @@ pub enum InputAction { Button(Button), } +impl FromStr for InputAction { + fn from_str(s: &str) -> Result { + Ok(match s.to_ascii_lowercase().as_str() { + "a" => InputAction::Key(Key::KeyA), + "b" => InputAction::Key(Key::KeyB), + "c" => InputAction::Key(Key::KeyC), + "d" => InputAction::Key(Key::KeyD), + "e" => InputAction::Key(Key::KeyE), + "f" => InputAction::Key(Key::KeyF), + "g" => InputAction::Key(Key::KeyG), + "h" => InputAction::Key(Key::KeyH), + "i" => InputAction::Key(Key::KeyI), + "j" => InputAction::Key(Key::KeyJ), + "k" => InputAction::Key(Key::KeyK), + "l" => InputAction::Key(Key::KeyL), + "m" => InputAction::Key(Key::KeyM), + "n" => InputAction::Key(Key::KeyN), + "o" => InputAction::Key(Key::KeyO), + "p" => InputAction::Key(Key::KeyP), + "q" => InputAction::Key(Key::KeyQ), + "r" => InputAction::Key(Key::KeyR), + "s" => InputAction::Key(Key::KeyS), + "t" => InputAction::Key(Key::KeyT), + "u" => InputAction::Key(Key::KeyU), + "v" => InputAction::Key(Key::KeyV), + "w" => InputAction::Key(Key::KeyW), + "x" => InputAction::Key(Key::KeyX), + "y" => InputAction::Key(Key::KeyY), + "z" => InputAction::Key(Key::KeyZ), + _ => return Err(error!("Failed to parse InputAction from string: {}", s)), + }) + } + + type Err = (); +} + impl PartialEq for InputAction { fn eq(&self, other: &Self) -> bool { match (self, other) { diff --git a/src/shortcut.rs b/src/shortcut.rs index 25f36e4..354088e 100644 --- a/src/shortcut.rs +++ b/src/shortcut.rs @@ -1,7 +1,8 @@ -// shortcut.rs use crate::listener::{InputAction, InputListener}; +use eframe::egui::TextBuffer; use std::collections::BTreeSet; use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; +use std::str::FromStr; use std::sync::{Arc, Mutex}; pub type ShortcutCallback = Arc) + Send + Sync + 'static>; @@ -21,11 +22,45 @@ impl KeyboardShortcut { } } -#[derive(Clone)] -pub struct KeyboardShortcutCallback { - pub shortcut: KeyboardShortcut, - pub callback: ShortcutCallback, - pub callback_name: String, +impl TextBuffer for KeyboardShortcut { + fn is_mutable(&self) -> bool { + true + } + + fn as_str(&self) -> &str { + Box::leak( + self.keys + .iter() + .fold(String::new(), |acc, k| acc + &format!("{}", k)) + .into_boxed_str(), + ) + } + + fn insert_text(&mut self, text: &str, char_index: usize) -> usize { + let mut new_keys: BTreeSet = BTreeSet::new(); + let mut index = 0; + for (i, key) in self.keys.iter().enumerate() { + if i == char_index { + for c in text.chars() { + new_keys.insert(InputAction::from_str(&c.to_string()).unwrap()); + index += 1; + } + } + new_keys.insert(*key); + } + self.keys = new_keys; + index + } + + fn delete_char_range(&mut self, char_range: std::ops::Range) { + let mut new_keys: BTreeSet = BTreeSet::new(); + for (i, key) in self.keys.iter().enumerate() { + if i < char_range.start || i >= char_range.end { + new_keys.insert(*key); + } + } + self.keys = new_keys; + } } impl Debug for KeyboardShortcut { @@ -42,10 +77,18 @@ impl Display for KeyboardShortcut { } } +#[derive(Clone)] +pub struct KeyboardShortcutCallback { + pub shortcut: KeyboardShortcut, + pub callback: ShortcutCallback, + pub callback_name: String, +} + pub struct ShortcutManager { input_listener: InputListener, shortcuts: Arc>>, active_shortcuts: Arc>>, + pub new_shortcut: KeyboardShortcutCallback, } impl ShortcutManager { @@ -54,6 +97,13 @@ impl ShortcutManager { input_listener, shortcuts: Arc::new(Mutex::new(Vec::new())), active_shortcuts: Arc::new(Mutex::new(BTreeSet::new())), + new_shortcut: KeyboardShortcutCallback { + shortcut: KeyboardShortcut { + keys: BTreeSet::new(), + }, + callback: Arc::new(|_keys_pressed| {}), + callback_name: "".to_string(), + }, } } @@ -137,6 +187,13 @@ impl Default for ShortcutManager { input_listener: InputListener::new(), shortcuts: Arc::new(Mutex::new(Vec::new())), active_shortcuts: Arc::new(Mutex::new(BTreeSet::new())), + new_shortcut: KeyboardShortcutCallback { + shortcut: KeyboardShortcut { + keys: BTreeSet::new(), + }, + callback: Arc::new(|_keys_pressed| {}), + callback_name: "".to_string(), + }, } } }