diff options
Diffstat (limited to 'scene/gui/graph_edit.cpp')
-rw-r--r-- | scene/gui/graph_edit.cpp | 105 |
1 files changed, 69 insertions, 36 deletions
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 1ddec4f587..79b73f7cc3 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -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; @@ -600,6 +601,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { to = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(to)) { connecting = true; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, false); } return; } @@ -616,6 +618,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_target = false; connecting_to = pos; just_disconnected = false; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, true); return; } } @@ -642,6 +645,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { fr = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(fr)) { connecting = true; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, true); } return; } @@ -658,7 +662,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_target = false; connecting_to = pos; just_disconnected = false; - + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, false); return; } } @@ -740,11 +744,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { } } - connecting = false; - top_layer->update(); - minimap->update(); - update(); - connections_layer->update(); + if (connecting) { + force_connection_drag_end(); + } } } @@ -772,8 +774,9 @@ bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &pos) } bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { - if (get_script_instance() && get_script_instance()->has_method("_is_in_input_hotzone")) { - return get_script_instance()->call("_is_in_input_hotzone", p_graph_node, p_slot_index, p_mouse_pos); + bool success; + if (GDVIRTUAL_CALL(_is_in_input_hotzone, p_graph_node, p_slot_index, p_mouse_pos, success)) { + return success; } else { Vector2 pos = p_graph_node->get_connection_input_position(p_slot_index) + p_graph_node->get_position(); return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, true); @@ -781,8 +784,9 @@ bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_slot_index, c } bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { - if (get_script_instance() && get_script_instance()->has_method("_is_in_output_hotzone")) { - return get_script_instance()->call("_is_in_output_hotzone", p_graph_node, p_slot_index, p_mouse_pos); + bool success; + if (GDVIRTUAL_CALL(_is_in_output_hotzone, p_graph_node, p_slot_index, p_mouse_pos, success)) { + return success; } else { Vector2 pos = p_graph_node->get_connection_output_position(p_slot_index) + p_graph_node->get_position(); return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, false); @@ -1066,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) { @@ -1162,9 +1162,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { minimap->update(); } else { if (connecting) { - connecting = false; - top_layer->update(); - minimap->update(); + force_connection_drag_end(); } else { emit_signal(SNAME("popup_request"), get_screen_position() + b->get_position()); } @@ -1326,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()) { @@ -1372,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) { @@ -1394,6 +1393,26 @@ void GraphEdit::clear_connections() { connections_layer->update(); } +void GraphEdit::force_connection_drag_end() { + ERR_FAIL_COND_MSG(!connecting, "Drag end requested without active drag!"); + connecting = false; + connecting_valid = false; + top_layer->update(); + minimap->update(); + update(); + connections_layer->update(); + 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); } @@ -2165,6 +2184,7 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_connection_activity", "from", "from_port", "to", "to_port", "amount"), &GraphEdit::set_connection_activity); ClassDB::bind_method(D_METHOD("get_connection_list"), &GraphEdit::_get_connection_list); ClassDB::bind_method(D_METHOD("clear_connections"), &GraphEdit::clear_connections); + ClassDB::bind_method(D_METHOD("force_connection_drag_end"), &GraphEdit::force_connection_drag_end); ClassDB::bind_method(D_METHOD("get_scroll_ofs"), &GraphEdit::get_scroll_ofs); ClassDB::bind_method(D_METHOD("set_scroll_ofs", "ofs"), &GraphEdit::set_scroll_ofs); @@ -2177,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); @@ -2216,8 +2239,8 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_right_disconnects_enabled"), &GraphEdit::is_right_disconnects_enabled); ClassDB::bind_method(D_METHOD("_update_scroll_offset"), &GraphEdit::_update_scroll_offset); - ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "_is_in_input_hotzone", PropertyInfo(Variant::OBJECT, "graph_node"), PropertyInfo(Variant::INT, "slot_index"), PropertyInfo(Variant::VECTOR2, "mouse_position"))); - ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "_is_in_output_hotzone", PropertyInfo(Variant::OBJECT, "graph_node"), PropertyInfo(Variant::INT, "slot_index"), PropertyInfo(Variant::VECTOR2, "mouse_position"))); + GDVIRTUAL_BIND(_is_in_input_hotzone, "graph_node", "slot_index", "mouse_position"); + GDVIRTUAL_BIND(_is_in_output_hotzone, "graph_node", "slot_index", "mouse_position"); ClassDB::bind_method(D_METHOD("get_zoom_hbox"), &GraphEdit::get_zoom_hbox); @@ -2231,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"); @@ -2262,6 +2286,11 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("begin_node_move")); ADD_SIGNAL(MethodInfo("end_node_move")); 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() { @@ -2274,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); |