Add centerbox widget

This commit is contained in:
elkowar 2021-08-12 16:19:00 +02:00
parent dcf27a0cbf
commit 9ee852c0fd
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
5 changed files with 59 additions and 18 deletions

View file

@ -1,4 +1,7 @@
use crate::{EwwPaths, config, daemon_response::DaemonResponseSender, display_backend, error_handling_ctx, eww_state, script_var_handler::*};
use crate::{
config, daemon_response::DaemonResponseSender, display_backend, error_handling_ctx, eww_state, script_var_handler::*,
EwwPaths,
};
use anyhow::*;
use debug_stub_derive::*;
use eww_shared_util::VarName;

View file

@ -35,10 +35,8 @@ pub fn format_error(err: &anyhow::Error) -> String {
for err in err.chain() {
format!("chain: {}", err);
}
match err.downcast_ref::<AstError>() {
Some(err) => stringify_diagnostic(err.to_diagnostic()).unwrap_or_else(|_| format!("{:?}", err)),
None => format!("{:?}", err),
}
let diag = anyhow_err_to_diagnostic(err);
stringify_diagnostic(diag).unwrap_or_else(|_| format!("{}", err))
}
pub fn anyhow_err_to_diagnostic(err: &anyhow::Error) -> Diagnostic<usize> {

View file

@ -70,17 +70,19 @@ fn build_builtin_gtk_widget(
if let Some(gtk_widget) = gtk_widget.dynamic_cast_ref::<gtk::Container>() {
resolve_container_attrs(&mut bargs, gtk_widget);
for child in &widget.children {
let child_widget = child.render(bargs.eww_state, window_name, widget_definitions).with_context(|| {
format!(
"{}error while building child '{:#?}' of '{}'",
format!("{} | ", widget.span),
&child,
&gtk_widget.get_widget_name()
)
})?;
gtk_widget.add(&child_widget);
child_widget.show();
if gtk_widget.get_children().is_empty() {
for child in &widget.children {
let child_widget = child.render(bargs.eww_state, window_name, widget_definitions).with_context(|| {
format!(
"{}error while building child '{:#?}' of '{}'",
format!("{} | ", widget.span),
&child,
&gtk_widget.get_widget_name()
)
})?;
gtk_widget.add(&child_widget);
child_widget.show();
}
}
}

View file

@ -1,14 +1,18 @@
#![allow(clippy::option_map_unit_fn)]
use super::{run_command, BuilderArgs};
use crate::{enum_parse, error_handling_ctx, eww_state, resolve_block, util::list_difference, widgets::widget_node};
use crate::{
enum_parse, error::DiagError, error_handling_ctx, eww_state, resolve_block, util::list_difference, widgets::widget_node,
};
use anyhow::*;
use gdk::WindowExt;
use glib;
use gtk::{self, prelude::*, ImageExt};
use itertools::Itertools;
use std::{cell::RefCell, collections::HashMap, rc::Rc, time::Duration};
use yuck::{
config::validate::ValidationError,
error::{AstError, AstResult, AstResultExt},
gen_diagnostic,
parser::from_ast::FromAst,
};
@ -20,6 +24,7 @@ use yuck::{
pub(super) fn widget_to_gtk_widget(bargs: &mut BuilderArgs) -> Result<gtk::Widget> {
let gtk_widget = match bargs.widget.name.as_str() {
"box" => build_gtk_box(bargs)?.upcast(),
"centerbox" => build_center_box(bargs)?.upcast(),
"scale" => build_gtk_scale(bargs)?.upcast(),
"progress" => build_gtk_progress(bargs)?.upcast(),
"image" => build_gtk_image(bargs)?.upcast(),
@ -494,6 +499,39 @@ fn build_gtk_box(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
Ok(gtk_widget)
}
/// @widget centerbox extends container
/// @desc a box that must contain exactly three children, which will be layed out at the start, center and end of the container.
fn build_center_box(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
let gtk_widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
resolve_block!(bargs, gtk_widget, {
// @prop orientation - orientation of the centerbox. possible values: $orientation
prop(orientation: as_string) { gtk_widget.set_orientation(parse_orientation(&orientation)?) },
});
if bargs.widget.children.len() < 3 {
Err(DiagError::new(gen_diagnostic!("centerbox must contain exactly 3 elements", bargs.widget.span)))?
} else if bargs.widget.children.len() > 3 {
let (_, additional_children) = bargs.widget.children.split_at(3);
// we know that there is more than three children, so unwrapping on first and left here is fine.
let first_span = additional_children.first().unwrap().span();
let last_span = additional_children.last().unwrap().span();
Err(DiagError::new(gen_diagnostic!("centerbox must contain exactly 3 elements, but got more", first_span.to(last_span))))?
}
let mut children =
bargs.widget.children.iter().map(|child| child.render(bargs.eww_state, bargs.window_name, bargs.widget_definitions));
// we know that we have exactly three children here, so we can unwrap here.
let (first, center, end) = children.next_tuple().unwrap();
let (first, center, end) = (first?, center?, end?);
gtk_widget.pack_start(&first, true, true, 0);
gtk_widget.set_center_widget(Some(&center));
gtk_widget.pack_end(&end, true, true, 0);
first.show();
center.show();
end.show();
Ok(gtk_widget)
}
/// @widget label
/// @desc A text widget giving you more control over how the text is displayed
fn build_gtk_label(bargs: &mut BuilderArgs) -> Result<gtk::Label> {

View file

@ -9,7 +9,7 @@ use yuck::{
error::{AstError, AstResult},
};
pub trait WidgetNode: std::fmt::Debug + dyn_clone::DynClone + Send + Sync {
pub trait WidgetNode: Spanned + std::fmt::Debug + dyn_clone::DynClone + Send + Sync {
fn get_name(&self) -> &str;
/// Generate a [gtk::Widget] from a [element::WidgetUse].