Skip to content

Commit 245fa3b

Browse files
committed
[GraphEdit] Improve UI control scheme by separating scroll_offset from scroll bars
1 parent c910e6a commit 245fa3b

File tree

5 files changed

+74
-60
lines changed

5 files changed

+74
-60
lines changed

editor/plugins/visual_shader_editor_plugin.cpp

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232

3333
#include "core/config/project_settings.h"
3434
#include "core/io/resource_loader.h"
35-
#include "core/io/resource_uid.h"
3635
#include "core/math/math_defs.h"
3736
#include "core/os/keyboard.h"
3837
#include "core/version_generated.gen.h"
@@ -1550,7 +1549,7 @@ void VisualShaderEditor::edit_shader(const Ref<Shader> &p_shader) {
15501549
_update_options_menu();
15511550
_update_preview();
15521551
_update_graph();
1553-
call_deferred("_restore_editor_state");
1552+
callable_mp(this, &VisualShaderEditor::_restore_editor_state).call_deferred();
15541553
}
15551554
}
15561555
}
@@ -1577,17 +1576,13 @@ void VisualShaderEditor::validate_script() {
15771576
void VisualShaderEditor::set_current_shader_type(VisualShader::Type p_type) {
15781577
current_type = p_type;
15791578

1580-
String id_string = visual_shader->get_path();
1581-
const ResourceUID::ID uid = ResourceLoader::get_resource_uid(id_string);
1582-
if (uid != ResourceUID::INVALID_ID) {
1583-
id_string = ResourceUID::get_singleton()->id_to_text(uid);
1584-
}
1579+
const String id_string = _get_vs_editor_cache_id_string();
15851580

1586-
vs_editor_cache->set_value("visual_shader", id_string + ":edited_type", p_type);
1581+
vs_editor_cache->set_value(id_string, "edited_type", p_type);
15871582
vs_editor_cache->save(EditorPaths::get_singleton()->get_project_settings_dir().path_join("vs_editor_cache.cfg"));
15881583

1589-
const Vector2 saved_scroll_offset = vs_editor_cache->get_value("visual_shader", id_string + ":type" + itos(p_type) + ":offset", Vector2());
1590-
const real_t saved_zoom = vs_editor_cache->get_value("visual_shader", id_string + ":type" + itos(p_type) + ":zoom", 1.0);
1584+
const Vector2 saved_scroll_offset = vs_editor_cache->get_value(id_string, "type" + itos(p_type) + ":offset", Vector2());
1585+
const real_t saved_zoom = vs_editor_cache->get_value(id_string, "type" + itos(p_type) + ":zoom", 1.0);
15911586

15921587
graph->set_zoom(saved_zoom);
15931588
graph->set_scroll_offset(saved_scroll_offset);
@@ -2485,13 +2480,9 @@ void VisualShaderEditor::_set_mode(int p_which) {
24852480
mode = MODE_FLAGS_SPATIAL_CANVASITEM;
24862481
}
24872482

2488-
String id_string = visual_shader->get_path();
2489-
const ResourceUID::ID uid = ResourceLoader::get_resource_uid(id_string);
2490-
if (uid != ResourceUID::INVALID_ID) {
2491-
id_string = ResourceUID::get_singleton()->id_to_text(uid);
2492-
}
2483+
const String id_string = _get_vs_editor_cache_id_string();
24932484

2494-
int saved_type = vs_editor_cache->get_value("visual_shader", id_string + ":edited_type", 0);
2485+
int saved_type = vs_editor_cache->get_value(id_string, "edited_type", 0);
24952486
edit_type->select(saved_type);
24962487
set_current_shader_type((VisualShader::Type)saved_type);
24972488
}
@@ -2652,25 +2643,28 @@ void VisualShaderEditor::_update_graph() {
26522643
}
26532644

26542645
void VisualShaderEditor::_restore_editor_state() {
2655-
String id_string = visual_shader->get_path();
2656-
const ResourceUID::ID uid = ResourceLoader::get_resource_uid(id_string);
2657-
if (uid != ResourceUID::INVALID_ID) {
2658-
id_string = ResourceUID::get_singleton()->id_to_text(uid);
2659-
}
2646+
const String id_string = _get_vs_editor_cache_id_string();
26602647

26612648
const int type = get_current_shader_type();
2662-
// const Vector2 saved_scroll_offset = EditorSettings::get_singleton()->get_project_metadata("visual_shader", uid_text + ":type" + itos(type) + ":offset", Vector2());
2663-
const Vector2 saved_scroll_offset = vs_editor_cache->get_value("visual_shader", id_string + ":type" + itos(type) + ":offset", Vector2());
2664-
// const real_t saved_zoom = EditorSettings::get_singleton()->get_project_metadata("visual_shader", uid_text + ":type" + itos(type) + ":zoom", 1.0);
2665-
const real_t saved_zoom = vs_editor_cache->get_value("visual_shader", id_string + ":type" + itos(type) + ":zoom", 1.0);
2649+
const Vector2 saved_scroll_offset = vs_editor_cache->get_value(id_string, "type" + itos(type) + ":offset", Vector2());
2650+
const real_t saved_zoom = vs_editor_cache->get_value(id_string, "type" + itos(type) + ":zoom", 1.0);
26662651

26672652
// Setting the scroll offset needs to be double-deferred because it requires min/max scroll offset to be final (as it gets clamped).
2668-
graph->call_deferred("set_zoom", saved_zoom);
2669-
graph->call_deferred("set_scroll_offset", saved_scroll_offset);
2653+
callable_mp(graph, &GraphEdit::set_zoom).call_deferred(saved_zoom);
2654+
callable_mp(graph, &GraphEdit::set_scroll_offset).call_deferred(saved_scroll_offset);
26702655

26712656
shader_fully_loaded = true;
26722657
}
26732658

2659+
String VisualShaderEditor::_get_vs_editor_cache_id_string() const {
2660+
String id_string = visual_shader->get_path();
2661+
const ResourceUID::ID uid = EditorFileSystem::get_singleton()->get_file_uid(id_string);
2662+
if (uid != ResourceUID::INVALID_ID) {
2663+
id_string = ResourceUID::get_singleton()->id_to_text(uid);
2664+
}
2665+
return id_string;
2666+
}
2667+
26742668
void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type, const String &p_name) {
26752669
VisualShader::Type type = get_current_shader_type();
26762670
Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node);
@@ -5192,15 +5186,11 @@ void VisualShaderEditor::_param_unselected() {
51925186
}
51935187

51945188
void VisualShaderEditor::_panning_debounce_timer_timeout() {
5195-
String id_string = visual_shader->get_path();
5196-
const ResourceUID::ID uid = ResourceLoader::get_resource_uid(id_string);
5197-
if (uid != ResourceUID::INVALID_ID) {
5198-
id_string = ResourceUID::get_singleton()->id_to_text(uid);
5199-
}
5189+
const String id_string = _get_vs_editor_cache_id_string();
52005190

52015191
const int type = get_current_shader_type();
5202-
vs_editor_cache->set_value("visual_shader", id_string + ":type" + itos(type) + ":offset", graph->get_scroll_offset() / EDSCALE);
5203-
vs_editor_cache->set_value("visual_shader", id_string + ":type" + itos(type) + ":zoom", graph->get_zoom());
5192+
vs_editor_cache->set_value(id_string, "type" + itos(type) + ":offset", graph->get_scroll_offset() / EDSCALE);
5193+
vs_editor_cache->set_value(id_string, "type" + itos(type) + ":zoom", graph->get_zoom());
52045194
vs_editor_cache->save(EditorPaths::get_singleton()->get_project_settings_dir().path_join("vs_editor_cache.cfg"));
52055195
}
52065196

@@ -6453,7 +6443,6 @@ void VisualShaderEditor::_bind_methods() {
64536443
ClassDB::bind_method("_update_parameter", &VisualShaderEditor::_update_parameter);
64546444
ClassDB::bind_method("_update_next_previews", &VisualShaderEditor::_update_next_previews);
64556445
ClassDB::bind_method("_update_current_param", &VisualShaderEditor::_update_current_param);
6456-
ClassDB::bind_method("_restore_editor_state", &VisualShaderEditor::_restore_editor_state);
64576446
}
64586447

64596448
VisualShaderEditor::VisualShaderEditor() {
@@ -7724,7 +7713,7 @@ VisualShaderEditor::VisualShaderEditor() {
77247713

77257714
panning_debounce_timer = memnew(Timer);
77267715
panning_debounce_timer->set_one_shot(true);
7727-
panning_debounce_timer->set_wait_time(0.25);
7716+
panning_debounce_timer->set_wait_time(1.0);
77287717
panning_debounce_timer->connect("timeout", callable_mp(this, &VisualShaderEditor::_panning_debounce_timer_timeout));
77297718
add_child(panning_debounce_timer);
77307719
}

editor/plugins/visual_shader_editor_plugin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ class VisualShaderEditor : public ShaderEditor {
389389

390390
void _restore_editor_state();
391391

392+
String _get_vs_editor_cache_id_string() const;
393+
392394
struct AddOption {
393395
String name;
394396
String category;

misc/extension_api_validation/4.4-stable.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,4 @@ GH-98566
8989
Validate extension JSON: API was removed: classes/VisualShader/methods/set_graph_offset
9090
Validate extension JSON: API was removed: classes/VisualShader/methods/get_graph_offset
9191

92-
The graph_offset property was removed from the resource. This information is now stored as project metadata.
92+
The graph_offset property was removed from the resource. This information is now stored in `vs_editor_cache.cfg`.

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);
@@ -847,7 +862,7 @@ void GraphEdit::_notification(int p_what) {
847862
} break;
848863

849864
case NOTIFICATION_RESIZED: {
850-
_update_scroll();
865+
_update_scrollbars();
851866
minimap->queue_redraw();
852867
callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred();
853868
} break;
@@ -1712,7 +1727,7 @@ void GraphEdit::_top_layer_draw() {
17121727
}
17131728

17141729
void GraphEdit::_update_top_connection_layer() {
1715-
_update_scroll();
1730+
_update_scrollbars();
17161731

17171732
if (!connecting) {
17181733
dragged_connection_line->clear_points();
@@ -2296,9 +2311,15 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
22962311
void GraphEdit::_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event) {
22972312
ERR_FAIL_NULL_MSG(connections_layer, "connections_layer is missing.");
22982313

2299-
h_scrollbar->set_value(h_scrollbar->get_value() - p_scroll_vec.x);
2300-
v_scrollbar->set_value(v_scrollbar->get_value() - p_scroll_vec.y);
2314+
scroll_offset = (scroll_offset - p_scroll_vec).clamp(min_scroll_offset, max_scroll_offset - get_size());
23012315

2316+
if (!awaiting_scroll_offset_update) {
2317+
callable_mp(this, &GraphEdit::_update_scroll_offset).call_deferred();
2318+
awaiting_scroll_offset_update = true;
2319+
}
2320+
minimap->queue_redraw();
2321+
queue_redraw();
2322+
callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred();
23022323
connections_layer->queue_redraw();
23032324
}
23042325

@@ -2400,7 +2421,7 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
24002421
return;
24012422
}
24022423

2403-
Vector2 scrollbar_offset = (Vector2(h_scrollbar->get_value(), v_scrollbar->get_value()) + p_center) / zoom;
2424+
Point2 zoom_anchor = (scroll_offset + p_center) / zoom;
24042425

24052426
zoom = p_zoom;
24062427

@@ -2409,14 +2430,12 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
24092430
zoom_minus_button->set_disabled(zoom == zoom_min);
24102431
zoom_plus_button->set_disabled(zoom == zoom_max);
24112432

2412-
_update_scroll();
2433+
_update_scrollbars();
24132434
minimap->queue_redraw();
24142435
connections_layer->queue_redraw();
24152436

24162437
if (is_visible_in_tree()) {
2417-
Vector2 offset = scrollbar_offset * zoom - p_center;
2418-
h_scrollbar->set_value(offset.x);
2419-
v_scrollbar->set_value(offset.y);
2438+
scroll_offset = zoom_anchor * zoom - p_center;
24202439
}
24212440

24222441
_update_zoom_label();
@@ -3180,8 +3199,8 @@ GraphEdit::GraphEdit() {
31803199
v_scrollbar->set_min(-10000);
31813200
v_scrollbar->set_max(10000);
31823201

3183-
h_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scroll_moved));
3184-
v_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scroll_moved));
3202+
h_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scrollbar_moved));
3203+
v_scrollbar->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_scrollbar_moved));
31853204

31863205
// Toolbar menu.
31873206

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)