Expose RichTextLabel selection to script

Expose existing get_selection_text and add methods to get the current
selection index from and index to.
This commit is contained in:
PouleyKetchoupp 2021-02-11 09:33:45 -07:00
parent a59286f019
commit 4586357dde
3 changed files with 56 additions and 9 deletions

View file

@ -80,6 +80,27 @@
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. 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_selected_text" qualifiers="const">
<return type="String">
</return>
<description>
Returns the current selection text. Does not include BBCodes.
</description>
</method>
<method name="get_selection_from" qualifiers="const">
<return type="int">
</return>
<description>
Returns the current selection first character index if a selection is active, [code]-1[/code] otherwise. Does not include BBCodes.
</description>
</method>
<method name="get_selection_to" qualifiers="const">
<return type="int">
</return>
<description>
Returns the current selection last character index if a selection is active, [code]-1[/code] otherwise. Does not include BBCodes.
</description>
</method>
<method name="get_total_character_count" qualifiers="const"> <method name="get_total_character_count" qualifiers="const">
<return type="int"> <return type="int">
</return> </return>

View file

@ -45,7 +45,7 @@
#include "editor/editor_scale.h" #include "editor/editor_scale.h"
#endif #endif
RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) { RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) const {
if (p_free) { if (p_free) {
if (p_item->subitems.size()) { if (p_item->subitems.size()) {
return p_item->subitems.front()->get(); return p_item->subitems.front()->get();
@ -90,7 +90,7 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
return nullptr; return nullptr;
} }
RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) { RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) const {
if (p_free) { if (p_free) {
if (p_item->subitems.size()) { if (p_item->subitems.size()) {
return p_item->subitems.back()->get(); return p_item->subitems.back()->get();
@ -147,7 +147,7 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item
case ITEM_TEXT: { case ITEM_TEXT: {
ItemText *t = (ItemText *)it; ItemText *t = (ItemText *)it;
offset += t->text.length(); offset += t->text.length();
if (offset > p_position) { if (offset >= p_position) {
return it; return it;
} }
} break; } break;
@ -454,6 +454,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
ItemImage *img = (ItemImage *)it; ItemImage *img = (ItemImage *)it;
l.text_buf->add_object((uint64_t)it, img->image->get_size(), img->inline_align, 1); l.text_buf->add_object((uint64_t)it, img->image->get_size(), img->inline_align, 1);
text += String::chr(0xfffc); text += String::chr(0xfffc);
l.char_count += 1;
} break; } break;
case ITEM_TABLE: { case ITEM_TABLE: {
ItemTable *table = static_cast<ItemTable *>(it); ItemTable *table = static_cast<ItemTable *>(it);
@ -3523,7 +3524,7 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
return false; return false;
} }
String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p_selection) { String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p_selection) const {
String text; String text;
ERR_FAIL_COND_V(p_frame == nullptr, text); ERR_FAIL_COND_V(p_frame == nullptr, text);
ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), text); ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), text);
@ -3590,7 +3591,7 @@ String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p
return text; return text;
} }
String RichTextLabel::get_selected_text() { String RichTextLabel::get_selected_text() const {
if (!selection.active || !selection.enabled) { if (!selection.active || !selection.enabled) {
return ""; return "";
} }
@ -3614,6 +3615,22 @@ bool RichTextLabel::is_selection_enabled() const {
return selection.enabled; return selection.enabled;
} }
int RichTextLabel::get_selection_from() const {
if (!selection.active || !selection.enabled) {
return -1;
}
return selection.from_frame->lines[selection.from_line].char_offset + selection.from_char;
}
int RichTextLabel::get_selection_to() const {
if (!selection.active || !selection.enabled) {
return -1;
}
return selection.to_frame->lines[selection.to_line].char_offset + selection.to_char - 1;
}
void RichTextLabel::set_bbcode(const String &p_bbcode) { void RichTextLabel::set_bbcode(const String &p_bbcode) {
bbcode = p_bbcode; bbcode = p_bbcode;
if (is_inside_tree() && use_bbcode) { if (is_inside_tree() && use_bbcode) {
@ -3649,6 +3666,8 @@ String RichTextLabel::get_text() {
text += t->text; text += t->text;
} else if (it->type == ITEM_NEWLINE) { } else if (it->type == ITEM_NEWLINE) {
text += "\n"; text += "\n";
} else if (it->type == ITEM_IMAGE) {
text += " ";
} else if (it->type == ITEM_INDENT || it->type == ITEM_LIST) { } else if (it->type == ITEM_INDENT || it->type == ITEM_LIST) {
text += "\t"; text += "\t";
} }
@ -3841,6 +3860,11 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_selection_enabled", "enabled"), &RichTextLabel::set_selection_enabled); ClassDB::bind_method(D_METHOD("set_selection_enabled", "enabled"), &RichTextLabel::set_selection_enabled);
ClassDB::bind_method(D_METHOD("is_selection_enabled"), &RichTextLabel::is_selection_enabled); ClassDB::bind_method(D_METHOD("is_selection_enabled"), &RichTextLabel::is_selection_enabled);
ClassDB::bind_method(D_METHOD("get_selection_from"), &RichTextLabel::get_selection_from);
ClassDB::bind_method(D_METHOD("get_selection_to"), &RichTextLabel::get_selection_to);
ClassDB::bind_method(D_METHOD("get_selected_text"), &RichTextLabel::get_selected_text);
ClassDB::bind_method(D_METHOD("parse_bbcode", "bbcode"), &RichTextLabel::parse_bbcode); ClassDB::bind_method(D_METHOD("parse_bbcode", "bbcode"), &RichTextLabel::parse_bbcode);
ClassDB::bind_method(D_METHOD("append_bbcode", "bbcode"), &RichTextLabel::append_bbcode); ClassDB::bind_method(D_METHOD("append_bbcode", "bbcode"), &RichTextLabel::append_bbcode);

View file

@ -389,7 +389,7 @@ private:
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); 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);
String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel); String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel) const;
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, Item *p_from, Item *p_to); bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, Item *p_from, Item *p_to);
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);
@ -427,8 +427,8 @@ private:
void _scroll_changed(double); void _scroll_changed(double);
void _gui_input(Ref<InputEvent> p_event); void _gui_input(Ref<InputEvent> p_event);
Item *_get_next_item(Item *p_item, bool p_free = false); Item *_get_next_item(Item *p_item, bool p_free = false) const;
Item *_get_prev_item(Item *p_item, bool p_free = false); Item *_get_prev_item(Item *p_item, bool p_free = false) const;
Rect2 _get_text_rect(); Rect2 _get_text_rect();
Ref<RichTextEffect> _get_custom_effect_by_code(String p_bbcode_identifier); Ref<RichTextEffect> _get_custom_effect_by_code(String p_bbcode_identifier);
@ -524,7 +524,9 @@ public:
void set_selection_enabled(bool p_enabled); void set_selection_enabled(bool p_enabled);
bool is_selection_enabled() const; bool is_selection_enabled() const;
String get_selected_text(); int get_selection_from() const;
int get_selection_to() const;
String get_selected_text() const;
void selection_copy(); void selection_copy();
Error parse_bbcode(const String &p_bbcode); Error parse_bbcode(const String &p_bbcode);