Add Spritesheet support to RichTextLabel BBCode

BBCode: [img region=0,0,16,16]res://icon.svg[/img]
This commit is contained in:
Petra Baranski 2022-10-10 16:55:28 +02:00
parent 77f4670d00
commit 546e017613
3 changed files with 45 additions and 10 deletions

View File

@ -23,9 +23,11 @@
<param index="2" name="height" type="int" default="0" />
<param index="3" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="4" name="inline_align" type="int" enum="InlineAlignment" default="5" />
<param index="5" name="region" type="Rect2" default="Rect2(0, 0, 0, 0)" />
<description>
Adds an image's opening and closing tags to the tag stack, optionally providing a [param width] and [param height] to resize the image and a [param color] to tint the image.
Adds an image's opening and closing tags to the tag stack, optionally providing a [param width] and [param height] to resize the image, a [param color] to tint the image and a [param region] to only use parts of the image.
If [param width] or [param height] is set to 0, the image size will be adjusted in order to keep the original aspect ratio.
If [param width] and [param height] are not set, but [param region] is, the region's rect will be used.
</description>
</method>
<method name="add_text">

View File

@ -2956,7 +2956,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
memdelete(p_item);
}
void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment) {
void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment, const Rect2 &p_region) {
_stop_thread();
MutexLock data_lock(data_mutex);
@ -2969,7 +2969,15 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width,
ERR_FAIL_COND(p_image->get_height() == 0);
ItemImage *item = memnew(ItemImage);
item->image = p_image;
if (p_region.has_area()) {
Ref<AtlasTexture> atlas_tex = memnew(AtlasTexture);
atlas_tex->set_atlas(p_image);
atlas_tex->set_region(p_region);
item->image = atlas_tex;
} else {
item->image = p_image;
}
item->color = p_color;
item->inline_align = p_alignment;
@ -2981,17 +2989,30 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width,
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();
if (p_region.has_area()) {
item->size.height = p_region.get_size().height * p_width / p_region.get_size().width;
} else {
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();
if (p_region.has_area()) {
item->size.width = p_region.get_size().width * p_height / p_region.get_size().height;
} else {
item->size.width = p_image->get_width() * p_height / p_image->get_height();
}
} else {
// keep original width and height
item->size = p_image->get_size();
if (p_region.has_area()) {
// if the image has a region, keep the region size
item->size = p_region.get_size();
} else {
// keep original width and height
item->size = p_image->get_size();
}
}
}
@ -4126,6 +4147,18 @@ void RichTextLabel::append_text(const String &p_bbcode) {
Ref<Texture2D> texture = ResourceLoader::load(image, "Texture2D");
if (texture.is_valid()) {
Rect2 region;
OptionMap::Iterator region_option = bbcode_options.find("region");
if (region_option) {
Vector<String> region_values = region_option->value.split(",", false);
if (region_values.size() == 4) {
region.position.x = region_values[0].to_float();
region.position.y = region_values[1].to_float();
region.size.x = region_values[2].to_float();
region.size.y = region_values[3].to_float();
}
}
Color color = Color(1.0, 1.0, 1.0);
OptionMap::Iterator color_option = bbcode_options.find("color");
if (color_option) {
@ -4154,7 +4187,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
}
add_image(texture, width, height, color, (InlineAlignment)alignment);
add_image(texture, width, height, color, (InlineAlignment)alignment, region);
}
pos = end;
@ -5209,7 +5242,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_parsed_text"), &RichTextLabel::get_parsed_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", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER));
ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align", "region"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(Rect2(0, 0, 0, 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", "font_size"), &RichTextLabel::push_font);

View File

@ -569,7 +569,7 @@ private:
public:
String get_parsed_text() const;
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), InlineAlignment p_alignment = INLINE_ALIGNMENT_CENTER);
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), InlineAlignment p_alignment = INLINE_ALIGNMENT_CENTER, const Rect2 &p_region = Rect2(0, 0, 0, 0));
void add_newline();
bool remove_line(const int p_line);
void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0));