1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +00:00

Merge pull request #62774 from Rindbee/make-the-meta-click-area-fit

Make the meta click area fit to its visible area
This commit is contained in:
Rémi Verschelde
2022-07-13 14:14:34 +02:00
committed by GitHub
2 changed files with 54 additions and 14 deletions

View File

@@ -149,7 +149,12 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item
return it; return it;
} }
} break; } break;
case ITEM_NEWLINE: case ITEM_NEWLINE: {
offset += 1;
if (offset == p_position) {
return it;
}
} break;
case ITEM_IMAGE: case ITEM_IMAGE:
case ITEM_TABLE: { case ITEM_TABLE: {
offset += 1; offset += 1;
@@ -1344,6 +1349,8 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool p_table) { float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool p_table) {
Vector2 off; Vector2 off;
bool line_clicked = false;
float text_rect_begin = 0.0;
int char_pos = -1; int char_pos = -1;
Line &l = p_frame->lines[p_line]; Line &l = p_frame->lines[p_line];
MutexLock lock(l.text_buf->get_mutex()); MutexLock lock(l.text_buf->get_mutex());
@@ -1469,8 +1476,12 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
} }
if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) { if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) {
if ((!rtl && p_click.x >= rect.position.x) || (rtl && p_click.x <= rect.position.x + rect.size.x)) {
char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x); char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
} }
line_clicked = true;
text_rect_begin = rtl ? rect.position.x + rect.size.x : rect.position.x;
}
// If table hit was detected, and line hit is in the table bounds use table hit. // If table hit was detected, and line hit is in the table bounds use table hit.
if (table_hit && (((char_pos + p_frame->lines[p_line].char_offset) >= table_range.x && (char_pos + p_frame->lines[p_line].char_offset) <= table_range.y) || char_pos == -1)) { if (table_hit && (((char_pos + p_frame->lines[p_line].char_offset) >= table_range.x && (char_pos + p_frame->lines[p_line].char_offset) <= table_range.y) || char_pos == -1)) {
@@ -1496,23 +1507,38 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
} }
// Text line hit. // Text line hit.
if (char_pos >= 0) { if (line_clicked) {
// Find item. // Find item.
if (r_click_item != nullptr) { if (r_click_item != nullptr) {
Item *it = p_frame->lines[p_line].from; Item *it = p_frame->lines[p_line].from;
Item *it_to = (p_line + 1 < (int)p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr; Item *it_to = (p_line + 1 < (int)p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr;
if (char_pos == p_frame->lines[p_line].char_count) { if (char_pos >= 0) {
// Selection after the end of line, select last item.
if (it_to != nullptr) {
*r_click_item = _get_prev_item(it_to);
} else {
for (Item *i = it; i; i = _get_next_item(i)) {
*r_click_item = i;
}
}
} else {
// Selection in the line.
*r_click_item = _get_item_at_pos(it, it_to, char_pos); *r_click_item = _get_item_at_pos(it, it_to, char_pos);
} else {
int stop = text_rect_begin;
*r_click_item = _find_indentable(it);
while (*r_click_item) {
Ref<Font> font = _find_font(*r_click_item);
if (!font.is_valid()) {
font = get_theme_font(SNAME("normal_font"));
}
int font_size = _find_font_size(*r_click_item);
if (font_size == -1) {
font_size = get_theme_font_size(SNAME("normal_font_size"));
}
if (rtl) {
stop += tab_size * font->get_char_size(' ', font_size).width;
if (stop > p_click.x) {
break;
}
} else {
stop -= tab_size * font->get_char_size(' ', font_size).width;
if (stop < p_click.x) {
break;
}
}
*r_click_item = _find_indentable((*r_click_item)->parent);
}
} }
} }
@@ -2069,6 +2095,19 @@ void RichTextLabel::_find_frame(Item *p_item, ItemFrame **r_frame, int *r_line)
} }
} }
RichTextLabel::Item *RichTextLabel::_find_indentable(Item *p_item) {
Item *indentable = p_item;
while (indentable) {
if (indentable->type == ITEM_INDENT || indentable->type == ITEM_LIST) {
return indentable;
}
indentable = indentable->parent;
}
return indentable;
}
Ref<Font> RichTextLabel::_find_font(Item *p_item) { Ref<Font> RichTextLabel::_find_font(Item *p_item) {
Item *fontitem = p_item; Item *fontitem = p_item;

View File

@@ -459,6 +459,7 @@ private:
String _roman(int p_num, bool p_capitalize) const; String _roman(int p_num, bool p_capitalize) const;
String _letters(int p_num, bool p_capitalize) const; String _letters(int p_num, bool p_capitalize) const;
Item *_find_indentable(Item *p_item);
Item *_get_item_at_pos(Item *p_item_from, Item *p_item_to, int p_position); Item *_get_item_at_pos(Item *p_item_from, Item *p_item_to, int p_position);
void _find_frame(Item *p_item, ItemFrame **r_frame, int *r_line); void _find_frame(Item *p_item, ItemFrame **r_frame, int *r_line);
int _find_font_size(Item *p_item); int _find_font_size(Item *p_item);