diff options
Diffstat (limited to 'scene/gui/rich_text_label.cpp')
-rw-r--r-- | scene/gui/rich_text_label.cpp | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index f26e05518e..a0f2096009 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -150,7 +150,12 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item return it; } } break; - case ITEM_IMAGE: + case ITEM_IMAGE: { + offset += 1; + if (offset > p_position) { + return it; + } + } break; case ITEM_TABLE: { offset += 1; } break; @@ -325,7 +330,11 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font if (table->columns[i].expand && total_ratio > 0 && remaining_width > 0) { table->columns[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; } - table->total_width += table->columns[i].width + theme_cache.table_h_separation; + if (i != col_count - 1) { + table->total_width += table->columns[i].width + theme_cache.table_h_separation; + } else { + table->total_width += table->columns[i].width; + } } // Resize to max_width if needed and distribute the remaining space. @@ -366,6 +375,7 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font idx = 0; table->total_height = 0; table->rows.clear(); + table->rows_baseline.clear(); Vector2 offset; float row_height = 0.0; @@ -379,13 +389,13 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font offset.x += frame->padding.position.x; float yofs = frame->padding.position.y; float prev_h = 0; + float row_baseline = 0.0; for (int i = 0; i < (int)frame->lines.size(); i++) { MutexLock sub_lock(frame->lines[i].text_buf->get_mutex()); frame->lines[i].text_buf->set_width(table->columns[column].width); table->columns[column].width = MAX(table->columns[column].width, ceil(frame->lines[i].text_buf->get_size().x)); frame->lines[i].offset.y = prev_h; - frame->lines[i].offset += offset; float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * theme_cache.line_separation; if (i > 0) { @@ -399,6 +409,9 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font } yofs += h; prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * theme_cache.line_separation; + + frame->lines[i].offset += offset; + row_baseline = MAX(row_baseline, frame->lines[i].text_buf->get_line_ascent(frame->lines[i].text_buf->get_line_count() - 1)); } yofs += frame->padding.size.y; offset.x += table->columns[column].width + theme_cache.table_h_separation + frame->padding.size.x; @@ -410,11 +423,17 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font table->total_height += row_height; offset.y += row_height; table->rows.push_back(row_height); + table->rows_baseline.push_back(table->total_height - row_height + row_baseline); row_height = 0; } idx++; } - l.text_buf->resize_object((uint64_t)it, Size2(table->total_width, table->total_height), table->inline_align); + int row_idx = (table->align_to_row < 0) ? table->rows_baseline.size() - 1 : table->align_to_row; + if (table->rows_baseline.size() != 0 && row_idx < (int)table->rows_baseline.size() - 1) { + l.text_buf->resize_object((uint64_t)it, Size2(table->total_width, table->total_height), table->inline_align, Math::round(table->rows_baseline[row_idx])); + } else { + l.text_buf->resize_object((uint64_t)it, Size2(table->total_width, table->total_height), table->inline_align); + } } break; default: break; @@ -600,7 +619,11 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> if (table->columns[i].expand && total_ratio > 0 && remaining_width > 0) { table->columns[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; } - table->total_width += table->columns[i].width + theme_cache.table_h_separation; + if (i != col_count - 1) { + table->total_width += table->columns[i].width + theme_cache.table_h_separation; + } else { + table->total_width += table->columns[i].width; + } } // Resize to max_width if needed and distribute the remaining space. @@ -641,6 +664,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> idx = 0; table->total_height = 0; table->rows.clear(); + table->rows_baseline.clear(); Vector2 offset; float row_height = 0.0; @@ -654,6 +678,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> offset.x += frame->padding.position.x; float yofs = frame->padding.position.y; float prev_h = 0; + float row_baseline = 0.0; for (int i = 0; i < (int)frame->lines.size(); i++) { MutexLock sub_lock(frame->lines[i].text_buf->get_mutex()); @@ -661,7 +686,6 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->columns[column].width = MAX(table->columns[column].width, ceil(frame->lines[i].text_buf->get_size().x)); frame->lines[i].offset.y = prev_h; - frame->lines[i].offset += offset; float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * theme_cache.line_separation; if (i > 0) { @@ -675,6 +699,9 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> } yofs += h; prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * theme_cache.line_separation; + + frame->lines[i].offset += offset; + row_baseline = MAX(row_baseline, frame->lines[i].text_buf->get_line_ascent(frame->lines[i].text_buf->get_line_count() - 1)); } yofs += frame->padding.size.y; offset.x += table->columns[column].width + theme_cache.table_h_separation + frame->padding.size.x; @@ -687,12 +714,17 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->total_height += row_height; offset.y += row_height; table->rows.push_back(row_height); + table->rows_baseline.push_back(table->total_height - row_height + row_baseline); row_height = 0; } idx++; } - - l.text_buf->add_object((uint64_t)it, Size2(table->total_width, table->total_height), table->inline_align, t_char_count); + int row_idx = (table->align_to_row < 0) ? table->rows_baseline.size() - 1 : table->align_to_row; + if (table->rows_baseline.size() != 0 && row_idx < (int)table->rows_baseline.size() - 1) { + l.text_buf->add_object((uint64_t)it, Size2(table->total_width, table->total_height), table->inline_align, t_char_count, Math::round(table->rows_baseline[row_idx])); + } else { + l.text_buf->add_object((uint64_t)it, Size2(table->total_width, table->total_height), table->inline_align, t_char_count); + } txt += String::chr(0xfffc).repeat(t_char_count); } break; default: @@ -3298,7 +3330,7 @@ void RichTextLabel::push_hint(const String &p_string) { _add_item(item, true); } -void RichTextLabel::push_table(int p_columns, InlineAlignment p_alignment) { +void RichTextLabel::push_table(int p_columns, InlineAlignment p_alignment, int p_align_to_row) { _stop_thread(); MutexLock data_lock(data_mutex); @@ -3308,6 +3340,7 @@ void RichTextLabel::push_table(int p_columns, InlineAlignment p_alignment) { item->columns.resize(p_columns); item->total_width = 0; item->inline_align = p_alignment; + item->align_to_row = p_align_to_row; for (int i = 0; i < (int)item->columns.size(); i++) { item->columns[i].expand = false; item->columns[i].expand_ratio = 1; @@ -3788,6 +3821,8 @@ void RichTextLabel::append_text(const String &p_bbcode) { alignment = INLINE_ALIGNMENT_TOP_TO; } else if (subtag[1] == "center" || subtag[1] == "c") { alignment = INLINE_ALIGNMENT_CENTER_TO; + } else if (subtag[1] == "baseline" || subtag[1] == "l") { + alignment = INLINE_ALIGNMENT_BASELINE_TO; } else if (subtag[1] == "bottom" || subtag[1] == "b") { alignment = INLINE_ALIGNMENT_BOTTOM_TO; } @@ -3809,8 +3844,12 @@ void RichTextLabel::append_text(const String &p_bbcode) { alignment = INLINE_ALIGNMENT_BOTTOM; } } + int row = -1; + if (subtag.size() > 3) { + row = subtag[3].to_int(); + } - push_table(columns, (InlineAlignment)alignment); + push_table(columns, (InlineAlignment)alignment, row); pos = brk_end + 1; tag_stack.push_front("table"); } else if (tag == "cell") { @@ -3862,6 +3901,11 @@ void RichTextLabel::append_text(const String &p_bbcode) { Color color1 = Color::from_string(subtag_a[1], fallback_color); set_cell_row_background_color(color1, color1); } + } else if (subtag_a[0] == "padding") { + Vector<String> subtag_b = subtag_a[1].split(","); + if (subtag_b.size() == 4) { + set_cell_padding(Rect2(subtag_b[0].to_float(), subtag_b[1].to_float(), subtag_b[2].to_float(), subtag_b[3].to_float())); + } } } } @@ -5287,7 +5331,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("push_hint", "description"), &RichTextLabel::push_hint); ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline); ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough); - ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGNMENT_TOP)); + ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align", "align_to_row"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGNMENT_TOP), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("push_dropcap", "string", "font", "size", "dropcap_margins", "color", "outline_size", "outline_color"), &RichTextLabel::push_dropcap, DEFVAL(Rect2()), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(0, 0, 0, 0))); ClassDB::bind_method(D_METHOD("set_table_column_expand", "column", "expand", "ratio"), &RichTextLabel::set_table_column_expand); ClassDB::bind_method(D_METHOD("set_cell_row_background_color", "odd_row_bg", "even_row_bg"), &RichTextLabel::set_cell_row_background_color); |