Skip to content

Commit

Permalink
Merge pull request #83957 from kitbdev/scene-tab-reuse
Browse files Browse the repository at this point in the history
Only update `EditorSceneTabs` tabs when necessary
  • Loading branch information
YuriSizov committed Dec 14, 2023
2 parents c978f6b + 473c209 commit 19f4dfb
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 19 deletions.
59 changes: 40 additions & 19 deletions editor/gui/editor_scene_tabs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,59 +190,83 @@ void EditorSceneTabs::_disable_menu_option_if(int p_option, bool p_condition) {
}
}

// TODO: This REALLY should be done in a better way than replacing all tabs after almost EVERY action.
void EditorSceneTabs::update_scene_tabs() {
tab_preview_panel->hide();

bool show_rb = EDITOR_GET("interface/scene_tabs/show_script_button");
if (scene_tabs->get_tab_count() == EditorNode::get_editor_data().get_edited_scene_count()) {
_update_tab_titles();
return;
}

if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
DisplayServer::get_singleton()->global_menu_clear("_dock");
}

scene_tabs->set_block_signals(true);
scene_tabs->set_tab_count(EditorNode::get_editor_data().get_edited_scene_count());
scene_tabs->set_block_signals(false);

if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) {
int global_menu_index = DisplayServer::get_singleton()->global_menu_add_item("_dock", EditorNode::get_editor_data().get_scene_title(i), callable_mp(this, &EditorSceneTabs::_global_menu_scene), Callable(), i);
scene_tabs->set_tab_metadata(i, global_menu_index);
}

DisplayServer::get_singleton()->global_menu_add_separator("_dock");
DisplayServer::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), callable_mp(this, &EditorSceneTabs::_global_menu_new_window));
}

_update_tab_titles();
}

void EditorSceneTabs::_update_tab_titles() {
bool show_rb = EDITOR_GET("interface/scene_tabs/show_script_button");

// Get all scene names, which may be ambiguous.
Vector<String> disambiguated_scene_names;
Vector<String> full_path_names;
for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) {
disambiguated_scene_names.append(EditorNode::get_editor_data().get_scene_title(i));
full_path_names.append(EditorNode::get_editor_data().get_scene_path(i));
}

EditorNode::disambiguate_filenames(full_path_names, disambiguated_scene_names);

// Workaround to ignore the tab_changed signal from the first added tab.
scene_tabs->disconnect("tab_changed", callable_mp(this, &EditorSceneTabs::_scene_tab_changed));

scene_tabs->clear_tabs();
Ref<Texture2D> script_icon = get_editor_theme_icon(SNAME("Script"));
for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) {
Node *type_node = EditorNode::get_editor_data().get_edited_scene_root(i);
Ref<Texture2D> icon;
if (type_node) {
icon = EditorNode::get_singleton()->get_object_icon(type_node, "Node");
}
scene_tabs->set_tab_icon(i, icon);

bool unsaved = EditorUndoRedoManager::get_singleton()->is_history_unsaved(EditorNode::get_editor_data().get_scene_history_id(i));
scene_tabs->add_tab(disambiguated_scene_names[i] + (unsaved ? "(*)" : ""), icon);
scene_tabs->set_tab_title(i, disambiguated_scene_names[i] + (unsaved ? "(*)" : ""));

if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
DisplayServer::get_singleton()->global_menu_add_item("_dock", EditorNode::get_editor_data().get_scene_title(i) + (unsaved ? "(*)" : ""), callable_mp(this, &EditorSceneTabs::_global_menu_scene), Callable(), i);
int global_menu_index = scene_tabs->get_tab_metadata(i);
DisplayServer::get_singleton()->global_menu_set_item_text("_dock", global_menu_index, EditorNode::get_editor_data().get_scene_title(i) + (unsaved ? "(*)" : ""));
DisplayServer::get_singleton()->global_menu_set_item_tag("_dock", global_menu_index, i);
}

if (show_rb && EditorNode::get_editor_data().get_scene_root_script(i).is_valid()) {
scene_tabs->set_tab_button_icon(i, script_icon);
} else {
scene_tabs->set_tab_button_icon(i, nullptr);
}
}

if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
DisplayServer::get_singleton()->global_menu_add_separator("_dock");
DisplayServer::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), callable_mp(this, &EditorSceneTabs::_global_menu_new_window));
int current_tab = EditorNode::get_editor_data().get_edited_scene();
if (scene_tabs->get_tab_count() > 0 && scene_tabs->get_current_tab() != current_tab) {
scene_tabs->set_block_signals(true);
scene_tabs->set_current_tab(current_tab);
scene_tabs->set_block_signals(false);
}

if (scene_tabs->get_tab_count() > 0) {
scene_tabs->set_current_tab(EditorNode::get_editor_data().get_edited_scene());
}
_scene_tabs_resized();
}

void EditorSceneTabs::_scene_tabs_resized() {
const Size2 add_button_size = Size2(scene_tab_add->get_size().x, scene_tabs->get_size().y);
if (scene_tabs->get_offset_buttons_visible()) {
// Move the add button to a fixed position.
Expand Down Expand Up @@ -271,9 +295,6 @@ void EditorSceneTabs::update_scene_tabs() {
scene_tab_add->set_rect(Rect2(Point2(last_tab.position.x + last_tab.size.width + hsep, last_tab.position.y), add_button_size));
}
}

// Reconnect after everything is done.
scene_tabs->connect("tab_changed", callable_mp(this, &EditorSceneTabs::_scene_tab_changed));
}

void EditorSceneTabs::_tab_preview_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, const Variant &p_udata) {
Expand Down Expand Up @@ -365,7 +386,7 @@ EditorSceneTabs::EditorSceneTabs() {
scene_tabs->connect("mouse_exited", callable_mp(this, &EditorSceneTabs::_scene_tab_exit));
scene_tabs->connect("gui_input", callable_mp(this, &EditorSceneTabs::_scene_tab_input));
scene_tabs->connect("active_tab_rearranged", callable_mp(this, &EditorSceneTabs::_reposition_active_tab));
scene_tabs->connect("resized", callable_mp(this, &EditorSceneTabs::update_scene_tabs));
scene_tabs->connect("resized", callable_mp(this, &EditorSceneTabs::_scene_tabs_resized));

scene_tabs_context_menu = memnew(PopupMenu);
tabbar_container->add_child(scene_tabs_context_menu);
Expand Down
2 changes: 2 additions & 0 deletions editor/gui/editor_scene_tabs.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ class EditorSceneTabs : public MarginContainer {
void _scene_tab_hovered(int p_tab);
void _scene_tab_exit();
void _scene_tab_input(const Ref<InputEvent> &p_input);
void _scene_tabs_resized();

void _update_tab_titles();
void _reposition_active_tab(int p_to_index);
void _update_context_menu();
void _disable_menu_option_if(int p_option, bool p_condition);
Expand Down

0 comments on commit 19f4dfb

Please sign in to comment.