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 {
|
impl App {
|
||||||
pub fn handle_user_command(&mut self, opts: &Opt) -> Result<()> {
|
pub fn handle_user_command(&mut self, opts: &Opt) -> Result<()> {
|
||||||
match &opts.action {
|
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::OpenWindow { window_name } => self.open_window(&window_name)?,
|
||||||
OptAction::CloseWindow { window_name } => self.close_window(&window_name)?,
|
OptAction::CloseWindow { window_name } => self.close_window(&window_name)?,
|
||||||
OptAction::KillServer => {
|
OptAction::KillServer => {
|
||||||
|
@ -43,7 +43,7 @@ impl App {
|
||||||
let result: Result<_> = try {
|
let result: Result<_> = try {
|
||||||
match event {
|
match event {
|
||||||
EwwEvent::UserCommand(command) => self.handle_user_command(&command)?,
|
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::ReloadConfig(config) => self.reload_all_windows(config)?,
|
||||||
EwwEvent::ReloadCss(css) => self.load_css(&css)?,
|
EwwEvent::ReloadCss(css) => self.load_css(&css)?,
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,8 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_state(&mut self, fieldname: VarName, value: PrimitiveValue) {
|
fn update_state(&mut self, fieldname: VarName, value: PrimitiveValue) -> Result<()> {
|
||||||
self.eww_state.update_value(fieldname, value);
|
self.eww_state.update_value(fieldname, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_window(&mut self, window_name: &str) -> Result<()> {
|
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};
|
use crate::value::{AttrValue, PrimitiveValue};
|
||||||
|
|
||||||
//pub struct StateChangeHandler(Box<dyn Fn(HashMap<String, PrimitiveValue>) + 'static>);
|
//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 {
|
pub struct StateChangeHandlers {
|
||||||
handlers: HashMap<VarName, Vec<Arc<dyn Fn(HashMap<String, PrimitiveValue>) + 'static>>>,
|
handlers: HashMap<VarName, Vec<Arc<StateChangeHandler>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateChangeHandlers {
|
impl StateChangeHandlers {
|
||||||
fn put_handler(&mut self, var_names: Vec<VarName>, handler: Arc<dyn Fn(HashMap<String, PrimitiveValue>) + 'static>) {
|
fn put_handler(&mut self, handler: StateChangeHandler) {
|
||||||
for var_name in var_names {
|
let handler = Arc::new(handler);
|
||||||
let entry: &mut Vec<Arc<dyn Fn(HashMap<String, PrimitiveValue>) + 'static>> =
|
for var_name in handler.unresolved_attrs.values() {
|
||||||
self.handlers.entry(var_name).or_insert_with(Vec::new);
|
let entry: &mut Vec<Arc<StateChangeHandler>> = self.handlers.entry(var_name.clone()).or_insert_with(Vec::new);
|
||||||
entry.push(handler);
|
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 {
|
pub struct EwwState {
|
||||||
state_change_handlers: StateChangeHandlers,
|
state_change_handlers: StateChangeHandlers,
|
||||||
//on_change_handlers: HashMap<VarName, Vec<StateChangeHandler>>,
|
|
||||||
state: HashMap<VarName, PrimitiveValue>,
|
state: HashMap<VarName, PrimitiveValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,97 +86,65 @@ impl EwwState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_callbacks(&mut self) {
|
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) {
|
pub fn update_value(&mut self, key: VarName, value: PrimitiveValue) -> Result<()> {
|
||||||
if let Some(handlers) = self.on_change_handlers.get(&key) {
|
if let Some(handlers) = self.state_change_handlers.get(&key) {
|
||||||
for on_change in handlers {
|
self.state.insert(key.clone(), value);
|
||||||
on_change(value.clone());
|
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,
|
&mut self,
|
||||||
local_env: &HashMap<VarName, AttrValue>,
|
local_env: &HashMap<VarName, AttrValue>,
|
||||||
value: &AttrValue,
|
mut needed_attributes: HashMap<String, AttrValue>,
|
||||||
set_value: F,
|
set_value: F,
|
||||||
) -> bool {
|
) {
|
||||||
match value {
|
let mut resolved_attrs = HashMap::new();
|
||||||
AttrValue::VarRef(name) => {
|
let mut unresolved_attrs: HashMap<String, VarName> = HashMap::new();
|
||||||
// get value from globals
|
needed_attributes
|
||||||
if let Some(value) = self.state.get(&name).cloned() {
|
.drain()
|
||||||
self.on_change_handlers
|
.for_each(|(attr_name, attr_value)| match attr_value {
|
||||||
.entry(name.clone())
|
AttrValue::Concrete(primitive) => {
|
||||||
.or_insert_with(Vec::new)
|
resolved_attrs.insert(attr_name, primitive);
|
||||||
.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
|
|
||||||
}
|
}
|
||||||
|
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());
|
if let Err(e) = result {
|
||||||
true
|
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> {
|
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');
|
let output = output.trim_matches('\n');
|
||||||
Ok(PrimitiveValue::from(output))
|
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 {
|
match self {
|
||||||
AttrValue::VarRef(x) => Ok(x),
|
AttrValue::VarRef(x) => Ok(x),
|
||||||
_ => Err(anyhow!("{:?} is not a variable reference", self)),
|
_ => 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 {
|
let gtk_widget = if let Some(gtk_container) = gtk_container {
|
||||||
gtk_container
|
gtk_container
|
||||||
} else if let Some(def) = widget_definitions.get(widget.name.as_str()) {
|
} 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();
|
let mut local_env = local_env.clone();
|
||||||
local_env.extend(widget.attrs.clone().into_iter().map(|(k, v)| (VarName(k), v)));
|
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)?;
|
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 anyhow::*;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::ImageExt;
|
use gtk::ImageExt;
|
||||||
|
use maplit::hashmap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
// TODO figure out how to
|
// TODO figure out how to
|
||||||
// TODO https://developer.gnome.org/gtk3/stable/GtkFixed.html
|
// 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
|
/// attributes that apply to all widgets
|
||||||
pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Widget) {
|
pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Widget) {
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_str => "class" => |v| gtk_widget.get_style_context().add_class(&v),
|
prop(class: as_string) { gtk_widget.get_style_context().add_class(&class) },
|
||||||
resolve_bool => "active" = true => |v| gtk_widget.set_sensitive(v),
|
prop(valign: as_string) { gtk_widget.set_valign(parse_align(&valign)) },
|
||||||
resolve_str => "valign" => |v| gtk_widget.set_valign(parse_align(&v)),
|
prop(halign: as_string) { gtk_widget.set_halign(parse_align(&halign)) },
|
||||||
resolve_str => "halign" => |v| gtk_widget.set_halign(parse_align(&v)),
|
prop(width: as_f64 ) { gtk_widget.set_size_request(width as i32, gtk_widget.get_allocated_height()) },
|
||||||
resolve_f64 => "width" => |v| gtk_widget.set_size_request(v as i32, gtk_widget.get_allocated_height()),
|
prop(height: as_f64 ) { gtk_widget.set_size_request(gtk_widget.get_allocated_width(), height as i32) },
|
||||||
resolve_f64 => "height" => |v| gtk_widget.set_size_request(gtk_widget.get_allocated_width(), v as i32),
|
prop(active: as_bool ) { gtk_widget.set_sensitive(active) },
|
||||||
resolve_bool => "visible" => |v| {
|
prop(visible: as_bool ) {
|
||||||
// TODO how do i call this only after the widget has been mapped? this is actually an issue,....
|
// 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
|
/// attributes that apply to all container widgets
|
||||||
pub(super) fn resolve_container_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Container) {
|
pub(super) fn resolve_container_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Container) {
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_bool => "vexpand" = false => |v| gtk_widget.set_vexpand(v),
|
prop(vexpand: as_bool) { gtk_widget.set_vexpand(vexpand) },
|
||||||
resolve_bool => "hexpand" = false => |v| gtk_widget.set_hexpand(v),
|
prop(hexpand: as_bool) { gtk_widget.set_hexpand(hexpand) },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn resolve_range_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
pub(super) fn resolve_range_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_f64 => "value" = req => |v| gtk_widget.set_value(v),
|
prop(value : as_f64) { gtk_widget.set_value(value)},
|
||||||
resolve_f64 => "min" => |v| gtk_widget.get_adjustment().set_lower(v),
|
prop(min : as_f64) { gtk_widget.get_adjustment().set_lower(min)},
|
||||||
resolve_f64 => "max" => |v| gtk_widget.get_adjustment().set_upper(v),
|
prop(max : as_f64) { gtk_widget.get_adjustment().set_upper(max)},
|
||||||
resolve_str => "orientation" => |v| gtk_widget.set_orientation(parse_orientation(&v)),
|
prop(orientation : as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)) },
|
||||||
resolve_str => "onchange" => |cmd| {
|
prop(onchange : as_string) {
|
||||||
gtk_widget.connect_value_changed(move |gtk_widget| {
|
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) {
|
pub(super) fn resolve_orientable_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::Range) {
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_str => "orientation" => |v| gtk_widget.set_orientation(parse_orientation(&v)),
|
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>> {
|
pub(super) fn widget_to_gtk_widget(bargs: &mut BuilderArgs) -> Result<Option<gtk::Widget>> {
|
||||||
let gtk_widget = match bargs.widget.name.as_str() {
|
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,
|
gtk::Orientation::Horizontal,
|
||||||
Some(>k::Adjustment::new(0.0, 0.0, 100.0, 1.0, 1.0, 1.0)),
|
Some(>k::Adjustment::new(0.0, 0.0, 100.0, 1.0, 1.0, 1.0)),
|
||||||
);
|
);
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_bool => "flipped" => |v| gtk_widget.set_inverted(v),
|
prop(flipped: as_bool) { gtk_widget.set_inverted(flipped) },
|
||||||
resolve_bool => "draw-value" = false => |v| gtk_widget.set_draw_value(v),
|
prop(draw_value: as_bool) { gtk_widget.set_draw_value(draw_value) },
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_gtk_button(bargs: &mut BuilderArgs) -> Result<gtk::Button> {
|
fn build_gtk_button(bargs: &mut BuilderArgs) -> Result<gtk::Button> {
|
||||||
let gtk_widget = gtk::Button::new();
|
let gtk_widget = gtk::Button::new();
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_str => "onclick" => |v| gtk_widget.connect_clicked(move |_| run_command(&v, ""))
|
prop(onclick: as_string) { gtk_widget.connect_clicked(move |_| run_command(&onclick, "")); }
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_gtk_image(bargs: &mut BuilderArgs) -> Result<gtk::Image> {
|
fn build_gtk_image(bargs: &mut BuilderArgs) -> Result<gtk::Image> {
|
||||||
let gtk_widget = gtk::Image::new();
|
let gtk_widget = gtk::Image::new();
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_str => "path" = req => |v| {
|
prop(path: as_string) { gtk_widget.set_from_file(Path::new(&path)); }
|
||||||
gtk_widget.set_from_file(Path::new(&v));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_gtk_layout(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
fn build_gtk_layout(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
||||||
let gtk_widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
let gtk_widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_f64 => "spacing" = 0.0 => |v| gtk_widget.set_spacing(v as i32),
|
prop(spacing: as_f64 ) { gtk_widget.set_spacing(spacing as i32) },
|
||||||
resolve_str => "orientation" => |v| gtk_widget.set_orientation(parse_orientation(&v)),
|
prop(orientation: as_string ) { gtk_widget.set_orientation(parse_orientation(&orientation)) },
|
||||||
resolve_bool => "space-evenly" = true => |v| gtk_widget.set_homogeneous(v),
|
prop(space_evenly: as_bool) { gtk_widget.set_homogeneous(space_evenly) },
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_gtk_label(bargs: &mut BuilderArgs) -> Result<gtk::Label> {
|
fn build_gtk_label(bargs: &mut BuilderArgs) -> Result<gtk::Label> {
|
||||||
let gtk_widget = gtk::Label::new(None);
|
let gtk_widget = gtk::Label::new(None);
|
||||||
resolve!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
resolve_str => "text" => |v| gtk_widget.set_text(&v),
|
prop(text: as_string) { gtk_widget.set_text(&text) },
|
||||||
});
|
});
|
||||||
Ok(gtk_widget)
|
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")?
|
.context("text node must contain exactly one child")?
|
||||||
.get_attr("text")?;
|
.get_attr("text")?;
|
||||||
let gtk_widget = gtk::Label::new(None);
|
let gtk_widget = gtk::Label::new(None);
|
||||||
bargs.eww_state.resolve_str(
|
bargs.eww_state.resolve(
|
||||||
bargs.local_env,
|
bargs.local_env,
|
||||||
text,
|
hashmap! {"text".to_owned() => text.clone() },
|
||||||
glib::clone!(@strong gtk_widget => move |v| gtk_widget.set_text(&v)),
|
glib::clone!(@strong gtk_widget => move |v| { gtk_widget.set_text(&v.get("text").unwrap().as_string().unwrap()); Ok(())}),
|
||||||
);
|
);
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_gtk_aspect_frame(bargs: &mut BuilderArgs) -> Result<gtk::AspectFrame> {
|
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);
|
let gtk_widget = gtk::AspectFrame::new(None, 0.5, 0.5, 1.0, true);
|
||||||
//resolve!(bargs, gtk_widget, {});
|
|
||||||
Ok(gtk_widget)
|
Ok(gtk_widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue