summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorkobewi <kobewi4e@gmail.com>2022-01-19 19:59:12 +0100
committerkobewi <kobewi4e@gmail.com>2022-01-21 18:35:06 +0100
commit74bfe88267263297b43fef35fd9f32a91750d4d2 (patch)
tree7928ce063d68c991a3a25cb1aae87683b8ded789 /scene
parent249c60e9d1aacd07d87786db8059f30aed02bb68 (diff)
Add ViewPanner to 2D editor
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/graph_edit.cpp18
-rw-r--r--scene/gui/graph_edit.h5
-rw-r--r--scene/gui/view_panner.cpp101
-rw-r--r--scene/gui/view_panner.h20
4 files changed, 101 insertions, 43 deletions
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 79b73f7cc3..2d58733d8f 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1070,7 +1070,9 @@ void GraphEdit::set_selected(Node *p_child) {
void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
- panner->gui_input(p_ev);
+ if (panner->gui_input(p_ev, warped_panning ? get_global_rect() : Rect2())) {
+ return;
+ }
Ref<InputEventMouseMotion> mm = p_ev;
@@ -1272,7 +1274,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
if (_filter_input(b->get_position())) {
return;
}
- if (Input::get_singleton()->is_key_pressed(Key::SPACE)) {
+ if (panner->is_panning()) {
return;
}
@@ -1367,7 +1369,7 @@ void GraphEdit::_pan_callback(Vector2 p_scroll_vec) {
v_scroll->set_value(v_scroll->get_value() - p_scroll_vec.y);
}
-void GraphEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
+void GraphEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) {
set_zoom_custom(p_scroll_vec.y < 0 ? zoom * zoom_step : zoom / zoom_step, p_origin);
}
@@ -1678,6 +1680,14 @@ HBoxContainer *GraphEdit::get_zoom_hbox() {
return zoom_hb;
}
+Ref<ViewPanner> GraphEdit::get_panner() {
+ return panner;
+}
+
+void GraphEdit::set_warped_panning(bool p_warped) {
+ warped_panning = p_warped;
+}
+
int GraphEdit::_set_operations(SET_OPERATIONS p_operation, Set<StringName> &r_u, const Set<StringName> &r_v) {
switch (p_operation) {
case GraphEdit::IS_EQUAL: {
@@ -2305,7 +2315,6 @@ GraphEdit::GraphEdit() {
panner.instantiate();
panner->set_callbacks(callable_mp(this, &GraphEdit::_scroll_callback), callable_mp(this, &GraphEdit::_pan_callback), callable_mp(this, &GraphEdit::_zoom_callback));
- panner->set_disable_rmb(true);
top_layer = memnew(GraphEditFilter(this));
add_child(top_layer, false, INTERNAL_MODE_BACK);
@@ -2313,6 +2322,7 @@ GraphEdit::GraphEdit() {
top_layer->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
top_layer->connect("draw", callable_mp(this, &GraphEdit::_top_layer_draw));
top_layer->connect("gui_input", callable_mp(this, &GraphEdit::_top_layer_input));
+ top_layer->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key));
connections_layer = memnew(Control);
add_child(connections_layer, false, INTERNAL_MODE_FRONT);
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 4e998d30a7..e0827a99a4 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -130,9 +130,10 @@ private:
float port_grab_distance_vertical;
Ref<ViewPanner> panner;
+ bool warped_panning = true;
void _scroll_callback(Vector2 p_scroll_vec);
void _pan_callback(Vector2 p_scroll_vec);
- void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
+ void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt);
bool connecting = false;
String connecting_from;
@@ -348,6 +349,8 @@ public:
bool is_connection_lines_antialiased() const;
HBoxContainer *get_zoom_hbox();
+ Ref<ViewPanner> get_panner();
+ void set_warped_panning(bool p_warped);
void arrange_nodes();
diff --git a/scene/gui/view_panner.cpp b/scene/gui/view_panner.cpp
index ba5e8d4a17..0fbc4485ab 100644
--- a/scene/gui/view_panner.cpp
+++ b/scene/gui/view_panner.cpp
@@ -31,22 +31,18 @@
#include "view_panner.h"
#include "core/input/input.h"
+#include "core/input/shortcut.h"
#include "core/os/keyboard.h"
bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
- // Alt modifier is unused, so ignore such events.
- if (mb->is_alt_pressed()) {
- return false;
- }
-
Vector2i scroll_vec = Vector2((mb->get_button_index() == MouseButton::WHEEL_RIGHT) - (mb->get_button_index() == MouseButton::WHEEL_LEFT), (mb->get_button_index() == MouseButton::WHEEL_DOWN) - (mb->get_button_index() == MouseButton::WHEEL_UP));
if (scroll_vec != Vector2()) {
if (control_scheme == SCROLL_PANS) {
if (mb->is_ctrl_pressed()) {
scroll_vec.y *= mb->get_factor();
- callback_helper(zoom_callback, scroll_vec, mb->get_position());
+ callback_helper(zoom_callback, varray(scroll_vec, mb->get_position(), mb->is_alt_pressed()));
return true;
} else {
Vector2 panning;
@@ -57,7 +53,7 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
panning.y += mb->get_factor() * scroll_vec.y;
panning.x += mb->get_factor() * scroll_vec.x;
}
- callback_helper(scroll_callback, panning);
+ callback_helper(scroll_callback, varray(panning));
return true;
}
} else {
@@ -70,23 +66,28 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
panning.y += mb->get_factor() * scroll_vec.y;
panning.x += mb->get_factor() * scroll_vec.x;
}
- callback_helper(scroll_callback, panning);
+ callback_helper(scroll_callback, varray(panning));
return true;
} else if (!mb->is_shift_pressed()) {
scroll_vec.y *= mb->get_factor();
- callback_helper(zoom_callback, scroll_vec, mb->get_position());
+ callback_helper(zoom_callback, varray(scroll_vec, mb->get_position(), mb->is_alt_pressed()));
return true;
}
}
}
- if (mb->get_button_index() == MouseButton::MIDDLE || (mb->get_button_index() == MouseButton::RIGHT && !disable_rmb) || (mb->get_button_index() == MouseButton::LEFT && (Input::get_singleton()->is_key_pressed(Key::SPACE) || (is_dragging && !mb->is_pressed())))) {
+ // Use Alt only for scrolling.
+ if (mb->is_alt_pressed()) {
+ return false;
+ }
+
+ if (mb->get_button_index() == MouseButton::MIDDLE || (enable_rmb && mb->get_button_index() == MouseButton::RIGHT) || (!simple_panning_enabled && mb->get_button_index() == MouseButton::LEFT && is_panning())) {
if (mb->is_pressed()) {
is_dragging = true;
} else {
is_dragging = false;
}
- return true;
+ return mb->get_button_index() != MouseButton::LEFT || mb->is_pressed(); // Don't consume LMB release events (it fixes some selection problems).
}
}
@@ -94,9 +95,20 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
if (mm.is_valid()) {
if (is_dragging) {
if (p_canvas_rect != Rect2()) {
- callback_helper(pan_callback, Input::get_singleton()->warp_mouse_motion(mm, p_canvas_rect));
+ callback_helper(pan_callback, varray(Input::get_singleton()->warp_mouse_motion(mm, p_canvas_rect)));
} else {
- callback_helper(pan_callback, mm->get_relative());
+ callback_helper(pan_callback, varray(mm->get_relative()));
+ }
+ return true;
+ }
+ }
+
+ Ref<InputEventKey> k = p_event;
+ if (k.is_valid()) {
+ if (pan_view_shortcut.is_valid() && pan_view_shortcut->matches_event(k)) {
+ pan_key_pressed = k->is_pressed();
+ if (simple_panning_enabled || (Input::get_singleton()->get_mouse_button_mask() & MouseButton::LEFT) != MouseButton::NONE) {
+ is_dragging = pan_key_pressed;
}
return true;
}
@@ -105,26 +117,20 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
return false;
}
-void ViewPanner::callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2) {
- if (p_callback == zoom_callback) {
- const Variant **argptr = (const Variant **)alloca(sizeof(Variant *) * 2);
- Variant var1 = p_arg1;
- argptr[0] = &var1;
- Variant var2 = p_arg2;
- argptr[1] = &var2;
-
- Variant result;
- Callable::CallError ce;
- p_callback.call(argptr, 2, result, ce);
- } else {
- const Variant **argptr = (const Variant **)alloca(sizeof(Variant *));
- Variant var = p_arg1;
- argptr[0] = &var;
-
- Variant result;
- Callable::CallError ce;
- p_callback.call(argptr, 1, result, ce);
+void ViewPanner::release_pan_key() {
+ pan_key_pressed = false;
+ is_dragging = false;
+}
+
+void ViewPanner::callback_helper(Callable p_callback, Vector<Variant> p_args) {
+ const Variant **argptr = (const Variant **)alloca(sizeof(Variant *) * p_args.size());
+ for (int i = 0; i < p_args.size(); i++) {
+ argptr[i] = &p_args[i];
}
+
+ Variant result;
+ Callable::CallError ce;
+ p_callback.call(argptr, p_args.size(), result, ce);
}
void ViewPanner::set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback) {
@@ -137,6 +143,33 @@ void ViewPanner::set_control_scheme(ControlScheme p_scheme) {
control_scheme = p_scheme;
}
-void ViewPanner::set_disable_rmb(bool p_disable) {
- disable_rmb = p_disable;
+void ViewPanner::set_enable_rmb(bool p_enable) {
+ enable_rmb = p_enable;
+}
+
+void ViewPanner::set_pan_shortcut(Ref<Shortcut> p_shortcut) {
+ pan_view_shortcut = p_shortcut;
+ pan_key_pressed = false;
+}
+
+void ViewPanner::set_simple_panning_enabled(bool p_enabled) {
+ simple_panning_enabled = p_enabled;
+}
+
+void ViewPanner::setup(ControlScheme p_scheme, Ref<Shortcut> p_shortcut, bool p_simple_panning) {
+ set_control_scheme(p_scheme);
+ set_pan_shortcut(p_shortcut);
+ set_simple_panning_enabled(p_simple_panning);
+}
+
+bool ViewPanner::is_panning() const {
+ return is_dragging || pan_key_pressed;
+}
+
+ViewPanner::ViewPanner() {
+ Array inputs;
+ inputs.append(InputEventKey::create_reference(Key::SPACE));
+
+ pan_view_shortcut.instantiate();
+ pan_view_shortcut->set_events(inputs);
}
diff --git a/scene/gui/view_panner.h b/scene/gui/view_panner.h
index 0a92cb3dfd..8423c2a1c0 100644
--- a/scene/gui/view_panner.h
+++ b/scene/gui/view_panner.h
@@ -34,6 +34,7 @@
#include "core/object/ref_counted.h"
class InputEvent;
+class Shortcut;
class ViewPanner : public RefCounted {
GDCLASS(ViewPanner, RefCounted);
@@ -46,23 +47,34 @@ public:
private:
bool is_dragging = false;
- bool disable_rmb = false;
+ bool pan_key_pressed = false;
+ bool enable_rmb = false;
+ bool simple_panning_enabled = false;
+
+ Ref<Shortcut> pan_view_shortcut;
Callable scroll_callback;
Callable pan_callback;
Callable zoom_callback;
- void callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2 = Vector2());
+ void callback_helper(Callable p_callback, Vector<Variant> p_args);
ControlScheme control_scheme = SCROLL_ZOOMS;
public:
void set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback);
void set_control_scheme(ControlScheme p_scheme);
- void set_disable_rmb(bool p_disable);
+ void set_enable_rmb(bool p_enable);
+ void set_pan_shortcut(Ref<Shortcut> p_shortcut);
+ void set_simple_panning_enabled(bool p_enabled);
+
+ void setup(ControlScheme p_scheme, Ref<Shortcut> p_shortcut, bool p_simple_panning);
- bool is_panning() const { return is_dragging; }
+ bool is_panning() const;
bool gui_input(const Ref<InputEvent> &p_ev, Rect2 p_canvas_rect = Rect2());
+ void release_pan_key();
+
+ ViewPanner();
};
#endif // VIEW_PANNER_H