window_positioning.rs

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