//! Alignment API demo, port of and . use bevy::prelude::*; use haalka::prelude::*; use strum::{Display, EnumIter, IntoEnumIterator}; fn main() { App::new() .add_plugins(( DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { position: WindowPosition::Centered(MonitorSelection::Primary), ..default() }), ..default() }), HaalkaPlugin, )) .add_systems(Startup, (ui_root, camera)) .run(); } #[derive(Clone, Copy, EnumIter, Display, PartialEq)] #[strum(crate = "strum")] enum RectangleAlignment { TopLeft, Top, TopRight, Right, BottomRight, Bottom, BottomLeft, Left, Center, } impl RectangleAlignment { fn to_align(&self) -> Align { match self { Self::TopLeft => Align::new().top().left(), Self::Top => Align::new().top().center_x(), Self::TopRight => Align::new().top().right(), Self::Right => Align::new().right().center_y(), Self::BottomRight => Align::new().bottom().right(), Self::Bottom => Align::new().bottom().center_x(), Self::BottomLeft => Align::new().bottom().left(), Self::Left => Align::new().left().center_y(), Self::Center => Align::center(), } } } #[derive(Clone, Copy, PartialEq)] enum Alignment { Self_, Content, } static ALIGNMENT: Lazy> = Lazy::new(|| Mutable::new(Alignment::Self_)); static RECTANGLE_SELF_ALIGNMENT: Lazy>> = Lazy::new(default); static RECTANGLE_CONTENT_ALIGNMENT: Lazy>> = Lazy::new(default); fn alignment_button(alignment: Alignment) -> impl Element { let hovered = Mutable::new(false); El::::new() .align(Align::center()) .width(Val::Px(250.)) .height(Val::Px(80.)) .background_color_signal( signal::or( hovered.signal(), ALIGNMENT .signal() .map(move |other_alignment| alignment == other_alignment), ) .map_bool(|| bevy::color::palettes::basic::GRAY.into(), || Color::BLACK) .map(BackgroundColor), ) .hovered_sync(hovered) .align_content(Align::center()) .on_click(move || ALIGNMENT.set(alignment)) .child(El::::new().text(text( match alignment { Alignment::Self_ => "align self", Alignment::Content => "align content", }, 30., ))) } fn ui_root(world: &mut World) { Column::::new() .width(Val::Percent(100.)) .height(Val::Percent(100.)) .with_style(|mut style| style.row_gap = Val::Px(15.)) .align_content(Align::center()) .align(Align::center()) .item( Row::::new() .with_style(|mut style| style.column_gap = Val::Px(15.)) .item(container("Column", Column::::new().items(rectangles()))) .item(container("El", El::::new().child(rectangle(1)))) // TODO: is this align content behavior buggy? .item(container("Grid", Grid::::new().cells(rectangles()))), ) .item( Row::::new() .with_style(|mut style| style.column_gap = Val::Px(15.)) .item( Column::::new() .with_style(|mut style| style.row_gap = Val::Px(15.)) .item(alignment_button(Alignment::Self_)) .item(alignment_button(Alignment::Content)), ) .item( Stack::::new() .layers(RectangleAlignment::iter().map(align_switcher)) .apply(container_style), ), ) .item( Row::::new() .with_style(|mut style| style.column_gap = Val::Px(15.)) .item(container("Row", Row::::new().items(rectangles()))) // TODO: is this align content behavior buggy? .item(container("Stack", Stack::::new().layers(rectangles()))), ) .spawn(world); } fn container_style(el: E) -> E { el.width(Val::Px(278.)).height(Val::Px(200.)).update_raw_el(|raw_el| { raw_el .insert::(bevy::color::palettes::basic::GRAY.into()) .with_component::