lazybar_core/
actions.rs

1use std::collections::HashMap;
2
3use anyhow::Result;
4use config::Value;
5use derive_builder::Builder;
6
7#[cfg(feature = "cursor")]
8use crate::bar::Cursor;
9use crate::remove_string_from_config;
10
11/// A map from mouse buttons to panel events
12#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Builder)]
13pub struct Actions {
14    /// The event that should be run when the panel is left-clicked
15    #[builder(default, setter(strip_option))]
16    pub left: Option<String>,
17    /// The event that should be run when the panel is right-clicked
18    #[builder(default, setter(strip_option))]
19    pub right: Option<String>,
20    /// The event that should be run when the panel is middle-clicked
21    #[builder(default, setter(strip_option))]
22    pub middle: Option<String>,
23    /// The event that should be run when the panel is scrolled up
24    #[builder(default, setter(strip_option))]
25    pub up: Option<String>,
26    /// The event that should be run when the panel is scrolled down
27    #[builder(default, setter(strip_option))]
28    pub down: Option<String>,
29}
30
31impl Actions {
32    /// Attempts to parse an instance of this type from a subset of tthe global
33    /// [`Config`][config::Config].
34    ///
35    /// Configuration options:
36    /// - `click_left`: The name of the event to run when the panel is
37    ///   left-clicked.
38    /// - `click_right`: The name of the event to run when the panel is
39    ///   right-clicked.
40    /// - `click_middle`: The name of the event to run when the panel is
41    ///   middle-clicked.
42    /// - `scroll_up`: The name of the event to run when the panel is scrolled
43    ///   up.
44    /// - `scroll_down`: The name of the event to run when the panel is scrolled
45    ///   down.
46    pub fn parse<S: std::hash::BuildHasher>(
47        table: &mut HashMap<String, Value, S>,
48    ) -> Result<Self> {
49        let mut builder = ActionsBuilder::default();
50
51        if let Some(left) = remove_string_from_config("click_left", table) {
52            builder.left(left);
53        }
54        if let Some(right) = remove_string_from_config("click_right", table) {
55            builder.right(right);
56        }
57        if let Some(middle) = remove_string_from_config("click_middle", table) {
58            builder.middle(middle);
59        }
60        if let Some(up) = remove_string_from_config("scroll_up", table) {
61            builder.up(up);
62        }
63        if let Some(down) = remove_string_from_config("scroll_down", table) {
64            builder.down(down);
65        }
66
67        Ok(builder.build()?)
68    }
69
70    /// Chooses a reasonable cursor based on the possible actions.
71    ///
72    /// - If the panel is scrollable, a cursor indicating that will be chosen.
73    /// - Otherwise, if the panel is clickable, a cursor indicating that will be
74    ///   chosen.
75    /// - Otherwise, the cursor will be set to the system default.
76    #[cfg(feature = "cursor")]
77    pub fn get_cursor(&self) -> Cursor {
78        if self.up.as_ref().or(self.down.as_ref()).is_some() {
79            Cursor::Scroll
80        } else if self
81            .left
82            .as_ref()
83            .or(self.middle.as_ref())
84            .or(self.right.as_ref())
85            .is_some()
86        {
87            Cursor::Click
88        } else {
89            Cursor::Default
90        }
91    }
92}