pub struct WindowConfig { /* private fields */ }
Expand description
Window configuration that can be applied to a WindowBuilder, or to an existing WindowHandle. It does not include anything related to app data.
Implementations§
Source§impl WindowConfig
impl WindowConfig
Sourcepub fn window_size_policy(self, size_policy: WindowSizePolicy) -> Self
pub fn window_size_policy(self, size_policy: WindowSizePolicy) -> Self
Set the window size policy.
Examples found in repository?
99 fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
100 let wait_duration = Duration::from_millis(500);
101 let resched_dur = Duration::from_millis(50);
102 let cursor_size = Size::new(15., 15.);
103 let now = Instant::now();
104 let new_state = match &self.state {
105 TooltipState::Fresh => match event {
106 Event::MouseMove(me) if ctx.is_hot() => Some(TooltipState::Waiting {
107 last_move: now,
108 timer_expire: now + wait_duration,
109 token: ctx.request_timer(wait_duration),
110 position_in_window_coordinates: me.window_pos,
111 }),
112 _ => None,
113 },
114 TooltipState::Waiting {
115 last_move,
116 timer_expire,
117 token,
118 position_in_window_coordinates,
119 } => match event {
120 Event::MouseMove(me) if ctx.is_hot() => {
121 let (cur_token, cur_expire) = if *timer_expire - now < resched_dur {
122 (ctx.request_timer(wait_duration), now + wait_duration)
123 } else {
124 (*token, *timer_expire)
125 };
126 Some(TooltipState::Waiting {
127 last_move: now,
128 timer_expire: cur_expire,
129 token: cur_token,
130 position_in_window_coordinates: me.window_pos,
131 })
132 }
133 Event::Timer(tok) if tok == token => {
134 let deadline = *last_move + wait_duration;
135 ctx.set_handled();
136 if deadline > now {
137 let wait_for = deadline - now;
138 tracing::info!("Waiting another {:?}", wait_for);
139 Some(TooltipState::Waiting {
140 last_move: *last_move,
141 timer_expire: deadline,
142 token: ctx.request_timer(wait_for),
143 position_in_window_coordinates: *position_in_window_coordinates,
144 })
145 } else {
146 let tooltip_position_in_window_coordinates =
147 (position_in_window_coordinates.to_vec2() + cursor_size.to_vec2())
148 .to_point();
149 let win_id = ctx.new_sub_window(
150 WindowConfig::default()
151 .show_titlebar(false)
152 .window_size_policy(WindowSizePolicy::Content)
153 .set_level(WindowLevel::Tooltip(ctx.window().clone()))
154 .set_position(tooltip_position_in_window_coordinates),
155 Label::<()>::new(self.tip.clone()),
156 (),
157 env.clone(),
158 );
159 Some(TooltipState::Showing(win_id))
160 }
161 }
162 _ => None,
163 },
164 TooltipState::Showing(win_id) => {
165 match event {
166 Event::MouseMove(me) if !ctx.is_hot() => {
167 // TODO another timer on leaving
168 tracing::info!("Sending close window for {:?}", win_id);
169 ctx.submit_command(CLOSE_WINDOW.to(*win_id));
170 Some(TooltipState::Waiting {
171 last_move: now,
172 timer_expire: now + wait_duration,
173 token: ctx.request_timer(wait_duration),
174 position_in_window_coordinates: me.window_pos,
175 })
176 }
177 _ => None,
178 }
179 }
180 };
181
182 if let Some(state) = new_state {
183 self.state = state;
184 }
185
186 if !ctx.is_handled() {
187 child.event(ctx, event, data, env);
188 }
189 }
Sourcepub fn window_size(self, size: impl Into<Size>) -> Self
pub fn window_size(self, size: impl Into<Size>) -> Self
Set the window’s initial drawing area size in display points.
You can pass in a tuple (width, height)
or a Size
,
e.g. to create a window with a drawing area 1000dp wide and 500dp high:
window.window_size((1000.0, 500.0));
The actual window size in pixels will depend on the platform DPI settings.
This should be considered a request to the platform to set the size of the window. The platform might increase the size a tiny bit due to DPI.
Examples found in repository?
332fn build_root_widget() -> impl Widget<HelloState> {
333 let label = EnvScope::new(
334 |env, _t| env.set(theme::TEXT_COLOR, env.get(theme::PRIMARY_LIGHT)),
335 ControllerHost::new(
336 Label::new(|data: &HelloState, _env: &Env| {
337 format!("Hello {}! {} ", data.name, data.sub.my_stuff)
338 }),
339 TooltipController::new("Tips! Are good"),
340 ),
341 );
342 // a textbox that modifies `name`.
343 let textbox = TextBox::new()
344 .with_placeholder("Who are we greeting?")
345 .fix_width(TEXT_BOX_WIDTH)
346 .lens(HelloState::sub.then(SubState::my_stuff));
347
348 let button = Button::new("Make sub window")
349 .on_click(|ctx, data: &mut SubState, env| {
350 let tb = TextBox::new().lens(SubState::my_stuff);
351 let drag_thing = Label::new("Drag me").controller(DragWindowController::new());
352 let col = Flex::column().with_child(drag_thing).with_child(tb);
353
354 ctx.new_sub_window(
355 WindowConfig::default()
356 .show_titlebar(false)
357 .window_size(Size::new(100., 100.))
358 .set_level(WindowLevel::AppWindow),
359 col,
360 data.clone(),
361 env.clone(),
362 );
363 })
364 .center()
365 .lens(HelloState::sub);
366
367 let check_box =
368 ControllerHost::new(Checkbox::new("Closeable?"), CancelClose).lens(HelloState::closeable);
369 // arrange the two widgets vertically, with some padding
370 let layout = Flex::column()
371 .with_child(label)
372 .with_flex_child(ScreenThing.lens(Unit::default()).padding(5.), 1.)
373 .with_spacer(VERTICAL_WIDGET_SPACING)
374 .with_child(textbox)
375 .with_child(button)
376 .with_child(check_box);
377
378 // center the two widgets in the available space
379 Align::centered(layout)
380}
Sourcepub fn with_min_size(self, size: impl Into<Size>) -> Self
pub fn with_min_size(self, size: impl Into<Size>) -> Self
Set the window’s minimum drawing area size in display points.
The actual minimum window size in pixels will depend on the platform DPI settings.
This should be considered a request to the platform to set the minimum size of the window. The platform might increase the size a tiny bit due to DPI.
To set the window’s initial drawing area size use window_size
.
Sourcepub fn show_titlebar(self, show_titlebar: bool) -> Self
pub fn show_titlebar(self, show_titlebar: bool) -> Self
Set whether the window should have a titlebar and decorations.
Examples found in repository?
99 fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
100 let wait_duration = Duration::from_millis(500);
101 let resched_dur = Duration::from_millis(50);
102 let cursor_size = Size::new(15., 15.);
103 let now = Instant::now();
104 let new_state = match &self.state {
105 TooltipState::Fresh => match event {
106 Event::MouseMove(me) if ctx.is_hot() => Some(TooltipState::Waiting {
107 last_move: now,
108 timer_expire: now + wait_duration,
109 token: ctx.request_timer(wait_duration),
110 position_in_window_coordinates: me.window_pos,
111 }),
112 _ => None,
113 },
114 TooltipState::Waiting {
115 last_move,
116 timer_expire,
117 token,
118 position_in_window_coordinates,
119 } => match event {
120 Event::MouseMove(me) if ctx.is_hot() => {
121 let (cur_token, cur_expire) = if *timer_expire - now < resched_dur {
122 (ctx.request_timer(wait_duration), now + wait_duration)
123 } else {
124 (*token, *timer_expire)
125 };
126 Some(TooltipState::Waiting {
127 last_move: now,
128 timer_expire: cur_expire,
129 token: cur_token,
130 position_in_window_coordinates: me.window_pos,
131 })
132 }
133 Event::Timer(tok) if tok == token => {
134 let deadline = *last_move + wait_duration;
135 ctx.set_handled();
136 if deadline > now {
137 let wait_for = deadline - now;
138 tracing::info!("Waiting another {:?}", wait_for);
139 Some(TooltipState::Waiting {
140 last_move: *last_move,
141 timer_expire: deadline,
142 token: ctx.request_timer(wait_for),
143 position_in_window_coordinates: *position_in_window_coordinates,
144 })
145 } else {
146 let tooltip_position_in_window_coordinates =
147 (position_in_window_coordinates.to_vec2() + cursor_size.to_vec2())
148 .to_point();
149 let win_id = ctx.new_sub_window(
150 WindowConfig::default()
151 .show_titlebar(false)
152 .window_size_policy(WindowSizePolicy::Content)
153 .set_level(WindowLevel::Tooltip(ctx.window().clone()))
154 .set_position(tooltip_position_in_window_coordinates),
155 Label::<()>::new(self.tip.clone()),
156 (),
157 env.clone(),
158 );
159 Some(TooltipState::Showing(win_id))
160 }
161 }
162 _ => None,
163 },
164 TooltipState::Showing(win_id) => {
165 match event {
166 Event::MouseMove(me) if !ctx.is_hot() => {
167 // TODO another timer on leaving
168 tracing::info!("Sending close window for {:?}", win_id);
169 ctx.submit_command(CLOSE_WINDOW.to(*win_id));
170 Some(TooltipState::Waiting {
171 last_move: now,
172 timer_expire: now + wait_duration,
173 token: ctx.request_timer(wait_duration),
174 position_in_window_coordinates: me.window_pos,
175 })
176 }
177 _ => None,
178 }
179 }
180 };
181
182 if let Some(state) = new_state {
183 self.state = state;
184 }
185
186 if !ctx.is_handled() {
187 child.event(ctx, event, data, env);
188 }
189 }
190
191 fn lifecycle(
192 &mut self,
193 child: &mut W,
194 ctx: &mut LifeCycleCtx,
195 event: &LifeCycle,
196 data: &T,
197 env: &Env,
198 ) {
199 if let LifeCycle::HotChanged(false) = event {
200 if let TooltipState::Showing(win_id) = self.state {
201 ctx.submit_command(CLOSE_WINDOW.to(win_id));
202 }
203 self.state = TooltipState::Fresh;
204 }
205 child.lifecycle(ctx, event, data, env)
206 }
207}
208
209struct DragWindowController {
210 init_pos: Option<Point>,
211 //dragging: bool
212}
213
214impl DragWindowController {
215 pub fn new() -> Self {
216 DragWindowController { init_pos: None }
217 }
218}
219
220impl<T, W: Widget<T>> Controller<T, W> for DragWindowController {
221 fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
222 match event {
223 Event::MouseDown(me) if me.buttons.has_left() => {
224 ctx.set_active(true);
225 self.init_pos = Some(me.window_pos)
226 }
227 Event::MouseMove(me) if ctx.is_active() && me.buttons.has_left() => {
228 if let Some(init_pos) = self.init_pos {
229 let within_window_change = me.window_pos.to_vec2() - init_pos.to_vec2();
230 let old_pos = ctx.window().get_position();
231 let new_pos = old_pos + within_window_change;
232 tracing::info!(
233 "Drag {:?} ",
234 (
235 init_pos,
236 me.window_pos,
237 within_window_change,
238 old_pos,
239 new_pos
240 )
241 );
242 ctx.window().set_position(new_pos)
243 }
244 }
245 Event::MouseUp(_me) if ctx.is_active() => {
246 self.init_pos = None;
247 ctx.set_active(false)
248 }
249 _ => (),
250 }
251 child.event(ctx, event, data, env)
252 }
253}
254
255struct ScreenThing;
256
257impl Widget<()> for ScreenThing {
258 fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut (), _env: &Env) {}
259
260 fn lifecycle(&mut self, _ctx: &mut LifeCycleCtx, _event: &LifeCycle, _data: &(), _env: &Env) {}
261
262 fn update(&mut self, _ctx: &mut UpdateCtx, _old_data: &(), _data: &(), _env: &Env) {}
263
264 fn layout(
265 &mut self,
266 _ctx: &mut LayoutCtx,
267 bc: &BoxConstraints,
268 _data: &(),
269 _env: &Env,
270 ) -> Size {
271 bc.constrain(Size::new(800.0, 600.0))
272 }
273
274 fn paint(&mut self, ctx: &mut PaintCtx, _data: &(), env: &Env) {
275 let sz = ctx.size();
276
277 let monitors = Screen::get_monitors();
278 let all = monitors
279 .iter()
280 .map(|x| x.virtual_rect())
281 .fold(Rect::ZERO, |s, r| r.union(s));
282 if all.width() > 0. && all.height() > 0. {
283 let trans = Affine::scale(f64::min(sz.width / all.width(), sz.height / all.height()))
284 * Affine::translate(all.origin().to_vec2()).inverse();
285 let font = env.get(theme::UI_FONT).family;
286
287 for (i, mon) in monitors.iter().enumerate() {
288 let vr = mon.virtual_rect();
289 let tr = trans.transform_rect_bbox(vr);
290 ctx.stroke(tr, &Color::WHITE, 1.0);
291
292 if let Ok(tl) = ctx
293 .text()
294 .new_text_layout(format!(
295 "{}:{}x{}@{},{}",
296 i,
297 vr.width(),
298 vr.height(),
299 vr.x0,
300 vr.y0
301 ))
302 .max_width(tr.width() - 5.)
303 .font(font.clone(), env.get(theme::TEXT_SIZE_NORMAL))
304 .text_color(Color::WHITE)
305 .build()
306 {
307 ctx.draw_text(&tl, tr.center() - tl.size().to_vec2() * 0.5);
308 }
309 }
310 }
311 }
312}
313
314struct CancelClose;
315
316impl<W: Widget<bool>> Controller<bool, W> for CancelClose {
317 fn event(
318 &mut self,
319 w: &mut W,
320 ctx: &mut EventCtx<'_, '_>,
321 event: &Event,
322 data: &mut bool,
323 env: &Env,
324 ) {
325 match (&data, event) {
326 (false, Event::WindowCloseRequested) => ctx.set_handled(),
327 _ => w.event(ctx, event, data, env),
328 }
329 }
330}
331
332fn build_root_widget() -> impl Widget<HelloState> {
333 let label = EnvScope::new(
334 |env, _t| env.set(theme::TEXT_COLOR, env.get(theme::PRIMARY_LIGHT)),
335 ControllerHost::new(
336 Label::new(|data: &HelloState, _env: &Env| {
337 format!("Hello {}! {} ", data.name, data.sub.my_stuff)
338 }),
339 TooltipController::new("Tips! Are good"),
340 ),
341 );
342 // a textbox that modifies `name`.
343 let textbox = TextBox::new()
344 .with_placeholder("Who are we greeting?")
345 .fix_width(TEXT_BOX_WIDTH)
346 .lens(HelloState::sub.then(SubState::my_stuff));
347
348 let button = Button::new("Make sub window")
349 .on_click(|ctx, data: &mut SubState, env| {
350 let tb = TextBox::new().lens(SubState::my_stuff);
351 let drag_thing = Label::new("Drag me").controller(DragWindowController::new());
352 let col = Flex::column().with_child(drag_thing).with_child(tb);
353
354 ctx.new_sub_window(
355 WindowConfig::default()
356 .show_titlebar(false)
357 .window_size(Size::new(100., 100.))
358 .set_level(WindowLevel::AppWindow),
359 col,
360 data.clone(),
361 env.clone(),
362 );
363 })
364 .center()
365 .lens(HelloState::sub);
366
367 let check_box =
368 ControllerHost::new(Checkbox::new("Closeable?"), CancelClose).lens(HelloState::closeable);
369 // arrange the two widgets vertically, with some padding
370 let layout = Flex::column()
371 .with_child(label)
372 .with_flex_child(ScreenThing.lens(Unit::default()).padding(5.), 1.)
373 .with_spacer(VERTICAL_WIDGET_SPACING)
374 .with_child(textbox)
375 .with_child(button)
376 .with_child(check_box);
377
378 // center the two widgets in the available space
379 Align::centered(layout)
380}
Sourcepub fn set_position(self, position: Point) -> Self
pub fn set_position(self, position: Point) -> Self
Sets the window position in virtual screen coordinates.
position
Position in pixels.
Examples found in repository?
99 fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
100 let wait_duration = Duration::from_millis(500);
101 let resched_dur = Duration::from_millis(50);
102 let cursor_size = Size::new(15., 15.);
103 let now = Instant::now();
104 let new_state = match &self.state {
105 TooltipState::Fresh => match event {
106 Event::MouseMove(me) if ctx.is_hot() => Some(TooltipState::Waiting {
107 last_move: now,
108 timer_expire: now + wait_duration,
109 token: ctx.request_timer(wait_duration),
110 position_in_window_coordinates: me.window_pos,
111 }),
112 _ => None,
113 },
114 TooltipState::Waiting {
115 last_move,
116 timer_expire,
117 token,
118 position_in_window_coordinates,
119 } => match event {
120 Event::MouseMove(me) if ctx.is_hot() => {
121 let (cur_token, cur_expire) = if *timer_expire - now < resched_dur {
122 (ctx.request_timer(wait_duration), now + wait_duration)
123 } else {
124 (*token, *timer_expire)
125 };
126 Some(TooltipState::Waiting {
127 last_move: now,
128 timer_expire: cur_expire,
129 token: cur_token,
130 position_in_window_coordinates: me.window_pos,
131 })
132 }
133 Event::Timer(tok) if tok == token => {
134 let deadline = *last_move + wait_duration;
135 ctx.set_handled();
136 if deadline > now {
137 let wait_for = deadline - now;
138 tracing::info!("Waiting another {:?}", wait_for);
139 Some(TooltipState::Waiting {
140 last_move: *last_move,
141 timer_expire: deadline,
142 token: ctx.request_timer(wait_for),
143 position_in_window_coordinates: *position_in_window_coordinates,
144 })
145 } else {
146 let tooltip_position_in_window_coordinates =
147 (position_in_window_coordinates.to_vec2() + cursor_size.to_vec2())
148 .to_point();
149 let win_id = ctx.new_sub_window(
150 WindowConfig::default()
151 .show_titlebar(false)
152 .window_size_policy(WindowSizePolicy::Content)
153 .set_level(WindowLevel::Tooltip(ctx.window().clone()))
154 .set_position(tooltip_position_in_window_coordinates),
155 Label::<()>::new(self.tip.clone()),
156 (),
157 env.clone(),
158 );
159 Some(TooltipState::Showing(win_id))
160 }
161 }
162 _ => None,
163 },
164 TooltipState::Showing(win_id) => {
165 match event {
166 Event::MouseMove(me) if !ctx.is_hot() => {
167 // TODO another timer on leaving
168 tracing::info!("Sending close window for {:?}", win_id);
169 ctx.submit_command(CLOSE_WINDOW.to(*win_id));
170 Some(TooltipState::Waiting {
171 last_move: now,
172 timer_expire: now + wait_duration,
173 token: ctx.request_timer(wait_duration),
174 position_in_window_coordinates: me.window_pos,
175 })
176 }
177 _ => None,
178 }
179 }
180 };
181
182 if let Some(state) = new_state {
183 self.state = state;
184 }
185
186 if !ctx.is_handled() {
187 child.event(ctx, event, data, env);
188 }
189 }
Sourcepub fn set_level(self, level: WindowLevel) -> Self
pub fn set_level(self, level: WindowLevel) -> Self
Sets the WindowLevel
of the window
Examples found in repository?
99 fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
100 let wait_duration = Duration::from_millis(500);
101 let resched_dur = Duration::from_millis(50);
102 let cursor_size = Size::new(15., 15.);
103 let now = Instant::now();
104 let new_state = match &self.state {
105 TooltipState::Fresh => match event {
106 Event::MouseMove(me) if ctx.is_hot() => Some(TooltipState::Waiting {
107 last_move: now,
108 timer_expire: now + wait_duration,
109 token: ctx.request_timer(wait_duration),
110 position_in_window_coordinates: me.window_pos,
111 }),
112 _ => None,
113 },
114 TooltipState::Waiting {
115 last_move,
116 timer_expire,
117 token,
118 position_in_window_coordinates,
119 } => match event {
120 Event::MouseMove(me) if ctx.is_hot() => {
121 let (cur_token, cur_expire) = if *timer_expire - now < resched_dur {
122 (ctx.request_timer(wait_duration), now + wait_duration)
123 } else {
124 (*token, *timer_expire)
125 };
126 Some(TooltipState::Waiting {
127 last_move: now,
128 timer_expire: cur_expire,
129 token: cur_token,
130 position_in_window_coordinates: me.window_pos,
131 })
132 }
133 Event::Timer(tok) if tok == token => {
134 let deadline = *last_move + wait_duration;
135 ctx.set_handled();
136 if deadline > now {
137 let wait_for = deadline - now;
138 tracing::info!("Waiting another {:?}", wait_for);
139 Some(TooltipState::Waiting {
140 last_move: *last_move,
141 timer_expire: deadline,
142 token: ctx.request_timer(wait_for),
143 position_in_window_coordinates: *position_in_window_coordinates,
144 })
145 } else {
146 let tooltip_position_in_window_coordinates =
147 (position_in_window_coordinates.to_vec2() + cursor_size.to_vec2())
148 .to_point();
149 let win_id = ctx.new_sub_window(
150 WindowConfig::default()
151 .show_titlebar(false)
152 .window_size_policy(WindowSizePolicy::Content)
153 .set_level(WindowLevel::Tooltip(ctx.window().clone()))
154 .set_position(tooltip_position_in_window_coordinates),
155 Label::<()>::new(self.tip.clone()),
156 (),
157 env.clone(),
158 );
159 Some(TooltipState::Showing(win_id))
160 }
161 }
162 _ => None,
163 },
164 TooltipState::Showing(win_id) => {
165 match event {
166 Event::MouseMove(me) if !ctx.is_hot() => {
167 // TODO another timer on leaving
168 tracing::info!("Sending close window for {:?}", win_id);
169 ctx.submit_command(CLOSE_WINDOW.to(*win_id));
170 Some(TooltipState::Waiting {
171 last_move: now,
172 timer_expire: now + wait_duration,
173 token: ctx.request_timer(wait_duration),
174 position_in_window_coordinates: me.window_pos,
175 })
176 }
177 _ => None,
178 }
179 }
180 };
181
182 if let Some(state) = new_state {
183 self.state = state;
184 }
185
186 if !ctx.is_handled() {
187 child.event(ctx, event, data, env);
188 }
189 }
190
191 fn lifecycle(
192 &mut self,
193 child: &mut W,
194 ctx: &mut LifeCycleCtx,
195 event: &LifeCycle,
196 data: &T,
197 env: &Env,
198 ) {
199 if let LifeCycle::HotChanged(false) = event {
200 if let TooltipState::Showing(win_id) = self.state {
201 ctx.submit_command(CLOSE_WINDOW.to(win_id));
202 }
203 self.state = TooltipState::Fresh;
204 }
205 child.lifecycle(ctx, event, data, env)
206 }
207}
208
209struct DragWindowController {
210 init_pos: Option<Point>,
211 //dragging: bool
212}
213
214impl DragWindowController {
215 pub fn new() -> Self {
216 DragWindowController { init_pos: None }
217 }
218}
219
220impl<T, W: Widget<T>> Controller<T, W> for DragWindowController {
221 fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
222 match event {
223 Event::MouseDown(me) if me.buttons.has_left() => {
224 ctx.set_active(true);
225 self.init_pos = Some(me.window_pos)
226 }
227 Event::MouseMove(me) if ctx.is_active() && me.buttons.has_left() => {
228 if let Some(init_pos) = self.init_pos {
229 let within_window_change = me.window_pos.to_vec2() - init_pos.to_vec2();
230 let old_pos = ctx.window().get_position();
231 let new_pos = old_pos + within_window_change;
232 tracing::info!(
233 "Drag {:?} ",
234 (
235 init_pos,
236 me.window_pos,
237 within_window_change,
238 old_pos,
239 new_pos
240 )
241 );
242 ctx.window().set_position(new_pos)
243 }
244 }
245 Event::MouseUp(_me) if ctx.is_active() => {
246 self.init_pos = None;
247 ctx.set_active(false)
248 }
249 _ => (),
250 }
251 child.event(ctx, event, data, env)
252 }
253}
254
255struct ScreenThing;
256
257impl Widget<()> for ScreenThing {
258 fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut (), _env: &Env) {}
259
260 fn lifecycle(&mut self, _ctx: &mut LifeCycleCtx, _event: &LifeCycle, _data: &(), _env: &Env) {}
261
262 fn update(&mut self, _ctx: &mut UpdateCtx, _old_data: &(), _data: &(), _env: &Env) {}
263
264 fn layout(
265 &mut self,
266 _ctx: &mut LayoutCtx,
267 bc: &BoxConstraints,
268 _data: &(),
269 _env: &Env,
270 ) -> Size {
271 bc.constrain(Size::new(800.0, 600.0))
272 }
273
274 fn paint(&mut self, ctx: &mut PaintCtx, _data: &(), env: &Env) {
275 let sz = ctx.size();
276
277 let monitors = Screen::get_monitors();
278 let all = monitors
279 .iter()
280 .map(|x| x.virtual_rect())
281 .fold(Rect::ZERO, |s, r| r.union(s));
282 if all.width() > 0. && all.height() > 0. {
283 let trans = Affine::scale(f64::min(sz.width / all.width(), sz.height / all.height()))
284 * Affine::translate(all.origin().to_vec2()).inverse();
285 let font = env.get(theme::UI_FONT).family;
286
287 for (i, mon) in monitors.iter().enumerate() {
288 let vr = mon.virtual_rect();
289 let tr = trans.transform_rect_bbox(vr);
290 ctx.stroke(tr, &Color::WHITE, 1.0);
291
292 if let Ok(tl) = ctx
293 .text()
294 .new_text_layout(format!(
295 "{}:{}x{}@{},{}",
296 i,
297 vr.width(),
298 vr.height(),
299 vr.x0,
300 vr.y0
301 ))
302 .max_width(tr.width() - 5.)
303 .font(font.clone(), env.get(theme::TEXT_SIZE_NORMAL))
304 .text_color(Color::WHITE)
305 .build()
306 {
307 ctx.draw_text(&tl, tr.center() - tl.size().to_vec2() * 0.5);
308 }
309 }
310 }
311 }
312}
313
314struct CancelClose;
315
316impl<W: Widget<bool>> Controller<bool, W> for CancelClose {
317 fn event(
318 &mut self,
319 w: &mut W,
320 ctx: &mut EventCtx<'_, '_>,
321 event: &Event,
322 data: &mut bool,
323 env: &Env,
324 ) {
325 match (&data, event) {
326 (false, Event::WindowCloseRequested) => ctx.set_handled(),
327 _ => w.event(ctx, event, data, env),
328 }
329 }
330}
331
332fn build_root_widget() -> impl Widget<HelloState> {
333 let label = EnvScope::new(
334 |env, _t| env.set(theme::TEXT_COLOR, env.get(theme::PRIMARY_LIGHT)),
335 ControllerHost::new(
336 Label::new(|data: &HelloState, _env: &Env| {
337 format!("Hello {}! {} ", data.name, data.sub.my_stuff)
338 }),
339 TooltipController::new("Tips! Are good"),
340 ),
341 );
342 // a textbox that modifies `name`.
343 let textbox = TextBox::new()
344 .with_placeholder("Who are we greeting?")
345 .fix_width(TEXT_BOX_WIDTH)
346 .lens(HelloState::sub.then(SubState::my_stuff));
347
348 let button = Button::new("Make sub window")
349 .on_click(|ctx, data: &mut SubState, env| {
350 let tb = TextBox::new().lens(SubState::my_stuff);
351 let drag_thing = Label::new("Drag me").controller(DragWindowController::new());
352 let col = Flex::column().with_child(drag_thing).with_child(tb);
353
354 ctx.new_sub_window(
355 WindowConfig::default()
356 .show_titlebar(false)
357 .window_size(Size::new(100., 100.))
358 .set_level(WindowLevel::AppWindow),
359 col,
360 data.clone(),
361 env.clone(),
362 );
363 })
364 .center()
365 .lens(HelloState::sub);
366
367 let check_box =
368 ControllerHost::new(Checkbox::new("Closeable?"), CancelClose).lens(HelloState::closeable);
369 // arrange the two widgets vertically, with some padding
370 let layout = Flex::column()
371 .with_child(label)
372 .with_flex_child(ScreenThing.lens(Unit::default()).padding(5.), 1.)
373 .with_spacer(VERTICAL_WIDGET_SPACING)
374 .with_child(textbox)
375 .with_child(button)
376 .with_child(check_box);
377
378 // center the two widgets in the available space
379 Align::centered(layout)
380}
Sourcepub fn set_always_on_top(self, always_on_top: bool) -> Self
pub fn set_always_on_top(self, always_on_top: bool) -> Self
Sets whether the window is always on top.
An always on top window stays on top, even after clicking off of it.
Sourcepub fn set_window_state(self, state: WindowState) -> Self
pub fn set_window_state(self, state: WindowState) -> Self
Sets the WindowState
of the window.
Sourcepub fn transparent(self, transparent: bool) -> Self
pub fn transparent(self, transparent: bool) -> Self
Set whether the window background should be transparent
Sourcepub fn apply_to_builder(&self, builder: &mut WindowBuilder)
pub fn apply_to_builder(&self, builder: &mut WindowBuilder)
Apply this window configuration to the passed in WindowBuilder
Sourcepub fn apply_to_handle(&self, win_handle: &mut WindowHandle)
pub fn apply_to_handle(&self, win_handle: &mut WindowHandle)
Apply this window configuration to the passed in WindowHandle