Merge pull request #42595 from bruvzg/ctl_rich_text

[Complex Text Layouts] Refactor RichTextLabel.
This commit is contained in:
Rémi Verschelde 2020-12-13 13:42:00 +01:00 committed by GitHub
commit bbf7bb3838
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 2336 additions and 1129 deletions

View file

@ -13,24 +13,6 @@
<methods>
</methods>
<members>
<member name="absolute_index" type="int" setter="set_absolute_index" getter="get_absolute_index" default="0">
The index of the current character (starting from 0). Setting this property won't affect drawing.
</member>
<member name="character" type="int" setter="set_character" getter="get_character" default="0">
The Unicode codepoint the character will use. This only affects non-whitespace characters. [method @GDScript.ord] can be useful here. For example, the following will replace all characters with asterisks:
[codeblocks]
[gdscript]
# `char_fx` is the CharFXTransform parameter from `_process_custom_fx()`.
# See the RichTextEffect documentation for details.
char_fx.character = ord("*")
[/gdscript]
[csharp]
// `char_fx` is the CharFXTransform parameter from `_process_custom_fx()`.
// See the RichTextEffect documentation for details.
charFx.Character = char.GetNumericValue('*');
[/csharp]
[/codeblocks]
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 0, 0, 0, 1 )">
The color the character will be drawn with.
</member>
@ -45,11 +27,20 @@
{"foo": "hello", "bar": true, "baz": 42, "color": Color(1, 1, 1, 1)}
[/codeblock]
</member>
<member name="font" type="RID" setter="set_font" getter="get_font">
Font resource used to render glyph.
</member>
<member name="glyph_index" type="int" setter="set_glyph_index" getter="get_glyph_index" default="0">
Font specific glyph index.
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )">
The position offset the character will be drawn with (in pixels).
</member>
<member name="relative_index" type="int" setter="set_relative_index" getter="get_relative_index" default="0">
The index of the current character (starting from 0). Setting this property won't affect drawing.
<member name="outline" type="bool" setter="set_outline" getter="is_outline" default="false">
If [code]ture[/code], FX transform is called for outline drawing. Setting this property won't affect drawing.
</member>
<member name="range" type="Vector2i" setter="set_range" getter="get_range" default="Vector2i( 0, 0 )">
Absolute character range in the string, corresponding to the glyph. Setting this property won't affect drawing.
</member>
<member name="visible" type="bool" setter="set_visibility" getter="is_visible" default="true">
If [code]true[/code], the character will be drawn. If [code]false[/code], the character will be hidden. Characters around hidden characters will reflow to take the space of hidden characters. If this is not desired, set their [member color] to [code]Color(1, 1, 1, 0)[/code] instead.

View file

@ -25,6 +25,8 @@
</argument>
<argument index="3" name="color" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<argument index="4" name="inline_align" type="int" enum="VAlign" default="0">
</argument>
<description>
Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image and a [code]color[/code] to tint the image.
If [code]width[/code] or [code]height[/code] is set to 0, the image size will be adjusted in order to keep the original aspect ratio.
@ -132,15 +134,6 @@
Terminates the current tag. Use after [code]push_*[/code] methods to close BBCodes manually. Does not need to follow [code]add_*[/code] methods.
</description>
</method>
<method name="push_align">
<return type="void">
</return>
<argument index="0" name="align" type="int" enum="RichTextLabel.Align">
</argument>
<description>
Adds an [code][align][/code] tag based on the given [code]align[/code] value. See [enum Align] for possible values.
</description>
</method>
<method name="push_bold">
<return type="void">
</return>
@ -180,6 +173,24 @@
Adds a [code][font][/code] tag to the tag stack. Overrides default fonts for its duration.
</description>
</method>
<method name="push_font_features">
<return type="void">
</return>
<argument index="0" name="opentype_features" type="Dictionary">
</argument>
<description>
Adds a [code][ot_feature][/code] tag to the tag stack. Overrides default OpenType font feature for its duration.
</description>
</method>
<method name="push_font_size">
<return type="void">
</return>
<argument index="0" name="font_size" type="int">
</argument>
<description>
Adds a [code][font_size][/code] tag to the tag stack. Overrides default font size for its duration.
</description>
</method>
<method name="push_indent">
<return type="void">
</return>
@ -199,10 +210,14 @@
<method name="push_list">
<return type="void">
</return>
<argument index="0" name="type" type="int" enum="RichTextLabel.ListType">
<argument index="0" name="level" type="int">
</argument>
<argument index="1" name="type" type="int" enum="RichTextLabel.ListType">
</argument>
<argument index="2" name="capitalize" type="bool">
</argument>
<description>
Adds a [code][list][/code] tag to the tag stack. Similar to the BBCodes [code][ol][/code] or [code][ul][/code], but supports more list types. Not fully implemented!
Adds [code][ol][/code] or [code][ul][/code] tag to the tag stack. Multiplies [code]level[/code] by current [member tab_size] to determine new margin length.
</description>
</method>
<method name="push_meta">
@ -228,6 +243,39 @@
Adds a [code][font][/code] tag with a normal font to the tag stack.
</description>
</method>
<method name="push_outline_color">
<return type="void">
</return>
<argument index="0" name="color" type="Color">
</argument>
<description>
Adds a [code][outline_color][/code] tag to the tag stack. Adds text outline for its duration.
</description>
</method>
<method name="push_outline_size">
<return type="void">
</return>
<argument index="0" name="outline_size" type="int">
</argument>
<description>
Adds a [code][outline_size][/code] tag to the tag stack. Overrides default text outline size for its duration.
</description>
</method>
<method name="push_paragraph">
<return type="void">
</return>
<argument index="0" name="align" type="int" enum="RichTextLabel.Align">
</argument>
<argument index="1" name="base_direction" type="int" enum="Control.TextDirection" default="0">
</argument>
<argument index="2" name="language" type="String" default="&quot;&quot;">
</argument>
<argument index="3" name="st_parser" type="int" enum="Control.StructuredTextParser" default="0">
</argument>
<description>
Adds a [code][p][/code] tag to the tag stack.
</description>
</method>
<method name="push_strikethrough">
<return type="void">
</return>
@ -240,8 +288,10 @@
</return>
<argument index="0" name="columns" type="int">
</argument>
<argument index="1" name="inline_align" type="int" enum="VAlign" default="0">
</argument>
<description>
Adds a [code][table=columns][/code] tag to the tag stack.
Adds a [code][table=columns,inline_align][/code] tag to the tag stack.
</description>
</method>
<method name="push_underline">
@ -270,6 +320,46 @@
Scrolls the window's top line to match [code]line[/code].
</description>
</method>
<method name="set_cell_border_color">
<return type="void">
</return>
<argument index="0" name="color" type="Color">
</argument>
<description>
Sets color of a table cell border.
</description>
</method>
<method name="set_cell_padding">
<return type="void">
</return>
<argument index="0" name="padding" type="Rect2">
</argument>
<description>
Sets inner padding of a table cell.
</description>
</method>
<method name="set_cell_row_background_color">
<return type="void">
</return>
<argument index="0" name="odd_row_bg" type="Color">
</argument>
<argument index="1" name="even_row_bg" type="Color">
</argument>
<description>
Sets color of a table cell. Separate colors for alternating rows can be specified.
</description>
</method>
<method name="set_cell_size_override">
<return type="void">
</return>
<argument index="0" name="min_size" type="Vector2">
</argument>
<argument index="1" name="max_size" type="Vector2">
</argument>
<description>
Sets minimum and maximum size overrides for a table cell.
</description>
</method>
<method name="set_table_column_expand">
<return type="void">
</return>
@ -302,6 +392,9 @@
If [code]true[/code], the label's height will be automatically updated to fit its content.
[b]Note:[/b] This property is used as a workaround to fix issues with [RichTextLabel] in [Container]s, but it's unreliable in some cases and will be removed in future versions.
</member>
<member name="language" type="String" setter="set_language" getter="get_language" default="&quot;&quot;">
Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
</member>
<member name="meta_underlined" type="bool" setter="set_meta_underline" getter="is_meta_underlined" default="true">
If [code]true[/code], the label underlines meta tags such as [code][url]{text}[/url][/code].
</member>
@ -322,6 +415,12 @@
<member name="selection_enabled" type="bool" setter="set_selection_enabled" getter="is_selection_enabled" default="false">
If [code]true[/code], the label allows text selection.
</member>
<member name="structured_text_bidi_override" type="int" setter="set_structured_text_bidi_override" getter="get_structured_text_bidi_override" enum="Control.StructuredTextParser" default="0">
Set BiDi algorithm override for the structured text.
</member>
<member name="structured_text_bidi_override_options" type="Array" setter="set_structured_text_bidi_override_options" getter="get_structured_text_bidi_override_options" default="[ ]">
Set additional options for BiDi override.
</member>
<member name="tab_size" type="int" setter="set_tab_size" getter="get_tab_size" default="4">
The number of spaces associated with a single tab length. Does not affect [code]\t[/code] in text tags, only indent tags.
</member>
@ -329,6 +428,9 @@
The raw text of the label.
When set, clears the tag stack and adds a raw text tag to the top of it. Does not parse BBCodes. Does not modify [member bbcode_text].
</member>
<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0">
Base text writing direction.
</member>
<member name="visible_characters" type="int" setter="set_visible_characters" getter="get_visible_characters" default="-1">
The restricted number of characters to display in the label. If [code]-1[/code], all characters will be displayed.
</member>
@ -375,7 +477,10 @@
<constant name="LIST_LETTERS" value="1" enum="ListType">
Each list item has a letter marker.
</constant>
<constant name="LIST_DOTS" value="2" enum="ListType">
<constant name="LIST_ROMAN" value="2" enum="ListType">
Each list item has a roman number marker.
</constant>
<constant name="LIST_DOTS" value="3" enum="ListType">
Each list item has a filled circle marker.
</constant>
<constant name="ITEM_FRAME" value="0" enum="ItemType">
@ -388,42 +493,56 @@
</constant>
<constant name="ITEM_FONT" value="4" enum="ItemType">
</constant>
<constant name="ITEM_COLOR" value="5" enum="ItemType">
<constant name="ITEM_FONT_SIZE" value="5" enum="ItemType">
</constant>
<constant name="ITEM_UNDERLINE" value="6" enum="ItemType">
<constant name="ITEM_FONT_FEATURES" value="6" enum="ItemType">
</constant>
<constant name="ITEM_STRIKETHROUGH" value="7" enum="ItemType">
<constant name="ITEM_COLOR" value="7" enum="ItemType">
</constant>
<constant name="ITEM_ALIGN" value="8" enum="ItemType">
<constant name="ITEM_OUTLINE_SIZE" value="8" enum="ItemType">
</constant>
<constant name="ITEM_INDENT" value="9" enum="ItemType">
<constant name="ITEM_OUTLINE_COLOR" value="9" enum="ItemType">
</constant>
<constant name="ITEM_LIST" value="10" enum="ItemType">
<constant name="ITEM_UNDERLINE" value="10" enum="ItemType">
</constant>
<constant name="ITEM_TABLE" value="11" enum="ItemType">
<constant name="ITEM_STRIKETHROUGH" value="11" enum="ItemType">
</constant>
<constant name="ITEM_FADE" value="12" enum="ItemType">
<constant name="ITEM_PARAGRAPH" value="12" enum="ItemType">
</constant>
<constant name="ITEM_SHAKE" value="13" enum="ItemType">
<constant name="ITEM_INDENT" value="13" enum="ItemType">
</constant>
<constant name="ITEM_WAVE" value="14" enum="ItemType">
<constant name="ITEM_LIST" value="14" enum="ItemType">
</constant>
<constant name="ITEM_TORNADO" value="15" enum="ItemType">
<constant name="ITEM_TABLE" value="15" enum="ItemType">
</constant>
<constant name="ITEM_RAINBOW" value="16" enum="ItemType">
<constant name="ITEM_FADE" value="16" enum="ItemType">
</constant>
<constant name="ITEM_CUSTOMFX" value="18" enum="ItemType">
<constant name="ITEM_SHAKE" value="17" enum="ItemType">
</constant>
<constant name="ITEM_META" value="17" enum="ItemType">
<constant name="ITEM_WAVE" value="18" enum="ItemType">
</constant>
<constant name="ITEM_TORNADO" value="19" enum="ItemType">
</constant>
<constant name="ITEM_RAINBOW" value="20" enum="ItemType">
</constant>
<constant name="ITEM_CUSTOMFX" value="22" enum="ItemType">
</constant>
<constant name="ITEM_META" value="21" enum="ItemType">
</constant>
</constants>
<theme_items>
<theme_item name="bold_font" type="Font">
The font used for bold text.
</theme_item>
<theme_item name="bold_font_size" type="int">
The font size used for bold text.
</theme_item>
<theme_item name="bold_italics_font" type="Font">
The font used for bold italics text.
</theme_item>
<theme_item name="bold_italics_font_size" type="int">
The font size used for bold italics text.
</theme_item>
<theme_item name="default_color" type="Color" default="Color( 1, 1, 1, 1 )">
The default text color.
</theme_item>
@ -439,18 +558,27 @@
<theme_item name="italics_font" type="Font">
The font used for italics text.
</theme_item>
<theme_item name="italics_font_size" type="int">
The font size used for italics text.
</theme_item>
<theme_item name="line_separation" type="int" default="1">
The vertical space between lines.
</theme_item>
<theme_item name="mono_font" type="Font">
The font used for monospace text.
</theme_item>
<theme_item name="mono_font_size" type="int">
The font size used for monospace text.
</theme_item>
<theme_item name="normal" type="StyleBox">
The normal background for the [RichTextLabel].
</theme_item>
<theme_item name="normal_font" type="Font">
The default text font.
</theme_item>
<theme_item name="normal_font_size" type="int">
The default text font size.
</theme_item>
<theme_item name="selection_color" type="Color" default="Color( 0.1, 0.1, 1, 0.8 )">
The color of the selection box.
</theme_item>
@ -463,9 +591,18 @@
<theme_item name="shadow_offset_y" type="int" default="1">
The vertical offset of the font's shadow.
</theme_item>
<theme_item name="table_border" type="Color" default="Color( 0, 0, 0, 0 )">
The default cell border color.
</theme_item>
<theme_item name="table_even_row_bg" type="Color" default="Color( 0, 0, 0, 0 )">
The default background color for even rows.
</theme_item>
<theme_item name="table_hseparation" type="int" default="3">
The horizontal separation of elements in a table.
</theme_item>
<theme_item name="table_odd_row_bg" type="Color" default="Color( 0, 0, 0, 0 )">
The default background color for odd rows.
</theme_item>
<theme_item name="table_vseparation" type="int" default="3">
The vertical separation of elements in a table.
</theme_item>

View file

@ -230,7 +230,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
if (p_overview) {
class_desc->push_cell();
class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
} else {
static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
class_desc->add_text(String(prefix));
@ -528,7 +528,7 @@ void EditorHelp::_update_doc() {
property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
class_desc->push_cell();
class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
class_desc->push_font(doc_code_font);
_add_type(cd.properties[i].type, cd.properties[i].enumeration);
class_desc->pop();
@ -729,7 +729,7 @@ void EditorHelp::_update_doc() {
theme_property_line[cd.theme_properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
class_desc->push_cell();
class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
class_desc->push_font(doc_code_font);
_add_type(cd.theme_properties[i].type);
class_desc->pop();
@ -1500,7 +1500,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
tag_stack.push_front(tag);
} else if (tag == "center") {
//align to center
p_rt->push_align(RichTextLabel::ALIGN_CENTER);
p_rt->push_paragraph(RichTextLabel::ALIGN_CENTER, Control::TEXT_DIRECTION_AUTO, "");
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "br") {

View file

@ -64,11 +64,8 @@ RichTextEffect::RichTextEffect() {
}
void CharFXTransform::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_relative_index"), &CharFXTransform::get_relative_index);
ClassDB::bind_method(D_METHOD("set_relative_index", "index"), &CharFXTransform::set_relative_index);
ClassDB::bind_method(D_METHOD("get_absolute_index"), &CharFXTransform::get_absolute_index);
ClassDB::bind_method(D_METHOD("set_absolute_index", "index"), &CharFXTransform::set_absolute_index);
ClassDB::bind_method(D_METHOD("get_range"), &CharFXTransform::get_range);
ClassDB::bind_method(D_METHOD("set_range", "range"), &CharFXTransform::set_range);
ClassDB::bind_method(D_METHOD("get_elapsed_time"), &CharFXTransform::get_elapsed_time);
ClassDB::bind_method(D_METHOD("set_elapsed_time", "time"), &CharFXTransform::set_elapsed_time);
@ -76,6 +73,9 @@ void CharFXTransform::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_visible"), &CharFXTransform::is_visible);
ClassDB::bind_method(D_METHOD("set_visibility", "visibility"), &CharFXTransform::set_visibility);
ClassDB::bind_method(D_METHOD("is_outline"), &CharFXTransform::is_outline);
ClassDB::bind_method(D_METHOD("set_outline", "outline"), &CharFXTransform::set_outline);
ClassDB::bind_method(D_METHOD("get_offset"), &CharFXTransform::get_offset);
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &CharFXTransform::set_offset);
@ -85,27 +85,24 @@ void CharFXTransform::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_environment"), &CharFXTransform::get_environment);
ClassDB::bind_method(D_METHOD("set_environment", "environment"), &CharFXTransform::set_environment);
ClassDB::bind_method(D_METHOD("get_character"), &CharFXTransform::get_character);
ClassDB::bind_method(D_METHOD("set_character", "character"), &CharFXTransform::set_character);
ClassDB::bind_method(D_METHOD("get_glyph_index"), &CharFXTransform::get_glyph_index);
ClassDB::bind_method(D_METHOD("set_glyph_index", "glyph_index"), &CharFXTransform::set_glyph_index);
ADD_PROPERTY(PropertyInfo(Variant::INT, "relative_index"), "set_relative_index", "get_relative_index");
ADD_PROPERTY(PropertyInfo(Variant::INT, "absolute_index"), "set_absolute_index", "get_absolute_index");
ClassDB::bind_method(D_METHOD("get_font"), &CharFXTransform::get_font);
ClassDB::bind_method(D_METHOD("set_font", "font"), &CharFXTransform::set_font);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "range"), "set_range", "get_range");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "elapsed_time"), "set_elapsed_time", "get_elapsed_time");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visibility", "is_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "outline"), "set_outline", "is_outline");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "env"), "set_environment", "get_environment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "character"), "set_character", "get_character");
ADD_PROPERTY(PropertyInfo(Variant::INT, "glyph_index"), "set_glyph_index", "get_glyph_index");
ADD_PROPERTY(PropertyInfo(Variant::RID, "font"), "set_font", "get_font");
}
CharFXTransform::CharFXTransform() {
relative_index = 0;
absolute_index = 0;
visibility = true;
offset = Point2();
color = Color();
character = 0;
elapsed_time = 0.0f;
}
CharFXTransform::~CharFXTransform() {

View file

@ -54,32 +54,37 @@ protected:
static void _bind_methods();
public:
uint64_t relative_index;
uint64_t absolute_index;
bool visibility;
Vector2i range;
bool visibility = true;
bool outline = false;
Point2 offset;
Color color;
char32_t character;
float elapsed_time;
float elapsed_time = 0.0f;
Dictionary environment;
uint32_t glpyh_index = 0;
RID font;
CharFXTransform();
~CharFXTransform();
uint64_t get_relative_index() { return relative_index; }
void set_relative_index(uint64_t p_index) { relative_index = p_index; }
uint64_t get_absolute_index() { return absolute_index; }
void set_absolute_index(uint64_t p_index) { absolute_index = p_index; }
Vector2i get_range() { return range; }
void set_range(const Vector2i &p_range) { range = p_range; }
float get_elapsed_time() { return elapsed_time; }
void set_elapsed_time(float p_elapsed_time) { elapsed_time = p_elapsed_time; }
bool is_visible() { return visibility; }
void set_visibility(bool p_vis) { visibility = p_vis; }
void set_visibility(bool p_visibility) { visibility = p_visibility; }
bool is_outline() { return outline; }
void set_outline(bool p_outline) { outline = p_outline; }
Point2 get_offset() { return offset; }
void set_offset(Point2 p_offset) { offset = p_offset; }
Color get_color() { return color; }
void set_color(Color p_color) { color = p_color; }
int get_character() { return (int)character; }
void set_character(int p_char) { character = (char32_t)p_char; }
uint32_t get_glyph_index() const { return glpyh_index; };
void set_glyph_index(uint32_t p_glpyh_index) { glpyh_index = p_glpyh_index; };
RID get_font() const { return font; };
void set_font(RID p_font) { font = p_font; };
Dictionary get_environment() { return environment; }
void set_environment(Dictionary p_environment) { environment = p_environment; }
};

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,7 @@
#include "rich_text_effect.h"
#include "scene/gui/scroll_bar.h"
#include "scene/resources/text_paragraph.h"
class RichTextLabel : public Control {
GDCLASS(RichTextLabel, Control);
@ -48,6 +49,7 @@ public:
enum ListType {
LIST_NUMBERS,
LIST_LETTERS,
LIST_ROMAN,
LIST_DOTS
};
@ -57,10 +59,14 @@ public:
ITEM_IMAGE,
ITEM_NEWLINE,
ITEM_FONT,
ITEM_FONT_SIZE,
ITEM_FONT_FEATURES,
ITEM_COLOR,
ITEM_OUTLINE_SIZE,
ITEM_OUTLINE_COLOR,
ITEM_UNDERLINE,
ITEM_STRIKETHROUGH,
ITEM_ALIGN,
ITEM_PARAGRAPH,
ITEM_INDENT,
ITEM_LIST,
ITEM_TABLE,
@ -80,31 +86,25 @@ private:
struct Item;
struct Line {
Item *from;
Vector<int> offset_caches;
Vector<int> height_caches;
Vector<int> ascent_caches;
Vector<int> descent_caches;
Vector<int> space_caches;
int height_cache;
int height_accum_cache;
int char_count;
int minimum_width;
int maximum_width;
Item *from = nullptr;
Line() {
from = nullptr;
char_count = 0;
}
Ref<TextParagraph> text_buf;
Vector2 offset;
int char_offset = 0;
int char_count = 0;
Line() { text_buf.instance(); }
};
struct Item {
int index;
Item *parent;
ItemType type;
int index = 0;
int char_ofs = 0;
Item *parent = nullptr;
ItemType type = ITEM_FRAME;
List<Item *> subitems;
List<Item *>::Element *E;
int line;
List<Item *>::Element *E = nullptr;
int line = 0;
void _clear_children() {
while (subitems.size()) {
@ -113,29 +113,26 @@ private:
}
}
Item() {
parent = nullptr;
E = nullptr;
line = 0;
index = 0;
type = ITEM_FRAME;
}
virtual ~Item() { _clear_children(); }
};
struct ItemFrame : public Item {
int parent_line;
bool cell;
Vector<Line> lines;
int first_invalid_line;
ItemFrame *parent_frame;
bool cell = false;
ItemFrame() {
type = ITEM_FRAME;
parent_frame = nullptr;
cell = false;
parent_line = 0;
}
Vector<Line> lines;
int first_invalid_line = 0;
int first_resized_line = 0;
ItemFrame *parent_frame = nullptr;
Color odd_row_bg = Color(0, 0, 0, 0);
Color even_row_bg = Color(0, 0, 0, 0);
Color border = Color(0, 0, 0, 0);
Size2 min_size_over = Size2(-1, -1);
Size2 max_size_over = Size2(-1, -1);
Rect2 padding;
ItemFrame() { type = ITEM_FRAME; }
};
struct ItemText : public Item {
@ -145,6 +142,7 @@ private:
struct ItemImage : public Item {
Ref<Texture2D> image;
VAlign inline_align = VALIGN_TOP;
Size2 size;
Color color;
ItemImage() { type = ITEM_IMAGE; }
@ -155,11 +153,31 @@ private:
ItemFont() { type = ITEM_FONT; }
};
struct ItemFontSize : public Item {
int font_size = 16;
ItemFontSize() { type = ITEM_FONT_SIZE; }
};
struct ItemFontFeatures : public Item {
Dictionary opentype_features;
ItemFontFeatures() { type = ITEM_FONT_FEATURES; }
};
struct ItemColor : public Item {
Color color;
ItemColor() { type = ITEM_COLOR; }
};
struct ItemOutlineSize : public Item {
int outline_size = 0;
ItemOutlineSize() { type = ITEM_OUTLINE_SIZE; }
};
struct ItemOutlineColor : public Item {
Color color;
ItemOutlineColor() { type = ITEM_OUTLINE_COLOR; }
};
struct ItemUnderline : public Item {
ItemUnderline() { type = ITEM_UNDERLINE; }
};
@ -173,18 +191,23 @@ private:
ItemMeta() { type = ITEM_META; }
};
struct ItemAlign : public Item {
Align align;
ItemAlign() { type = ITEM_ALIGN; }
struct ItemParagraph : public Item {
Align align = ALIGN_LEFT;
String language;
Control::TextDirection direction = Control::TEXT_DIRECTION_AUTO;
Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT;
ItemParagraph() { type = ITEM_PARAGRAPH; }
};
struct ItemIndent : public Item {
int level;
int level = 0;
ItemIndent() { type = ITEM_INDENT; }
};
struct ItemList : public Item {
ListType list_type;
ListType list_type = LIST_DOTS;
bool capitalize = false;
int level = 0;
ItemList() { type = ITEM_LIST; }
};
@ -202,37 +225,32 @@ private:
};
Vector<Column> columns;
int total_width;
Vector<float> rows;
int total_width = 0;
int total_height = 0;
VAlign inline_align = VALIGN_TOP;
ItemTable() { type = ITEM_TABLE; }
};
struct ItemFade : public Item {
int starting_index;
int length;
int starting_index = 0;
int length = 0;
ItemFade() { type = ITEM_FADE; }
};
struct ItemFX : public Item {
float elapsed_time;
ItemFX() {
elapsed_time = 0.0f;
}
float elapsed_time = 0.f;
};
struct ItemShake : public ItemFX {
int strength;
float rate;
uint64_t _current_rng;
uint64_t _previous_rng;
int strength = 0;
float rate = 0.0f;
uint64_t _current_rng = 0;
uint64_t _previous_rng = 0;
ItemShake() {
strength = 0;
rate = 0.0f;
_current_rng = 0;
type = ITEM_SHAKE;
}
ItemShake() { type = ITEM_SHAKE; }
void reroll_random() {
_previous_rng = _current_rng;
@ -251,38 +269,25 @@ private:
};
struct ItemWave : public ItemFX {
float frequency;
float amplitude;
float frequency = 1.0f;
float amplitude = 1.0f;
ItemWave() {
frequency = 1.0f;
amplitude = 1.0f;
type = ITEM_WAVE;
}
ItemWave() { type = ITEM_WAVE; }
};
struct ItemTornado : public ItemFX {
float radius;
float frequency;
float radius = 1.0f;
float frequency = 1.0f;
ItemTornado() {
radius = 1.0f;
frequency = 1.0f;
type = ITEM_TORNADO;
}
ItemTornado() { type = ITEM_TORNADO; }
};
struct ItemRainbow : public ItemFX {
float saturation;
float value;
float frequency;
float saturation = 0.8f;
float value = 0.8f;
float frequency = 1.0f;
ItemRainbow() {
saturation = 0.8f;
value = 0.8f;
frequency = 1.0f;
type = ITEM_RAINBOW;
}
ItemRainbow() { type = ITEM_RAINBOW; }
};
struct ItemCustomFX : public ItemFX {
@ -291,7 +296,6 @@ private:
ItemCustomFX() {
type = ITEM_CUSTOMFX;
char_fx_transform.instance();
}
@ -316,7 +320,8 @@ private:
int scroll_w;
bool scroll_updated;
bool updating_scroll;
int current_idx;
int current_idx = 1;
int current_char_ofs = 0;
int visible_line_count;
int tab_size;
@ -336,23 +341,25 @@ private:
void _add_item(Item *p_item, bool p_enter = false, bool p_ensure_newline = false);
void _remove_item(Item *p_item, const int p_line, const int p_subitem_line);
struct ProcessState {
int line_width;
};
enum ProcessMode {
PROCESS_CACHE,
PROCESS_DRAW,
PROCESS_POINTER
};
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT;
Array st_args;
struct Selection {
Item *click;
ItemFrame *click_frame;
int click_line;
Item *click_item;
int click_char;
Item *from;
ItemFrame *from_frame;
int from_line;
Item *from_item;
int from_char;
Item *to;
ItemFrame *to_frame;
int to_line;
Item *to_item;
int to_char;
bool active; // anything selected? i.e. from, to, etc. valid?
@ -364,13 +371,34 @@ private:
int visible_characters;
float percent_visible;
int _process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Color &p_font_color_shadow, bool p_shadow_as_outline, const Point2 &shadow_ofs, const Point2i &p_click_pos = Point2i(), Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr, int p_char_count = 0);
void _find_click(ItemFrame *p_frame, const Point2i &p_click, 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);
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 _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width);
float _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);
String _roman(int p_num, bool p_capitalize) const;
String _letters(int p_num, bool p_capitalize) const;
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);
Ref<Font> _find_font(Item *p_item);
int _find_margin(Item *p_item, const Ref<Font> &p_base_font);
int _find_font_size(Item *p_item);
Dictionary _find_font_features(Item *p_item);
int _find_outline_size(Item *p_item);
ItemList *_find_list_item(Item *p_item);
int _find_list(Item *p_item, Vector<int> &r_index, Vector<ItemList *> &r_list);
int _find_margin(Item *p_item, const Ref<Font> &p_base_font, int p_base_font_size);
Align _find_align(Item *p_item);
TextServer::Direction _find_direction(Item *p_item);
Control::StructuredTextParser _find_stt(Item *p_item);
String _find_language(Item *p_item);
Color _find_color(Item *p_item, const Color &p_default_color);
Color _find_outline_color(Item *p_item, const Color &p_default_color);
bool _find_underline(Item *p_item);
bool _find_strikethrough(Item *p_item);
bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = nullptr);
@ -394,8 +422,6 @@ private:
bool use_bbcode;
String bbcode;
void _update_all_lines();
int fixed_width;
bool fit_content_height;
@ -406,23 +432,27 @@ protected:
public:
String get_text();
void add_text(const String &p_text);
void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0));
void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0), VAlign p_align = VALIGN_TOP);
void add_newline();
bool remove_line(const int p_line);
void push_font(const Ref<Font> &p_font);
void push_font_size(int p_font_size);
void push_font_features(const Dictionary &p_features);
void push_outline_size(int p_font_size);
void push_normal();
void push_bold();
void push_bold_italics();
void push_italics();
void push_mono();
void push_color(const Color &p_color);
void push_outline_color(const Color &p_color);
void push_underline();
void push_strikethrough();
void push_align(Align p_align);
void push_paragraph(Align p_align, Control::TextDirection p_direction = Control::TEXT_DIRECTION_INHERITED, const String &p_language = "", Control::StructuredTextParser p_st_parser = STRUCTURED_TEXT_DEFAULT);
void push_indent(int p_level);
void push_list(ListType p_list);
void push_list(int p_level, ListType p_list, bool p_capitalize);
void push_meta(const Variant &p_meta);
void push_table(int p_columns);
void push_table(int p_columns, VAlign p_align = VALIGN_TOP);
void push_fade(int p_start_index, int p_length);
void push_shake(int p_strength, float p_rate);
void push_wave(float p_frequency, float p_amplitude);
@ -430,6 +460,10 @@ public:
void push_rainbow(float p_saturation, float p_value, float p_frequency);
void push_customfx(Ref<RichTextEffect> p_custom_effect, Dictionary p_environment);
void set_table_column_expand(int p_column, bool p_expand, int p_ratio = 1);
void set_cell_row_background_color(const Color &p_odd_row_bg, const Color &p_even_row_bg);
void set_cell_border_color(const Color &p_color);
void set_cell_size_override(const Size2 &p_min_size, const Size2 &p_max_size);
void set_cell_padding(const Rect2 &p_padding);
int get_current_table_column() const;
void push_cell();
void pop();
@ -484,6 +518,18 @@ public:
void set_text(const String &p_string);
void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;
void set_language(const String &p_language);
String get_language() const;
void set_structured_text_bidi_override(Control::StructuredTextParser p_parser);
Control::StructuredTextParser get_structured_text_bidi_override() const;
void set_structured_text_bidi_override_options(Array p_args);
Array get_structured_text_bidi_override_options() const;
void set_visible_characters(int p_visible);
int get_visible_characters() const;
int get_total_character_count() const;

View file

@ -803,6 +803,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font("bold_italics_font", "RichTextLabel", Ref<Font>());
theme->set_font("mono_font", "RichTextLabel", Ref<Font>());
theme->set_font_size("normal_font_size", "RichTextLabel", -1);
theme->set_font_size("bold_font_size", "RichTextLabel", -1);
theme->set_font_size("italics_font_size", "RichTextLabel", -1);
theme->set_font_size("bold_italics_font_size", "RichTextLabel", -1);
theme->set_font_size("mono_font_size", "RichTextLabel", -1);
theme->set_color("default_color", "RichTextLabel", Color(1, 1, 1));
theme->set_color("font_color_selected", "RichTextLabel", font_color_selection);
theme->set_color("selection_color", "RichTextLabel", Color(0.1, 0.1, 1, 0.8));
@ -817,6 +823,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("table_hseparation", "RichTextLabel", 3 * scale);
theme->set_constant("table_vseparation", "RichTextLabel", 3 * scale);
theme->set_color("table_odd_row_bg", "RichTextLabel", Color(0, 0, 0, 0));
theme->set_color("table_even_row_bg", "RichTextLabel", Color(0, 0, 0, 0));
theme->set_color("table_border", "RichTextLabel", Color(0, 0, 0, 0));
// Containers
theme->set_stylebox("bg", "VSplitContainer", make_stylebox(vsplit_bg_png, 1, 1, 1, 1));