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