RichTextLabel: adds separate get_total_x_count
, get_visible_x_count
and scroll_to_x
functions for wrapped lines and paragraphs (newlines).
This commit is contained in:
parent
380bb2d533
commit
e4651a44ab
@ -70,7 +70,14 @@
|
|||||||
<return type="int">
|
<return type="int">
|
||||||
</return>
|
</return>
|
||||||
<description>
|
<description>
|
||||||
Returns the total number of newlines in the tag stack's text tags. Considers wrapped text as one line.
|
Returns the total number of lines in the text. Wrapped text is counted as multiple lines.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_paragraph_count" qualifiers="const">
|
||||||
|
<return type="int">
|
||||||
|
</return>
|
||||||
|
<description>
|
||||||
|
Returns the total number of paragraphs (newlines or [code]p[/code] tags in the tag stack's text tags). Considers wrapped text as one paragraph.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_total_character_count" qualifiers="const">
|
<method name="get_total_character_count" qualifiers="const">
|
||||||
@ -94,6 +101,13 @@
|
|||||||
Returns the number of visible lines.
|
Returns the number of visible lines.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="get_visible_paragraph_count" qualifiers="const">
|
||||||
|
<return type="int">
|
||||||
|
</return>
|
||||||
|
<description>
|
||||||
|
Returns the number of visible paragraphs. A paragraph is considered visible if at least one of its lines is visible.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="install_effect">
|
<method name="install_effect">
|
||||||
<return type="void">
|
<return type="void">
|
||||||
</return>
|
</return>
|
||||||
@ -342,6 +356,15 @@
|
|||||||
Scrolls the window's top line to match [code]line[/code].
|
Scrolls the window's top line to match [code]line[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="scroll_to_paragraph">
|
||||||
|
<return type="void">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="paragraph" type="int">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
Scrolls the window's top line to match first line of the [code]paragraph[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="set_cell_border_color">
|
<method name="set_cell_border_color">
|
||||||
<return type="void">
|
<return type="void">
|
||||||
</return>
|
</return>
|
||||||
|
@ -618,11 +618,11 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void 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_color_shadow, bool p_shadow_as_outline, const Point2 &p_shadow_ofs) {
|
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_color_shadow, bool p_shadow_as_outline, const Point2 &p_shadow_ofs) {
|
||||||
Vector2 off;
|
Vector2 off;
|
||||||
|
|
||||||
ERR_FAIL_COND(p_frame == nullptr);
|
ERR_FAIL_COND_V(p_frame == nullptr, 0);
|
||||||
ERR_FAIL_COND(p_line < 0 || p_line >= p_frame->lines.size());
|
ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), 0);
|
||||||
|
|
||||||
Line &l = p_frame->lines.write[p_line];
|
Line &l = p_frame->lines.write[p_line];
|
||||||
|
|
||||||
@ -631,7 +631,7 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
|
|||||||
Variant meta;
|
Variant meta;
|
||||||
|
|
||||||
if (it_from == nullptr) {
|
if (it_from == nullptr) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RID ci = get_canvas_item();
|
RID ci = get_canvas_item();
|
||||||
@ -699,14 +699,24 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
|
|||||||
}
|
}
|
||||||
l.text_buf->draw_dropcap(ci, p_ofs + ((rtl) ? Vector2() : Vector2(l.offset.x, 0)), l.dc_color);
|
l.text_buf->draw_dropcap(ci, p_ofs + ((rtl) ? Vector2() : Vector2(l.offset.x, 0)), l.dc_color);
|
||||||
|
|
||||||
|
int line_count = 0;
|
||||||
|
Size2 ctrl_size = get_size();
|
||||||
// Draw text.
|
// Draw text.
|
||||||
for (int line = 0; line < l.text_buf->get_line_count(); line++) {
|
for (int line = 0; line < l.text_buf->get_line_count(); line++) {
|
||||||
RID rid = l.text_buf->get_line_rid(line);
|
RID rid = l.text_buf->get_line_rid(line);
|
||||||
|
if (p_ofs.y + off.y >= ctrl_size.height) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (p_ofs.y + off.y + TS->shaped_text_get_size(rid).y <= 0) {
|
||||||
|
off.y += TS->shaped_text_get_size(rid).y;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float width = l.text_buf->get_width();
|
float width = l.text_buf->get_width();
|
||||||
float length = TS->shaped_text_get_width(rid);
|
float length = TS->shaped_text_get_width(rid);
|
||||||
|
|
||||||
// Draw line.
|
// Draw line.
|
||||||
|
line_count++;
|
||||||
|
|
||||||
if (rtl) {
|
if (rtl) {
|
||||||
off.x = p_width - l.offset.x - width;
|
off.x = p_width - l.offset.x - width;
|
||||||
@ -1068,6 +1078,8 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
|
|||||||
}
|
}
|
||||||
off.y += TS->shaped_text_get_descent(rid);
|
off.y += TS->shaped_text_get_descent(rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return line_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool *r_outside) {
|
void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool *r_outside) {
|
||||||
@ -1392,13 +1404,14 @@ void RichTextLabel::_notification(int p_what) {
|
|||||||
bool use_outline = get_theme_constant("shadow_as_outline");
|
bool use_outline = get_theme_constant("shadow_as_outline");
|
||||||
Point2 shadow_ofs(get_theme_constant("shadow_offset_x"), get_theme_constant("shadow_offset_y"));
|
Point2 shadow_ofs(get_theme_constant("shadow_offset_x"), get_theme_constant("shadow_offset_y"));
|
||||||
|
|
||||||
|
visible_paragraph_count = 0;
|
||||||
visible_line_count = 0;
|
visible_line_count = 0;
|
||||||
|
|
||||||
// New cache draw.
|
// New cache draw.
|
||||||
Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs);
|
Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs);
|
||||||
while (ofs.y < size.height && from_line < main->lines.size()) {
|
while (ofs.y < size.height && from_line < main->lines.size()) {
|
||||||
visible_line_count++;
|
visible_paragraph_count++;
|
||||||
_draw_line(main, from_line, ofs, text_rect.size.x, base_color, outline_size, outline_color, font_color_shadow, use_outline, shadow_ofs);
|
visible_line_count += _draw_line(main, from_line, ofs, text_rect.size.x, base_color, outline_size, outline_color, font_color_shadow, use_outline, shadow_ofs);
|
||||||
ofs.y += main->lines[from_line].text_buf->get_size().y;
|
ofs.y += main->lines[from_line].text_buf->get_size().y;
|
||||||
from_line++;
|
from_line++;
|
||||||
}
|
}
|
||||||
@ -3367,14 +3380,46 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RichTextLabel::scroll_to_line(int p_line) {
|
void RichTextLabel::scroll_to_paragraph(int p_paragraph) {
|
||||||
ERR_FAIL_INDEX(p_line, main->lines.size());
|
ERR_FAIL_INDEX(p_paragraph, main->lines.size());
|
||||||
_validate_line_caches(main);
|
_validate_line_caches(main);
|
||||||
vscroll->set_value(main->lines[p_line].offset.y);
|
vscroll->set_value(main->lines[p_paragraph].offset.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
int RichTextLabel::get_paragraph_count() const {
|
||||||
|
return current_frame->lines.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int RichTextLabel::get_visible_paragraph_count() const {
|
||||||
|
if (!is_visible()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return visible_paragraph_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextLabel::scroll_to_line(int p_line) {
|
||||||
|
_validate_line_caches(main);
|
||||||
|
|
||||||
|
int line_count = 0;
|
||||||
|
for (int i = 0; i < main->lines.size(); i++) {
|
||||||
|
if ((line_count <= p_line) && (line_count + main->lines[i].text_buf->get_line_count() >= p_line)) {
|
||||||
|
float line_offset = 0.f;
|
||||||
|
for (int j = 0; j < p_line - line_count; j++) {
|
||||||
|
line_offset += main->lines[i].text_buf->get_line_size(j).y;
|
||||||
|
}
|
||||||
|
vscroll->set_value(main->lines[i].offset.y + line_offset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
line_count += main->lines[i].text_buf->get_line_count();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int RichTextLabel::get_line_count() const {
|
int RichTextLabel::get_line_count() const {
|
||||||
return current_frame->lines.size();
|
int line_count = 0;
|
||||||
|
for (int i = 0; i < main->lines.size(); i++) {
|
||||||
|
line_count += main->lines[i].text_buf->get_line_count();
|
||||||
|
}
|
||||||
|
return line_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RichTextLabel::get_visible_line_count() const {
|
int RichTextLabel::get_visible_line_count() const {
|
||||||
@ -3783,6 +3828,7 @@ void RichTextLabel::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("get_v_scroll"), &RichTextLabel::get_v_scroll);
|
ClassDB::bind_method(D_METHOD("get_v_scroll"), &RichTextLabel::get_v_scroll);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("scroll_to_line", "line"), &RichTextLabel::scroll_to_line);
|
ClassDB::bind_method(D_METHOD("scroll_to_line", "line"), &RichTextLabel::scroll_to_line);
|
||||||
|
ClassDB::bind_method(D_METHOD("scroll_to_paragraph", "paragraph"), &RichTextLabel::scroll_to_paragraph);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_tab_size", "spaces"), &RichTextLabel::set_tab_size);
|
ClassDB::bind_method(D_METHOD("set_tab_size", "spaces"), &RichTextLabel::set_tab_size);
|
||||||
ClassDB::bind_method(D_METHOD("get_tab_size"), &RichTextLabel::get_tab_size);
|
ClassDB::bind_method(D_METHOD("get_tab_size"), &RichTextLabel::get_tab_size);
|
||||||
@ -3813,6 +3859,9 @@ void RichTextLabel::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("get_line_count"), &RichTextLabel::get_line_count);
|
ClassDB::bind_method(D_METHOD("get_line_count"), &RichTextLabel::get_line_count);
|
||||||
ClassDB::bind_method(D_METHOD("get_visible_line_count"), &RichTextLabel::get_visible_line_count);
|
ClassDB::bind_method(D_METHOD("get_visible_line_count"), &RichTextLabel::get_visible_line_count);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_paragraph_count"), &RichTextLabel::get_paragraph_count);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_visible_paragraph_count"), &RichTextLabel::get_visible_paragraph_count);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_content_height"), &RichTextLabel::get_content_height);
|
ClassDB::bind_method(D_METHOD("get_content_height"), &RichTextLabel::get_content_height);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("parse_expressions_for_values", "expressions"), &RichTextLabel::parse_expressions_for_values);
|
ClassDB::bind_method(D_METHOD("parse_expressions_for_values", "expressions"), &RichTextLabel::parse_expressions_for_values);
|
||||||
|
@ -337,6 +337,7 @@ private:
|
|||||||
bool updating_scroll;
|
bool updating_scroll;
|
||||||
int current_idx = 1;
|
int current_idx = 1;
|
||||||
int current_char_ofs = 0;
|
int current_char_ofs = 0;
|
||||||
|
int visible_paragraph_count;
|
||||||
int visible_line_count;
|
int visible_line_count;
|
||||||
|
|
||||||
int tab_size;
|
int tab_size;
|
||||||
@ -393,7 +394,7 @@ private:
|
|||||||
|
|
||||||
void _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, int *r_char_offset);
|
void _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, int *r_char_offset);
|
||||||
void _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width);
|
void _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width);
|
||||||
void _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_color_shadow, bool p_shadow_as_outline, const Point2 &shadow_ofs);
|
int _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_color_shadow, bool p_shadow_as_outline, const Point2 &shadow_ofs);
|
||||||
float _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 = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr);
|
float _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 = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr);
|
||||||
|
|
||||||
String _roman(int p_num, bool p_capitalize) const;
|
String _roman(int p_num, bool p_capitalize) const;
|
||||||
@ -507,6 +508,10 @@ public:
|
|||||||
|
|
||||||
bool search(const String &p_string, bool p_from_selection = false, bool p_search_previous = false);
|
bool search(const String &p_string, bool p_from_selection = false, bool p_search_previous = false);
|
||||||
|
|
||||||
|
void scroll_to_paragraph(int p_paragraph);
|
||||||
|
int get_paragraph_count() const;
|
||||||
|
int get_visible_paragraph_count() const;
|
||||||
|
|
||||||
void scroll_to_line(int p_line);
|
void scroll_to_line(int p_line);
|
||||||
int get_line_count() const;
|
int get_line_count() const;
|
||||||
int get_visible_line_count() const;
|
int get_visible_line_count() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user