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>
<argument index="0" name="image" type="Texture">
</argument>
<argument index="1" name="width" type="int" default="0">
</argument>
<argument index="2" name="height" type="int" default="0">
</argument>
<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>
</method>
<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)
*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)
line_is_blank = false;
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++;
ADVANCE(img->image->get_width());
CHECK_HEIGHT((img->image->get_height() + font->get_descent()));
ADVANCE(img->size.width);
CHECK_HEIGHT((img->size.height + font->get_descent()));
} break;
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)
return;
@ -1643,6 +1643,30 @@ void RichTextLabel::add_image(const Ref<Texture> &p_image) {
ItemImage *item = memnew(ItemImage);
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);
}
@ -2125,6 +2149,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
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");
@ -2133,6 +2158,32 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = end;
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=")) {
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("add_text", "text"), &RichTextLabel::add_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("remove_line", "line"), &RichTextLabel::remove_line);
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);

View file

@ -148,6 +148,7 @@ private:
struct ItemImage : public Item {
Ref<Texture> image;
Size2 size;
ItemImage() { type = ITEM_IMAGE; }
};
@ -406,7 +407,7 @@ protected:
public:
String get_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();
bool remove_line(const int p_line);
void push_font(const Ref<Font> &p_font);