Skip to content

Commit

Permalink
Add overlay widget (#457)
Browse files Browse the repository at this point in the history
  • Loading branch information
viandoxdev authored May 26, 2022
1 parent 3297c4e commit c855ec0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions crates/eww/src/widgets/build_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
41 changes: 41 additions & 0 deletions crates/eww/src/widgets/widget_definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub const BUILTIN_WIDGET_NAMES: &[&str] = &[
WIDGET_NAME_CHECKBOX,
WIDGET_NAME_REVEALER,
WIDGET_NAME_SCROLL,
WIDGET_NAME_OVERLAY,
];

//// widget definitions
Expand All @@ -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,
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit c855ec0

Please sign in to comment.