From f5004b78d0468641cd03619ecfecb42429621a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Wed, 22 Mar 2017 21:18:47 +0100 Subject: [PATCH] Implement warped mouse panning for 2D & 3D editors Enabled by default as in Blender, but can be disabled separately for 2D & 3D; the core functionality is in Input so this could be reused or even exposed to scripts in the future --- core/os/input.h | 1 + editor/editor_settings.cpp | 3 +++ editor/plugins/canvas_item_editor_plugin.cpp | 12 ++++++++++-- editor/plugins/spatial_editor_plugin.cpp | 10 +++++++++- main/input_default.cpp | 11 +++++++++++ main/input_default.h | 1 + 6 files changed, 35 insertions(+), 3 deletions(-) diff --git a/core/os/input.h b/core/os/input.h index 2f6359632e3..3c33c46ebaa 100644 --- a/core/os/input.h +++ b/core/os/input.h @@ -81,6 +81,7 @@ public: virtual int get_mouse_button_mask() const = 0; virtual void warp_mouse_pos(const Vector2 &p_to) = 0; + virtual Point2i warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect) = 0; virtual Vector3 get_gravity() const = 0; virtual Vector3 get_accelerometer() const = 0; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 9e5021af6e3..2cdf0764401 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -580,6 +580,7 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { hints["editors/3d/zoom_modifier"] = PropertyInfo(Variant::INT, "editors/3d/zoom_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); set("editors/3d/emulate_numpad", false); set("editors/3d/emulate_3_button_mouse", false); + set("editors/3d/warped_mouse_panning", true); set("editors/2d/bone_width", 5); set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9)); @@ -589,6 +590,8 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { set("editors/2d/keep_margins_when_changing_anchors", false); + set("editors/2d/warped_mouse_panning", true); + set("run/window_placement/rect", 0); hints["run/window_placement/rect"] = PropertyInfo(Variant::INT, "run/window_placement/rect", PROPERTY_HINT_ENUM, "Default,Centered,Custom Position,Force Maximized,Force Full Screen"); String screen_hints = TTR("Default (Same as Editor)"); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 7b015e484f3..7f2daae420c 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1471,8 +1471,16 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) { if (drag == DRAG_NONE) { if ((m.button_mask & BUTTON_MASK_LEFT && tool == TOOL_PAN) || m.button_mask & BUTTON_MASK_MIDDLE || (m.button_mask & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE))) { - h_scroll->set_value(h_scroll->get_value() - m.relative_x / zoom); - v_scroll->set_value(v_scroll->get_value() - m.relative_y / zoom); + + Point2i relative; + if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) { + relative = Input::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect()); + } else { + relative = Point2i(m.relative_x, m.relative_y); + } + + h_scroll->set_value(h_scroll->get_value() - relative.x / zoom); + v_scroll->set_value(v_scroll->get_value() - relative.y / zoom); } return; diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index fcfb20bd7d8..c00652bc355 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -29,6 +29,7 @@ #include "spatial_editor_plugin.h" #include "camera_matrix.h" +#include "core/os/input.h" #include "editor/animation_editor.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" @@ -1400,12 +1401,19 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { if (nav_scheme == NAVIGATION_MAYA && m.mod.shift) pan_speed *= pan_speed_modifier; + Point2i relative; + if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) { + relative = Input::get_singleton()->warp_mouse_motion(m, surface->get_global_rect()); + } else { + relative = Point2i(m.relative_x, m.relative_y); + } + Transform camera_transform; camera_transform.translate(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); - Vector3 translation(-m.relative_x * pan_speed, m.relative_y * pan_speed, 0); + Vector3 translation(-relative.x * pan_speed, relative.y * pan_speed, 0); translation *= cursor.distance / DISTANCE_DEFAULT; camera_transform.translate(translation); cursor.pos = camera_transform.origin; diff --git a/main/input_default.cpp b/main/input_default.cpp index bc409960d6f..8e352ca8e3d 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -478,6 +478,17 @@ void InputDefault::warp_mouse_pos(const Vector2 &p_to) { OS::get_singleton()->warp_mouse_pos(p_to); } +Point2i InputDefault::warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect) { + + const Point2i rel_warped(Math::fmod(p_motion.relative_x, p_rect.size.x), Math::fmod(p_motion.relative_y, p_rect.size.y)); + const Point2i pos_local = Point2i(p_motion.global_x, p_motion.global_y) - p_rect.pos; + const Point2i 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) { + OS::get_singleton()->warp_mouse_pos(pos_warped + p_rect.pos); + } + return rel_warped; +} + void InputDefault::iteration(float p_step) { } diff --git a/main/input_default.h b/main/input_default.h index fecdb215d7c..4f298d6d555 100644 --- a/main/input_default.h +++ b/main/input_default.h @@ -200,6 +200,7 @@ public: virtual int get_mouse_button_mask() const; virtual void warp_mouse_pos(const Vector2 &p_to); + virtual Point2i warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect); virtual void parse_input_event(const InputEvent &p_event);