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}