3434#include " core/input/input.h"
3535#include " core/io/dir_access.h"
3636#include " core/object/callable_mp.h"
37+ #include " core/object/class_db.h"
3738#include " core/os/os.h"
3839#include " core/os/time.h"
3940#include " core/version.h"
@@ -175,7 +176,7 @@ void ProjectListItemControl::_notification(int p_what) {
175176 } break ;
176177
177178 case NOTIFICATION_READY : {
178- set_project_title_autowrap ( );
179+ call_deferred ( " set_project_title_autowrap " );
179180 } break ;
180181 }
181182}
@@ -424,80 +425,90 @@ void ProjectListItemControl::set_is_grayed(bool p_grayed) {
424425 }
425426}
426427
427- void ProjectListItemControl::set_project_title_index (int p_title_index) {
428- project_title_index = p_title_index;
429- }
430-
431428void ProjectListItemControl::set_project_title_autowrap () {
432429 title_fullsize_cache = project_title->get_size ().x ;
433- window_size_cache = get_window ()->get_size ().x ;
430+ ProjectList *pl = get_list ();
431+ pl->window_size_cache = get_window ()->get_size ().x ;
434432
435433 int tag_size = 0 ;
436- int tag_maxsize = 0 ;
437434 for (Node *child : tag_container->iterate_children ()) {
438435 ProjectTag *tag = Object::cast_to<ProjectTag>(child);
439436 tag_size += tag->get_size ().x ;
440-
441- if (tag_maxsize == 0 ) {
442- tag_maxsize = tag->get_custom_maximum_size ().x ;
443- }
444- }
445- tag_size_cache = MIN (tag_size, tag_maxsize);
446- int &title_size_cache = get_list ()->title_size_cache [project_title_index];
447-
448- int size_check = 800 * EDSCALE ;
449- if (title_size_cache == 0 ) {
450- title_size_cache = size_check;
451437 }
438+ tag_size_cache = tag_size;
452439
453- if (title_fullsize_cache > size_check - tag_size_cache ) {
440+ if (title_fullsize_cache > pl-> title_size_cache - tag_size ) {
454441 resize_project_title ();
455442 }
456443}
457444
458445void 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;
466-
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) {
446+ const int title_available_space = get_list ()->title_size_cache - tag_size_cache;
447+ if (title_fullsize_cache <= title_available_space) {
471448 project_title->set_custom_maximum_size (Vector2 (-1 , -1 ));
472449 project_title->set_custom_minimum_size (Vector2 (0 , 0 ));
473450 project_title->set_autowrap_mode (TextServer::AUTOWRAP_OFF );
474-
475451 return ;
476452 }
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;
481453
482- int abs_minsize = (200 * EDSCALE );
454+ const int abs_minsize = (200 * EDSCALE );
483455 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- }
456+ const int title_maxsize = title_available_space;
457+ const int title_minsize = MAX (title_maxsize, abs_minsize);
458+ project_title->set_custom_maximum_size (Vector2 (MAX (title_minsize, title_maxsize), -1 ));
492459 project_title->set_custom_minimum_size (Vector2 (title_minsize, 0 ));
493460 project_title->set_autowrap_mode (TextServer::AUTOWRAP_WORD_SMART );
494461 }
495462}
496463
464+ int ProjectListItemControl::get_edge_elements_width () const {
465+ // Returns the combined width of the left spacer, favorite button, project icon,
466+ // right spacer, and the separation constant (10 * EDSCALE)
467+ int width = 0 ;
468+ int child_count = get_child_count ();
469+ // Left spacer (first child)
470+ if (child_count > 0 ) {
471+ Control *spacer = Object::cast_to<Control>(get_child (0 ));
472+ if (spacer) {
473+ width += spacer->get_size ().x ;
474+ }
475+ }
476+ // Favorite button
477+ if (favorite_button) {
478+ width += favorite_button->get_size ().x ;
479+ }
480+ // Project icon
481+ if (project_icon) {
482+ width += project_icon->get_size ().x ;
483+ }
484+ // Right spacer (last child)
485+ if (child_count > 0 ) {
486+ Control *right_spacer = Object::cast_to<Control>(get_child (child_count - 1 ));
487+ if (right_spacer) {
488+ width += right_spacer->get_size ().x ;
489+ }
490+ }
491+ // Separation constant
492+ width += 10 * EDSCALE ;
493+ return width;
494+ }
495+
496+ void ProjectList::_set_title_size_cache () {
497+ if (!_projects.is_empty ()) {
498+ Item &item = _projects.write [0 ];
499+ // Approx. size of project_title + tag_size
500+ title_size_cache = get_size ().x - item.control ->get_edge_elements_width () - 100 * EDSCALE ;
501+ } else {
502+ title_size_cache = -1 ;
503+ }
504+ }
505+
497506void ProjectListItemControl::_bind_methods () {
498507 ADD_SIGNAL (MethodInfo (" favorite_pressed" ));
499508 ADD_SIGNAL (MethodInfo (" explore_pressed" ));
500509 ADD_SIGNAL (MethodInfo (" request_menu" ));
510+
511+ ClassDB::bind_method (D_METHOD (" set_project_title_autowrap" ), &ProjectListItemControl::set_project_title_autowrap);
501512}
502513
503514ProjectListItemControl::ProjectListItemControl () {
@@ -661,6 +672,10 @@ bool ProjectList::project_feature_looks_like_version(const String &p_feature) {
661672
662673void ProjectList::_notification (int p_what) {
663674 switch (p_what) {
675+ case NOTIFICATION_READY : {
676+ _set_title_size_cache ();
677+ } break ;
678+
664679 case NOTIFICATION_TRANSLATION_CHANGED : {
665680 if (is_ready ()) {
666681 for (const Item &item : _projects) {
@@ -936,14 +951,12 @@ void ProjectList::update_project_list() {
936951 // If you have 150 projects, it may read through 150 files on your disk at once + load 150 icons.
937952 // FIXME: Does it really have to be a full, hard reload? Runtime updates should be made much cheaper.
938953
939- int temp_title_index = -1 ;
940954 if (ProjectManager::get_singleton ()->is_initialized ()) {
941955 // Clear whole list
942956 for (int i = 0 ; i < _projects.size (); ++i) {
943957 Item &project = _projects.write [i];
944958 CRASH_COND (project.control == nullptr );
945959
946- temp_title_index = project.project_title_index ;
947960 memdelete (project.control ); // Why not queue_free()?
948961 }
949962
@@ -956,9 +969,6 @@ void ProjectList::update_project_list() {
956969
957970 // Create controls
958971 for (int i = 0 ; i < _projects.size (); ++i) {
959- Item &item = _projects.write [i];
960- item.project_title_index = temp_title_index;
961-
962972 _create_project_item_control (i);
963973 }
964974
@@ -1146,14 +1156,10 @@ int ProjectList::refresh_project(const String &dir_path) {
11461156
11471157 bool was_selected = _selected_project_paths.has (dir_path);
11481158
1149- int temp_title_index = -1 ;
1150-
11511159 // Remove item in any case
11521160 for (int i = 0 ; i < _projects.size (); ++i) {
11531161 const Item &existing_item = _projects[i];
11541162 if (existing_item.path == dir_path) {
1155- temp_title_index = existing_item.project_title_index ;
1156-
11571163 _remove_project (i, false );
11581164 break ;
11591165 }
@@ -1165,7 +1171,6 @@ int ProjectList::refresh_project(const String &dir_path) {
11651171
11661172 Item item = load_project_data (dir_path, is_favorite);
11671173
1168- item.project_title_index = temp_title_index;
11691174 _projects.push_back (item);
11701175 _create_project_item_control (_projects.size () - 1 );
11711176
@@ -1233,16 +1238,11 @@ void ProjectList::_create_project_item_control(int p_index) {
12331238#endif
12341239 hb->connect (" request_menu" , callable_mp (this , &ProjectList::_open_menu).bind (hb));
12351240
1236- if (item.project_title_index == -1 ) {
1237- project_title_index_count++;
1238- title_size_cache[project_title_index_count] = 0 ;
1239- item.project_title_index = project_title_index_count;
1240- hb->set_project_title_index (project_title_index_count);
1241- } else {
1242- hb->set_project_title_index (item.project_title_index );
1243- }
1244-
12451241 project_list_vbox->add_child (hb);
1242+
1243+ if (title_size_cache == -1 ) {
1244+ _set_title_size_cache ();
1245+ }
12461246}
12471247
12481248void ProjectList::_update_project_control_translatable_fields (const Item &item) {
@@ -1597,6 +1597,16 @@ void ProjectList::erase_selected_projects(bool p_delete_project_contents) {
15971597// Resize project titles.
15981598
15991599void ProjectList::resize_project_titles () {
1600+ Window *win = get_window ();
1601+ if (win == nullptr ) {
1602+ return ;
1603+ }
1604+
1605+ const int window_size = win->get_size ().x ;
1606+ const int difference = window_size - window_size_cache;
1607+ window_size_cache = window_size;
1608+ title_size_cache += difference;
1609+
16001610 for (Item &item : _projects) {
16011611 item.control ->resize_project_title ();
16021612 }
0 commit comments