1use gpui::*;
2use prelude::FluentBuilder as _;
3
4struct SubWindow {
5 custom_titlebar: bool,
6}
7
8fn button(text: &str, on_click: impl Fn(&mut WindowContext) + 'static) -> impl IntoElement {
9 div()
10 .id(SharedString::from(text.to_string()))
11 .flex_none()
12 .px_2()
13 .bg(rgb(0xf7f7f7))
14 .active(|this| this.opacity(0.85))
15 .border_1()
16 .border_color(rgb(0xe0e0e0))
17 .rounded_md()
18 .cursor_pointer()
19 .child(text.to_string())
20 .on_click(move |_, cx| on_click(cx))
21}
22
23impl Render for SubWindow {
24 fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
25 div()
26 .flex()
27 .flex_col()
28 .bg(rgb(0xffffff))
29 .size_full()
30 .gap_2()
31 .when(self.custom_titlebar, |cx| {
32 cx.child(
33 div()
34 .flex()
35 .h(px(32.))
36 .px_4()
37 .bg(gpui::blue())
38 .text_color(gpui::white())
39 .w_full()
40 .child(
41 div()
42 .flex()
43 .items_center()
44 .justify_center()
45 .size_full()
46 .child("Custom Titlebar"),
47 ),
48 )
49 })
50 .child(
51 div()
52 .p_8()
53 .gap_2()
54 .child("SubWindow")
55 .child(button("Close", |cx| {
56 cx.remove_window();
57 })),
58 )
59 }
60}
61
62struct WindowDemo {}
63
64impl Render for WindowDemo {
65 fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
66 let window_bounds =
67 WindowBounds::Windowed(Bounds::centered(None, size(px(300.0), px(300.0)), cx));
68
69 div()
70 .p_4()
71 .flex()
72 .flex_wrap()
73 .bg(rgb(0xffffff))
74 .size_full()
75 .justify_center()
76 .items_center()
77 .gap_2()
78 .child(button("Normal", move |cx| {
79 cx.open_window(
80 WindowOptions {
81 window_bounds: Some(window_bounds),
82 ..Default::default()
83 },
84 |cx| {
85 cx.new_view(|_cx| SubWindow {
86 custom_titlebar: false,
87 })
88 },
89 )
90 .unwrap();
91 }))
92 .child(button("Popup", move |cx| {
93 cx.open_window(
94 WindowOptions {
95 window_bounds: Some(window_bounds),
96 kind: WindowKind::PopUp,
97 ..Default::default()
98 },
99 |cx| {
100 cx.new_view(|_cx| SubWindow {
101 custom_titlebar: false,
102 })
103 },
104 )
105 .unwrap();
106 }))
107 .child(button("Custom Titlebar", move |cx| {
108 cx.open_window(
109 WindowOptions {
110 titlebar: None,
111 window_bounds: Some(window_bounds),
112 ..Default::default()
113 },
114 |cx| {
115 cx.new_view(|_cx| SubWindow {
116 custom_titlebar: true,
117 })
118 },
119 )
120 .unwrap();
121 }))
122 .child(button("Invisible", move |cx| {
123 cx.open_window(
124 WindowOptions {
125 show: false,
126 window_bounds: Some(window_bounds),
127 ..Default::default()
128 },
129 |cx| {
130 cx.new_view(|_cx| SubWindow {
131 custom_titlebar: false,
132 })
133 },
134 )
135 .unwrap();
136 }))
137 .child(button("Unmovable", move |cx| {
138 cx.open_window(
139 WindowOptions {
140 is_movable: false,
141 titlebar: None,
142 window_bounds: Some(window_bounds),
143 ..Default::default()
144 },
145 |cx| {
146 cx.new_view(|_cx| SubWindow {
147 custom_titlebar: false,
148 })
149 },
150 )
151 .unwrap();
152 }))
153 .child(button("Hide Application", |cx| {
154 cx.hide();
155
156 // Restore the application after 3 seconds
157 cx.spawn(|mut cx| async move {
158 Timer::after(std::time::Duration::from_secs(3)).await;
159 cx.update(|cx| {
160 cx.activate(false);
161 })
162 })
163 .detach();
164 }))
165 }
166}
167
168fn main() {
169 App::new().run(|cx: &mut AppContext| {
170 let bounds = Bounds::centered(None, size(px(800.0), px(600.0)), cx);
171 cx.open_window(
172 WindowOptions {
173 window_bounds: Some(WindowBounds::Windowed(bounds)),
174 ..Default::default()
175 },
176 |cx| cx.new_view(|_cx| WindowDemo {}),
177 )
178 .unwrap();
179 });
180}