lazybar_core/
highlight.rs

1use anyhow::Result;
2use csscolorparser::Color;
3
4use crate::{parser, remove_color_from_config, remove_float_from_config};
5
6/// Describes a bar to be drawn below a workspace name
7#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
8pub struct Highlight {
9    /// the height in pixels of the top highlight
10    pub overline_height: f64,
11    /// the color of the top highlight
12    pub overline_color: Color,
13    /// the height in pixels of the bottom highlight
14    pub underline_height: f64,
15    /// the color of the bottom highlight
16    pub underline_color: Color,
17}
18
19impl Highlight {
20    /// Creates an empty instance (height set to `0.0`, color set to black).
21    ///
22    /// This creates the same [`Highlight`] as [`Highlight::default`], but this
23    /// is a const function.
24    #[must_use]
25    pub const fn empty() -> Self {
26        Self {
27            overline_height: 0.0,
28            overline_color: Color::new(0.0, 0.0, 0.0, 1.0),
29            underline_height: 0.0,
30            underline_color: Color::new(0.0, 0.0, 0.0, 1.0),
31        }
32    }
33
34    /// Creates a new instance.
35    #[must_use]
36    pub const fn new(
37        overline_height: f64,
38        overline_color: Color,
39        underline_height: f64,
40        underline_color: Color,
41    ) -> Self {
42        Self {
43            overline_height,
44            overline_color,
45            underline_height,
46            underline_color,
47        }
48    }
49
50    /// Draws the {over,under}lines associated with this highlight.
51    ///
52    /// The current point of `cr` should have the same x coordinate as the left
53    /// edge of the expected rectangles.
54    pub fn draw(
55        &self,
56        cr: &cairo::Context,
57        bar_height: f64,
58        width: f64,
59    ) -> Result<()> {
60        cr.save()?;
61
62        if self.overline_height > 0.0 {
63            cr.rectangle(0.0, 0.0, width, self.overline_height);
64            cr.set_source_rgba(
65                self.overline_color.r.into(),
66                self.overline_color.g.into(),
67                self.overline_color.b.into(),
68                self.overline_color.a.into(),
69            );
70            cr.fill()?;
71        }
72
73        if self.underline_height > 0.0 {
74            cr.rectangle(
75                0.0,
76                bar_height - self.underline_height,
77                width,
78                self.underline_height,
79            );
80            cr.set_source_rgba(
81                self.underline_color.r.into(),
82                self.underline_color.g.into(),
83                self.underline_color.b.into(),
84                self.underline_color.a.into(),
85            );
86            cr.fill()?;
87        }
88
89        cr.restore()?;
90
91        Ok(())
92    }
93
94    /// Parses a new instance from a subset of the global
95    /// [`Config`][config::Config]
96    ///
97    /// Configuration options:
98    ///
99    /// - `{over,under}line_height`: the height in pixels of the highlight
100    ///   - type: f64
101    ///   - default: none
102    /// - `{over,under}line_color`: the color of the highlight
103    ///   - type: String
104    ///   - default: none
105    pub fn parse(name: impl AsRef<str>) -> Option<Self> {
106        let highlights_table = parser::HIGHLIGHTS.get().unwrap();
107        let mut highlight_table = highlights_table
108            .get(name.as_ref())?
109            .clone()
110            .into_table()
111            .ok()?;
112
113        let overline_height =
114            remove_float_from_config("overline_height", &mut highlight_table)
115                .unwrap_or(0.0);
116
117        let overline_color =
118            remove_color_from_config("overline_color", &mut highlight_table)
119                .unwrap_or(Color {
120                    r: 0.0,
121                    g: 0.0,
122                    b: 0.0,
123                    a: 0.0,
124                });
125
126        let underline_height =
127            remove_float_from_config("underline_height", &mut highlight_table)
128                .unwrap_or(0.0);
129
130        let underline_color =
131            remove_color_from_config("underline_color", &mut highlight_table)
132                .unwrap_or(Color {
133                    r: 0.0,
134                    g: 0.0,
135                    b: 0.0,
136                    a: 0.0,
137                });
138
139        Some(Self {
140            overline_height,
141            overline_color,
142            underline_height,
143            underline_color,
144        })
145    }
146}