From 27d11de6616c410422d7abd579d09b3abc02f43a Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Fri, 21 Apr 2023 23:51:29 +0100 Subject: [PATCH] refactor(config): split common code into separate file --- src/config/common.rs | 121 +++++++++++++++++++++++++++++++++++++++++++ src/config/mod.rs | 18 +------ 2 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 src/config/common.rs diff --git a/src/config/common.rs b/src/config/common.rs new file mode 100644 index 0000000..eb65c2d --- /dev/null +++ b/src/config/common.rs @@ -0,0 +1,121 @@ +use crate::dynamic_string::DynamicString; +use crate::script::{Script, ScriptInput}; +use crate::send; +use gtk::gdk::ScrollDirection; +use gtk::prelude::*; +use gtk::EventBox; +use serde::Deserialize; +use tokio::spawn; +use tracing::trace; + +/// Common configuration options +/// which can be set on every module. +#[derive(Debug, Deserialize, Clone)] +pub struct CommonConfig { + pub show_if: Option, + + pub on_click_left: Option, + pub on_click_right: Option, + pub on_click_middle: Option, + pub on_scroll_up: Option, + pub on_scroll_down: Option, + pub on_mouse_enter: Option, + pub on_mouse_exit: Option, + + pub tooltip: Option, +} + +impl CommonConfig { + /// Configures the module's container according to the common config options. + pub fn install(mut self, container: &EventBox) { + self.install_show_if(container); + + let left_click_script = self.on_click_left.map(Script::new_polling); + let middle_click_script = self.on_click_middle.map(Script::new_polling); + let right_click_script = self.on_click_right.map(Script::new_polling); + + container.connect_button_press_event(move |_, event| { + let script = match event.button() { + 1 => left_click_script.as_ref(), + 2 => middle_click_script.as_ref(), + 3 => right_click_script.as_ref(), + _ => None, + }; + + if let Some(script) = script { + trace!("Running on-click script: {}", event.button()); + script.run_as_oneshot(None); + } + + Inhibit(false) + }); + + let scroll_up_script = self.on_scroll_up.map(Script::new_polling); + let scroll_down_script = self.on_scroll_down.map(Script::new_polling); + + container.connect_scroll_event(move |_, event| { + let script = match event.direction() { + ScrollDirection::Up => scroll_up_script.as_ref(), + ScrollDirection::Down => scroll_down_script.as_ref(), + _ => None, + }; + + if let Some(script) = script { + trace!("Running on-scroll script: {}", event.direction()); + script.run_as_oneshot(None); + } + + Inhibit(false) + }); + + macro_rules! install_oneshot { + ($option:expr, $method:ident) => { + $option.map(Script::new_polling).map(|script| { + container.$method(move |_, _| { + script.run_as_oneshot(None); + Inhibit(false) + }); + }) + }; + } + + install_oneshot!(self.on_mouse_enter, connect_enter_notify_event); + install_oneshot!(self.on_mouse_exit, connect_leave_notify_event); + + if let Some(tooltip) = self.tooltip { + let container = container.clone(); + DynamicString::new(&tooltip, move |string| { + container.set_tooltip_text(Some(&string)); + Continue(true) + }); + } + } + + fn install_show_if(&mut self, container: &EventBox) { + self.show_if.take().map_or_else( + || { + container.show_all(); + }, + |show_if| { + let script = Script::new_polling(show_if); + let container = container.clone(); + let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); + spawn(async move { + script + .run(None, |_, success| { + send!(tx, success); + }) + .await; + }); + rx.attach(None, move |success| { + if success { + container.show_all(); + } else { + container.hide(); + }; + Continue(true) + }); + }, + ); + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 23b35ce..a55570d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,3 +1,4 @@ +mod common; mod r#impl; mod truncate; @@ -18,27 +19,12 @@ use crate::modules::sysinfo::SysInfoModule; use crate::modules::tray::TrayModule; #[cfg(feature = "workspaces")] use crate::modules::workspaces::WorkspacesModule; -use crate::script::ScriptInput; use serde::Deserialize; use std::collections::HashMap; +pub use self::common::CommonConfig; pub use self::truncate::{EllipsizeMode, TruncateMode}; -#[derive(Debug, Deserialize, Clone)] -pub struct CommonConfig { - pub show_if: Option, - - pub on_click_left: Option, - pub on_click_right: Option, - pub on_click_middle: Option, - pub on_scroll_up: Option, - pub on_scroll_down: Option, - pub on_mouse_enter: Option, - pub on_mouse_exit: Option, - - pub tooltip: Option, -} - #[derive(Debug, Deserialize, Clone)] #[serde(tag = "type", rename_all = "snake_case")] pub enum ModuleConfig {