feat(core): add Enable/Disable option in context menu

This commit is contained in:
Federico Terzi 2021-05-23 16:07:17 +02:00
parent 5abea19016
commit 2ad8dfa8a5
3 changed files with 69 additions and 16 deletions

View File

@ -72,6 +72,8 @@ pub enum EventType {
Disabled, Disabled,
Enabled, Enabled,
DisableRequest,
EnableRequest,
SecureInputEnabled, SecureInputEnabled,
SecureInputDisabled, SecureInputDisabled,

View File

@ -17,6 +17,8 @@
* along with espanso. If not, see <https://www.gnu.org/licenses/>. * along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/ */
use std::cell::RefCell;
use super::super::Middleware; use super::super::Middleware;
use crate::engine::event::{ use crate::engine::event::{
ui::{MenuItem, ShowContextMenuEvent, SimpleMenuItem}, ui::{MenuItem, ShowContextMenuEvent, SimpleMenuItem},
@ -25,12 +27,18 @@ use crate::engine::event::{
const CONTEXT_ITEM_EXIT: u32 = 0; const CONTEXT_ITEM_EXIT: u32 = 0;
const CONTEXT_ITEM_RELOAD: u32 = 1; const CONTEXT_ITEM_RELOAD: u32 = 1;
const CONTEXT_ITEM_ENABLE: u32 = 2;
const CONTEXT_ITEM_DISABLE: u32 = 3;
pub struct ContextMenuMiddleware {} pub struct ContextMenuMiddleware {
is_enabled: RefCell<bool>,
}
impl ContextMenuMiddleware { impl ContextMenuMiddleware {
pub fn new() -> Self { pub fn new() -> Self {
Self {} Self {
is_enabled: RefCell::new(true),
}
} }
} }
@ -39,7 +47,9 @@ impl Middleware for ContextMenuMiddleware {
"context_menu" "context_menu"
} }
fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event {
let mut is_enabled = self.is_enabled.borrow_mut();
match &event.etype { match &event.etype {
EventType::TrayIconClicked => { EventType::TrayIconClicked => {
// TODO: fetch top matches for the active config to be added // TODO: fetch top matches for the active config to be added
@ -53,6 +63,18 @@ impl Middleware for ContextMenuMiddleware {
EventType::ShowContextMenu(ShowContextMenuEvent { EventType::ShowContextMenu(ShowContextMenuEvent {
// TODO: add actual entries // TODO: add actual entries
items: vec![ items: vec![
MenuItem::Simple(if *is_enabled {
SimpleMenuItem {
id: CONTEXT_ITEM_DISABLE,
label: "Disable".to_string(),
}
} else {
SimpleMenuItem {
id: CONTEXT_ITEM_ENABLE,
label: "Enable".to_string(),
}
}),
MenuItem::Separator,
MenuItem::Simple(SimpleMenuItem { MenuItem::Simple(SimpleMenuItem {
id: CONTEXT_ITEM_RELOAD, id: CONTEXT_ITEM_RELOAD,
label: "Reload config".to_string(), label: "Reload config".to_string(),
@ -76,12 +98,28 @@ impl Middleware for ContextMenuMiddleware {
event.source_id, event.source_id,
EventType::ExitRequested(ExitMode::RestartWorker), EventType::ExitRequested(ExitMode::RestartWorker),
), ),
CONTEXT_ITEM_ENABLE => {
dispatch(Event::caused_by(event.source_id, EventType::EnableRequest));
Event::caused_by(event.source_id, EventType::NOOP)
}
CONTEXT_ITEM_DISABLE => {
dispatch(Event::caused_by(event.source_id, EventType::DisableRequest));
Event::caused_by(event.source_id, EventType::NOOP)
}
custom => { custom => {
// TODO: handle dynamic items // TODO: handle dynamic items
todo!() todo!()
} }
} }
} }
EventType::Disabled => {
*is_enabled = false;
event
}
EventType::Enabled => {
*is_enabled = true;
event
}
_ => event, _ => event,
} }
} }

View File

@ -22,16 +22,18 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use log::{info}; use log::info;
use super::super::Middleware; use super::super::Middleware;
use crate::engine::{event::{Event, EventType, input::{Key, KeyboardEvent, Status, Variant}}}; use crate::engine::event::{
input::{Key, KeyboardEvent, Status, Variant},
Event, EventType,
};
pub struct DisableOptions { pub struct DisableOptions {
pub toggle_key: Option<Key>, pub toggle_key: Option<Key>,
pub toggle_key_variant: Option<Variant>, pub toggle_key_variant: Option<Variant>,
pub toggle_key_maximum_window: Duration, pub toggle_key_maximum_window: Duration,
// TODO: toggle shortcut? // TODO: toggle shortcut?
} }
@ -60,21 +62,32 @@ impl Middleware for DisableMiddleware {
let mut has_status_changed = false; let mut has_status_changed = false;
let mut enabled = self.enabled.borrow_mut(); let mut enabled = self.enabled.borrow_mut();
if let EventType::Keyboard(m_event) = &event.etype { match &event.etype {
if is_toggle_key(m_event, &self.options) { EventType::Keyboard(m_event) => {
let mut last_toggle_press = self.last_toggle_press.borrow_mut(); if is_toggle_key(m_event, &self.options) {
if let Some(previous_press) = *last_toggle_press { let mut last_toggle_press = self.last_toggle_press.borrow_mut();
if previous_press.elapsed() < self.options.toggle_key_maximum_window { if let Some(previous_press) = *last_toggle_press {
*enabled = !*enabled; if previous_press.elapsed() < self.options.toggle_key_maximum_window {
*last_toggle_press = None; *enabled = !*enabled;
has_status_changed = true; *last_toggle_press = None;
has_status_changed = true;
} else {
*last_toggle_press = Some(Instant::now());
}
} else { } else {
*last_toggle_press = Some(Instant::now()); *last_toggle_press = Some(Instant::now());
} }
} else {
*last_toggle_press = Some(Instant::now());
} }
},
EventType::EnableRequest => {
*enabled = true;
has_status_changed = true;
},
EventType::DisableRequest => {
*enabled = false;
has_status_changed = true;
} }
_ => {}
} }
if has_status_changed { if has_status_changed {