Fix ItemList layout (+EditorFileDialog)

This commit is contained in:
Hendrik Brucker 2021-08-21 00:22:09 +02:00
parent a031579286
commit 72e49eadec
6 changed files with 51 additions and 19 deletions

View File

@ -403,6 +403,9 @@
<member name="select_mode" type="int" setter="set_select_mode" getter="get_select_mode" enum="ItemList.SelectMode" default="0">
Allows single or multiple item selection. See the [enum SelectMode] constants.
</member>
<member name="text_overrun_behavior" type="int" setter="set_text_overrun_behavior" getter="get_text_overrun_behavior" enum="TextParagraph.OverrunBehavior" default="0">
Sets the clipping behavior when the text exceeds an item's bounding rectangle. See [enum TextParagraph.OverrunBehavior] for a description of all modes.
</member>
</members>
<signals>
<signal name="item_activated">

View File

@ -728,6 +728,7 @@ void EditorFileDialog::update_file_list() {
item_list->set_icon_mode(ItemList::ICON_MODE_TOP);
item_list->set_fixed_column_width(thumbnail_size * 3 / 2);
item_list->set_max_text_lines(2);
item_list->set_text_overrun_behavior(TextParagraph::OVERRUN_TRIM_ELLIPSIS);
item_list->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
if (thumbnail_size < 64) {
@ -1645,6 +1646,7 @@ EditorFileDialog::EditorFileDialog() {
item_list->connect("item_rmb_selected", callable_mp(this, &EditorFileDialog::_item_list_item_rmb_selected));
item_list->connect("rmb_clicked", callable_mp(this, &EditorFileDialog::_item_list_rmb_clicked));
item_list->set_allow_rmb_select(true);
list_vb->add_child(item_list);
item_menu = memnew(PopupMenu);

View File

@ -48,6 +48,8 @@ void ItemList::_shape(int p_idx) {
} else {
item.text_buf->set_flags(TextServer::BREAK_NONE);
}
item.text_buf->set_text_overrun_behavior(text_overrun_behavior);
item.text_buf->set_max_lines_visible(max_text_lines);
}
int ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) {
@ -453,6 +455,7 @@ void ItemList::set_max_text_lines(int p_lines) {
for (int i = 0; i < items.size(); i++) {
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
items.write[i].text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
items.write[i].text_buf->set_max_lines_visible(p_lines);
} else {
items.write[i].text_buf->set_flags(TextServer::BREAK_NONE);
}
@ -930,8 +933,14 @@ void ItemList::_notification(int p_what) {
}
if (items[i].text != "") {
int max_width = -1;
if (fixed_column_width) {
max_width = fixed_column_width;
} else if (same_column_width) {
max_width = items[i].rect_cache.size.x;
}
items.write[i].text_buf->set_width(max_width);
Size2 s = items[i].text_buf->get_size();
//s.width=MIN(s.width,fixed_column_width);
if (icon_mode == ICON_MODE_TOP) {
minsize.x = MAX(minsize.x, s.width);
@ -1139,11 +1148,8 @@ void ItemList::_notification(int p_what) {
if (icon_mode == ICON_MODE_TOP) {
pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width) / 2);
pos.y += MIN(
Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2),
items[i].rect_cache.size.height - items[i].min_rect_cache.size.height);
text_ofs.y = icon_size.height + icon_margin;
text_ofs.y += items[i].rect_cache.size.height - items[i].min_rect_cache.size.height;
pos.y += icon_margin;
text_ofs.y = icon_size.height + icon_margin * 2;
} else {
pos.y += Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2);
text_ofs.x = icon_size.width + icon_margin;
@ -1210,7 +1216,6 @@ void ItemList::_notification(int p_what) {
text_ofs.x = size.width - text_ofs.x - max_len;
}
items.write[i].text_buf->set_width(max_len);
items.write[i].text_buf->set_align(HALIGN_CENTER);
if (outline_size > 0 && font_outline_color.a > 0) {
@ -1488,6 +1493,21 @@ bool ItemList::has_auto_height() const {
return auto_height;
}
void ItemList::set_text_overrun_behavior(TextParagraph::OverrunBehavior p_behavior) {
if (text_overrun_behavior != p_behavior) {
text_overrun_behavior = p_behavior;
for (int i = 0; i < items.size(); i++) {
items.write[i].text_buf->set_text_overrun_behavior(p_behavior);
}
shape_changed = true;
update();
}
}
TextParagraph::OverrunBehavior ItemList::get_text_overrun_behavior() const {
return text_overrun_behavior;
}
void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_item", "text", "icon", "selectable"), &ItemList::add_item, DEFVAL(Variant()), DEFVAL(true));
ClassDB::bind_method(D_METHOD("add_icon_item", "icon", "selectable"), &ItemList::add_icon_item, DEFVAL(true));
@ -1599,6 +1619,9 @@ void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_items"), &ItemList::_set_items);
ClassDB::bind_method(D_METHOD("_get_items"), &ItemList::_get_items);
ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &ItemList::set_text_overrun_behavior);
ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &ItemList::get_text_overrun_behavior);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items");
ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Multi"), "set_select_mode", "get_select_mode");
@ -1606,6 +1629,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::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_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_GROUP("Columns", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_columns", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), "set_max_columns", "get_max_columns");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "same_column_width"), "set_same_column_width", "is_same_column_width");

View File

@ -95,6 +95,7 @@ private:
SelectMode select_mode = SELECT_SINGLE;
IconMode icon_mode = ICON_MODE_LEFT;
VScrollBar *scroll_bar;
TextParagraph::OverrunBehavior text_overrun_behavior = TextParagraph::OVERRUN_NO_TRIMMING;
uint64_t search_time_msec = 0;
String search_string;
@ -182,6 +183,9 @@ public:
void set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color);
Color get_item_custom_fg_color(int p_idx) const;
void set_text_overrun_behavior(TextParagraph::OverrunBehavior p_behavior);
TextParagraph::OverrunBehavior get_text_overrun_behavior() const;
void select(int p_idx, bool p_single = true);
void deselect(int p_idx);
void deselect_all();

View File

@ -437,7 +437,8 @@ Size2 TextParagraph::get_non_wraped_size() const {
Size2 TextParagraph::get_size() const {
const_cast<TextParagraph *>(this)->_shape_lines();
Size2 size;
for (int i = 0; i < lines_rid.size(); i++) {
int visible_lines = (max_lines_visible >= 0) ? MIN(max_lines_visible, lines_rid.size()) : lines_rid.size();
for (int i = 0; i < visible_lines; i++) {
Size2 lsize = TS->shaped_text_get_size(lines_rid[i]);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
size.x = MAX(size.x, lsize.x);
@ -587,15 +588,15 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
l_width -= h_offset;
}
}
float length = TS->shaped_text_get_width(lines_rid[i]);
float line_width = TS->shaped_text_get_width(lines_rid[i]);
if (width > 0) {
switch (align) {
case HALIGN_FILL:
if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += l_width - length;
ofs.x += l_width - line_width;
} else {
ofs.y += l_width - length;
ofs.y += l_width - line_width;
}
}
break;
@ -603,16 +604,16 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
break;
case HALIGN_CENTER: {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += Math::floor((l_width - length) / 2.0);
ofs.x += Math::floor((l_width - line_width) / 2.0);
} else {
ofs.y += Math::floor((l_width - length) / 2.0);
ofs.y += Math::floor((l_width - line_width) / 2.0);
}
} break;
case HALIGN_RIGHT: {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x += l_width - length;
ofs.x += l_width - line_width;
} else {
ofs.y += l_width - length;
ofs.y += l_width - line_width;
}
} break;
}

View File

@ -665,9 +665,7 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w
continue;
}
if (l_gl[i].count > 0) {
//Ignore trailing spaces.
bool is_space = (l_gl[i].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE;
if ((p_width > 0) && (width + (is_space ? 0 : l_gl[i].advance) > p_width) && (last_safe_break >= 0)) {
if ((p_width > 0) && (width + l_gl[i].advance * l_gl[i].repeat > p_width) && (last_safe_break >= 0)) {
lines.push_back(Vector2i(line_start, l_gl[last_safe_break].end));
line_start = l_gl[last_safe_break].end;
i = last_safe_break;
@ -698,7 +696,7 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w
last_safe_break = i;
}
}
width += l_gl[i].advance;
width += l_gl[i].advance * l_gl[i].repeat;
}
if (l_size > 0) {