mirror of
https://github.com/godotengine/godot.git
synced 2025-01-25 20:12:34 -05:00
Merge pull request #53185 from KoBeWi/viewing_pan
This commit is contained in:
commit
b5495783b2
10 changed files with 312 additions and 65 deletions
|
@ -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>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
136
scene/gui/view_panner.cpp
Normal 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
63
scene/gui/view_panner.h
Normal 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
|
Loading…
Add table
Reference in a new issue