diff --git a/Cargo.lock b/Cargo.lock index 800cedc..9033e91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -229,6 +229,9 @@ dependencies = [ "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -324,6 +327,48 @@ name = "nodrop" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "num" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-bigint" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-complex" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-derive" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-integer" version = "0.1.41" @@ -333,6 +378,27 @@ dependencies = [ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "num-iter" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-rational" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-traits" version = "0.2.8" @@ -742,7 +808,13 @@ dependencies = [ "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" +"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" +"checksum num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fcb0cf31fb3ff77e6d2a6ebd6800df7fdcd106f2ad89113c9130bcd07f93dffc" +"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" +"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e" +"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" diff --git a/Cargo.toml b/Cargo.toml index 4c772b3..bf7b913 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,9 @@ regex = "1.3.1" log = "0.4.8" simplelog = "0.7.1" zip = "0.5.3" +num = "0.2.0" +num-traits = "0.2.8" +num-derive = "0.2.5" [dev-dependencies] tempfile = "3.1.0" diff --git a/src/context/windows.rs b/src/context/windows.rs index 4bf02b1..c62e821 100644 --- a/src/context/windows.rs +++ b/src/context/windows.rs @@ -1,6 +1,6 @@ use std::sync::mpsc::Sender; use crate::bridge::windows::*; -use crate::event::{Event, KeyEvent, KeyModifier, ActionEvent}; +use crate::event::{Event, KeyEvent, KeyModifier, ActionEvent, ActionType}; use crate::event::KeyModifier::*; use std::ffi::c_void; use std::fs::create_dir_all; @@ -137,7 +137,7 @@ extern fn context_menu_click_callback(_self: *mut c_void, id: i32) { unsafe { let _self = _self as *mut WindowsContext; - let event = Event::Action(ActionEvent::ContextMenuClick(id)); + let event = Event::Action(ActionEvent::ContextMenuClick(ActionType::from(id))); (*_self).send_channel.send(event).unwrap(); } } \ No newline at end of file diff --git a/src/engine.rs b/src/engine.rs index a9fabf6..44dc3ab 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -5,7 +5,7 @@ use crate::config::BackendType; use crate::clipboard::ClipboardManager; use log::{info}; use crate::ui::{UIManager, MenuItem, MenuItemType}; -use crate::event::{ActionEventReceiver, Event, ActionEvent}; +use crate::event::{ActionEventReceiver, Event, ActionEvent, ActionType}; use std::cell::RefCell; pub struct Engine<'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>, @@ -36,7 +36,7 @@ impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>, U: UIMan menu.push(MenuItem{ item_type: MenuItemType::Button, item_name: toggle_text, - item_id: 2, + item_id: ActionType::Toggle as i32, }); menu.push(MenuItem{ @@ -48,7 +48,7 @@ impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>, U: UIMan menu.push(MenuItem{ item_type: MenuItemType::Button, item_name: "Exit".to_owned(), - item_id: 1, + item_id: ActionType::Exit as i32, }); menu @@ -119,7 +119,7 @@ impl <'a, S: KeyboardSender, C: ClipboardManager, self.ui_manager.show_menu(self.build_menu()); }, ActionEvent::ContextMenuClick(id) => { - println!("{}", id); + } } } diff --git a/src/event/manager.rs b/src/event/manager.rs index bd3117b..b3f0471 100644 --- a/src/event/manager.rs +++ b/src/event/manager.rs @@ -7,17 +7,17 @@ pub trait EventManager { pub struct DefaultEventManager<'a, K: KeyEventReceiver, A: ActionEventReceiver> { receive_channel: Receiver, - key_receiver: &'a K, - action_receiver: &'a A, + key_receivers: Vec<&'a K>, + action_receivers: Vec<&'a A>, } impl<'a, K: KeyEventReceiver, A: ActionEventReceiver> DefaultEventManager<'a, K, A> { - pub fn new(receive_channel: Receiver, key_receiver: &'a K, - action_receiver: &'a A) -> DefaultEventManager<'a, K, A> { + pub fn new(receive_channel: Receiver, key_receivers: Vec<&'a K>, + action_receivers: Vec<&'a A>) -> DefaultEventManager<'a, K, A> { DefaultEventManager { receive_channel, - key_receiver, - action_receiver, + key_receivers, + action_receivers, } } } @@ -29,10 +29,10 @@ impl <'a, K: KeyEventReceiver, A: ActionEventReceiver> EventManager for DefaultE Ok(event) => { match event { Event::Key(key_event) => { - self.key_receiver.on_key_event(key_event); + self.key_receivers.iter().for_each(move |&receiver| receiver.on_key_event(key_event.clone())); }, Event::Action(action_event) => { - self.action_receiver.on_action_event(action_event); + self.action_receivers.iter().for_each(|&receiver| receiver.on_action_event(action_event.clone())); } } }, diff --git a/src/event/mod.rs b/src/event/mod.rs index f474635..294a2d0 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -2,19 +2,36 @@ pub(crate) mod manager; use serde::{Serialize, Deserialize}; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Event { Action(ActionEvent), Key(KeyEvent) } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum ActionEvent { IconClick, - ContextMenuClick(i32) + ContextMenuClick(ActionType) } -#[derive(Debug)] +#[derive(Debug, Clone)] +pub enum ActionType { + Noop = 0, + Toggle = 1, + Exit = 2, +} + +impl From for ActionType { + fn from(id: i32) -> Self { + match id { + 1 => ActionType::Toggle, + 2 => ActionType::Exit, + _ => ActionType::Noop, + } + } +} + +#[derive(Debug, Clone)] pub enum KeyEvent { Char(char), Modifier(KeyModifier) diff --git a/src/main.rs b/src/main.rs index 22654ec..c22093e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate num_derive; + use std::sync::{mpsc, Arc}; use crate::matcher::Matcher; use crate::matcher::scrolling::ScrollingMatcher; @@ -122,8 +125,8 @@ fn espanso_background(receive_channel: Receiver, config_set: ConfigSet) { let event_manager = DefaultEventManager::new( receive_channel, - &matcher, - &engine, + vec!(&matcher), + vec!(&engine, &matcher), ); event_manager.eventloop(); diff --git a/src/matcher/scrolling.rs b/src/matcher/scrolling.rs index f3e93de..7fe8d04 100644 --- a/src/matcher/scrolling.rs +++ b/src/matcher/scrolling.rs @@ -1,6 +1,6 @@ use crate::matcher::{Match, MatchReceiver}; use std::cell::RefCell; -use crate::event::KeyModifier; +use crate::event::{KeyModifier, ActionEventReceiver, ActionEvent, ActionType}; use crate::config::ConfigManager; use crate::event::KeyModifier::BACKSPACE; use std::time::SystemTime; @@ -19,7 +19,29 @@ struct MatchEntry<'a> { _match: &'a Match } -impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMatcher<'a, R, M> where{ +impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ScrollingMatcher<'a, R, M> { + pub fn new(config_manager: &'a M, receiver: &'a R) -> ScrollingMatcher<'a, R, M> { + let current_set_queue = RefCell::new(VecDeque::new()); + let toggle_press_time = RefCell::new(SystemTime::now()); + + ScrollingMatcher{ + config_manager, + receiver, + current_set_queue, + toggle_press_time, + is_enabled: RefCell::new(true) + } + } + + fn toggle(&self) { + let mut is_enabled = self.is_enabled.borrow_mut(); + *is_enabled = !(*is_enabled); + + self.receiver.on_toggle(*is_enabled); + } +} + +impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMatcher<'a, R, M> { fn handle_char(&self, c: char) { // if not enabled, avoid any processing if !*(self.is_enabled.borrow()) { @@ -79,14 +101,13 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa let mut toggle_press_time = self.toggle_press_time.borrow_mut(); if let Ok(elapsed) = toggle_press_time.elapsed() { if elapsed.as_millis() < config.toggle_interval as u128 { - let mut is_enabled = self.is_enabled.borrow_mut(); - *is_enabled = !(*is_enabled); + let mut is_enabled = self.is_enabled.borrow(); if !*is_enabled { self.current_set_queue.borrow_mut().clear(); } - self.receiver.on_toggle(*is_enabled); + self.toggle(); } } @@ -100,17 +121,19 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa } } } -impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ScrollingMatcher<'a, R, M> { - pub fn new(config_manager: &'a M, receiver: &'a R) -> ScrollingMatcher<'a, R, M> { - let current_set_queue = RefCell::new(VecDeque::new()); - let toggle_press_time = RefCell::new(SystemTime::now()); - ScrollingMatcher{ - config_manager, - receiver, - current_set_queue, - toggle_press_time, - is_enabled: RefCell::new(true) +impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ActionEventReceiver for ScrollingMatcher<'a, R, M> { + fn on_action_event(&self, e: ActionEvent) { + match e { + ActionEvent::ContextMenuClick(action_type) => { + match action_type { + ActionType::Toggle => { + self.toggle(); + }, + _ => {} + } + }, + _ => {} } } } \ No newline at end of file