Most stuff works
This commit is contained in:
parent
1f86c72ef6
commit
2df0984ac3
5 changed files with 182 additions and 133 deletions
|
@ -26,7 +26,7 @@ pub struct App {
|
|||
impl App {
|
||||
pub fn handle_user_command(&mut self, opts: &Opt) -> Result<()> {
|
||||
match &opts.action {
|
||||
OptAction::Update { fieldname, value } => self.update_state(fieldname.clone(), value.clone()),
|
||||
OptAction::Update { fieldname, value } => self.update_state(fieldname.clone(), value.clone())?,
|
||||
OptAction::OpenWindow { window_name } => self.open_window(&window_name)?,
|
||||
OptAction::CloseWindow { window_name } => self.close_window(&window_name)?,
|
||||
OptAction::KillServer => {
|
||||
|
@ -43,7 +43,7 @@ impl App {
|
|||
let result: Result<_> = try {
|
||||
match event {
|
||||
EwwEvent::UserCommand(command) => self.handle_user_command(&command)?,
|
||||
EwwEvent::UpdateVar(key, value) => self.update_state(key, value),
|
||||
EwwEvent::UpdateVar(key, value) => self.update_state(key, value)?,
|
||||
EwwEvent::ReloadConfig(config) => self.reload_all_windows(config)?,
|
||||
EwwEvent::ReloadCss(css) => self.load_css(&css)?,
|
||||
}
|
||||
|
@ -53,8 +53,8 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_state(&mut self, fieldname: VarName, value: PrimitiveValue) {
|
||||
self.eww_state.update_value(fieldname, value);
|
||||
fn update_state(&mut self, fieldname: VarName, value: PrimitiveValue) -> Result<()> {
|
||||
self.eww_state.update_value(fieldname, value)
|
||||
}
|
||||
|
||||
fn close_window(&mut self, window_name: &str) -> Result<()> {
|
||||
|
|
178
src/eww_state.rs
178
src/eww_state.rs
|
@ -7,24 +7,56 @@ use std::sync::Arc;
|
|||
use crate::value::{AttrValue, PrimitiveValue};
|
||||
|
||||
//pub struct StateChangeHandler(Box<dyn Fn(HashMap<String, PrimitiveValue>) + 'static>);
|
||||
pub struct StateChangeHandler {
|
||||
func: Box<dyn Fn(HashMap<String, PrimitiveValue>) -> Result<()> + 'static>,
|
||||
constant_values: HashMap<String, PrimitiveValue>,
|
||||
unresolved_attrs: HashMap<String, VarName>,
|
||||
}
|
||||
|
||||
impl StateChangeHandler {
|
||||
fn run_with_state(&self, state: &HashMap<VarName, PrimitiveValue>) -> Result<()> {
|
||||
let mut all_resolved_attrs = self.constant_values.clone();
|
||||
for (attr_name, var_ref) in self.unresolved_attrs.iter() {
|
||||
let resolved = state
|
||||
.get(var_ref)
|
||||
// TODO provide context here, including line numbers
|
||||
.with_context(|| format!("Unknown variable '{}' was referenced", var_ref))?;
|
||||
all_resolved_attrs.insert(attr_name.to_owned(), resolved.clone());
|
||||
}
|
||||
|
||||
let result: Result<_> = (self.func)(all_resolved_attrs);
|
||||
if let Err(err) = result {
|
||||
eprintln!("WARN: Error while resolving attributes: {}", err);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StateChangeHandlers {
|
||||
handlers: HashMap<VarName, Vec<Arc<dyn Fn(HashMap<String, PrimitiveValue>) + 'static>>>,
|
||||
handlers: HashMap<VarName, Vec<Arc<StateChangeHandler>>>,
|
||||
}
|
||||
|
||||
impl StateChangeHandlers {
|
||||
fn put_handler(&mut self, var_names: Vec<VarName>, handler: Arc<dyn Fn(HashMap<String, PrimitiveValue>) + 'static>) {
|
||||
for var_name in var_names {
|
||||
let entry: &mut Vec<Arc<dyn Fn(HashMap<String, PrimitiveValue>) + 'static>> =
|
||||
self.handlers.entry(var_name).or_insert_with(Vec::new);
|
||||
entry.push(handler);
|
||||
fn put_handler(&mut self, handler: StateChangeHandler) {
|
||||
let handler = Arc::new(handler);
|
||||
for var_name in handler.unresolved_attrs.values() {
|
||||
let entry: &mut Vec<Arc<StateChangeHandler>> = self.handlers.entry(var_name.clone()).or_insert_with(Vec::new);
|
||||
entry.push(handler.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn get(&self, key: &VarName) -> Option<&Vec<Arc<StateChangeHandler>>> {
|
||||
self.handlers.get(key)
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.handlers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EwwState {
|
||||
state_change_handlers: StateChangeHandlers,
|
||||
//on_change_handlers: HashMap<VarName, Vec<StateChangeHandler>>,
|
||||
state: HashMap<VarName, PrimitiveValue>,
|
||||
}
|
||||
|
||||
|
@ -54,97 +86,65 @@ impl EwwState {
|
|||
}
|
||||
|
||||
pub fn clear_callbacks(&mut self) {
|
||||
self.on_change_handlers.clear();
|
||||
self.state_change_handlers.clear();
|
||||
}
|
||||
|
||||
pub fn update_value(&mut self, key: VarName, value: PrimitiveValue) {
|
||||
if let Some(handlers) = self.on_change_handlers.get(&key) {
|
||||
for on_change in handlers {
|
||||
on_change(value.clone());
|
||||
pub fn update_value(&mut self, key: VarName, value: PrimitiveValue) -> Result<()> {
|
||||
if let Some(handlers) = self.state_change_handlers.get(&key) {
|
||||
self.state.insert(key.clone(), value);
|
||||
for handler in handlers {
|
||||
handler
|
||||
.run_with_state(&self.state)
|
||||
.with_context(|| format!("When updating value of {}", &key))?;
|
||||
}
|
||||
}
|
||||
self.state.insert(key, value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn resolve<F: Fn(PrimitiveValue) + 'static + Clone>(
|
||||
pub fn resolve<F: Fn(HashMap<String, PrimitiveValue>) -> Result<()> + 'static + Clone>(
|
||||
&mut self,
|
||||
local_env: &HashMap<VarName, AttrValue>,
|
||||
value: &AttrValue,
|
||||
mut needed_attributes: HashMap<String, AttrValue>,
|
||||
set_value: F,
|
||||
) -> bool {
|
||||
match value {
|
||||
AttrValue::VarRef(name) => {
|
||||
// get value from globals
|
||||
if let Some(value) = self.state.get(&name).cloned() {
|
||||
self.on_change_handlers
|
||||
.entry(name.clone())
|
||||
.or_insert_with(Vec::new)
|
||||
.push(Box::new(set_value.clone()));
|
||||
self.resolve(local_env, &value.into(), set_value)
|
||||
} else if let Some(value) = local_env.get(&name).cloned() {
|
||||
// get value from local
|
||||
self.resolve(local_env, &value, set_value)
|
||||
} else {
|
||||
eprintln!("WARN: unknown variable '{}' was referenced", name);
|
||||
false
|
||||
) {
|
||||
let mut resolved_attrs = HashMap::new();
|
||||
let mut unresolved_attrs: HashMap<String, VarName> = HashMap::new();
|
||||
needed_attributes
|
||||
.drain()
|
||||
.for_each(|(attr_name, attr_value)| match attr_value {
|
||||
AttrValue::Concrete(primitive) => {
|
||||
resolved_attrs.insert(attr_name, primitive);
|
||||
}
|
||||
AttrValue::VarRef(var_name) => match local_env.get(&var_name) {
|
||||
Some(AttrValue::VarRef(var_ref_from_local)) => {
|
||||
unresolved_attrs.insert(attr_name, var_ref_from_local.clone());
|
||||
}
|
||||
Some(AttrValue::Concrete(concrete_from_local)) => {
|
||||
resolved_attrs.insert(attr_name, concrete_from_local.clone());
|
||||
}
|
||||
None => {
|
||||
unresolved_attrs.insert(attr_name, var_name);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
let result: Result<_> = try {
|
||||
if unresolved_attrs.is_empty() {
|
||||
set_value(resolved_attrs)?;
|
||||
} else {
|
||||
let handler = StateChangeHandler {
|
||||
func: Box::new(set_value.clone()),
|
||||
constant_values: resolved_attrs,
|
||||
unresolved_attrs,
|
||||
};
|
||||
handler.run_with_state(&self.state)?;
|
||||
self.state_change_handlers.put_handler(handler);
|
||||
}
|
||||
AttrValue::Concrete(value) => {
|
||||
set_value(value.clone());
|
||||
true
|
||||
}
|
||||
};
|
||||
if let Err(e) = result {
|
||||
eprintln!("{}", e);
|
||||
}
|
||||
}
|
||||
|
||||
//pub fn resolve_attrs<F: Fn(HashMap<String, PrimitiveValue>) + 'static + Clone>(
|
||||
//&mut self,
|
||||
//local_env: &HashMap<VarName, AttrValue>,
|
||||
//unresolved_attrs: HashMap<String, AttrValue>,
|
||||
//state_update_handler: F,
|
||||
//) {
|
||||
//let var_names = values.iter().filter_map(|value| value.as_var_ref().ok()).collect();
|
||||
//self.state_change_handlers
|
||||
//.put_handler(var_names, Arc::new(state_update_handler))
|
||||
//}
|
||||
|
||||
pub fn resolve_f64<F: Fn(f64) + 'static + Clone>(
|
||||
&mut self,
|
||||
local_env: &HashMap<VarName, AttrValue>,
|
||||
value: &AttrValue,
|
||||
set_value: F,
|
||||
) -> bool {
|
||||
self.resolve(local_env, value, move |x| {
|
||||
if let Err(e) = x.as_f64().map(|v| set_value(v)) {
|
||||
eprintln!("error while resolving value: {}", e);
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn resolve_bool<F: Fn(bool) + 'static + Clone>(
|
||||
&mut self,
|
||||
local_env: &HashMap<VarName, AttrValue>,
|
||||
value: &AttrValue,
|
||||
set_value: F,
|
||||
) -> bool {
|
||||
self.resolve(local_env, value, move |x| {
|
||||
if let Err(e) = x.as_bool().map(|v| set_value(v)) {
|
||||
eprintln!("error while resolving value: {}", e);
|
||||
};
|
||||
})
|
||||
}
|
||||
pub fn resolve_str<F: Fn(String) + 'static + Clone>(
|
||||
&mut self,
|
||||
local_env: &HashMap<VarName, AttrValue>,
|
||||
value: &AttrValue,
|
||||
set_value: F,
|
||||
) -> bool {
|
||||
self.resolve(local_env, value, move |x| {
|
||||
if let Err(e) = x.as_string().map(|v| set_value(v.clone())) {
|
||||
eprintln!("error while resolving value: {}", e);
|
||||
};
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_command(cmd: &str) -> Result<PrimitiveValue> {
|
||||
|
@ -152,3 +152,11 @@ pub fn run_command(cmd: &str) -> Result<PrimitiveValue> {
|
|||
let output = output.trim_matches('\n');
|
||||
Ok(PrimitiveValue::from(output))
|
||||
}
|
||||
|
||||
pub fn recursive_lookup<'a>(data: &'a HashMap<VarName, AttrValue>, key: &VarName) -> Result<&'a PrimitiveValue> {
|
||||
match data.get(key) {
|
||||
Some(AttrValue::Concrete(x)) => Ok(x),
|
||||
Some(AttrValue::VarRef(x)) => recursive_lookup(data, x),
|
||||
None => Err(anyhow!("No value found for key '{}'", key)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ impl AttrValue {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn as_var_ref(&self) -> Result<VarName> {
|
||||
pub fn as_var_ref(&self) -> Result<&VarName> {
|
||||
match self {
|
||||
AttrValue::VarRef(x) => Ok(x),
|
||||
_ => Err(anyhow!("{:?} is not a variable reference", self)),
|
||||
|
|
|
@ -37,6 +37,7 @@ pub fn element_to_gtk_thing(
|
|||
let gtk_widget = if let Some(gtk_container) = gtk_container {
|
||||
gtk_container
|
||||
} else if let Some(def) = widget_definitions.get(widget.name.as_str()) {
|
||||
// TODO widget cleanup phase, where widget arguments are resolved as far as possible beforehand?
|
||||
let mut local_env = local_env.clone();
|
||||
local_env.extend(widget.attrs.clone().into_iter().map(|(k, v)| (VarName(k), v)));
|
||||
let custom_widget = element_to_gtk_thing(widget_definitions, eww_state, &local_env, &def.structure)?;
|
||||
|
|
|
@ -4,58 +4,101 @@ use crate::value::{AttrValue, PrimitiveValue, VarName};
|
|||
use anyhow::*;
|
||||
use gtk::prelude::*;
|
||||
use gtk::ImageExt;
|
||||
use maplit::hashmap;
|
||||
use std::path::Path;
|
||||
|
||||
// TODO figure out how to
|
||||
// TODO https://developer.gnome.org/gtk3/stable/GtkFixed.html
|
||||
|
||||
// general attributes
|
||||
#[macro_export]
|
||||
macro_rules! resolve_block {
|
||||
($args:ident, $gtk_widget:ident, {
|
||||
$(
|
||||
prop( $( $attr_name:ident : $typecast_func:ident ),*) $code:block
|
||||
),+ $(,)?
|
||||
}) => {
|
||||
$({
|
||||
$(
|
||||
$args.unhandled_attrs.retain(|a| a != &::std::stringify!($attr_name).replace('_', "-"));
|
||||
)*
|
||||
// TODO reimplement unused warnings
|
||||
let attr_map: Result<_> = try {
|
||||
::maplit::hashmap! {
|
||||
$(
|
||||
::std::stringify!($attr_name).to_owned() => $args.widget.get_attr(&::std::stringify!($attr_name).replace('_', "-"))?.clone()
|
||||
),*
|
||||
}
|
||||
};
|
||||
if let Ok(attr_map) = attr_map {
|
||||
$args.eww_state.resolve(
|
||||
$args.local_env,
|
||||
attr_map,
|
||||
::glib::clone!(@strong $gtk_widget => move |attrs| {
|
||||
$(
|
||||
let $attr_name = attrs.get( ::std::stringify!($attr_name) ).context("REEE")?.$typecast_func()?;
|
||||
)*
|
||||
$code
|
||||
Ok(())
|
||||
})
|
||||
);
|
||||
}
|
||||
})+
|
||||
};
|
||||
|
||||
// required
|
||||
//($args:ident, $gtk_widget:ident, $func:ident => $attr:literal req => |$arg:ident| $body:expr) => {
|
||||
//$args.unhandled_attrs.retain(|a| a != &$attr);
|
||||
//$args.eww_state.$func($args.local_env, $args.widget.get_attr($attr)?, {
|
||||
//let $gtk_widget = $gtk_widget.clone();
|
||||
//move |$arg| { $body; }
|
||||
//});
|
||||
//};
|
||||
}
|
||||
/// attributes that apply to all widgets
|
||||
pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Widget) {
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_str => "class" => |v| gtk_widget.get_style_context().add_class(&v),
|
||||
resolve_bool => "active" = true => |v| gtk_widget.set_sensitive(v),
|
||||
resolve_str => "valign" => |v| gtk_widget.set_valign(parse_align(&v)),
|
||||
resolve_str => "halign" => |v| gtk_widget.set_halign(parse_align(&v)),
|
||||
resolve_f64 => "width" => |v| gtk_widget.set_size_request(v as i32, gtk_widget.get_allocated_height()),
|
||||
resolve_f64 => "height" => |v| gtk_widget.set_size_request(gtk_widget.get_allocated_width(), v as i32),
|
||||
resolve_bool => "visible" => |v| {
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(class: as_string) { gtk_widget.get_style_context().add_class(&class) },
|
||||
prop(valign: as_string) { gtk_widget.set_valign(parse_align(&valign)) },
|
||||
prop(halign: as_string) { gtk_widget.set_halign(parse_align(&halign)) },
|
||||
prop(width: as_f64 ) { gtk_widget.set_size_request(width as i32, gtk_widget.get_allocated_height()) },
|
||||
prop(height: as_f64 ) { gtk_widget.set_size_request(gtk_widget.get_allocated_width(), height as i32) },
|
||||
prop(active: as_bool ) { gtk_widget.set_sensitive(active) },
|
||||
prop(visible: as_bool ) {
|
||||
// TODO how do i call this only after the widget has been mapped? this is actually an issue,....
|
||||
if v { gtk_widget.show(); } else { gtk_widget.hide(); }
|
||||
}
|
||||
if visible { gtk_widget.show(); } else { gtk_widget.hide(); }
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/// attributes that apply to all container widgets
|
||||
pub(super) fn resolve_container_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Container) {
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_bool => "vexpand" = false => |v| gtk_widget.set_vexpand(v),
|
||||
resolve_bool => "hexpand" = false => |v| gtk_widget.set_hexpand(v),
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(vexpand: as_bool) { gtk_widget.set_vexpand(vexpand) },
|
||||
prop(hexpand: as_bool) { gtk_widget.set_hexpand(hexpand) },
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) fn resolve_range_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_f64 => "value" = req => |v| gtk_widget.set_value(v),
|
||||
resolve_f64 => "min" => |v| gtk_widget.get_adjustment().set_lower(v),
|
||||
resolve_f64 => "max" => |v| gtk_widget.get_adjustment().set_upper(v),
|
||||
resolve_str => "orientation" => |v| gtk_widget.set_orientation(parse_orientation(&v)),
|
||||
resolve_str => "onchange" => |cmd| {
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(value : as_f64) { gtk_widget.set_value(value)},
|
||||
prop(min : as_f64) { gtk_widget.get_adjustment().set_lower(min)},
|
||||
prop(max : as_f64) { gtk_widget.get_adjustment().set_upper(max)},
|
||||
prop(orientation : as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)) },
|
||||
prop(onchange : as_string) {
|
||||
gtk_widget.connect_value_changed(move |gtk_widget| {
|
||||
run_command(&cmd, gtk_widget.get_value());
|
||||
run_command(&onchange, gtk_widget.get_value());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) fn resolve_orientable_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_str => "orientation" => |v| gtk_widget.set_orientation(parse_orientation(&v)),
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(orientation: as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)) },
|
||||
});
|
||||
}
|
||||
|
||||
// widget definitions
|
||||
//// widget definitions
|
||||
|
||||
pub(super) fn widget_to_gtk_widget(bargs: &mut BuilderArgs) -> Result<Option<gtk::Widget>> {
|
||||
let gtk_widget = match bargs.widget.name.as_str() {
|
||||
|
@ -78,45 +121,43 @@ fn build_gtk_scale(bargs: &mut BuilderArgs) -> Result<gtk::Scale> {
|
|||
gtk::Orientation::Horizontal,
|
||||
Some(>k::Adjustment::new(0.0, 0.0, 100.0, 1.0, 1.0, 1.0)),
|
||||
);
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_bool => "flipped" => |v| gtk_widget.set_inverted(v),
|
||||
resolve_bool => "draw-value" = false => |v| gtk_widget.set_draw_value(v),
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(flipped: as_bool) { gtk_widget.set_inverted(flipped) },
|
||||
prop(draw_value: as_bool) { gtk_widget.set_draw_value(draw_value) },
|
||||
});
|
||||
Ok(gtk_widget)
|
||||
}
|
||||
|
||||
fn build_gtk_button(bargs: &mut BuilderArgs) -> Result<gtk::Button> {
|
||||
let gtk_widget = gtk::Button::new();
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_str => "onclick" => |v| gtk_widget.connect_clicked(move |_| run_command(&v, ""))
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(onclick: as_string) { gtk_widget.connect_clicked(move |_| run_command(&onclick, "")); }
|
||||
});
|
||||
Ok(gtk_widget)
|
||||
}
|
||||
|
||||
fn build_gtk_image(bargs: &mut BuilderArgs) -> Result<gtk::Image> {
|
||||
let gtk_widget = gtk::Image::new();
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_str => "path" = req => |v| {
|
||||
gtk_widget.set_from_file(Path::new(&v));
|
||||
}
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(path: as_string) { gtk_widget.set_from_file(Path::new(&path)); }
|
||||
});
|
||||
Ok(gtk_widget)
|
||||
}
|
||||
|
||||
fn build_gtk_layout(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
||||
let gtk_widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_f64 => "spacing" = 0.0 => |v| gtk_widget.set_spacing(v as i32),
|
||||
resolve_str => "orientation" => |v| gtk_widget.set_orientation(parse_orientation(&v)),
|
||||
resolve_bool => "space-evenly" = true => |v| gtk_widget.set_homogeneous(v),
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(spacing: as_f64 ) { gtk_widget.set_spacing(spacing as i32) },
|
||||
prop(orientation: as_string ) { gtk_widget.set_orientation(parse_orientation(&orientation)) },
|
||||
prop(space_evenly: as_bool) { gtk_widget.set_homogeneous(space_evenly) },
|
||||
});
|
||||
Ok(gtk_widget)
|
||||
}
|
||||
|
||||
fn build_gtk_label(bargs: &mut BuilderArgs) -> Result<gtk::Label> {
|
||||
let gtk_widget = gtk::Label::new(None);
|
||||
resolve!(bargs, gtk_widget, {
|
||||
resolve_str => "text" => |v| gtk_widget.set_text(&v),
|
||||
resolve_block!(bargs, gtk_widget, {
|
||||
prop(text: as_string) { gtk_widget.set_text(&text) },
|
||||
});
|
||||
Ok(gtk_widget)
|
||||
}
|
||||
|
@ -130,17 +171,16 @@ fn build_gtk_text(bargs: &mut BuilderArgs) -> Result<gtk::Label> {
|
|||
.context("text node must contain exactly one child")?
|
||||
.get_attr("text")?;
|
||||
let gtk_widget = gtk::Label::new(None);
|
||||
bargs.eww_state.resolve_str(
|
||||
bargs.eww_state.resolve(
|
||||
bargs.local_env,
|
||||
text,
|
||||
glib::clone!(@strong gtk_widget => move |v| gtk_widget.set_text(&v)),
|
||||
hashmap! {"text".to_owned() => text.clone() },
|
||||
glib::clone!(@strong gtk_widget => move |v| { gtk_widget.set_text(&v.get("text").unwrap().as_string().unwrap()); Ok(())}),
|
||||
);
|
||||
Ok(gtk_widget)
|
||||
}
|
||||
|
||||
fn build_gtk_aspect_frame(bargs: &mut BuilderArgs) -> Result<gtk::AspectFrame> {
|
||||
let gtk_widget = gtk::AspectFrame::new(None, 0.5, 0.5, 1.0, true);
|
||||
//resolve!(bargs, gtk_widget, {});
|
||||
Ok(gtk_widget)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue