diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 7d8dfa0d76a..1215e9e8905 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -115,11 +115,11 @@ Vector2 GraphEditMinimap::_get_render_size() { } Vector2 GraphEditMinimap::_get_graph_offset() { - return Vector2(ge->h_scrollbar->get_min(), ge->v_scrollbar->get_min()); + return ge->min_scroll_offset; } Vector2 GraphEditMinimap::_get_graph_size() { - Vector2 graph_size = Vector2(ge->h_scrollbar->get_max(), ge->v_scrollbar->get_max()) - Vector2(ge->h_scrollbar->get_min(), ge->v_scrollbar->get_min()); + Vector2 graph_size = ge->max_scroll_offset - ge->min_scroll_offset; if (graph_size.width == 0) { graph_size.width = 1; @@ -411,17 +411,25 @@ String GraphEdit::get_connections_description(const StringName &p_node, int p_po void GraphEdit::set_scroll_offset(const Vector2 &p_offset) { setting_scroll_offset = true; - h_scrollbar->set_value(p_offset.x); - v_scrollbar->set_value(p_offset.y); - _update_scroll(); + scroll_offset = p_offset.clamp(min_scroll_offset, max_scroll_offset - get_size()); + if (!awaiting_scroll_offset_update) { + callable_mp(this, &GraphEdit::_update_scroll_offset).call_deferred(); + awaiting_scroll_offset_update = true; + } + minimap->queue_redraw(); + queue_redraw(); + _update_scrollbars(); + callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred(); setting_scroll_offset = false; } Vector2 GraphEdit::get_scroll_offset() const { - return Vector2(h_scrollbar->get_value(), v_scrollbar->get_value()); + return scroll_offset; } -void GraphEdit::_scroll_moved(double) { +void GraphEdit::_scrollbar_moved(double) { + scroll_offset.x = h_scrollbar->get_value(); + scroll_offset.y = v_scrollbar->get_value(); if (!awaiting_scroll_offset_update) { callable_mp(this, &GraphEdit::_update_scroll_offset).call_deferred(); awaiting_scroll_offset_update = true; @@ -443,14 +451,14 @@ void GraphEdit::_update_scroll_offset() { } Point2 pos = graph_element->get_position_offset() * zoom; - pos -= Point2(h_scrollbar->get_value(), v_scrollbar->get_value()); + pos -= scroll_offset; graph_element->set_position(pos); if (graph_element->get_scale() != Vector2(zoom, zoom)) { graph_element->set_scale(Vector2(zoom, zoom)); } } - connections_layer->set_position(-Point2(h_scrollbar->get_value(), v_scrollbar->get_value())); + connections_layer->set_position(-scroll_offset); set_block_minimum_size_adjust(false); awaiting_scroll_offset_update = false; @@ -460,14 +468,18 @@ void GraphEdit::_update_scroll_offset() { } } -void GraphEdit::_update_scroll() { +void GraphEdit::_update_scrollbars() { if (updating) { return; } updating = true; + h_scrollbar->set_value_no_signal(scroll_offset.x); + v_scrollbar->set_value_no_signal(scroll_offset.y); + set_block_minimum_size_adjust(true); + // Determine the graph "canvas" size in screen space. Rect2 screen_rect; for (int i = 0; i < get_child_count(); i++) { GraphElement *graph_element = Object::cast_to(get_child(i)); @@ -484,6 +496,9 @@ void GraphEdit::_update_scroll() { screen_rect.position -= get_size(); screen_rect.size += get_size() * 2.0; + min_scroll_offset = screen_rect.position; + max_scroll_offset = screen_rect.position + screen_rect.size; + h_scrollbar->set_min(screen_rect.position.x); h_scrollbar->set_max(screen_rect.position.x + screen_rect.size.width); h_scrollbar->set_page(get_size().x); @@ -849,7 +864,7 @@ void GraphEdit::_notification(int p_what) { } break; case NOTIFICATION_RESIZED: { - _update_scroll(); + _update_scrollbars(); minimap->queue_redraw(); callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred(); } break; @@ -1714,7 +1729,7 @@ void GraphEdit::_top_layer_draw() { } void GraphEdit::_update_top_connection_layer() { - _update_scroll(); + _update_scrollbars(); if (!connecting) { dragged_connection_line->clear_points(); @@ -2302,9 +2317,15 @@ void GraphEdit::key_input(const Ref &p_ev) { void GraphEdit::_pan_callback(Vector2 p_scroll_vec, Ref p_event) { ERR_FAIL_NULL_MSG(connections_layer, "connections_layer is missing."); - h_scrollbar->set_value(h_scrollbar->get_value() - p_scroll_vec.x); - v_scrollbar->set_value(v_scrollbar->get_value() - p_scroll_vec.y); + scroll_offset = (scroll_offset - p_scroll_vec).clamp(min_scroll_offset, max_scroll_offset - get_size()); + if (!awaiting_scroll_offset_update) { + callable_mp(this, &GraphEdit::_update_scroll_offset).call_deferred(); + awaiting_scroll_offset_update = true; + } + minimap->queue_redraw(); + queue_redraw(); + callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred(); connections_layer->queue_redraw(); } @@ -2406,7 +2427,7 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) { return; } - Vector2 scrollbar_offset = (Vector2(h_scrollbar->get_value(), v_scrollbar->get_value()) + p_center) / zoom; + Point2 zoom_anchor = (scroll_offset + p_center) / zoom; zoom = p_zoom; @@ -2415,14 +2436,12 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) { zoom_minus_button->set_disabled(zoom == zoom_min); zoom_plus_button->set_disabled(zoom == zoom_max); - _update_scroll(); + _update_scrollbars(); minimap->queue_redraw(); connections_layer->queue_redraw(); if (is_visible_in_tree()) { - Vector2 offset = scrollbar_offset * zoom - p_center; - h_scrollbar->set_value(offset.x); - v_scrollbar->set_value(offset.y); + scroll_offset = zoom_anchor * zoom - p_center; } _update_zoom_label(); @@ -3193,8 +3212,8 @@ GraphEdit::GraphEdit() { v_scrollbar->set_min(-10000); v_scrollbar->set_max(10000); - h_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scroll_moved)); - v_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scroll_moved)); + h_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scrollbar_moved)); + v_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scrollbar_moved)); // Toolbar menu. diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 3b8289f0186..4023efc44ac 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -228,6 +228,10 @@ private: float zoom_min = 0.0; float zoom_max = 0.0; + Vector2 min_scroll_offset; + Vector2 max_scroll_offset; + Vector2 scroll_offset; + bool box_selecting = false; bool box_selection_mode_additive = false; Point2 box_selecting_from; @@ -327,9 +331,9 @@ private: void _ensure_node_order_from_root(const StringName &p_node); void _ensure_node_order_from(Node *p_node); - void _update_scroll(); + void _update_scrollbars(); void _update_scroll_offset(); - void _scroll_moved(double); + void _scrollbar_moved(double); virtual void gui_input(const Ref &p_ev) override; void _top_connection_layer_input(const Ref &p_ev);