leftwm_core/models/
scratchpad.rs

1use crate::models::Size;
2use serde::{Deserialize, Serialize};
3
4use super::{Xyhw, XyhwBuilder};
5
6#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
7pub struct ScratchPad {
8    pub name: ScratchPadName,
9    pub args: Option<Vec<String>>,
10    pub value: String,
11    // relative x of scratchpad, 25 means 25% of workspace x
12    pub x: Option<Size>,
13    // relative y of scratchpad, 25 means 25% of workspace y
14    pub y: Option<Size>,
15    // relative height of scratchpad, 50 means 50% of workspace height
16    pub height: Option<Size>,
17    // relative width of scratchpad, 50 means 50% of workspace width
18    pub width: Option<Size>,
19}
20
21impl ScratchPad {
22    // Get size and position of scratchpad from config and workspace size.
23    pub fn xyhw(&self, xyhw: &Xyhw) -> Xyhw {
24        let x_sane = sane_dimension(self.x, 0.25, xyhw.w());
25        let y_sane = sane_dimension(self.y, 0.25, xyhw.h());
26        let height_sane = sane_dimension(self.height, 0.50, xyhw.h());
27        let width_sane = sane_dimension(self.width, 0.50, xyhw.w());
28
29        XyhwBuilder {
30            x: xyhw.x() + x_sane,
31            y: xyhw.y() + y_sane,
32            h: height_sane,
33            w: width_sane,
34            ..XyhwBuilder::default()
35        }
36        .into()
37    }
38}
39
40/// Newtype used as the name for a scratchpad, can be seen as some sort of symbol in languages like
41/// Lisp/Scheme/...
42#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
43#[serde(from = "String")]
44#[serde(into = "String")]
45pub struct ScratchPadName(String);
46
47impl From<String> for ScratchPadName {
48    fn from(other: String) -> Self {
49        Self(other)
50    }
51}
52
53impl From<ScratchPadName> for String {
54    fn from(other: ScratchPadName) -> Self {
55        other.0
56    }
57}
58
59impl From<&str> for ScratchPadName {
60    fn from(other: &str) -> Self {
61        Self(other.to_string())
62    }
63}
64
65impl PartialEq<&str> for ScratchPadName {
66    fn eq(&self, other: &&str) -> bool {
67        &self.0.as_str() == other
68    }
69}
70
71fn sane_dimension(config_value: Option<Size>, default_ratio: f32, max_pixel: i32) -> i32 {
72    match config_value {
73        Some(size @ Size::Ratio(r)) if (0.0..=1.0).contains(&r) => size.into_absolute(max_pixel),
74        Some(Size::Pixel(pixel)) if (0..=max_pixel).contains(&pixel) => pixel,
75        _ => Size::Ratio(default_ratio).into_absolute(max_pixel),
76    }
77}