From ffd4a2d5a592b3339ddd684efcdad33504c9b001 Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Sun, 11 Oct 2020 20:30:53 +0200 Subject: [PATCH] Correctly implement image sizing (although ugly) --- src/eww_state.rs | 27 ++++++++++++++++++++++ src/widgets/widget_definitions.rs | 37 +++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/eww_state.rs b/src/eww_state.rs index 76f87ab..1263746 100644 --- a/src/eww_state.rs +++ b/src/eww_state.rs @@ -109,7 +109,34 @@ impl EwwState { Ok(()) } + /// resolves a value if possible, using the current eww_state + /// Expects there to be at max one level of nesting var_refs from local-env. + /// This means that no elements in the local_env may be var-refs into the local_env again, but only into the global state. + pub fn resolve_once<'a>( + &'a self, + local_env: &'a HashMap, + value: &'a AttrValue, + ) -> Result<&'a PrimitiveValue> { + match value { + AttrValue::Concrete(primitive) => Ok(&primitive), + AttrValue::VarRef(var_name) => match local_env.get(var_name) { + // look up if variables are found in the local env, and resolve as far as possible + Some(AttrValue::Concrete(primitive)) => Ok(primitive), + Some(AttrValue::VarRef(var_name)) => self + .variables_state + .get(var_name) + .ok_or_else(|| anyhow!("Unknown variable '{}' referenced", var_name)), + None => self + .variables_state + .get(var_name) + .ok_or_else(|| anyhow!("Unknown variable '{}' referenced", var_name)), + }, + } + } + /// Resolve takes a function that applies a set of fully resolved attribute values to it's gtk widget. + /// Expects there to be at max one level of nesting var_refs from local-env. + /// This means that no elements in the local_env may be var-refs into the local_env again, but only into the global state. pub fn resolve) -> Result<()> + 'static + Clone>( &mut self, window_name: &WindowName, diff --git a/src/widgets/widget_definitions.rs b/src/widgets/widget_definitions.rs index 2c0efa8..58e9d2b 100644 --- a/src/widgets/widget_definitions.rs +++ b/src/widgets/widget_definitions.rs @@ -9,6 +9,8 @@ use gtk::ImageExt; use maplit::hashmap; use std::path::Path; +use gdk_pixbuf; + // TODO figure out how to // TODO https://developer.gnome.org/gtk3/stable/GtkFixed.html @@ -32,6 +34,21 @@ pub(super) fn widget_to_gtk_widget(bargs: &mut BuilderArgs) -> Result Result { fn build_gtk_image(bargs: &mut BuilderArgs) -> Result { let gtk_widget = gtk::Image::new(); resolve_block!(bargs, gtk_widget, { - prop(path: as_string) { gtk_widget.set_from_file(Path::new(&path)); } + prop(path: as_string) { + gtk_widget.set_from_file(Path::new(&path)); + }, + prop(path: as_string, width: as_f64, height: as_f64) { + let pixbuf = gdk_pixbuf::Pixbuf::from_file_at_size(std::path::PathBuf::from(path), width as i32, height as i32)?; + gtk_widget.set_from_pixbuf(Some(&pixbuf)); + } }); Ok(gtk_widget) } @@ -194,3 +217,13 @@ fn parse_align(o: &str) -> Result { _ => bail!("Couldn't parse alignment: '{}'", o), }) } + +fn connect_first_map, F: Fn(&W) + 'static>(widget: &W, func: F) { + // TODO it would be better to actually remove the connect_map after first map, but that would be highly annoying to implement... + let is_first_map = std::rc::Rc::new(std::cell::RefCell::new(true)); + widget.connect_map(move |w| { + if is_first_map.replace(false) { + func(&w); + } + }); +}