diff --git a/Cargo.toml b/Cargo.toml index f51b22e..3844c52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,7 @@ toml = "0.8" dirs = "5.0" inputbot = "0.6.0" thiserror = "2.0.11" +slint = "1.9.2" + +[build-dependencies] +slint-build = "1.9.2" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..e70714e --- /dev/null +++ b/build.rs @@ -0,0 +1,3 @@ +fn main() { + slint_build::compile("ui/window.slint").expect("Slint build failed"); +} diff --git a/src/listen.rs b/src/listen.rs index a21ca25..832b5d9 100644 --- a/src/listen.rs +++ b/src/listen.rs @@ -1,5 +1,3 @@ -use std::str::FromStr; - use inputbot::{KeybdKey, KeybdKey::*, MouseButton, MouseButton::*}; pub fn listen(keys: Vec, m_buttons: Vec) { @@ -172,7 +170,7 @@ pub fn keybdkey_from_config(key: &str) -> KeybdKey { } } -fn string_from_keybdkey(key: KeybdKey) -> String { +pub fn string_from_keybdkey(key: KeybdKey) -> String { match key { BackspaceKey => String::from("🡐"), TabKey => String::from("⇌"), @@ -306,7 +304,7 @@ pub fn mousebutton_from_config(button: &str) -> MouseButton { } } -fn string_from_mousebutton(button: MouseButton) -> String { +pub fn string_from_mousebutton(button: MouseButton) -> String { match button { LeftButton => String::from("M1"), MiddleButton => String::from("M3"), diff --git a/src/main.rs b/src/main.rs index 7924037..0be2550 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,27 +1,124 @@ -use inputbot::{get_keybd_key, KeybdKey, KeybdKeyIter, MouseButton}; +slint::include_modules!(); +use inputbot::{KeybdKey, MouseButton}; +use listen::*; +use slint::Color; +//use theme::*; mod config; mod listen; +//mod theme; -fn main() -> Result<(), config::ConfigError> { - println!("Hello, world!"); +use std::thread; + +fn parse_config() -> Result { let config_dir = dirs::config_dir().expect("Config directory not found"); let keydisplay_dir = config_dir.join("keydisplay"); - let config = config::Config::load_or_create(keydisplay_dir)?; + config::Config::load_or_create(keydisplay_dir) +} +// obs +const GREY: slint_generatedMainWindow::Theme = Theme { + app_background: Color::from_argb_encoded(0xFF2F2F2F), + key_background: Color::from_argb_encoded(0xFF363636), + key_background_pressed: Color::from_argb_encoded(0xFF212121), + key_border: Color::from_argb_encoded(0xFF737373), + key_text: Color::from_argb_encoded(0xFFFFFFFF), + key_text_pressed: Color::from_argb_encoded(0xFFFFFFFF), +}; + +// florisboard themes +const NIGHT: slint_generatedMainWindow::Theme = Theme { + app_background: Color::from_argb_encoded(0xFF000000), + key_background: Color::from_argb_encoded(0xFF111111), + key_background_pressed: Color::from_argb_encoded(0xFF212121), + key_border: Color::from_argb_encoded(0xFF707070), + key_text: Color::from_argb_encoded(0xFFEEEEEE), + key_text_pressed: Color::from_argb_encoded(0xFFEEEEEE), +}; + +const DAY: slint_generatedMainWindow::Theme = Theme { + app_background: Color::from_argb_encoded(0xFFE0E0E0), + key_background: Color::from_argb_encoded(0xFFFFFFFF), + key_background_pressed: Color::from_argb_encoded(0xFFEEEEEE), + key_border: Color::from_argb_encoded(0xFFFFFFFF), + key_text: Color::from_argb_encoded(0xFF000000), + key_text_pressed: Color::from_argb_encoded(0xFF000000), +}; + +// guess +const CATPPUCCIN_MOCHA: slint_generatedMainWindow::Theme = Theme { + app_background: Color::from_argb_encoded(0xFF181825), + key_background: Color::from_argb_encoded(0xFF1E1E2E), + key_background_pressed: Color::from_argb_encoded(0xFF313244), + key_border: Color::from_argb_encoded(0xFFF5E0DC), + key_text: Color::from_argb_encoded(0xFFCDD6F4), + key_text_pressed: Color::from_argb_encoded(0xFFCDD6F4), +}; + +pub fn theme_from_config(theme: &str) -> slint_generatedMainWindow::Theme { + match theme { + "grey" => GREY, + "night" => NIGHT, + "day" => DAY, + "catppuccin_mocha" => CATPPUCCIN_MOCHA, + _ => { + println!("invalid theme provided by config, defaulting to grey"); + GREY + } + } +} + +fn run_gui( + keys: Vec, + m_buttons: Vec, + theme: String, +) -> Result<(), slint::PlatformError> { + let ui = MainWindow::new()?; + + let mut keyitems: Vec = Vec::new(); + for key in keys { + keyitems.push(KeyData { + key: string_from_keybdkey(key).into(), + }) + } + + let mut mouseitems: Vec = Vec::new(); + for button in m_buttons { + mouseitems.push(KeyData { + key: string_from_mousebutton(button).into(), + }) + } + + ui.set_theme(theme_from_config(&theme)); + + ui.set_keys(std::rc::Rc::new(slint::VecModel::from(keyitems)).into()); + ui.set_m_buttons(std::rc::Rc::new(slint::VecModel::from(mouseitems)).into()); + + ui.run() +} + +fn main() { + println!("Hello, world!"); + + let config = parse_config().unwrap(); let mut config_to_keys: Vec = Vec::new(); for key in config.listen.keys { // rust is magic 😍 🦀 - config_to_keys.push(listen::keybdkey_from_config(&key)); + config_to_keys.push(keybdkey_from_config(&key)); } let mut config_to_mouse: Vec = Vec::new(); for button in config.listen.mouse { - config_to_mouse.push(listen::mousebutton_from_config(&button)); + config_to_mouse.push(mousebutton_from_config(&button)); } - listen::listen(config_to_keys, config_to_mouse); + let hack = config_to_keys.clone(); + let hack2 = config_to_mouse.clone(); - Ok(()) + thread::spawn(move || { + listen(config_to_keys, config_to_mouse); + }); + + let _ = run_gui(hack, hack2, config.theme); } diff --git a/ui/window.slint b/ui/window.slint new file mode 100644 index 0000000..120df43 --- /dev/null +++ b/ui/window.slint @@ -0,0 +1,74 @@ +export struct Theme { + app_background: color, + key_background: color, + key_background_pressed: color, + key_border: color, + key_text: color, + key_text_pressed: color, +} + +struct KeyData { + key: string, +} + +component Key inherits Rectangle { + in-out property key_text_content; + + in-out property key_background; + in-out property key_border; + in-out property key_text_color; + + width: 100px; + height: 100px; + border-width: 5px; + border-radius: 5px; + background: key_background; + border-color: key_border; + + Text { + text: "\{key_text_content}"; + font-weight: 800; + color: key_text_color; + horizontal-alignment: center; + vertical-alignment: center; + } +} + +export component MainWindow inherits Window { + in-out property theme; + in-out property <[KeyData]> keys; + in-out property <[KeyData]> m_buttons; + keys: []; + m_buttons: []; + + title: "keydisplay"; + + // 14 px padding + 100px for every key + 5px for every space + 14 px padding + width: 14px+(100px*(keys.length + m_buttons.length))+(5px*(keys.length + m_buttons.length - 1))+14px; + height: 128px; + + default-font-size: 25px; + background: theme.app_background; + + HorizontalLayout { + padding: 14px; + spacing: 5px; + + for key[i] in keys : Key{ + key_text_content: key.key; + key_background: theme.key_background; + key_border: theme.key_border; + key_text_color: theme.key_text; + + } + + for button[i] in m_buttons : Key{ + key_text_content: button.key; + key_background: theme.key_background; + key_border: theme.key_border; + key_text_color: theme.key_text; + + } + } + +}