diff options
Diffstat (limited to 'scene/gui/rich_text_label.cpp')
-rw-r--r-- | scene/gui/rich_text_label.cpp | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index fe25d027f6..b50fad0e42 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -254,7 +254,12 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> for (int i = 0; i < col_count; i++) { remaining_width -= table->columns[i].min_width; if (table->columns[i].max_width > table->columns[i].min_width) { + // If the column can grow, allow it to grow. table->columns.write[i].expand = true; + } else { + // Otherwise make it shrink as much as possible, so that other columns can grow if needs be. + // We keep the max width as is to spread the remaining space between the columns later. + table->columns.write[i].min_width = 0; } if (table->columns[i].expand) { total_ratio += table->columns[i].expand_ratio; @@ -264,7 +269,7 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> // Assign actual widths. for (int i = 0; i < col_count; i++) { table->columns.write[i].width = table->columns[i].min_width; - if (table->columns[i].expand && total_ratio > 0) { + if (table->columns[i].expand && total_ratio > 0 && remaining_width > 0) { table->columns.write[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; } table->total_width += table->columns[i].width + hseparation; @@ -325,13 +330,16 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->columns.write[column].width = MAX(table->columns.write[column].width, ceil(frame->lines[i].text_buf->get_size().x)); if (i > 0) { - frame->lines.write[i].offset.y = frame->lines[i - 1].offset.y + frame->lines[i - 1].text_buf->get_size().y; + frame->lines.write[i].offset.y = frame->lines[i - 1].offset.y + frame->lines[i - 1].text_buf->get_size().y + get_theme_constant(SNAME("line_separation")); } else { frame->lines.write[i].offset.y = 0; } frame->lines.write[i].offset += offset; - float h = frame->lines[i].text_buf->get_size().y; + float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * get_theme_constant(SNAME("line_separation")); + if (i > 0) { + h += get_theme_constant(SNAME("line_separation")); + } if (frame->min_size_over.y > 0) { h = MAX(h, frame->min_size_over.y); } @@ -499,7 +507,12 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> for (int i = 0; i < col_count; i++) { remaining_width -= table->columns[i].min_width; if (table->columns[i].max_width > table->columns[i].min_width) { + // If the column can grow, allow it to grow. table->columns.write[i].expand = true; + } else { + // Otherwise make it shrink as much as possible, so that other columns can grow if needs be. + // We keep the max width as is to spread the remaining space between the columns later. + table->columns.write[i].min_width = 0; } if (table->columns[i].expand) { total_ratio += table->columns[i].expand_ratio; @@ -509,7 +522,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> // Assign actual widths. for (int i = 0; i < col_count; i++) { table->columns.write[i].width = table->columns[i].min_width; - if (table->columns[i].expand && total_ratio > 0) { + if (table->columns[i].expand && total_ratio > 0 && remaining_width > 0) { table->columns.write[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; } table->total_width += table->columns[i].width + hseparation; @@ -570,13 +583,16 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->columns.write[column].width = MAX(table->columns.write[column].width, ceil(frame->lines[i].text_buf->get_size().x)); if (i > 0) { - frame->lines.write[i].offset.y = frame->lines[i - 1].offset.y + frame->lines[i - 1].text_buf->get_size().y; + frame->lines.write[i].offset.y = frame->lines[i - 1].offset.y + frame->lines[i - 1].text_buf->get_size().y + get_theme_constant(SNAME("line_separation")); } else { frame->lines.write[i].offset.y = 0; } frame->lines.write[i].offset += offset; - float h = frame->lines[i].text_buf->get_size().y; + float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * get_theme_constant(SNAME("line_separation")); + if (i > 0) { + h += get_theme_constant(SNAME("line_separation")); + } if (frame->min_size_over.y > 0) { h = MAX(h, frame->min_size_over.y); } @@ -622,11 +638,12 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> } int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs, int &r_processed_glyphs) { - Vector2 off; - ERR_FAIL_COND_V(p_frame == nullptr, 0); ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), 0); + Vector2 off; + int line_spacing = get_theme_constant(SNAME("line_separation")); + Line &l = p_frame->lines.write[p_line]; Item *it_from = l.from; @@ -712,6 +729,10 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o Size2 ctrl_size = get_size(); // Draw text. for (int line = 0; line < l.text_buf->get_line_count(); line++) { + if (line > 0) { + off.y += line_spacing; + } + RID rid = l.text_buf->get_line_rid(line); if (p_ofs.y + off.y >= ctrl_size.height) { break; @@ -1005,7 +1026,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o float y_off = TS->shaped_text_get_underline_position(rid); float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width); - } else if (_find_strikethrough(it)) { + } + if (_find_strikethrough(it)) { Color uc = font_color; uc.a *= 0.5; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; @@ -2175,10 +2197,6 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { } // Resize lines without reshaping. - Size2 size = get_size(); - if (fixed_width != -1) { - size.width = fixed_width; - } Rect2 text_rect = _get_text_rect(); Ref<Font> base_font = get_theme_font(SNAME("normal_font")); @@ -2199,7 +2217,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { vscroll->set_max(total_height); vscroll->set_page(text_rect.size.height); if (scroll_follow && scroll_following) { - vscroll->set_value(total_height - size.height); + vscroll->set_value(total_height); } updating_scroll = false; @@ -2210,10 +2228,6 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { } // Shape invalid lines. - Size2 size = get_size(); - if (fixed_width != -1) { - size.width = fixed_width; - } Rect2 text_rect = _get_text_rect(); Ref<Font> base_font = get_theme_font(SNAME("normal_font")); @@ -2236,7 +2250,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { vscroll->set_max(total_height); vscroll->set_page(text_rect.size.height); if (scroll_follow && scroll_following) { - vscroll->set_value(total_height - size.height); + vscroll->set_value(total_height); } updating_scroll = false; @@ -2363,6 +2377,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub // Then remove the provided item itself. p_item->parent->subitems.erase(p_item); } + memdelete(p_item); } void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment) { @@ -3064,6 +3079,12 @@ void RichTextLabel::append_text(const String &p_bbcode) { push_strikethrough(); pos = brk_end + 1; tag_stack.push_front(tag); + } else if (tag == "lb") { + add_text("["); + pos = brk_end + 1; + } else if (tag == "rb") { + add_text("]"); + pos = brk_end + 1; } else if (tag == "lrm") { add_text(String::chr(0x200E)); pos = brk_end + 1; @@ -4199,7 +4220,7 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "RichTextEffect"), (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE)), "set_effects", "get_effects"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language"); ADD_GROUP("Structured Text", "structured_text_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override"); |