I'm implementing a Rust alternative to .NET's DragMove method however the result causes the application to flicker between two relative positions.
See screencast and sample project .
Code I'm using to perform the drag move:
let mut mouse_down = false;
let mut last_pos: Option<PhysicalPosition<f64>> = None;
event_loop.run(move |event, _, control_flow| match event {
Event::WindowEvent {
event: WindowEvent::CursorMoved {
position,
..
},
..
} => {
let gl_window = display.gl_window();
let window = gl_window.window();
if mouse_down {
if last_pos.is_some() {
let previous_pos = last_pos.unwrap();
let delta_x = previous_pos.x - position.x;
let delta_y = previous_pos.y - position.y;
window.set_outer_position(PhysicalPosition::new(position.x + delta_x, position.y + delta_y));
}
last_pos = Some(position);
}
}
Event::WindowEvent {
event: WindowEvent::MouseInput{
state,
button,
..
},
..
} => {
mouse_down = button == MouseButton::Left && state == ElementState::Pressed;
if !mouse_down {
last_pos = None;
}
}
_ => {}
});
CursorMoved reports
(x,y) coords in pixels relative to the top-left corner of the window .
When you're later using that position to set_outer_position
, you are essentially reinterpreting window-relative coordinates as screen-relative.
You should instead apply the offset to the position returned from outer_position .
While that fixes the immediate problem, I'm not sure it is enough to account for the window movement. When you're handling the next CursorMoved
event, the coordinates are still window-relative, but the window has since moved. That may produce artifacts all over.
A more robust solution would store the window's position when the drag-move operation starts, and offset that position by the accumulated deltas.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.