Skip to content

Commit b55b9fe

Browse files
committed
[GraphEdit] Improve UI control scheme by separating scroll_offset from scroll bars
1 parent 666d7c0 commit b55b9fe

File tree

2 files changed

+46
-23
lines changed

2 files changed

+46
-23
lines changed

scene/gui/graph_edit.cpp

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ Vector2 GraphEditMinimap::_get_render_size() {
115115
}
116116

117117
Vector2 GraphEditMinimap::_get_graph_offset() {
118-
return Vector2(ge->h_scrollbar->get_min(), ge->v_scrollbar->get_min());
118+
return ge->min_scroll_offset;
119119
}
120120

121121
Vector2 GraphEditMinimap::_get_graph_size() {
122-
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());
122+
Vector2 graph_size = ge->max_scroll_offset - ge->min_scroll_offset;
123123

124124
if (graph_size.width == 0) {
125125
graph_size.width = 1;
@@ -411,17 +411,25 @@ String GraphEdit::get_connections_description(const StringName &p_node, int p_po
411411

412412
void GraphEdit::set_scroll_offset(const Vector2 &p_offset) {
413413
setting_scroll_offset = true;
414-
h_scrollbar->set_value(p_offset.x);
415-
v_scrollbar->set_value(p_offset.y);
416-
_update_scroll();
414+
scroll_offset = p_offset.clamp(min_scroll_offset, max_scroll_offset - get_size());
415+
if (!awaiting_scroll_offset_update) {
416+
callable_mp(this, &GraphEdit::_update_scroll_offset).call_deferred();
417+
awaiting_scroll_offset_update = true;
418+
}
419+
minimap->queue_redraw();
420+
queue_redraw();
421+
_update_scrollbars();
422+
callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred();
417423
setting_scroll_offset = false;
418424
}
419425

420426
Vector2 GraphEdit::get_scroll_offset() const {
421-
return Vector2(h_scrollbar->get_value(), v_scrollbar->get_value());
427+
return scroll_offset;
422428
}
423429

424-
void GraphEdit::_scroll_moved(double) {
430+
void GraphEdit::_scrollbar_moved(double) {
431+
scroll_offset.x = h_scrollbar->get_value();
432+
scroll_offset.y = v_scrollbar->get_value();
425433
if (!awaiting_scroll_offset_update) {
426434
callable_mp(this, &GraphEdit::_update_scroll_offset).call_deferred();
427435
awaiting_scroll_offset_update = true;
@@ -443,14 +451,14 @@ void GraphEdit::_update_scroll_offset() {
443451
}
444452

445453
Point2 pos = graph_element->get_position_offset() * zoom;
446-
pos -= Point2(h_scrollbar->get_value(), v_scrollbar->get_value());
454+
pos -= scroll_offset;
447455
graph_element->set_position(pos);
448456
if (graph_element->get_scale() != Vector2(zoom, zoom)) {
449457
graph_element->set_scale(Vector2(zoom, zoom));
450458
}
451459
}
452460

453-
connections_layer->set_position(-Point2(h_scrollbar->get_value(), v_scrollbar->get_value()));
461+
connections_layer->set_position(-scroll_offset);
454462
set_block_minimum_size_adjust(false);
455463
awaiting_scroll_offset_update = false;
456464

@@ -460,14 +468,18 @@ void GraphEdit::_update_scroll_offset() {
460468
}
461469
}
462470

463-
void GraphEdit::_update_scroll() {
471+
void GraphEdit::_update_scrollbars() {
464472
if (updating) {
465473
return;
466474
}
467475
updating = true;
468476

477+
h_scrollbar->set_value_no_signal(scroll_offset.x);
478+
v_scrollbar->set_value_no_signal(scroll_offset.y);
479+
469480
set_block_minimum_size_adjust(true);
470481

482+
// Determine the graph "canvas" size in screen space.
471483
Rect2 screen_rect;
472484
for (int i = 0; i < get_child_count(); i++) {
473485
GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
@@ -484,6 +496,9 @@ void GraphEdit::_update_scroll() {
484496
screen_rect.position -= get_size();
485497
screen_rect.size += get_size() * 2.0;
486498

499+
min_scroll_offset = screen_rect.position;
500+
max_scroll_offset = screen_rect.position + screen_rect.size;
501+
487502
h_scrollbar->set_min(screen_rect.position.x);
488503
h_scrollbar->set_max(screen_rect.position.x + screen_rect.size.width);
489504
h_scrollbar->set_page(get_size().x);
@@ -849,7 +864,7 @@ void GraphEdit::_notification(int p_what) {
849864
} break;
850865

851866
case NOTIFICATION_RESIZED: {
852-
_update_scroll();
867+
_update_scrollbars();
853868
minimap->queue_redraw();
854869
callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred();
855870
} break;
@@ -1714,7 +1729,7 @@ void GraphEdit::_top_layer_draw() {
17141729
}
17151730

17161731
void GraphEdit::_update_top_connection_layer() {
1717-
_update_scroll();
1732+
_update_scrollbars();
17181733

17191734
if (!connecting) {
17201735
dragged_connection_line->clear_points();
@@ -2302,9 +2317,15 @@ void GraphEdit::key_input(const Ref<InputEvent> &p_ev) {
23022317
void GraphEdit::_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event) {
23032318
ERR_FAIL_NULL_MSG(connections_layer, "connections_layer is missing.");
23042319

2305-
h_scrollbar->set_value(h_scrollbar->get_value() - p_scroll_vec.x);
2306-
v_scrollbar->set_value(v_scrollbar->get_value() - p_scroll_vec.y);
2320+
scroll_offset = (scroll_offset - p_scroll_vec).clamp(min_scroll_offset, max_scroll_offset - get_size());
23072321

2322+
if (!awaiting_scroll_offset_update) {
2323+
callable_mp(this, &GraphEdit::_update_scroll_offset).call_deferred();
2324+
awaiting_scroll_offset_update = true;
2325+
}
2326+
minimap->queue_redraw();
2327+
queue_redraw();
2328+
callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred();
23082329
connections_layer->queue_redraw();
23092330
}
23102331

@@ -2406,7 +2427,7 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
24062427
return;
24072428
}
24082429

2409-
Vector2 scrollbar_offset = (Vector2(h_scrollbar->get_value(), v_scrollbar->get_value()) + p_center) / zoom;
2430+
Point2 zoom_anchor = (scroll_offset + p_center) / zoom;
24102431

24112432
zoom = p_zoom;
24122433

@@ -2415,14 +2436,12 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
24152436
zoom_minus_button->set_disabled(zoom == zoom_min);
24162437
zoom_plus_button->set_disabled(zoom == zoom_max);
24172438

2418-
_update_scroll();
2439+
_update_scrollbars();
24192440
minimap->queue_redraw();
24202441
connections_layer->queue_redraw();
24212442

24222443
if (is_visible_in_tree()) {
2423-
Vector2 offset = scrollbar_offset * zoom - p_center;
2424-
h_scrollbar->set_value(offset.x);
2425-
v_scrollbar->set_value(offset.y);
2444+
scroll_offset = zoom_anchor * zoom - p_center;
24262445
}
24272446

24282447
_update_zoom_label();
@@ -3193,8 +3212,8 @@ GraphEdit::GraphEdit() {
31933212
v_scrollbar->set_min(-10000);
31943213
v_scrollbar->set_max(10000);
31953214

3196-
h_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scroll_moved));
3197-
v_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scroll_moved));
3215+
h_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scrollbar_moved));
3216+
v_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scrollbar_moved));
31983217

31993218
// Toolbar menu.
32003219

scene/gui/graph_edit.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ class GraphEdit : public Control {
228228
float zoom_min = 0.0;
229229
float zoom_max = 0.0;
230230

231+
Vector2 min_scroll_offset;
232+
Vector2 max_scroll_offset;
233+
Vector2 scroll_offset;
234+
231235
bool box_selecting = false;
232236
bool box_selection_mode_additive = false;
233237
Point2 box_selecting_from;
@@ -327,9 +331,9 @@ class GraphEdit : public Control {
327331
void _ensure_node_order_from_root(const StringName &p_node);
328332
void _ensure_node_order_from(Node *p_node);
329333

330-
void _update_scroll();
334+
void _update_scrollbars();
331335
void _update_scroll_offset();
332-
void _scroll_moved(double);
336+
void _scrollbar_moved(double);
333337
virtual void gui_input(const Ref<InputEvent> &p_ev) override;
334338
void _top_connection_layer_input(const Ref<InputEvent> &p_ev);
335339

0 commit comments

Comments
 (0)