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}