1use gpui::{
2 App, Application, Bounds, Context, Window, WindowBounds, WindowOptions, div, prelude::*, px,
3 rgb, size,
4};
5use gpui_hooks::{HookedRender, hook_element};
6use gpui_hooks::hooks::{UseCallbackHook, UseEffectHook, UseMemoHook, UseRefHook, UseStateHook};
8
9#[hook_element]
10struct CounterApp {}
11
12impl HookedRender for CounterApp {
13 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
14 let (count, set_count) = self.use_state(|| 0i32);
16
17 let count_val = count();
19 let doubled = self.use_memo(|| count_val * 2, [count_val]);
20
21 self.use_effect(
23 || {
24 println!("Effect: count changed to {}", count_val);
25 Some(|| {
27 println!("Effect cleanup: previous effect is being cleaned up");
28 })
29 },
30 [count_val],
31 );
32
33 let prev_count_ref = self.use_ref(|| 0i32);
35 let current_count = count_val;
36
37 if current_count != *prev_count_ref.borrow() {
39 *prev_count_ref.borrow_mut() = current_count;
40 }
41
42 let handle_increment = self.use_callback(
44 || {
45 let count_val = current_count;
46 Box::new(move || {
47 println!("Callback executed with count: {}", count_val);
48 count_val + 1
49 }) as Box<dyn Fn() -> i32>
50 },
51 [current_count],
52 );
53
54 div()
55 .flex()
56 .flex_col()
57 .gap_3()
58 .bg(rgb(0x2d2d2d))
59 .size(px(500.0))
60 .justify_center()
61 .items_center()
62 .shadow_lg()
63 .border_1()
64 .border_color(rgb(0x555555))
65 .text_xl()
66 .text_color(rgb(0xffffff))
67 .child(format!("Count: {}", count()))
69 .child(format!("Doubled (useMemo): {}", doubled()))
71 .child(format!(
73 "Previous count (useRef): {}",
74 *prev_count_ref.borrow()
75 ))
76 .child("Check console for effect and callback logs")
78 .child(div().child("click me").id("counter").on_click(cx.listener(
79 move |_this, _, _window, cx| {
80 set_count(count() + 1);
81 cx.notify();
82 },
83 )))
84 .child(
86 div()
87 .child("test callback")
88 .id("callback-test")
89 .on_click(cx.listener(move |_this, _, _window, _cx| {
90 let result = handle_increment();
91 println!("Callback returned: {}", result);
92 })),
93 )
94 }
95}
96
97fn main() {
98 Application::new().run(|cx: &mut App| {
99 let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx);
100 cx.open_window(
101 WindowOptions {
102 window_bounds: Some(WindowBounds::Windowed(bounds)),
103 ..Default::default()
104 },
105 |_, cx| {
106 cx.new(|_| CounterApp {
107 ..Default::default()
108 })
109 },
110 )
111 .unwrap();
112 });
113}