mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Merge pull request #100444 from Sauermann/fix-view-panner-mouse-warp
Fix `ViewPanner` panning-mouse-warp
This commit is contained in:
commit
cbfc34d279
15 changed files with 64 additions and 7 deletions
|
@ -1377,6 +1377,40 @@ void Viewport::warp_mouse(const Vector2 &p_position) {
|
|||
Input::get_singleton()->warp_mouse(gpos);
|
||||
}
|
||||
|
||||
Point2 Viewport::wrap_mouse_in_rect(const Vector2 &p_relative, const Rect2 &p_rect) {
|
||||
// Move the mouse cursor from its current position to a location bounded by `p_rect`
|
||||
// in accordance with a heuristic that takes the traveled distance `p_relative` of the mouse
|
||||
// into account.
|
||||
|
||||
// All parameters are in viewport coordinates.
|
||||
// p_relative denotes the distance to the previous mouse position.
|
||||
// p_rect denotes the area, in which the mouse should be confined in.
|
||||
|
||||
// The relative distance reported for the next event after a warp is in the boundaries of the
|
||||
// size of the rect on that axis, but it may be greater, in which case there's no problem as
|
||||
// fmod() will warp it, but if the pointer has moved in the opposite direction between the
|
||||
// pointer relocation and the subsequent event, the reported relative distance will be less
|
||||
// than the size of the rect and thus fmod() will be disabled for handling the situation.
|
||||
// And due to this mouse warping mechanism being stateless, we need to apply some heuristics
|
||||
// to detect the warp: if the relative distance is greater than the half of the size of the
|
||||
// relevant rect (checked per each axis), it will be considered as the consequence of a former
|
||||
// pointer warp.
|
||||
|
||||
const Point2 rel_sign(p_relative.x >= 0.0f ? 1 : -1, p_relative.y >= 0.0 ? 1 : -1);
|
||||
const Size2 warp_margin = p_rect.size * 0.5f;
|
||||
const Point2 rel_warped(
|
||||
Math::fmod(p_relative.x + rel_sign.x * warp_margin.x, p_rect.size.x) - rel_sign.x * warp_margin.x,
|
||||
Math::fmod(p_relative.y + rel_sign.y * warp_margin.y, p_rect.size.y) - rel_sign.y * warp_margin.y);
|
||||
|
||||
const Point2 pos_local = get_mouse_position() - p_rect.position;
|
||||
const Point2 pos_warped(Math::fposmod(pos_local.x, p_rect.size.x), Math::fposmod(pos_local.y, p_rect.size.y));
|
||||
if (pos_warped != pos_local) {
|
||||
warp_mouse(pos_warped + p_rect.position);
|
||||
}
|
||||
|
||||
return rel_warped;
|
||||
}
|
||||
|
||||
void Viewport::_gui_sort_roots() {
|
||||
if (!gui.roots_order_dirty) {
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue