summaryrefslogtreecommitdiffstats
path: root/scene/gui/item_list.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/item_list.cpp')
-rw-r--r--scene/gui/item_list.cpp121
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_");