95 lines
2.3 KiB
Rust
95 lines
2.3 KiB
Rust
use ruin_app::prelude::*;
|
|
|
|
#[ruin_runtime::async_main]
|
|
async fn main() -> ruin_app::Result<()> {
|
|
let title = "RUIN Counter";
|
|
|
|
App::new()
|
|
.window(
|
|
Window::new()
|
|
.title(title)
|
|
.app_id("dev.ruin.counter")
|
|
.size(960.0, 640.0),
|
|
)
|
|
.mount(view! {
|
|
CounterApp(title = title) {}
|
|
})
|
|
.run()
|
|
.await
|
|
}
|
|
|
|
#[component]
|
|
fn CounterApp(title: &'static str) -> impl IntoView {
|
|
let count = use_signal(|| 0_i32);
|
|
let doubled = use_memo({
|
|
let count = count.clone();
|
|
move || count.get() * 2
|
|
});
|
|
|
|
use_window_title({
|
|
let count = count.clone();
|
|
move || format!("{title} ({})", count.get())
|
|
});
|
|
|
|
view! {
|
|
column(gap = 16.0, padding = 24.0) {
|
|
text(role = TextRole::Heading(1), size = 32.0, weight = FontWeight::Semibold) {
|
|
title
|
|
}
|
|
|
|
CounterActions(count = count.clone()) {}
|
|
|
|
block(
|
|
padding = 16.0,
|
|
gap = 8.0,
|
|
background = surfaces::raised(),
|
|
border_radius = 12.0,
|
|
border = Border::new(2.0, Color::rgb(0, 0, 0))
|
|
) {
|
|
text(size = 18.0) { "count = "; count.clone() }
|
|
text(color = colors::muted()) { "double = "; doubled.clone() }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
fn CounterActions(count: Signal<i32>) -> impl IntoView {
|
|
view! {
|
|
row(gap = 8.0) {
|
|
button(
|
|
on_press = {
|
|
let count = count.clone();
|
|
move |_| {
|
|
count.update(|value| *value -= 1);
|
|
}
|
|
},
|
|
) {
|
|
"-1"
|
|
}
|
|
|
|
button(
|
|
on_press = {
|
|
let count = count.clone();
|
|
move |_| {
|
|
let _ = count.set(0);
|
|
}
|
|
},
|
|
) {
|
|
"Reset"
|
|
}
|
|
|
|
button(
|
|
on_press = {
|
|
let count = count.clone();
|
|
move |_| {
|
|
count.update(|value| *value += 1);
|
|
}
|
|
},
|
|
) {
|
|
"+1"
|
|
}
|
|
}
|
|
}
|
|
}
|