slightly clean up widget_definitions.rs

This commit is contained in:
elkowar 2021-06-23 11:00:40 +02:00
parent 9e81c7d221
commit 10d3d9375f
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
2 changed files with 57 additions and 36 deletions

View file

@ -50,6 +50,48 @@ macro_rules! loop_select {
} }
} }
/// Parse a string with a concrete set of options into some data-structure,
/// and return a nicely formatted error message on invalid values. I.e.:
/// ```rs
/// let input = "up";
/// enum_parse { "direction", input,
/// "up" => Direction::Up,
/// "down" => Direction::Down,
/// }
/// ```
#[macro_export]
macro_rules! enum_parse {
($name:literal, $input:expr, $($($s:literal)|* => $val:expr),* $(,)?) => {
let input = $input;
match input {
$( $( $s )|* => Ok($val) ),*,
_ => Err(anyhow!(concat!("Couldn't parse ", $name, ": '{}'. Possible values are ", $($($s),*),*), input))
}
};
}
/// Compute the difference of two lists, returning a tuple of
/// (
/// elements that where in a but not in b,
/// elements that where in b but not in a
/// ).
pub fn list_difference<'a, 'b, T: PartialEq>(a: &'a [T], b: &'b [T]) -> (Vec<&'a T>, Vec<&'b T>) {
let mut missing = Vec::new();
for elem in a {
if !b.contains(elem) {
missing.push(elem);
}
}
let mut new = Vec::new();
for elem in b {
if !a.contains(elem) {
new.push(elem);
}
}
(missing, new)
}
/// Joins two paths while keeping it somewhat pretty. /// Joins two paths while keeping it somewhat pretty.
/// If the second path is absolute, this will just return the second path. /// If the second path is absolute, this will just return the second path.
/// If it is relative, it will return the second path joined onto the first path, removing any `./` if present. /// If it is relative, it will return the second path joined onto the first path, removing any `./` if present.
@ -112,7 +154,6 @@ pub fn parse_duration(s: &str) -> Result<std::time::Duration> {
} }
} }
pub trait IterAverage { pub trait IterAverage {
fn avg(self) -> f32; fn avg(self) -> f32;
} }

View file

@ -1,6 +1,11 @@
#![allow(clippy::option_map_unit_fn)] #![allow(clippy::option_map_unit_fn)]
use super::{run_command, BuilderArgs}; use super::{run_command, BuilderArgs};
use crate::{config, eww_state, resolve_block, value::AttrVal, widgets::widget_node, util::parse_duration}; use crate::{
config, enum_parse, eww_state, resolve_block,
util::{list_difference, parse_duration},
value::AttrVal,
widgets::widget_node,
};
use anyhow::*; use anyhow::*;
use gdk::WindowExt; use gdk::WindowExt;
use glib; use glib;
@ -275,11 +280,11 @@ fn build_gtk_revealer(bargs: &mut BuilderArgs) -> Result<gtk::Revealer> {
let gtk_widget = gtk::Revealer::new(); let gtk_widget = gtk::Revealer::new();
resolve_block!(bargs, gtk_widget, { resolve_block!(bargs, gtk_widget, {
// @prop transition - the name of the transition. Possible values: $transition // @prop transition - the name of the transition. Possible values: $transition
prop(transition: as_string) { gtk_widget.set_transition_type(parse_transition(&transition)?); }, prop(transition: as_string = "crossfade") { gtk_widget.set_transition_type(parse_transition(&transition)?); },
// @prop reveal - sets if the child is revealed or not // @prop reveal - sets if the child is revealed or not
prop(reveal: as_bool) { gtk_widget.set_reveal_child(reveal); }, prop(reveal: as_bool) { gtk_widget.set_reveal_child(reveal); },
// @prop duration - the duration of the reveal transition // @prop duration - the duration of the reveal transition
prop(duration: as_string) { gtk_widget.set_transition_duration(parse_duration(&duration)?.as_millis() as u32); }, prop(duration: as_string = "500ms") { gtk_widget.set_transition_duration(parse_duration(&duration)?.as_millis() as u32); },
}); });
Ok(gtk_widget) Ok(gtk_widget)
} }
@ -568,36 +573,33 @@ fn build_gtk_calendar(bargs: &mut BuilderArgs) -> Result<gtk::Calendar> {
/// @var orientation - "vertical", "v", "horizontal", "h" /// @var orientation - "vertical", "v", "horizontal", "h"
fn parse_orientation(o: &str) -> Result<gtk::Orientation> { fn parse_orientation(o: &str) -> Result<gtk::Orientation> {
Ok(match o { enum_parse! { "orientation", o,
"vertical" | "v" => gtk::Orientation::Vertical, "vertical" | "v" => gtk::Orientation::Vertical,
"horizontal" | "h" => gtk::Orientation::Horizontal, "horizontal" | "h" => gtk::Orientation::Horizontal,
_ => bail!(r#"Couldn't parse orientation: '{}'. Possible values are "vertical", "v", "horizontal", "h""#, o), }
})
} }
/// @var transition - "slideright", "slideleft", "slideup", "slidedown", "crossfade", "none" /// @var transition - "slideright", "slideleft", "slideup", "slidedown", "crossfade", "none"
fn parse_transition(t: &str) -> Result<gtk::RevealerTransitionType> { fn parse_transition(t: &str) -> Result<gtk::RevealerTransitionType> {
Ok(match t { enum_parse! { "transition", t,
"slideright" => gtk::RevealerTransitionType::SlideRight, "slideright" => gtk::RevealerTransitionType::SlideRight,
"slideleft" => gtk::RevealerTransitionType::SlideLeft, "slideleft" => gtk::RevealerTransitionType::SlideLeft,
"slideup" => gtk::RevealerTransitionType::SlideUp, "slideup" => gtk::RevealerTransitionType::SlideUp,
"slidedown" => gtk::RevealerTransitionType::SlideDown, "slidedown" => gtk::RevealerTransitionType::SlideDown,
"crossfade" => gtk::RevealerTransitionType::Crossfade, "fade" | "crossfade" => gtk::RevealerTransitionType::Crossfade,
"none" => gtk::RevealerTransitionType::None, "none" => gtk::RevealerTransitionType::None,
_ => bail!(r#"Couldn't parse transition: '{}'. Possible values are "slideright", "slideleft", "slideup", "slidedown", "crossfade" and "none" "#, t), }
})
} }
/// @var alignment - "fill", "baseline", "center", "start", "end" /// @var alignment - "fill", "baseline", "center", "start", "end"
fn parse_align(o: &str) -> Result<gtk::Align> { fn parse_align(o: &str) -> Result<gtk::Align> {
Ok(match o { enum_parse! { "alignment", o,
"fill" => gtk::Align::Fill, "fill" => gtk::Align::Fill,
"baseline" => gtk::Align::Baseline, "baseline" => gtk::Align::Baseline,
"center" => gtk::Align::Center, "center" => gtk::Align::Center,
"start" => gtk::Align::Start, "start" => gtk::Align::Start,
"end" => gtk::Align::End, "end" => gtk::Align::End,
_ => bail!(r#"Couldn't parse alignment: '{}'. Possible values are "fill", "baseline", "center", "start", "end""#, o), }
})
} }
fn connect_first_map<W: IsA<gtk::Widget>, F: Fn(&W) + 'static>(widget: &W, func: F) { fn connect_first_map<W: IsA<gtk::Widget>, F: Fn(&W) + 'static>(widget: &W, func: F) {
@ -610,25 +612,3 @@ fn connect_first_map<W: IsA<gtk::Widget>, F: Fn(&W) + 'static>(widget: &W, func:
} }
}); });
} }
/// Compute the difference of two lists, returning a tuple of
/// (
/// elements that where in a but not in b,
/// elements that where in b but not in a
/// ).
fn list_difference<'a, 'b, T: PartialEq>(a: &'a [T], b: &'b [T]) -> (Vec<&'a T>, Vec<&'b T>) {
let mut missing = Vec::new();
for elem in a {
if !b.contains(elem) {
missing.push(elem);
}
}
let mut new = Vec::new();
for elem in b {
if !a.contains(elem) {
new.push(elem);
}
}
(missing, new)
}