Add overlay widget (#457)

This commit is contained in:
viandox 2022-05-26 13:40:09 +02:00 committed by GitHub
parent 3297c4eb70
commit c855ec07d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 0 deletions

View file

@ -33,6 +33,7 @@ All notable changes to eww will be listed here, starting at changes since versio
- Add transform widget (By: druskus20)
- Add `:onaccept` to input field, add `:onclick` to eventbox
- Add `EWW_CMD`, `EWW_CONFIG_DIR`, `EWW_EXECUTABLE` magic variables
- Add `overlay` widget (By: viandoxdev)
### Notable Internal changes
- Rework state management completely, now making local state and dynamic widget hierarchy changes possible.

View file

@ -341,6 +341,11 @@ pub struct CustomWidgetInvocation {
/// Make sure that [`gtk::Bin`] widgets only get a single child.
fn validate_container_children_count(container: &gtk::Container, widget_use: &BasicWidgetUse) -> Result<(), DiagError> {
// ignore for overlay as it can take more than one.
if container.dynamic_cast_ref::<gtk::Overlay>().is_some() {
return Ok(());
}
if container.dynamic_cast_ref::<gtk::Bin>().is_some() && widget_use.children.len() > 1 {
Err(DiagError::new(gen_diagnostic! {
kind = Severity::Error,

View file

@ -79,6 +79,7 @@ pub const BUILTIN_WIDGET_NAMES: &[&str] = &[
WIDGET_NAME_CHECKBOX,
WIDGET_NAME_REVEALER,
WIDGET_NAME_SCROLL,
WIDGET_NAME_OVERLAY,
];
//// widget definitions
@ -105,6 +106,7 @@ pub(super) fn widget_use_to_gtk_widget(bargs: &mut BuilderArgs) -> Result<gtk::W
WIDGET_NAME_CHECKBOX => build_gtk_checkbox(bargs)?.upcast(),
WIDGET_NAME_REVEALER => build_gtk_revealer(bargs)?.upcast(),
WIDGET_NAME_SCROLL => build_gtk_scrolledwindow(bargs)?.upcast(),
WIDGET_NAME_OVERLAY => build_gtk_overlay(bargs)?.upcast(),
_ => {
return Err(AstError::ValidationError(ValidationError::UnknownWidget(
bargs.widget_use.name_span,
@ -514,6 +516,45 @@ fn build_gtk_box(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
Ok(gtk_widget)
}
const WIDGET_NAME_OVERLAY: &str = "overlay";
/// @widget overlay
/// @desc a widget that places its children on top of each other. The overlay widget takes the size
/// of its first child.
fn build_gtk_overlay(bargs: &mut BuilderArgs) -> Result<gtk::Overlay> {
let gtk_widget = gtk::Overlay::new();
// no def_widget because this widget has no props.
// And this widget has no proprs because they would pretty much just be the same as boxes,
// so you might as well just use a box inside the widget to get them.
match bargs.widget_use.children.len().cmp(&1) {
Ordering::Less => {
Err(DiagError::new(gen_diagnostic!("overlay must contain at least one element", bargs.widget_use.span)).into())
}
Ordering::Greater | Ordering::Equal => {
let mut children = bargs.widget_use.children.iter().map(|child| {
build_gtk_widget(
bargs.scope_graph,
bargs.widget_defs.clone(),
bargs.calling_scope,
child.clone(),
bargs.custom_widget_invocation.clone(),
)
});
// we have more than one children, we can unwrap
let first = children.next().unwrap()?;
gtk_widget.add(&first);
first.show();
for child in children {
let child = child?;
gtk_widget.add_overlay(&child);
child.show();
}
Ok(gtk_widget)
}
}
}
const WIDGET_NAME_CENTERBOX: &str = "centerbox";
/// @widget centerbox
/// @desc a box that must contain exactly three children, which will be layed out at the start, center and end of the container.