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