Skip to content

Commit c2f696a

Browse files
[Project Manager] Fix Wrap Long Project Title
Fixes several issues where long project titles were not wrapping correctly in the project list. Co-authored-by: unit-tick <official.prince.john@gmail.com>
1 parent c050c09 commit c2f696a

3 files changed

Lines changed: 66 additions & 75 deletions

File tree

editor/project_manager/project_list.cpp

Lines changed: 51 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -424,72 +424,60 @@ void ProjectListItemControl::set_is_grayed(bool p_grayed) {
424424
}
425425
}
426426

427-
void ProjectListItemControl::set_project_title_index(int p_title_index) {
428-
project_title_index = p_title_index;
429-
}
430-
431427
void ProjectListItemControl::set_project_title_autowrap() {
428+
ProjectList *pl = get_list();
432429
title_fullsize_cache = project_title->get_size().x;
433-
window_size_cache = get_window()->get_size().x;
434430

435431
int tag_size = 0;
436432
int tag_maxsize = 0;
437433
for (Node *child : tag_container->iterate_children()) {
438434
ProjectTag *tag = Object::cast_to<ProjectTag>(child);
439-
tag_size += tag->get_size().x;
440-
441-
if (tag_maxsize == 0) {
442-
tag_maxsize = tag->get_custom_maximum_size().x;
435+
int temp_tag_size = tag->get_size().x;
436+
tag_size += temp_tag_size;
437+
if (temp_tag_size > tag_maxsize) {
438+
tag_maxsize = temp_tag_size;
443439
}
444440
}
441+
tag_fullsize_cache = tag_size;
445442
tag_size_cache = MIN(tag_size, tag_maxsize);
446-
int &title_size_cache = get_list()->title_size_cache[project_title_index];
447443

448-
int size_check = 800 * EDSCALE;
449-
if (title_size_cache == 0) {
450-
title_size_cache = size_check;
444+
const int project_title_and_tags_fullsize = title_fullsize_cache + tag_size;
445+
int &largest_project_title_and_tags_fullsize = pl->largest_project_title_and_tags_fullsize;
446+
if (project_title_and_tags_fullsize > largest_project_title_and_tags_fullsize) {
447+
largest_project_title_and_tags_fullsize = project_title_and_tags_fullsize;
451448
}
452449

453-
if (title_fullsize_cache > size_check - tag_size_cache) {
454-
resize_project_title();
450+
int &abs_title_and_tags_minsize = pl->abs_title_and_tags_minsize_cache;
451+
if (abs_title_and_tags_minsize == 0) {
452+
ProjectTag *tag = memnew(ProjectTag("dummy"));
453+
const int abs_tag_maxsize = tag->get_custom_maximum_size().x;
454+
memdelete(tag);
455+
abs_title_and_tags_minsize = (200 * EDSCALE) + abs_tag_maxsize;
455456
}
456-
}
457457

458-
void ProjectListItemControl::resize_project_title() {
459-
if (get_window() == nullptr) {
460-
return;
461-
}
462-
463-
int window_size = get_window()->get_size().x;
464-
int difference = window_size - window_size_cache;
465-
window_size_cache = window_size;
458+
int &title_and_tags_size = pl->title_and_tags_size_cache;
466459

467-
int &title_size_cache = get_list()->title_size_cache[project_title_index];
468-
title_size_cache += difference;
469-
470-
if (title_size_cache > title_fullsize_cache + tag_size_cache) {
471-
project_title->set_custom_maximum_size(Vector2(-1, -1));
472-
project_title->set_custom_minimum_size(Vector2(0, 0));
473-
project_title->set_autowrap_mode(TextServer::AUTOWRAP_OFF);
460+
if (title_fullsize_cache > title_and_tags_size - tag_size && !pl->before_ready) {
461+
resize_project_title(title_and_tags_size, abs_title_and_tags_minsize);
462+
}
463+
}
474464

465+
void ProjectListItemControl::resize_project_title(int p_title_and_tags_size, int p_abs_title_and_tags_minsize) {
466+
if (p_title_and_tags_size >= title_fullsize_cache + tag_fullsize_cache) {
467+
if (project_title->get_autowrap_mode() != TextServer::AUTOWRAP_OFF) {
468+
project_title->set_custom_maximum_size(Vector2(-1, -1));
469+
project_title->set_custom_minimum_size(Vector2(0, 0));
470+
project_title->set_autowrap_mode(TextServer::AUTOWRAP_OFF);
471+
}
475472
return;
476473
}
477-
ProjectTag tag = ProjectTag("dummy");
478-
int tag_maxsize = tag.get_custom_maximum_size().x;
479-
int title_maxsize = title_size_cache - tag_size_cache;
480-
int title_minsize = title_size_cache - tag_maxsize;
481474

482-
int abs_minsize = (200 * EDSCALE);
483-
if (title_fullsize_cache > abs_minsize) {
484-
if (title_minsize < abs_minsize) {
485-
title_minsize = abs_minsize + tag_maxsize - tag_size_cache;
486-
}
487-
if (title_maxsize < title_minsize) {
488-
project_title->set_custom_maximum_size(Vector2(title_minsize, -1));
489-
} else {
490-
project_title->set_custom_maximum_size(Vector2(title_maxsize, -1));
491-
}
492-
project_title->set_custom_minimum_size(Vector2(title_minsize, 0));
475+
const int abs_title_minsize = p_abs_title_and_tags_minsize - tag_size_cache;
476+
if (title_fullsize_cache >= abs_title_minsize) {
477+
const int title_maxsize = p_title_and_tags_size - tag_size_cache;
478+
const int title_size = MAX(title_maxsize, abs_title_minsize);
479+
project_title->set_custom_maximum_size(Vector2(title_size, -1));
480+
project_title->set_custom_minimum_size(Vector2(title_size, 0));
493481
project_title->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
494482
}
495483
}
@@ -701,7 +689,12 @@ void ProjectList::_notification(int p_what) {
701689
AccessibilityServer::get_singleton()->update_set_role(ae, AccessibilityServerEnums::AccessibilityRole::ROLE_LIST_BOX);
702690
AccessibilityServer::get_singleton()->update_set_list_item_count(ae, _projects.size());
703691
AccessibilityServer::get_singleton()->update_set_flag(ae, AccessibilityServerEnums::AccessibilityFlags::FLAG_MULTISELECTABLE, false);
704-
}
692+
} break;
693+
694+
case NOTIFICATION_READY: {
695+
window_size_cache = get_window()->get_size().x;
696+
before_ready = false;
697+
} break;
705698
}
706699
}
707700

@@ -934,14 +927,12 @@ void ProjectList::update_project_list() {
934927
// If you have 150 projects, it may read through 150 files on your disk at once + load 150 icons.
935928
// FIXME: Does it really have to be a full, hard reload? Runtime updates should be made much cheaper.
936929

937-
int temp_title_index = -1;
938930
if (ProjectManager::get_singleton()->is_initialized()) {
939931
// Clear whole list
940932
for (int i = 0; i < _projects.size(); ++i) {
941933
Item &project = _projects.write[i];
942934
CRASH_COND(project.control == nullptr);
943935

944-
temp_title_index = project.project_title_index;
945936
memdelete(project.control); // Why not queue_free()?
946937
}
947938

@@ -954,9 +945,6 @@ void ProjectList::update_project_list() {
954945

955946
// Create controls
956947
for (int i = 0; i < _projects.size(); ++i) {
957-
Item &item = _projects.write[i];
958-
item.project_title_index = temp_title_index;
959-
960948
_create_project_item_control(i);
961949
}
962950

@@ -1144,14 +1132,10 @@ int ProjectList::refresh_project(const String &dir_path) {
11441132

11451133
bool was_selected = _selected_project_paths.has(dir_path);
11461134

1147-
int temp_title_index = -1;
1148-
11491135
// Remove item in any case
11501136
for (int i = 0; i < _projects.size(); ++i) {
11511137
const Item &existing_item = _projects[i];
11521138
if (existing_item.path == dir_path) {
1153-
temp_title_index = existing_item.project_title_index;
1154-
11551139
_remove_project(i, false);
11561140
break;
11571141
}
@@ -1163,7 +1147,6 @@ int ProjectList::refresh_project(const String &dir_path) {
11631147

11641148
Item item = load_project_data(dir_path, is_favorite);
11651149

1166-
item.project_title_index = temp_title_index;
11671150
_projects.push_back(item);
11681151
_create_project_item_control(_projects.size() - 1);
11691152

@@ -1230,15 +1213,6 @@ void ProjectList::_create_project_item_control(int p_index) {
12301213
#endif
12311214
hb->connect("request_menu", callable_mp(this, &ProjectList::_open_menu).bind(hb));
12321215

1233-
if (item.project_title_index == -1) {
1234-
project_title_index_count++;
1235-
title_size_cache[project_title_index_count] = 0;
1236-
item.project_title_index = project_title_index_count;
1237-
hb->set_project_title_index(project_title_index_count);
1238-
} else {
1239-
hb->set_project_title_index(item.project_title_index);
1240-
}
1241-
12421216
project_list_vbox->add_child(hb);
12431217
item.control = hb;
12441218
}
@@ -1587,8 +1561,18 @@ void ProjectList::erase_selected_projects(bool p_delete_project_contents) {
15871561
// Resize project titles.
15881562

15891563
void ProjectList::resize_project_titles() {
1564+
Window *win = get_window();
1565+
if (win == nullptr) {
1566+
return;
1567+
}
1568+
1569+
const int window_size = win->get_size().x;
1570+
const int difference = window_size - window_size_cache;
1571+
window_size_cache = window_size;
1572+
title_and_tags_size_cache += difference;
1573+
15901574
for (Item &item : _projects) {
1591-
item.control->resize_project_title();
1575+
item.control->resize_project_title(title_and_tags_size_cache, abs_title_and_tags_minsize_cache);
15921576
}
15931577
}
15941578

editor/project_manager/project_list.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ class ProjectListItemControl : public HBoxContainer {
6262

6363
Color favorite_focus_color;
6464

65-
int project_title_index = -1;
66-
6765
bool project_is_missing = false;
6866
bool icon_needs_reload = true;
6967
bool is_selected = false;
@@ -97,8 +95,8 @@ class ProjectListItemControl : public HBoxContainer {
9795
// Caches for resizing project titles.
9896

9997
int title_fullsize_cache = 0;
98+
int tag_fullsize_cache = 0;
10099
int tag_size_cache = 0;
101-
int window_size_cache = 0;
102100

103101
protected:
104102
void _notification(int p_what);
@@ -119,10 +117,9 @@ class ProjectListItemControl : public HBoxContainer {
119117
void set_is_favorite(bool p_favorite);
120118
void set_is_missing(bool p_missing);
121119
void set_is_grayed(bool p_grayed);
122-
void set_project_title_index(int p_title_index);
123120
void set_project_title_autowrap();
124121

125-
void resize_project_title();
122+
void resize_project_title(int p_title_size, int p_abs_title_and_tags_minsize);
126123

127124
ProjectListItemControl();
128125
};
@@ -171,7 +168,6 @@ class ProjectList : public ScrollContainer {
171168
bool missing = false;
172169
bool recovery_mode = false;
173170
int version = 0;
174-
int project_title_index = -1;
175171

176172
ProjectListItemControl *control = nullptr;
177173

@@ -220,8 +216,11 @@ class ProjectList : public ScrollContainer {
220216
String get_last_edited_string() const;
221217
};
222218

223-
HashMap<int, int> title_size_cache;
224-
int project_title_index_count = -1;
219+
bool before_ready = true;
220+
int window_size_cache = 0;
221+
int title_and_tags_size_cache = 0;
222+
int largest_project_title_and_tags_fullsize = 0;
223+
int abs_title_and_tags_minsize_cache = 0;
225224

226225
private:
227226
String _config_path;

editor/project_manager/project_manager.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ void ProjectManager::_notification(int p_what) {
112112
_select_main_view(MAIN_VIEW_PROJECTS);
113113
_update_list_placeholder();
114114
_titlebar_resized();
115+
116+
Ref<StyleBox> root_sb = root_container->get_theme_stylebox(SNAME("panel"), SNAME("PanelContainer"));
117+
const int root_padding = root_sb.is_valid() ? root_sb->get_margin(SIDE_LEFT) + root_sb->get_margin(SIDE_RIGHT) : 0.0f;
118+
const int pl_width = project_list->get_size().x;
119+
const int pl_edge_width = pl_width - project_list->largest_project_title_and_tags_fullsize;
120+
project_list->title_and_tags_size_cache = root_container->get_size().x - pl_edge_width - project_list_sidebar->get_size().x - root_padding;
121+
122+
project_list->resize_project_titles();
115123
} break;
116124

117125
case NOTIFICATION_TRANSLATION_CHANGED: {

0 commit comments

Comments
 (0)