Support for resized images in RichTextLabel

BBCode Tag:
[img=<width>x<height>]{path}[/img]
This commit is contained in:
PouleyKetchoupp
2019-10-16 12:00:15 +02:00
parent 26bbb26738
commit 9f8ffd4146
3 changed files with 66 additions and 9 deletions

View File

@ -16,8 +16,13 @@
</return> </return>
<argument index="0" name="image" type="Texture"> <argument index="0" name="image" type="Texture">
</argument> </argument>
<argument index="1" name="width" type="int" default="0">
</argument>
<argument index="2" name="height" type="int" default="0">
</argument>
<description> <description>
Adds an image's opening and closing tags to the tag stack. 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.
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.
</description> </description>
</method> </method>
<method name="add_text"> <method name="add_text">

View File

@ -624,19 +624,19 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
if (p_mode == PROCESS_POINTER && r_click_char) if (p_mode == PROCESS_POINTER && r_click_char)
*r_click_char = 0; *r_click_char = 0;
ENSURE_WIDTH(img->image->get_width()); ENSURE_WIDTH(img->size.width);
bool visible = visible_characters < 0 || (p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - font->get_descent() - img->image->get_height(), img->image->get_height())); bool visible = visible_characters < 0 || (p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - font->get_descent() - img->size.height, img->size.height));
if (visible) if (visible)
line_is_blank = false; line_is_blank = false;
if (p_mode == PROCESS_DRAW && visible) { if (p_mode == PROCESS_DRAW && visible) {
img->image->draw(ci, p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->image->get_height())); img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size));
} }
p_char_count++; p_char_count++;
ADVANCE(img->image->get_width()); ADVANCE(img->size.width);
CHECK_HEIGHT((img->image->get_height() + font->get_descent())); CHECK_HEIGHT((img->size.height + font->get_descent()));
} break; } break;
case ITEM_NEWLINE: { case ITEM_NEWLINE: {
@ -1634,7 +1634,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
} }
} }
void RichTextLabel::add_image(const Ref<Texture> &p_image) { void RichTextLabel::add_image(const Ref<Texture> &p_image, const int p_width, const int p_height) {
if (current->type == ITEM_TABLE) if (current->type == ITEM_TABLE)
return; return;
@ -1643,6 +1643,30 @@ void RichTextLabel::add_image(const Ref<Texture> &p_image) {
ItemImage *item = memnew(ItemImage); ItemImage *item = memnew(ItemImage);
item->image = p_image; item->image = p_image;
if (p_width > 0) {
// custom width
item->size.width = p_width;
if (p_height > 0) {
// custom height
item->size.height = p_height;
} else {
// calculate height to keep aspect ratio
item->size.height = p_image->get_height() * p_width / p_image->get_width();
}
} else {
if (p_height > 0) {
// custom height
item->size.height = p_height;
// calculate width to keep aspect ratio
item->size.width = p_image->get_width() * p_height / p_image->get_height();
} else {
// keep original width and height
item->size.height = p_image->get_height();
item->size.width = p_image->get_width();
}
}
_add_item(item, false); _add_item(item, false);
} }
@ -2125,6 +2149,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
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();
String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1); String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
Ref<Texture> texture = ResourceLoader::load(image, "Texture"); Ref<Texture> texture = ResourceLoader::load(image, "Texture");
@ -2133,6 +2158,32 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = end; pos = end;
tag_stack.push_front(tag); tag_stack.push_front(tag);
} else if (tag.begins_with("img=")) {
int width = 0;
int height = 0;
String params = tag.substr(4, tag.length());
int sep = params.find("x");
if (sep == -1) {
width = params.to_int();
} else {
width = params.substr(0, sep).to_int();
height = params.substr(sep + 1, params.length()).to_int();
}
int end = p_bbcode.find("[", brk_end);
if (end == -1)
end = p_bbcode.length();
String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
Ref<Texture> texture = ResourceLoader::load(image, "Texture");
if (texture.is_valid())
add_image(texture, width, height);
pos = end;
tag_stack.push_front("img");
} else if (tag.begins_with("color=")) { } else if (tag.begins_with("color=")) {
String col = tag.substr(6, tag.length()); String col = tag.substr(6, tag.length());
@ -2581,7 +2632,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text); ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text); ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);
ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text); ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text);
ClassDB::bind_method(D_METHOD("add_image", "image"), &RichTextLabel::add_image); ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0));
ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline); ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line); ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font); ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);

View File

@ -148,6 +148,7 @@ private:
struct ItemImage : public Item { struct ItemImage : public Item {
Ref<Texture> image; Ref<Texture> image;
Size2 size;
ItemImage() { type = ITEM_IMAGE; } ItemImage() { type = ITEM_IMAGE; }
}; };
@ -406,7 +407,7 @@ protected:
public: public:
String get_text(); String get_text();
void add_text(const String &p_text); void add_text(const String &p_text);
void add_image(const Ref<Texture> &p_image); void add_image(const Ref<Texture> &p_image, const int p_width = 0, const int p_height = 0);
void add_newline(); void add_newline();
bool remove_line(const int p_line); bool remove_line(const int p_line);
void push_font(const Ref<Font> &p_font); void push_font(const Ref<Font> &p_font);