use window_of_opportunity::{app::Application, component::Component, ui};
#[derive(Debug, Default)]
struct Counter {
thing: String,
}
impl Component for Counter {
fn render(
&self,
ctx: &window_of_opportunity::state::Ctx,
_children: Vec<Box<window_of_opportunity::element::Element>>,
) -> Box<window_of_opportunity::element::Element> {
let count = ctx.use_state("count", || 0);
let increment = ctx.set_state("count", |c: &mut i32| *c += 1);
ui! {
Button on_click(increment) { { Text format!("count: {count}") } }
}
}
}
#[derive(Debug, Default)]
struct Pane {}
impl Component for Pane {
fn render(
&self,
ctx: &window_of_opportunity::state::Ctx,
mut children: Vec<Box<window_of_opportunity::element::Element>>,
) -> Box<window_of_opportunity::element::Element> {
let first = ctx.use_state("first", || true);
let switch = ctx.set_state(
"first",
|f: &mut bool| if *f == true { *f = false } else { *f = true },
);
let text = if first {
"first from pane"
} else {
"second from pane"
};
if children.is_empty() {
ui! { Div {
{ Button on_click(switch) {{ Text text.to_string()}}}
{ List rows(2usize) on_display_item(|ctx, row| {
let first = ctx.use_state("first", || true);
let items = if first { ["one", "two"] } else { ["ein", "zwei"] };
let color = if row == 0 { "blue" } else { "green" };
ui! {
Div height(24.) padding(4.) background(color) {
{ Text format!("row {row}: {}", items[row]) }
}
}
}) }
}
}
} else {
let child = children.remove(0);
ui! { Div { CHILDREN child }}
}
}
}
#[derive(Debug, Default)]
struct Typing {}
impl Component for Typing {
fn render(
&self,
ctx: &window_of_opportunity::state::Ctx,
_children: Vec<Box<window_of_opportunity::element::Element>>,
) -> Box<window_of_opportunity::element::Element> {
let text = ctx.use_state("text", || String::new());
ui! {
Div direction("column") gap(6.) {
{ Text format!("echo: {text}") }
{ Input value(text) placeholder("type here...")
on_change(|state, t| state.update("text", |s: &mut String| *s = t)) }
}
}
}
}
#[derive(Debug, Default)]
struct Window {}
impl Component for Window {
fn render(
&self,
ctx: &window_of_opportunity::state::Ctx,
_children: Vec<Box<window_of_opportunity::element::Element>>,
) -> Box<window_of_opportunity::element::Element> {
let (w, h) = ctx.use_state("window/size", || (640., 820.));
let first = ctx.use_state("first", || true);
let title = if first {
"One message"
} else {
"Another message"
};
ui! {
Window width(w) height(h) title(title)
on_resize(|state, w, h|
state.update("window/size", |s: &mut (f64, f64)| *s = (w, h))) {
{ Div direction("column") gap(10.) padding(16.) {
{ Pane }
{ Div height(80.) background("blue") {} }
{ Div direction("row") gap(10.) height(60.) {
{ Button { Text "Hello, and this should mean a bigger button" } }
{ Button { Text "Two" } }
{ Div width(80.) background("red") {} }
} }
{ Counter thing("blah".into())} { Typing }
{ Div height(40.) background("green") {} } } }
}
}
}
}
fn main() {
let window = Box::new(Window {});
let app = Application {};
app.run(window, |_state, _message: ()| ())
}