Skip to content

Commit 6807ec6

Browse files
committed
Merge pull request #109441 from aaronp64/rtl_table_search
Fix issues searching `RichTextLabel` when search result is in a table
2 parents cd70d36 + f0eddb8 commit 6807ec6

File tree

2 files changed

+44
-18
lines changed

2 files changed

+44
-18
lines changed

scene/gui/rich_text_label.cpp

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6593,23 +6593,36 @@ bool RichTextLabel::_is_click_inside_selection() const {
65936593
}
65946594
}
65956595

6596+
bool RichTextLabel::_search_table_cell(ItemTable *p_table, List<Item *>::Element *p_cell, const String &p_string, bool p_reverse_search, int p_from_line) {
6597+
ERR_FAIL_COND_V(p_cell->get()->type != ITEM_FRAME, false); // Children should all be frames.
6598+
ItemFrame *frame = static_cast<ItemFrame *>(p_cell->get());
6599+
if (p_from_line < 0) {
6600+
p_from_line = (int)frame->lines.size() - 1;
6601+
}
6602+
6603+
if (p_reverse_search) {
6604+
for (int i = p_from_line; i >= 0; i--) {
6605+
if (_search_line(frame, i, p_string, -1, p_reverse_search)) {
6606+
return true;
6607+
}
6608+
}
6609+
} else {
6610+
for (int i = p_from_line; i < (int)frame->lines.size(); i++) {
6611+
if (_search_line(frame, i, p_string, 0, p_reverse_search)) {
6612+
return true;
6613+
}
6614+
}
6615+
}
6616+
6617+
return false;
6618+
}
6619+
65966620
bool RichTextLabel::_search_table(ItemTable *p_table, List<Item *>::Element *p_from, const String &p_string, bool p_reverse_search) {
65976621
List<Item *>::Element *E = p_from;
65986622
while (E != nullptr) {
6599-
ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames.
6600-
ItemFrame *frame = static_cast<ItemFrame *>(E->get());
6601-
if (p_reverse_search) {
6602-
for (int i = (int)frame->lines.size() - 1; i >= 0; i--) {
6603-
if (_search_line(frame, i, p_string, -1, p_reverse_search)) {
6604-
return true;
6605-
}
6606-
}
6607-
} else {
6608-
for (int i = 0; i < (int)frame->lines.size(); i++) {
6609-
if (_search_line(frame, i, p_string, 0, p_reverse_search)) {
6610-
return true;
6611-
}
6612-
}
6623+
int from_line = p_reverse_search ? -1 : 0;
6624+
if (_search_table_cell(p_table, E, p_string, p_reverse_search, from_line)) {
6625+
return true;
66136626
}
66146627
E = p_reverse_search ? E->prev() : E->next();
66156628
}
@@ -6697,7 +6710,8 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
66976710
char_idx = p_search_previous ? -1 : 0;
66986711

66996712
// Next, check to see if the current search result is in a table
6700-
if (selection.from_frame->parent != nullptr && selection.from_frame->parent->type == ITEM_TABLE) {
6713+
bool in_table = selection.from_frame->parent != nullptr && selection.from_frame->parent->type == ITEM_TABLE;
6714+
if (in_table) {
67016715
// Find last search result in table
67026716
ItemTable *parent_table = static_cast<ItemTable *>(selection.from_frame->parent);
67036717
List<Item *>::Element *parent_element = p_search_previous ? parent_table->subitems.back() : parent_table->subitems.front();
@@ -6707,9 +6721,17 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
67076721
ERR_FAIL_NULL_V(parent_element, false);
67086722
}
67096723

6724+
// Search remainder of current cell
6725+
int from_line = p_search_previous ? selection.from_line - 1 : selection.from_line + 1;
6726+
if (from_line >= 0 && _search_table_cell(parent_table, parent_element, p_string, p_search_previous, from_line)) {
6727+
scroll_to_selection();
6728+
queue_redraw();
6729+
return true;
6730+
}
6731+
67106732
// Search remainder of table
67116733
if (!(p_search_previous && parent_element == parent_table->subitems.front()) &&
6712-
parent_element != parent_table->subitems.back()) {
6734+
!(!p_search_previous && parent_element == parent_table->subitems.back())) {
67136735
parent_element = p_search_previous ? parent_element->prev() : parent_element->next(); // Don't want to search current item
67146736
ERR_FAIL_NULL_V(parent_element, false);
67156737

@@ -6722,7 +6744,10 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
67226744
}
67236745
}
67246746

6725-
ending_line = selection.from_frame->line + selection.from_line;
6747+
ending_line = selection.from_frame->line;
6748+
if (!in_table) {
6749+
ending_line += selection.from_line;
6750+
}
67266751
current_line = p_search_previous ? ending_line - 1 : ending_line + 1;
67276752
} else if (p_search_previous) {
67286753
current_line = ending_line;

scene/gui/rich_text_label.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,9 @@ class RichTextLabel : public Control {
631631
void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr, bool p_meta = false);
632632

633633
String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel) const;
634-
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search);
634+
bool _search_table_cell(ItemTable *p_table, List<Item *>::Element *p_cell, const String &p_string, bool p_reverse_search, int p_from_line);
635635
bool _search_table(ItemTable *p_table, List<Item *>::Element *p_from, const String &p_string, bool p_reverse_search);
636+
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search);
636637

637638
float _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, float p_h, int *r_char_offset);
638639
float _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, float p_h);

0 commit comments

Comments
 (0)