#[path = "utils/ui.rs"]
mod ui;
use gpui::{App, Application, Bounds, Window, WindowBounds, WindowOptions, prelude::*, px, size};
use gpui_tea::{Command, Dispatcher, IntoView, Model, ModelContext, Program, View};
#[derive(Clone, Copy)]
enum Msg {
Increment,
Reset,
}
struct Counter {
value: i32,
}
impl Model for Counter {
type Msg = Msg;
fn update(
&mut self,
msg: Self::Msg,
_cx: &mut App,
_scope: &ModelContext<Self::Msg>,
) -> Command<Self::Msg> {
match msg {
Msg::Increment => self.value += 1,
Msg::Reset => self.value = 0,
}
Command::none()
}
fn view(
&self,
_window: &mut Window,
_cx: &mut App,
_scope: &ModelContext<Self::Msg>,
dispatcher: &Dispatcher<Self::Msg>,
) -> View {
ui::AppFrame::new().child(
ui::Card::new()
.child(ui::Text::new(
ui::TextRole::Eyebrow,
"gpui_tea example",
))
.child(ui::Text::new(
ui::TextRole::Title,
"Minimal mounted program",
))
.child(ui::Text::new(
ui::TextRole::Body,
"A mounted Program owns state and receives follow-up messages through Dispatcher.",
))
.child(ui::Metric::new(self.value.to_string()))
.child(
ui::action_row()
.child(
ui::Button::new("increment", "Increment")
.variant(ui::ButtonVariant::Primary)
.build()
.on_click({
let dispatcher = dispatcher.clone();
move |_event, _window, _cx| {
dispatcher
.dispatch(Msg::Increment)
.expect("the mounted counter program should accept increment clicks");
}
}),
)
.child(
ui::Button::new("reset", "Reset")
.variant(ui::ButtonVariant::Outline)
.build()
.on_click({
let dispatcher = dispatcher.clone();
move |_event, _window, _cx| {
dispatcher
.dispatch(Msg::Reset)
.expect("the mounted counter program should accept reset clicks");
}
}),
),
),
)
.into_view()
}
}
fn main() {
Application::new().run(|cx: &mut App| {
let bounds = Bounds::centered(None, size(px(800.0), px(600.0)), cx);
cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
..Default::default()
},
|_, cx| Program::mount(Counter { value: 0 }, cx),
)
.unwrap();
cx.activate(true);
});
}