diff options
Diffstat (limited to 'scene/gui/item_list.cpp')
-rw-r--r-- | scene/gui/item_list.cpp | 121 |
1 files changed, 95 insertions, 26 deletions
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index bf16c0699e..f3cf29d0cf 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -32,7 +32,6 @@ #include "core/config/project_settings.h" #include "core/os/os.h" -#include "core/string/translation.h" #include "scene/theme/theme_db.h" void ItemList::_shape_text(int p_idx) { @@ -58,12 +57,12 @@ int ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bo Item item; item.icon = p_texture; item.text = p_item; - item.xl_text = atr(p_item); item.selectable = p_selectable; items.push_back(item); int item_id = items.size() - 1; - _shape_text(items.size() - 1); + items.write[item_id].xl_text = _atr(item_id, p_item); + _shape_text(item_id); queue_redraw(); shape_changed = true; @@ -95,7 +94,7 @@ void ItemList::set_item_text(int p_idx, const String &p_text) { } items.write[p_idx].text = p_text; - items.write[p_idx].xl_text = atr(p_text); + items.write[p_idx].xl_text = _atr(p_idx, p_text); _shape_text(p_idx); queue_redraw(); shape_changed = true; @@ -141,6 +140,24 @@ String ItemList::get_item_language(int p_idx) const { return items[p_idx].language; } +void ItemList::set_item_auto_translate_mode(int p_idx, AutoTranslateMode p_mode) { + if (p_idx < 0) { + p_idx += get_item_count(); + } + ERR_FAIL_INDEX(p_idx, items.size()); + if (items[p_idx].auto_translate_mode != p_mode) { + items.write[p_idx].auto_translate_mode = p_mode; + items.write[p_idx].xl_text = _atr(p_idx, items[p_idx].text); + _shape_text(p_idx); + queue_redraw(); + } +} + +Node::AutoTranslateMode ItemList::get_item_auto_translate_mode(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, items.size(), AUTO_TRANSLATE_MODE_INHERIT); + return items[p_idx].auto_translate_mode; +} + void ItemList::set_item_tooltip_enabled(int p_idx, const bool p_enabled) { if (p_idx < 0) { p_idx += get_item_count(); @@ -1022,7 +1039,7 @@ void ItemList::_notification(int p_what) { } break; case NOTIFICATION_TRANSLATION_CHANGED: { for (int i = 0; i < items.size(); i++) { - items.write[i].xl_text = atr(items[i].text); + items.write[i].xl_text = _atr(i, items[i].text); _shape_text(i); } shape_changed = true; @@ -1039,7 +1056,7 @@ void ItemList::_notification(int p_what) { scroll_bar->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -theme_cache.panel_style->get_margin(SIDE_BOTTOM)); Size2 size = get_size(); - int width = size.width - theme_cache.panel_style->get_minimum_size().width; + int width = size.width - theme_cache.panel_style->get_margin(SIDE_RIGHT); if (scroll_bar->is_visible()) { width -= scroll_bar_minwidth; } @@ -1192,9 +1209,9 @@ void ItemList::_notification(int p_what) { Point2 pos = items[i].rect_cache.position + icon_ofs + base_ofs; if (icon_mode == ICON_MODE_TOP) { - pos.y += theme_cache.v_separation / 2; + pos.y += MAX(theme_cache.v_separation, 0) / 2; } else { - pos.x += theme_cache.h_separation / 2; + pos.x += MAX(theme_cache.h_separation, 0) / 2; } if (icon_mode == ICON_MODE_TOP) { @@ -1243,8 +1260,8 @@ void ItemList::_notification(int p_what) { } Point2 draw_pos = items[i].rect_cache.position; - draw_pos.x += theme_cache.h_separation / 2; - draw_pos.y += theme_cache.v_separation / 2; + draw_pos.x += MAX(theme_cache.h_separation, 0) / 2; + draw_pos.y += MAX(theme_cache.v_separation, 0) / 2; if (rtl) { draw_pos.x = size.width - draw_pos.x - tag_icon_size.x; } @@ -1283,8 +1300,7 @@ void ItemList::_notification(int p_what) { text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; - text_ofs.x += theme_cache.h_separation / 2; - text_ofs.y += theme_cache.v_separation / 2; + text_ofs.y += MAX(theme_cache.v_separation, 0) / 2; if (rtl) { text_ofs.x = size.width - text_ofs.x - max_len; @@ -1292,7 +1308,7 @@ void ItemList::_notification(int p_what) { items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_CENTER); - float text_w = items[i].rect_cache.size.width - theme_cache.h_separation; + float text_w = items[i].rect_cache.size.width; items.write[i].text_buf->set_width(text_w); if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { @@ -1307,17 +1323,17 @@ void ItemList::_notification(int p_what) { if (icon_mode == ICON_MODE_TOP) { text_ofs.x += (items[i].rect_cache.size.width - size2.x) / 2; - text_ofs.x += theme_cache.h_separation / 2; - text_ofs.y += theme_cache.v_separation / 2; + text_ofs.x += MAX(theme_cache.h_separation, 0) / 2; + text_ofs.y += MAX(theme_cache.v_separation, 0) / 2; } else { text_ofs.y += (items[i].rect_cache.size.height - size2.y) / 2; - text_ofs.x += theme_cache.h_separation / 2; + text_ofs.x += MAX(theme_cache.h_separation, 0) / 2; } text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; - float text_w = width - text_ofs.x - theme_cache.h_separation; + float text_w = width - text_ofs.x; items.write[i].text_buf->set_width(text_w); if (rtl) { @@ -1410,14 +1426,14 @@ void ItemList::force_update_list_size() { max_column_width = MAX(max_column_width, minsize.x); // Elements need to adapt to the selected size. - minsize.y += theme_cache.v_separation; - minsize.x += theme_cache.h_separation; + minsize.y += MAX(theme_cache.v_separation, 0); + minsize.x += MAX(theme_cache.h_separation, 0); items.write[i].rect_cache.size = minsize; items.write[i].min_rect_cache.size = minsize; } - int fit_size = size.x - theme_cache.panel_style->get_minimum_size().width - scroll_bar_minwidth; + int fit_size = size.x - theme_cache.panel_style->get_minimum_size().width; //2-attempt best fit current_columns = 0x7FFFFFFF; @@ -1430,12 +1446,13 @@ void ItemList::force_update_list_size() { bool all_fit = true; Vector2 ofs; int col = 0; + int max_w = 0; int max_h = 0; separators.clear(); for (int i = 0; i < items.size(); i++) { - if (current_columns > 1 && items[i].rect_cache.size.width + ofs.x > fit_size) { + if (current_columns > 1 && items[i].rect_cache.size.width + ofs.x > fit_size && !auto_width) { // Went past. current_columns = MAX(col, 1); all_fit = false; @@ -1443,7 +1460,7 @@ void ItemList::force_update_list_size() { } if (same_column_width) { - items.write[i].rect_cache.size.x = max_column_width + theme_cache.h_separation; + items.write[i].rect_cache.size.x = max_column_width + MAX(theme_cache.h_separation, 0); } items.write[i].rect_cache.position = ofs; @@ -1461,6 +1478,7 @@ void ItemList::force_update_list_size() { items.write[j].rect_cache.size.y = max_h; } + max_w = MAX(max_w, ofs.x); ofs.x = 0; ofs.y += max_h; col = 0; @@ -1468,22 +1486,30 @@ void ItemList::force_update_list_size() { } } + float page = MAX(0, size.height - theme_cache.panel_style->get_minimum_size().height); + float max = MAX(page, ofs.y + max_h); + if (page >= max) { + fit_size -= scroll_bar_minwidth; + } + if (all_fit) { for (int j = items.size() - 1; j >= 0 && col > 0; j--, col--) { items.write[j].rect_cache.size.y = max_h; } - float page = MAX(0, size.height - theme_cache.panel_style->get_minimum_size().height); - float max = MAX(page, ofs.y + max_h); if (auto_height) { auto_height_value = ofs.y + max_h + theme_cache.panel_style->get_minimum_size().height; } + if (auto_width) { + auto_width_value = max_w + theme_cache.panel_style->get_minimum_size().width; + } scroll_bar->set_max(max); scroll_bar->set_page(page); if (max <= page) { scroll_bar->set_value(0); scroll_bar->hide(); } else { + auto_width_value += scroll_bar_minwidth; scroll_bar->show(); if (do_autoscroll_to_bottom) { @@ -1509,6 +1535,23 @@ void ItemList::_mouse_exited() { } } +String ItemList::_atr(int p_idx, const String &p_text) const { + ERR_FAIL_INDEX_V(p_idx, items.size(), atr(p_text)); + switch (items[p_idx].auto_translate_mode) { + case AUTO_TRANSLATE_MODE_INHERIT: { + return atr(p_text); + } break; + case AUTO_TRANSLATE_MODE_ALWAYS: { + return tr(p_text); + } break; + case AUTO_TRANSLATE_MODE_DISABLED: { + return p_text; + } break; + } + + ERR_FAIL_V_MSG(atr(p_text), "Unexpected auto translate mode: " + itos(items[p_idx].auto_translate_mode)); +} + int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const { Vector2 pos = p_pos; pos -= theme_cache.panel_style->get_offset(); @@ -1667,16 +1710,35 @@ bool ItemList::is_anything_selected() { } Size2 ItemList::get_minimum_size() const { + Size2 min_size; + if (auto_width) { + min_size.x = auto_width_value; + } + if (auto_height) { - return Size2(0, auto_height_value); + min_size.y = auto_height_value; } - return Size2(); + return min_size; } void ItemList::set_autoscroll_to_bottom(const bool p_enable) { do_autoscroll_to_bottom = p_enable; } +void ItemList::set_auto_width(bool p_enable) { + if (auto_width == p_enable) { + return; + } + + auto_width = p_enable; + shape_changed = true; + queue_redraw(); +} + +bool ItemList::has_auto_width() const { + return auto_width; +} + void ItemList::set_auto_height(bool p_enable) { if (auto_height == p_enable) { return; @@ -1748,6 +1810,9 @@ void ItemList::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_language", "idx", "language"), &ItemList::set_item_language); ClassDB::bind_method(D_METHOD("get_item_language", "idx"), &ItemList::get_item_language); + ClassDB::bind_method(D_METHOD("set_item_auto_translate_mode", "idx", "mode"), &ItemList::set_item_auto_translate_mode); + ClassDB::bind_method(D_METHOD("get_item_auto_translate_mode", "idx"), &ItemList::get_item_auto_translate_mode); + ClassDB::bind_method(D_METHOD("set_item_icon_transposed", "idx", "transposed"), &ItemList::set_item_icon_transposed); ClassDB::bind_method(D_METHOD("is_item_icon_transposed", "idx"), &ItemList::is_item_icon_transposed); @@ -1829,6 +1894,9 @@ void ItemList::_bind_methods() { ClassDB::bind_method(D_METHOD("set_allow_search", "allow"), &ItemList::set_allow_search); ClassDB::bind_method(D_METHOD("get_allow_search"), &ItemList::get_allow_search); + ClassDB::bind_method(D_METHOD("set_auto_width", "enable"), &ItemList::set_auto_width); + ClassDB::bind_method(D_METHOD("has_auto_width"), &ItemList::has_auto_width); + ClassDB::bind_method(D_METHOD("set_auto_height", "enable"), &ItemList::set_auto_height); ClassDB::bind_method(D_METHOD("has_auto_height"), &ItemList::has_auto_height); @@ -1850,6 +1918,7 @@ void ItemList::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_text_lines", PROPERTY_HINT_RANGE, "1,10,1,or_greater"), "set_max_text_lines", "get_max_text_lines"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_width"), "set_auto_width", "has_auto_width"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_"); |