window_positioning.rs

  1#![cfg_attr(target_family = "wasm", no_main)]
  2
  3use gpui::{
  4    App, Bounds, Context, DisplayId, Hsla, Pixels, SharedString, Size, Window,
  5    WindowBackgroundAppearance, WindowBounds, WindowKind, WindowOptions, div, point, prelude::*,
  6    px, rgb,
  7};
  8use gpui_platform::application;
  9
 10struct WindowContent {
 11    text: SharedString,
 12    bounds: Bounds<Pixels>,
 13    bg: Hsla,
 14}
 15
 16impl Render for WindowContent {
 17    fn render(&mut self, window: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
 18        let window_bounds = window.bounds();
 19
 20        div()
 21            .flex()
 22            .flex_col()
 23            .bg(self.bg)
 24            .size_full()
 25            .items_center()
 26            .text_color(rgb(0xffffff))
 27            .child(self.text.clone())
 28            .child(
 29                div()
 30                    .flex()
 31                    .flex_col()
 32                    .text_sm()
 33                    .items_center()
 34                    .size_full()
 35                    .child(format!(
 36                        "origin: {}, {} size: {}, {}",
 37                        self.bounds.origin.x,
 38                        self.bounds.origin.y,
 39                        self.bounds.size.width,
 40                        self.bounds.size.height
 41                    ))
 42                    .child(format!(
 43                        "cx.bounds() origin: {}, {} size {}, {}",
 44                        window_bounds.origin.x,
 45                        window_bounds.origin.y,
 46                        window_bounds.size.width,
 47                        window_bounds.size.height
 48                    )),
 49            )
 50    }
 51}
 52
 53fn build_window_options(display_id: DisplayId, bounds: Bounds<Pixels>) -> WindowOptions {
 54    WindowOptions {
 55        // Set the bounds of the window in screen coordinates
 56        window_bounds: Some(WindowBounds::Windowed(bounds)),
 57        // Specify the display_id to ensure the window is created on the correct screen
 58        display_id: Some(display_id),
 59        titlebar: None,
 60        window_background: WindowBackgroundAppearance::Transparent,
 61        focus: false,
 62        show: true,
 63        kind: WindowKind::PopUp,
 64        is_movable: false,
 65        app_id: None,
 66        window_min_size: None,
 67        window_decorations: None,
 68        tabbing_identifier: None,
 69        ..Default::default()
 70    }
 71}
 72
 73fn run_example() {
 74    application().run(|cx: &mut App| {
 75        // Create several new windows, positioned in the top right corner of each screen
 76        let size = Size {
 77            width: px(350.),
 78            height: px(75.),
 79        };
 80        let margin_offset = px(150.);
 81
 82        for screen in cx.displays() {
 83            let bounds = Bounds {
 84                origin: point(margin_offset, margin_offset),
 85                size,
 86            };
 87
 88            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
 89                cx.new(|_| WindowContent {
 90                    text: format!("Top Left {:?}", screen.id()).into(),
 91                    bg: gpui::red(),
 92                    bounds,
 93                })
 94            })
 95            .unwrap();
 96
 97            let bounds = Bounds {
 98                origin: screen.bounds().top_right()
 99                    - point(size.width + margin_offset, -margin_offset),
100                size,
101            };
102
103            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
104                cx.new(|_| WindowContent {
105                    text: format!("Top Right {:?}", screen.id()).into(),
106                    bg: gpui::red(),
107                    bounds,
108                })
109            })
110            .unwrap();
111
112            let bounds = Bounds {
113                origin: screen.bounds().bottom_left()
114                    - point(-margin_offset, size.height + margin_offset),
115                size,
116            };
117
118            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
119                cx.new(|_| WindowContent {
120                    text: format!("Bottom Left {:?}", screen.id()).into(),
121                    bg: gpui::blue(),
122                    bounds,
123                })
124            })
125            .unwrap();
126
127            let bounds = Bounds {
128                origin: screen.bounds().bottom_right()
129                    - point(size.width + margin_offset, size.height + margin_offset),
130                size,
131            };
132
133            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
134                cx.new(|_| WindowContent {
135                    text: format!("Bottom Right {:?}", screen.id()).into(),
136                    bg: gpui::blue(),
137                    bounds,
138                })
139            })
140            .unwrap();
141
142            let bounds = Bounds {
143                origin: point(screen.bounds().center().x - size.center().x, margin_offset),
144                size,
145            };
146
147            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
148                cx.new(|_| WindowContent {
149                    text: format!("Top Center {:?}", screen.id()).into(),
150                    bg: gpui::black(),
151                    bounds,
152                })
153            })
154            .unwrap();
155
156            let bounds = Bounds {
157                origin: point(margin_offset, screen.bounds().center().y - size.center().y),
158                size,
159            };
160
161            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
162                cx.new(|_| WindowContent {
163                    text: format!("Left Center {:?}", screen.id()).into(),
164                    bg: gpui::black(),
165                    bounds,
166                })
167            })
168            .unwrap();
169
170            let bounds = Bounds {
171                origin: point(
172                    screen.bounds().center().x - size.center().x,
173                    screen.bounds().center().y - size.center().y,
174                ),
175                size,
176            };
177
178            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
179                cx.new(|_| WindowContent {
180                    text: format!("Center {:?}", screen.id()).into(),
181                    bg: gpui::black(),
182                    bounds,
183                })
184            })
185            .unwrap();
186
187            let bounds = Bounds {
188                origin: point(
189                    screen.bounds().size.width - size.width - margin_offset,
190                    screen.bounds().center().y - size.center().y,
191                ),
192                size,
193            };
194
195            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
196                cx.new(|_| WindowContent {
197                    text: format!("Right Center {:?}", screen.id()).into(),
198                    bg: gpui::black(),
199                    bounds,
200                })
201            })
202            .unwrap();
203
204            let bounds = Bounds {
205                origin: point(
206                    screen.bounds().center().x - size.center().x,
207                    screen.bounds().size.height - size.height - margin_offset,
208                ),
209                size,
210            };
211
212            cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
213                cx.new(|_| WindowContent {
214                    text: format!("Bottom Center {:?}", screen.id()).into(),
215                    bg: gpui::black(),
216                    bounds,
217                })
218            })
219            .unwrap();
220        }
221    });
222}
223
224#[cfg(not(target_family = "wasm"))]
225fn main() {
226    run_example();
227}
228
229#[cfg(target_family = "wasm")]
230#[wasm_bindgen::prelude::wasm_bindgen(start)]
231pub fn start() {
232    gpui_platform::web_init();
233    run_example();
234}