Skip to content

Instantly share code, notes, and snippets.

@MartinKavik
Created January 24, 2024 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MartinKavik/66504cfbf07a85882979261f35603701 to your computer and use it in GitHub Desktop.
Save MartinKavik/66504cfbf07a85882979261f35603701 to your computer and use it in GitHub Desktop.
MoonZoon error box
use std::any::Any;
use zoon::{once_cell::sync::Lazy, *, named_color::*};
fn main() {
start_app("app", root);
}
#[derive(Clone, Copy)]
struct DecreaseButtonPressed;
#[derive(Clone, Copy)]
struct IncreaseButtonPressed;
#[derive(Clone, Copy)]
struct CloseButtonPressed;
static COUNTER: Lazy<Mutable<i32>> = Lazy::new(|| {
on(|DecreaseButtonPressed| *COUNTER.lock_mut() -= 1);
on(|IncreaseButtonPressed| *COUNTER.lock_mut() += 1);
Mutable::new(0)
});
static ERROR_BOX_VISIBLE: Lazy<Mutable<bool>> = Lazy::new(|| {
on(|CloseButtonPressed| ERROR_BOX_VISIBLE.set(false));
Mutable::new(true)
});
fn root() -> impl Element {
Stack::new()
.s(Height::screen())
.layer(counter())
.layer_signal(ERROR_BOX_VISIBLE.signal().map_true(error_box))
}
fn error_box() -> impl Element {
Row::new()
.s(Align::center())
.s(Borders::all(Border::new()))
.s(Gap::new().x(20))
.s(Background::new().color(named_color::RED_3))
.s(Padding::new().x(20).y(10))
.s(RoundedCorners::all(5))
.item("Error!")
.item({
let (hovered, hovered_signal) = Mutable::new_and_signal(false);
Button::new()
.s(Borders::all(Border::new()))
.s(RoundedCorners::all_max())
.s(Padding::all(10))
.s(Background::new().color_signal(hovered_signal.map_bool(|| GRAY_3, || GRAY_4)))
.label("X")
.on_hovered_change(move |is_hovered| hovered.set(is_hovered))
.on_press(|| emit(CloseButtonPressed))
})
}
fn counter() -> impl Element {
Row::new()
.s(Align::center())
.s(Gap::new().x(15))
.item(counter_button("-", DecreaseButtonPressed))
.item_signal(COUNTER.signal())
.item(counter_button("+", IncreaseButtonPressed))
}
fn counter_button(label: &str, app_event: impl Any + Copy) -> impl Element {
let (hovered, hovered_signal) = Mutable::new_and_signal(false);
Button::new()
.s(Width::exact(45))
.s(RoundedCorners::all_max())
.s(Background::new()
.color_signal(hovered_signal.map_bool(|| hsluv!(300, 75, 85), || hsluv!(300, 75, 75))))
.on_hovered_change(move |is_hovered| hovered.set(is_hovered))
.label(label)
.on_press(move || emit(app_event))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment