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