Merge pull request #22353 from YeldhamDev/bbcode_strikethrough

Add proper strikethrough BBCode to RichTextLabel
This commit is contained in:
Rémi Verschelde 2018-09-24 14:34:54 +02:00 committed by GitHub
commit 49665a46d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 15 deletions

View File

@ -320,14 +320,17 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
Color color; Color color;
Color font_color_shadow; Color font_color_shadow;
bool underline = false; bool underline = false;
bool strikethrough = false;
if (p_mode == PROCESS_DRAW) { if (p_mode == PROCESS_DRAW) {
color = _find_color(text, p_base_color); color = _find_color(text, p_base_color);
font_color_shadow = _find_color(text, p_font_color_shadow); font_color_shadow = _find_color(text, p_font_color_shadow);
underline = _find_underline(text); if (_find_underline(text) || (_find_meta(text, &meta) && underline_meta)) {
if (_find_meta(text, &meta) && underline_meta) {
underline = true; underline = true;
} else if (_find_strikethrough(text)) {
strikethrough = true;
} }
} else if (p_mode == PROCESS_CACHE) { } else if (p_mode == PROCESS_CACHE) {
@ -469,6 +472,15 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
underline_width *= EDSCALE; underline_width *= EDSCALE;
#endif #endif
VS::get_singleton()->canvas_item_add_line(ci, p_ofs + Point2(align_ofs + wofs, uy), p_ofs + Point2(align_ofs + wofs + w, uy), uc, underline_width); VS::get_singleton()->canvas_item_add_line(ci, p_ofs + Point2(align_ofs + wofs, uy), p_ofs + Point2(align_ofs + wofs + w, uy), uc, underline_width);
} else if (strikethrough) {
Color uc = color;
uc.a *= 0.5;
int uy = y + lh / 2 - line_descent + 2;
float strikethrough_width = 1.0;
#ifdef TOOLS_ENABLED
strikethrough_width *= EDSCALE;
#endif
VS::get_singleton()->canvas_item_add_line(ci, p_ofs + Point2(align_ofs + wofs, uy), p_ofs + Point2(align_ofs + wofs + w, uy), uc, strikethrough_width);
} }
} }
@ -1227,6 +1239,23 @@ bool RichTextLabel::_find_underline(Item *p_item) {
return false; return false;
} }
bool RichTextLabel::_find_strikethrough(Item *p_item) {
Item *item = p_item;
while (item) {
if (item->type == ITEM_STRIKETHROUGH) {
return true;
}
item = item->parent;
}
return false;
}
bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta) { bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta) {
Item *item = p_item; Item *item = p_item;
@ -1458,6 +1487,7 @@ void RichTextLabel::push_font(const Ref<Font> &p_font) {
item->font = p_font; item->font = p_font;
_add_item(item, true); _add_item(item, true);
} }
void RichTextLabel::push_color(const Color &p_color) { void RichTextLabel::push_color(const Color &p_color) {
ERR_FAIL_COND(current->type == ITEM_TABLE); ERR_FAIL_COND(current->type == ITEM_TABLE);
@ -1466,6 +1496,7 @@ void RichTextLabel::push_color(const Color &p_color) {
item->color = p_color; item->color = p_color;
_add_item(item, true); _add_item(item, true);
} }
void RichTextLabel::push_underline() { void RichTextLabel::push_underline() {
ERR_FAIL_COND(current->type == ITEM_TABLE); ERR_FAIL_COND(current->type == ITEM_TABLE);
@ -1474,6 +1505,14 @@ void RichTextLabel::push_underline() {
_add_item(item, true); _add_item(item, true);
} }
void RichTextLabel::push_strikethrough() {
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemStrikethrough *item = memnew(ItemStrikethrough);
_add_item(item, true);
}
void RichTextLabel::push_align(Align p_align) { void RichTextLabel::push_align(Align p_align) {
ERR_FAIL_COND(current->type == ITEM_TABLE); ERR_FAIL_COND(current->type == ITEM_TABLE);
@ -1683,7 +1722,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
} }
if (brk_pos == p_bbcode.length()) if (brk_pos == p_bbcode.length())
break; //nothing else o add break; //nothing else to add
int brk_end = p_bbcode.find("]", brk_pos + 1); int brk_end = p_bbcode.find("]", brk_pos + 1);
@ -1749,7 +1788,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
int columns = tag.substr(6, tag.length()).to_int(); int columns = tag.substr(6, tag.length()).to_int();
if (columns < 1) if (columns < 1)
columns = 1; columns = 1;
//use monospace font
push_table(columns); push_table(columns);
pos = brk_end + 1; pos = brk_end + 1;
tag_stack.push_front("table"); tag_stack.push_front("table");
@ -1763,7 +1802,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
int ratio = tag.substr(5, tag.length()).to_int(); int ratio = tag.substr(5, tag.length()).to_int();
if (ratio < 1) if (ratio < 1)
ratio = 1; ratio = 1;
//use monospace font
set_table_column_expand(get_current_table_column(), true, ratio); set_table_column_expand(get_current_table_column(), true, ratio);
push_cell(); push_cell();
pos = brk_end + 1; pos = brk_end + 1;
@ -1776,43 +1815,37 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
tag_stack.push_front(tag); tag_stack.push_front(tag);
} else if (tag == "s") { } else if (tag == "s") {
//use strikethrough (not supported underline instead) //use strikethrough
push_underline(); push_strikethrough();
pos = brk_end + 1; pos = brk_end + 1;
tag_stack.push_front(tag); tag_stack.push_front(tag);
} else if (tag == "center") { } else if (tag == "center") {
//use underline
push_align(ALIGN_CENTER); push_align(ALIGN_CENTER);
pos = brk_end + 1; pos = brk_end + 1;
tag_stack.push_front(tag); tag_stack.push_front(tag);
} else if (tag == "fill") { } else if (tag == "fill") {
//use underline
push_align(ALIGN_FILL); push_align(ALIGN_FILL);
pos = brk_end + 1; pos = brk_end + 1;
tag_stack.push_front(tag); tag_stack.push_front(tag);
} else if (tag == "right") { } else if (tag == "right") {
//use underline
push_align(ALIGN_RIGHT); push_align(ALIGN_RIGHT);
pos = brk_end + 1; pos = brk_end + 1;
tag_stack.push_front(tag); tag_stack.push_front(tag);
} else if (tag == "ul") { } else if (tag == "ul") {
//use underline
push_list(LIST_DOTS); push_list(LIST_DOTS);
pos = brk_end + 1; pos = brk_end + 1;
tag_stack.push_front(tag); tag_stack.push_front(tag);
} else if (tag == "ol") { } else if (tag == "ol") {
//use underline
push_list(LIST_NUMBERS); push_list(LIST_NUMBERS);
pos = brk_end + 1; pos = brk_end + 1;
tag_stack.push_front(tag); tag_stack.push_front(tag);
} else if (tag == "indent") { } else if (tag == "indent") {
//use underline
indent_level++; indent_level++;
push_indent(indent_level); push_indent(indent_level);
pos = brk_end + 1; pos = brk_end + 1;
@ -1820,7 +1853,6 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
} else if (tag == "url") { } else if (tag == "url") {
//use strikethrough (not supported underline instead)
int end = p_bbcode.find("[", brk_end); int end = p_bbcode.find("[", brk_end);
if (end == -1) if (end == -1)
end = p_bbcode.length(); end = p_bbcode.length();
@ -1838,7 +1870,6 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
tag_stack.push_front("url"); tag_stack.push_front("url");
} else if (tag == "img") { } else if (tag == "img") {
//use strikethrough (not supported underline instead)
int end = p_bbcode.find("[", brk_end); int end = p_bbcode.find("[", brk_end);
if (end == -1) if (end == -1)
end = p_bbcode.length(); end = p_bbcode.length();
@ -2145,6 +2176,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("push_list", "type"), &RichTextLabel::push_list); ClassDB::bind_method(D_METHOD("push_list", "type"), &RichTextLabel::push_list);
ClassDB::bind_method(D_METHOD("push_meta", "data"), &RichTextLabel::push_meta); ClassDB::bind_method(D_METHOD("push_meta", "data"), &RichTextLabel::push_meta);
ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline); ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline);
ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough);
ClassDB::bind_method(D_METHOD("push_table", "columns"), &RichTextLabel::push_table); ClassDB::bind_method(D_METHOD("push_table", "columns"), &RichTextLabel::push_table);
ClassDB::bind_method(D_METHOD("set_table_column_expand", "column", "expand", "ratio"), &RichTextLabel::set_table_column_expand); ClassDB::bind_method(D_METHOD("set_table_column_expand", "column", "expand", "ratio"), &RichTextLabel::set_table_column_expand);
ClassDB::bind_method(D_METHOD("push_cell"), &RichTextLabel::push_cell); ClassDB::bind_method(D_METHOD("push_cell"), &RichTextLabel::push_cell);
@ -2233,6 +2265,7 @@ void RichTextLabel::_bind_methods() {
BIND_ENUM_CONSTANT(ITEM_FONT); BIND_ENUM_CONSTANT(ITEM_FONT);
BIND_ENUM_CONSTANT(ITEM_COLOR); BIND_ENUM_CONSTANT(ITEM_COLOR);
BIND_ENUM_CONSTANT(ITEM_UNDERLINE); BIND_ENUM_CONSTANT(ITEM_UNDERLINE);
BIND_ENUM_CONSTANT(ITEM_STRIKETHROUGH);
BIND_ENUM_CONSTANT(ITEM_ALIGN); BIND_ENUM_CONSTANT(ITEM_ALIGN);
BIND_ENUM_CONSTANT(ITEM_INDENT); BIND_ENUM_CONSTANT(ITEM_INDENT);
BIND_ENUM_CONSTANT(ITEM_LIST); BIND_ENUM_CONSTANT(ITEM_LIST);

View File

@ -62,6 +62,7 @@ public:
ITEM_FONT, ITEM_FONT,
ITEM_COLOR, ITEM_COLOR,
ITEM_UNDERLINE, ITEM_UNDERLINE,
ITEM_STRIKETHROUGH,
ITEM_ALIGN, ITEM_ALIGN,
ITEM_INDENT, ITEM_INDENT,
ITEM_LIST, ITEM_LIST,
@ -164,6 +165,11 @@ private:
ItemUnderline() { type = ITEM_UNDERLINE; } ItemUnderline() { type = ITEM_UNDERLINE; }
}; };
struct ItemStrikethrough : public Item {
ItemStrikethrough() { type = ITEM_STRIKETHROUGH; }
};
struct ItemMeta : public Item { struct ItemMeta : public Item {
Variant meta; Variant meta;
@ -277,6 +283,7 @@ private:
Align _find_align(Item *p_item); Align _find_align(Item *p_item);
Color _find_color(Item *p_item, const Color &p_default_color); Color _find_color(Item *p_item, const Color &p_default_color);
bool _find_underline(Item *p_item); bool _find_underline(Item *p_item);
bool _find_strikethrough(Item *p_item);
bool _find_meta(Item *p_item, Variant *r_meta); bool _find_meta(Item *p_item, Variant *r_meta);
void _update_scroll(); void _update_scroll();
@ -307,6 +314,7 @@ public:
void push_font(const Ref<Font> &p_font); void push_font(const Ref<Font> &p_font);
void push_color(const Color &p_color); void push_color(const Color &p_color);
void push_underline(); void push_underline();
void push_strikethrough();
void push_align(Align p_align); void push_align(Align p_align);
void push_indent(int p_level); void push_indent(int p_level);
void push_list(ListType p_list); void push_list(ListType p_list);