window.rs

  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}