mod utils;
use utils::*;
use bevy::{diagnostic::LogDiagnosticsPlugin, prelude::*, ui::Pressed};
use haalka::prelude::*;
fn main() {
App::new()
.add_plugins((examples_plugin, LogDiagnosticsPlugin::default()))
.add_systems(
Startup,
(
|world: &mut World| {
ui_root().spawn(world);
},
camera,
),
)
.run();
}
const SIZE: usize = 20; const FONT_SIZE: f32 = 5.83;
const HOVERED_COLOR: Color = Color::srgb(0.25, 0.25, 0.25);
const PRESSED_COLOR: Color = Color::srgb(0.35, 0.75, 0.35);
fn button(i: usize, j: usize) -> jonmo::Builder {
let color = as_rainbow(j % i.max(1));
let lazy_entity = LazyEntity::new();
let pressed = signal::from_entity(lazy_entity.clone())
.has_component::<Pressed>()
.dedupe();
let hovered = signal::from_entity(lazy_entity.clone())
.has_component::<Hovered>()
.dedupe();
let total = SIZE as f32;
let width = 90. / total;
jonmo::Builder::new()
.insert(Node::default())
.insert((Pickable::default(), Hoverable, Pressable))
.with_component::<Node>(move |mut node| {
node.width = Val::Percent(width);
node.height = Val::Percent(width);
node.bottom = Val::Percent(100. / total * i as f32);
node.left = Val::Percent(100. / total * j as f32);
node.align_items = AlignItems::Center;
node.position_type = PositionType::Absolute;
node.border = UiRect::all(Val::Percent(10. / total));
})
.lazy_entity(lazy_entity)
.component_signal(
signal::zip!(pressed, hovered)
.dedupe()
.map_in(move |(pressed, hovered)| {
if pressed {
PRESSED_COLOR
} else if hovered {
HOVERED_COLOR
} else {
color
}
})
.map_in(BackgroundColor)
.map_in(Some),
)
.insert(BorderColor::all(as_rainbow(i % j.max(1))))
.child(jonmo::Builder::from((
Text(format!("{i} {j}")),
TextFont::from_font_size(FONT_SIZE),
TextColor(Color::srgb(0.2, 0.2, 0.2)),
)))
}
fn camera(mut commands: Commands) {
commands.spawn(Camera2d);
}
fn as_rainbow(i: usize) -> Color {
Color::hsl((i as f32 / SIZE as f32) * 360.0, 0.9, 0.8)
}
fn ui_root() -> impl Element {
El::<Node>::new()
.with_node(|mut node| {
node.flex_direction = FlexDirection::Column;
node.justify_content = JustifyContent::Center;
node.align_items = AlignItems::Center;
node.width = Val::Percent(100.);
node.height = Val::Percent(100.);
})
.with_builder(|builder| builder.children((0..SIZE).flat_map(|i| (0..SIZE).map(move |j| button(i, j)))))
}