Merge pull request #53185 from KoBeWi/viewing_pan

This commit is contained in:
Rémi Verschelde 2022-01-12 11:36:41 +01:00 committed by GitHub
commit b5495783b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 312 additions and 65 deletions

View file

@ -214,6 +214,9 @@
<member name="minimap_size" type="Vector2" setter="set_minimap_size" getter="get_minimap_size" default="Vector2(240, 160)">
The size of the minimap rectangle. The map itself is based on the size of the grid area and is scaled to fit this rectangle.
</member>
<member name="panning_scheme" type="int" setter="set_panning_scheme" getter="get_panning_scheme" enum="GraphEdit.PanningScheme" default="0">
Defines the control scheme for panning with mouse wheel.
</member>
<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="right_disconnects" type="bool" setter="set_right_disconnects" getter="is_right_disconnects_enabled" default="false">
If [code]true[/code], enables disconnection of existing connections in the GraphEdit by dragging the right end.
@ -345,6 +348,14 @@
</description>
</signal>
</signals>
<constants>
<constant name="SCROLL_ZOOMS" value="0" enum="PanningScheme">
[kbd]Mouse Wheel[/kbd] will zoom, [kbd]Ctrl + Mouse Wheel[/kbd] will move the view.
</constant>
<constant name="SCROLL_PANS" value="1" enum="PanningScheme">
[kbd]Mouse Wheel[/kbd] will move the view, [kbd]Ctrl + Mouse Wheel[/kbd] will zoom.
</constant>
</constants>
<theme_items>
<theme_item name="activity" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
</theme_item>

View file

@ -6038,6 +6038,9 @@ EditorNode::EditorNode() {
EDITOR_DEF("interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_VHS_CIRCLE);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle", PROPERTY_USAGE_DEFAULT));
EDITOR_DEF("run/auto_save/save_before_running", true);
EDITOR_DEF("interface/editors/sub_editor_panning_scheme", 0);
// Should be in sync with ControlScheme in ViewPanner.
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/editors/sub_editor_panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans", PROPERTY_USAGE_DEFAULT));
const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false);
for (const String &E : textfile_ext) {

View file

@ -37,57 +37,31 @@
#include "scene/gui/label.h"
#include "scene/gui/panel.h"
#include "scene/gui/texture_rect.h"
#include "scene/gui/view_panner.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
void TileAtlasView::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
drag_type = DRAG_TYPE_NONE;
Vector2i scroll_vec = Vector2((mb->get_button_index() == MouseButton::WHEEL_LEFT) - (mb->get_button_index() == MouseButton::WHEEL_RIGHT), (mb->get_button_index() == MouseButton::WHEEL_UP) - (mb->get_button_index() == MouseButton::WHEEL_DOWN));
if (scroll_vec != Vector2()) {
if (mb->is_ctrl_pressed()) {
if (mb->is_shift_pressed()) {
panning.x += 32 * mb->get_factor() * scroll_vec.y;
panning.y += 32 * mb->get_factor() * scroll_vec.x;
} else {
panning.y += 32 * mb->get_factor() * scroll_vec.y;
panning.x += 32 * mb->get_factor() * scroll_vec.x;
}
emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
_update_zoom_and_panning(true);
accept_event();
} else if (!mb->is_shift_pressed()) {
zoom_widget->set_zoom_by_increments(scroll_vec.y * 2);
emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
_update_zoom_and_panning(true);
accept_event();
}
}
if (mb->get_button_index() == MouseButton::MIDDLE || mb->get_button_index() == MouseButton::RIGHT) {
if (mb->is_pressed()) {
drag_type = DRAG_TYPE_PAN;
} else {
drag_type = DRAG_TYPE_NONE;
}
accept_event();
}
if (panner->gui_input(p_event)) {
accept_event();
}
}
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
if (drag_type == DRAG_TYPE_PAN) {
panning += mm->get_relative();
_update_zoom_and_panning();
emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
accept_event();
}
}
void TileAtlasView::_scroll_callback(Vector2 p_scroll_vec) {
_pan_callback(-p_scroll_vec * 32);
}
void TileAtlasView::_pan_callback(Vector2 p_scroll_vec) {
panning += p_scroll_vec;
emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
_update_zoom_and_panning(true);
}
void TileAtlasView::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
zoom_widget->set_zoom_by_increments(-p_scroll_vec.y * 2);
emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
_update_zoom_and_panning(true);
}
Size2i TileAtlasView::_compute_base_tiles_control_size() {
@ -548,6 +522,11 @@ void TileAtlasView::update() {
void TileAtlasView::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED:
panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int());
break;
case NOTIFICATION_READY:
button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons")));
break;
@ -561,6 +540,9 @@ void TileAtlasView::_bind_methods() {
TileAtlasView::TileAtlasView() {
set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
panner.instantiate();
panner->set_callbacks(callable_mp(this, &TileAtlasView::_scroll_callback), callable_mp(this, &TileAtlasView::_pan_callback), callable_mp(this, &TileAtlasView::_zoom_callback));
Panel *panel = memnew(Panel);
panel->set_clip_contents(true);
panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);

View file

@ -41,6 +41,8 @@
#include "scene/gui/texture_rect.h"
#include "scene/resources/tile_set.h"
class ViewPanner;
class TileAtlasView : public Control {
GDCLASS(TileAtlasView, Control);
@ -64,6 +66,11 @@ private:
void _center_view();
virtual void gui_input(const Ref<InputEvent> &p_event) override;
Ref<ViewPanner> panner;
void _scroll_callback(Vector2 p_scroll_vec);
void _pan_callback(Vector2 p_scroll_vec);
void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
Map<Vector2, Map<int, Rect2i>> alternative_tiles_rect_cache;
void _update_alternative_tiles_rect_cache();

View file

@ -3209,6 +3209,10 @@ void VisualShaderEditor::_notification(int p_what) {
}
}
if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int());
}
if (p_what == NOTIFICATION_DRAG_BEGIN) {
Dictionary dd = get_viewport()->gui_get_drag_data();
if (members->is_visible_in_tree() && dd.has("id")) {

View file

@ -3753,6 +3753,11 @@ void VisualScriptEditor::_toggle_scripts_pressed() {
void VisualScriptEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int());
} break;
case NOTIFICATION_READY: {
variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members));
variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED);

View file

@ -35,6 +35,7 @@
#include "core/os/keyboard.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/view_panner.h"
constexpr int MINIMAP_OFFSET = 12;
constexpr int MINIMAP_PADDING = 5;
@ -1069,13 +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);
Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid() && ((mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE || ((mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && Input::get_singleton()->is_key_pressed(Key::SPACE)))) {
Vector2i relative = Input::get_singleton()->warp_mouse_motion(mm, get_global_rect());
h_scroll->set_value(h_scroll->get_value() - relative.x);
v_scroll->set_value(v_scroll->get_value() - relative.y);
}
if (mm.is_valid() && dragging) {
if (!moving_selection) {
@ -1327,22 +1324,6 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
top_layer->update();
minimap->update();
}
int scroll_direction = (b->get_button_index() == MouseButton::WHEEL_DOWN) - (b->get_button_index() == MouseButton::WHEEL_UP);
if (scroll_direction != 0) {
if (b->is_ctrl_pressed()) {
if (b->is_shift_pressed()) {
// Horizontal scrolling.
h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * b->get_factor() / 8) * scroll_direction);
} else {
// Vertical scrolling.
v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * b->get_factor() / 8) * scroll_direction);
}
} else {
// Zooming.
set_zoom_custom(scroll_direction < 0 ? zoom * zoom_step : zoom / zoom_step, b->get_position());
}
}
}
if (p_ev->is_pressed()) {
@ -1373,6 +1354,23 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
}
}
void GraphEdit::_scroll_callback(Vector2 p_scroll_vec) {
if (p_scroll_vec.x != 0) {
h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * Math::abs(p_scroll_vec.x) / 8) * SIGN(p_scroll_vec.x));
} else {
v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * Math::abs(p_scroll_vec.y) / 8) * SIGN(p_scroll_vec.y));
}
}
void GraphEdit::_pan_callback(Vector2 p_scroll_vec) {
h_scroll->set_value(h_scroll->get_value() - p_scroll_vec.x);
v_scroll->set_value(v_scroll->get_value() - p_scroll_vec.y);
}
void GraphEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
set_zoom_custom(p_scroll_vec.y < 0 ? zoom * zoom_step : zoom / zoom_step, p_origin);
}
void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity) {
for (Connection &E : connections) {
if (E.from == p_from && E.from_port == p_from_port && E.to == p_to && E.to_port == p_to_port) {
@ -1406,6 +1404,15 @@ void GraphEdit::force_connection_drag_end() {
emit_signal(SNAME("connection_drag_ended"));
}
void GraphEdit::set_panning_scheme(PanningScheme p_scheme) {
panning_scheme = p_scheme;
panner->set_control_scheme((ViewPanner::ControlScheme)p_scheme);
}
GraphEdit::PanningScheme GraphEdit::get_panning_scheme() const {
return panning_scheme;
}
void GraphEdit::set_zoom(float p_zoom) {
set_zoom_custom(p_zoom, get_size() / 2);
}
@ -2190,6 +2197,9 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type);
ClassDB::bind_method(D_METHOD("get_connection_line", "from", "to"), &GraphEdit::get_connection_line);
ClassDB::bind_method(D_METHOD("set_panning_scheme", "scheme"), &GraphEdit::set_panning_scheme);
ClassDB::bind_method(D_METHOD("get_panning_scheme"), &GraphEdit::get_panning_scheme);
ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom);
ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom);
@ -2244,6 +2254,7 @@ void GraphEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset"), "set_scroll_ofs", "get_scroll_ofs");
ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_distance"), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_snap"), "set_use_snap", "is_using_snap");
ADD_PROPERTY(PropertyInfo(Variant::INT, "panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans"), "set_panning_scheme", "get_panning_scheme");
ADD_GROUP("Connection Lines", "connection_lines");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_thickness"), "set_connection_lines_thickness", "get_connection_lines_thickness");
@ -2277,6 +2288,9 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "ofs")));
ADD_SIGNAL(MethodInfo("connection_drag_started", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::STRING, "slot"), PropertyInfo(Variant::BOOL, "is_output")));
ADD_SIGNAL(MethodInfo("connection_drag_ended"));
BIND_ENUM_CONSTANT(SCROLL_ZOOMS);
BIND_ENUM_CONSTANT(SCROLL_PANS);
}
GraphEdit::GraphEdit() {
@ -2289,6 +2303,10 @@ GraphEdit::GraphEdit() {
// Allow zooming 4 times from the default zoom level.
zoom_max = (1 * Math::pow(zoom_step, 4));
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);
top_layer->set_mouse_filter(MOUSE_FILTER_PASS);

View file

@ -41,6 +41,7 @@
#include "scene/gui/texture_rect.h"
class GraphEdit;
class ViewPanner;
class GraphEditFilter : public Control {
GDCLASS(GraphEditFilter, Control);
@ -103,6 +104,12 @@ public:
float activity = 0.0;
};
// Should be in sync with ControlScheme in ViewPanner.
enum PanningScheme {
SCROLL_ZOOMS,
SCROLL_PANS,
};
private:
Label *zoom_label;
Button *zoom_minus;
@ -122,6 +129,11 @@ private:
float port_grab_distance_horizontal = 0.0;
float port_grab_distance_vertical;
Ref<ViewPanner> panner;
void _scroll_callback(Vector2 p_scroll_vec);
void _pan_callback(Vector2 p_scroll_vec);
void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
bool connecting = false;
String connecting_from;
bool connecting_out = false;
@ -136,6 +148,7 @@ private:
bool connecting_valid = false;
Vector2 click_pos;
PanningScheme panning_scheme = SCROLL_ZOOMS;
bool dragging = false;
bool just_selected = false;
bool moving_selection = false;
@ -277,6 +290,9 @@ public:
void remove_valid_connection_type(int p_type, int p_with_type);
bool is_valid_connection_type(int p_type, int p_with_type) const;
void set_panning_scheme(PanningScheme p_scheme);
PanningScheme get_panning_scheme() const;
void set_zoom(float p_zoom);
void set_zoom_custom(float p_zoom, const Vector2 &p_center);
float get_zoom() const;
@ -338,4 +354,6 @@ public:
GraphEdit();
};
VARIANT_ENUM_CAST(GraphEdit::PanningScheme);
#endif // GRAPHEdit_H

136
scene/gui/view_panner.cpp Normal file
View file

@ -0,0 +1,136 @@
/*************************************************************************/
/* view_panner.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "view_panner.h"
#include "core/input/input.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()) {
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()) {
callback_helper(zoom_callback, scroll_vec, mb->get_position());
} else {
Vector2 panning;
if (mb->is_shift_pressed()) {
panning.x += mb->get_factor() * scroll_vec.y;
panning.y += mb->get_factor() * scroll_vec.x;
} else {
panning.y += mb->get_factor() * scroll_vec.y;
panning.x += mb->get_factor() * scroll_vec.x;
}
callback_helper(scroll_callback, panning);
return true;
}
} else {
if (mb->is_ctrl_pressed()) {
Vector2 panning;
if (mb->is_shift_pressed()) {
panning.x += mb->get_factor() * scroll_vec.y;
panning.y += mb->get_factor() * scroll_vec.x;
} else {
panning.y += mb->get_factor() * scroll_vec.y;
panning.x += mb->get_factor() * scroll_vec.x;
}
callback_helper(scroll_callback, panning);
return true;
} else if (!mb->is_shift_pressed()) {
callback_helper(zoom_callback, scroll_vec, mb->get_position());
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) || !mb->is_pressed()))) {
if (mb->is_pressed()) {
is_dragging = true;
} else {
is_dragging = false;
}
return true;
}
}
Ref<InputEventMouseMotion> mm = p_event;
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));
} else {
callback_helper(pan_callback, mm->get_relative());
}
return true;
}
}
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::set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback) {
scroll_callback = p_scroll_callback;
pan_callback = p_pan_callback;
zoom_callback = p_zoom_callback;
}
void ViewPanner::set_control_scheme(ControlScheme p_scheme) {
control_scheme = p_scheme;
}
void ViewPanner::set_disable_rmb(bool p_disable) {
disable_rmb = p_disable;
}

63
scene/gui/view_panner.h Normal file
View file

@ -0,0 +1,63 @@
/*************************************************************************/
/* view_panner.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef VIEW_PANNER_H
#define VIEW_PANNER_H
#include "core/object/ref_counted.h"
class InputEvent;
class ViewPanner : public RefCounted {
GDCLASS(ViewPanner, RefCounted);
bool is_dragging = false;
bool disable_rmb = false;
Callable scroll_callback;
Callable pan_callback;
Callable zoom_callback;
void callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2 = Vector2());
public:
enum ControlScheme {
SCROLL_ZOOMS,
SCROLL_PANS,
};
ControlScheme control_scheme = SCROLL_ZOOMS;
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);
bool gui_input(const Ref<InputEvent> &p_ev, Rect2 p_canvas_rect = Rect2());
};
#endif // VIEW_PANNER_H