mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	Merge pull request #80410 from bruvzg/rtl_img_features
[RTL] Add support for image dynamic updating, padding, tooltips and size in percent.
This commit is contained in:
		
						commit
						ca8b229e1c
					
				
					 7 changed files with 347 additions and 52 deletions
				
			
		|  | @ -24,10 +24,17 @@ | |||
| 			<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)" /> | ||||
| 			<param index="6" name="key" type="Variant" default="null" /> | ||||
| 			<param index="7" name="pad" type="bool" default="false" /> | ||||
| 			<param index="8" name="tooltip" type="String" default="""" /> | ||||
| 			<param index="9" name="size_in_percent" type="bool" default="false" /> | ||||
| 			<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, 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. | ||||
| 				[param key] is an optional identifier, that can be used to modify the image via [method update_image]. | ||||
| 				If [param pad] is set, and the image is smaller than the size specified by [param width] and [param height], the image padding is added to match the size instead of upscaling. | ||||
| 				If [param size_in_percent] is set, [param width] and [param height] values are percentages of the control width instead of pixels. | ||||
| 			</description> | ||||
| 		</method> | ||||
| 		<method name="add_text"> | ||||
|  | @ -539,6 +546,23 @@ | |||
| 				If [param expand] is [code]false[/code], the column will not contribute to the total ratio. | ||||
| 			</description> | ||||
| 		</method> | ||||
| 		<method name="update_image"> | ||||
| 			<return type="void" /> | ||||
| 			<param index="0" name="key" type="Variant" /> | ||||
| 			<param index="1" name="mask" type="int" enum="RichTextLabel.ImageUpdateMask" is_bitfield="true" /> | ||||
| 			<param index="2" name="image" type="Texture2D" /> | ||||
| 			<param index="3" name="width" type="int" default="0" /> | ||||
| 			<param index="4" name="height" type="int" default="0" /> | ||||
| 			<param index="5" name="color" type="Color" default="Color(1, 1, 1, 1)" /> | ||||
| 			<param index="6" name="inline_align" type="int" enum="InlineAlignment" default="5" /> | ||||
| 			<param index="7" name="region" type="Rect2" default="Rect2(0, 0, 0, 0)" /> | ||||
| 			<param index="8" name="pad" type="bool" default="false" /> | ||||
| 			<param index="9" name="tooltip" type="String" default="""" /> | ||||
| 			<param index="10" name="size_in_percent" type="bool" default="false" /> | ||||
| 			<description> | ||||
| 				Updates the existing images with the key [param key]. Only properties specified by [param mask] bits are updated. See [method add_image]. | ||||
| 			</description> | ||||
| 		</method> | ||||
| 	</methods> | ||||
| 	<members> | ||||
| 		<member name="autowrap_mode" type="int" setter="set_autowrap_mode" getter="get_autowrap_mode" enum="TextServer.AutowrapMode" default="3"> | ||||
|  | @ -667,6 +691,30 @@ | |||
| 		<constant name="MENU_MAX" value="2" enum="MenuItems"> | ||||
| 			Represents the size of the [enum MenuItems] enum. | ||||
| 		</constant> | ||||
| 		<constant name="UPDATE_TEXTURE" value="1" enum="ImageUpdateMask" is_bitfield="true"> | ||||
| 			If this bit is set, [method update_image] changes image texture. | ||||
| 		</constant> | ||||
| 		<constant name="UPDATE_SIZE" value="2" enum="ImageUpdateMask" is_bitfield="true"> | ||||
| 			If this bit is set, [method update_image] changes image size. | ||||
| 		</constant> | ||||
| 		<constant name="UPDATE_COLOR" value="4" enum="ImageUpdateMask" is_bitfield="true"> | ||||
| 			If this bit is set, [method update_image] changes image color. | ||||
| 		</constant> | ||||
| 		<constant name="UPDATE_ALIGNMENT" value="8" enum="ImageUpdateMask" is_bitfield="true"> | ||||
| 			If this bit is set, [method update_image] changes image inline alignment. | ||||
| 		</constant> | ||||
| 		<constant name="UPDATE_REGION" value="16" enum="ImageUpdateMask" is_bitfield="true"> | ||||
| 			If this bit is set, [method update_image] changes image texture region. | ||||
| 		</constant> | ||||
| 		<constant name="UPDATE_PAD" value="32" enum="ImageUpdateMask" is_bitfield="true"> | ||||
| 			If this bit is set, [method update_image] changes image padding. | ||||
| 		</constant> | ||||
| 		<constant name="UPDATE_TOOLTIP" value="64" enum="ImageUpdateMask" is_bitfield="true"> | ||||
| 			If this bit is set, [method update_image] changes image tooltip. | ||||
| 		</constant> | ||||
| 		<constant name="UPDATE_WIDTH_IN_PERCENT" value="128" enum="ImageUpdateMask" is_bitfield="true"> | ||||
| 			If this bit is set, [method update_image] changes image width from/to percents. | ||||
| 		</constant> | ||||
| 	</constants> | ||||
| 	<theme_items> | ||||
| 		<theme_item name="default_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)"> | ||||
|  |  | |||
|  | @ -2269,20 +2269,46 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control | |||
| 
 | ||||
| 			pos = brk_end + 1; | ||||
| 			tag_stack.push_front("url"); | ||||
| 		} else if (tag == "img") { | ||||
| 		} else if (tag.begins_with("img")) { | ||||
| 			int width = 0; | ||||
| 			int height = 0; | ||||
| 			bool size_in_percent = false; | ||||
| 			if (tag.length() > 4) { | ||||
| 				Vector<String> subtags = tag.substr(4, tag.length()).split(" "); | ||||
| 				HashMap<String, String> bbcode_options; | ||||
| 				for (int i = 0; i < subtags.size(); i++) { | ||||
| 					const String &expr = subtags[i]; | ||||
| 					int value_pos = expr.find("="); | ||||
| 					if (value_pos > -1) { | ||||
| 						bbcode_options[expr.substr(0, value_pos)] = expr.substr(value_pos + 1).unquote(); | ||||
| 					} | ||||
| 				} | ||||
| 				HashMap<String, String>::Iterator width_option = bbcode_options.find("width"); | ||||
| 				if (width_option) { | ||||
| 					width = width_option->value.to_int(); | ||||
| 					if (width_option->value.ends_with("%")) { | ||||
| 						size_in_percent = true; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				HashMap<String, String>::Iterator height_option = bbcode_options.find("height"); | ||||
| 				if (height_option) { | ||||
| 					height = height_option->value.to_int(); | ||||
| 					if (height_option->value.ends_with("%")) { | ||||
| 						size_in_percent = true; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			int end = bbcode.find("[", brk_end); | ||||
| 			if (end == -1) { | ||||
| 				end = bbcode.length(); | ||||
| 			} | ||||
| 			String image = bbcode.substr(brk_end + 1, end - brk_end - 1); | ||||
| 
 | ||||
| 			Ref<Texture2D> texture = ResourceLoader::load(base_path.path_join(image), "Texture2D"); | ||||
| 			if (texture.is_valid()) { | ||||
| 				p_rt->add_image(texture); | ||||
| 			} | ||||
| 			p_rt->add_image(ResourceLoader::load(base_path.path_join(image), "Texture2D"), width, height, Color(1, 1, 1), INLINE_ALIGNMENT_CENTER, Rect2(), Variant(), false, String(), size_in_percent); | ||||
| 
 | ||||
| 			pos = end; | ||||
| 			tag_stack.push_front(tag); | ||||
| 			tag_stack.push_front("img"); | ||||
| 		} else if (tag.begins_with("color=")) { | ||||
| 			String col = tag.substr(6, tag.length()); | ||||
| 			Color color = Color::from_string(col, Color()); | ||||
|  |  | |||
|  | @ -169,6 +169,8 @@ Validate extension JSON: API was removed: classes/GraphNode/signals/raise_reques | |||
| Validate extension JSON: API was removed: classes/GraphNode/signals/resize_request | ||||
| 
 | ||||
| Refactor GraphNode (splitup in GraphElement and GraphNode) | ||||
| 
 | ||||
| 
 | ||||
| GH-81070 | ||||
| -------- | ||||
| Validate extension JSON: API was removed: classes/TileMap/methods/get_quadrant_size | ||||
|  | @ -190,4 +192,9 @@ GH-79965 | |||
| -------- | ||||
| Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/PopupMenu/methods/clear': arguments | ||||
| 
 | ||||
| 
 | ||||
| GH-80410 | ||||
| -------- | ||||
| Validate extension JSON: Error: Field 'classes/RichTextLabel/methods/add_image/arguments': size changed value in new API, from 6 to 10. | ||||
| 
 | ||||
| Added optional argument. Compatibility method registered. | ||||
|  |  | |||
|  | @ -83,6 +83,13 @@ partial class RenderingDevice | |||
| 
 | ||||
| partial class RichTextLabel | ||||
| { | ||||
|     /// <inheritdoc cref="AddImage(Texture2D, int, int, Nullable{Color}, InlineAlignment, Nullable{Rect2}, Variant, bool, string, bool)"/> | ||||
|     [EditorBrowsable(EditorBrowsableState.Never)] | ||||
|     public void AddImage(Texture2D image, int width, int height, Nullable<Color> color, InlineAlignment inlineAlign, Nullable<Rect2> region) | ||||
|     { | ||||
|         AddImage(image, width, height, color, inlineAlign, region, key: default, pad: false, tooltip: "", sizeInPercent: false); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc cref="PushList(int, ListType, bool, string)"/> | ||||
|     [EditorBrowsable(EditorBrowsableState.Never)] | ||||
|     public void PushList(int level, ListType type, bool capitalize) | ||||
|  |  | |||
							
								
								
									
										41
									
								
								scene/gui/rich_text_label.compat.inc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								scene/gui/rich_text_label.compat.inc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | |||
| /**************************************************************************/ | ||||
| /*  rich_text_label.compat.inc                                            */ | ||||
| /**************************************************************************/ | ||||
| /*                         This file is part of:                          */ | ||||
| /*                             GODOT ENGINE                               */ | ||||
| /*                        https://godotengine.org                         */ | ||||
| /**************************************************************************/ | ||||
| /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | ||||
| /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | ||||
| /*                                                                        */ | ||||
| /* Permission is hereby granted, free of charge, to any person obtaining  */ | ||||
| /* a copy of this software and associated documentation files (the        */ | ||||
| /* "Software"), to deal in the Software without restriction, including    */ | ||||
| /* without limitation the rights to use, copy, modify, merge, publish,    */ | ||||
| /* distribute, sublicense, and/or sell copies of the Software, and to     */ | ||||
| /* permit persons to whom the Software is furnished to do so, subject to  */ | ||||
| /* the following conditions:                                              */ | ||||
| /*                                                                        */ | ||||
| /* The above copyright notice and this permission notice shall be         */ | ||||
| /* included in all copies or substantial portions of the Software.        */ | ||||
| /*                                                                        */ | ||||
| /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ | ||||
| /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ | ||||
| /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ | ||||
| /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ | ||||
| /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ | ||||
| /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ | ||||
| /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ | ||||
| /**************************************************************************/ | ||||
| 
 | ||||
| #ifndef DISABLE_DEPRECATED | ||||
| 
 | ||||
| void RichTextLabel::_add_image_bind_compat_80410(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment, const Rect2 &p_region) { | ||||
| 	add_image(p_image, p_width, p_height, p_color, p_alignment, p_region, Variant(), false, String(), false); | ||||
| } | ||||
| 
 | ||||
| void RichTextLabel::_bind_compatibility_methods() { | ||||
| 	ClassDB::bind_compatibility_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align", "region"), &RichTextLabel::_add_image_bind_compat_80410, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(Rect2())); | ||||
| } | ||||
| 
 | ||||
| #endif // DISABLE_DEPRECATED
 | ||||
|  | @ -29,6 +29,7 @@ | |||
| /**************************************************************************/ | ||||
| 
 | ||||
| #include "rich_text_label.h" | ||||
| #include "rich_text_label.compat.inc" | ||||
| 
 | ||||
| #include "core/input/input_map.h" | ||||
| #include "core/math/math_defs.h" | ||||
|  | @ -301,6 +302,14 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font | |||
| 	Item *it_to = (p_line + 1 < (int)p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr; | ||||
| 	for (Item *it = l.from; it && it != it_to; it = _get_next_item(it)) { | ||||
| 		switch (it->type) { | ||||
| 			case ITEM_IMAGE: { | ||||
| 				ItemImage *img = static_cast<ItemImage *>(it); | ||||
| 				Size2 img_size = img->size; | ||||
| 				if (img->size_in_percent) { | ||||
| 					img_size = _get_image_size(img->image, p_width * img->rq_size.width / 100.f, p_width * img->rq_size.height / 100.f, img->region); | ||||
| 					l.text_buf->resize_object((uint64_t)it, img_size, img->inline_align, 1); | ||||
| 				} | ||||
| 			} break; | ||||
| 			case ITEM_TABLE: { | ||||
| 				ItemTable *table = static_cast<ItemTable *>(it); | ||||
| 				int col_count = table->columns.size(); | ||||
|  | @ -575,7 +584,11 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> | |||
| 			} break; | ||||
| 			case ITEM_IMAGE: { | ||||
| 				ItemImage *img = static_cast<ItemImage *>(it); | ||||
| 				l.text_buf->add_object((uint64_t)it, img->size, img->inline_align, 1); | ||||
| 				Size2 img_size = img->size; | ||||
| 				if (img->size_in_percent) { | ||||
| 					img_size = _get_image_size(img->image, p_width * img->rq_size.width / 100.f, p_width * img->rq_size.height / 100.f, img->region); | ||||
| 				} | ||||
| 				l.text_buf->add_object((uint64_t)it, img_size, img->inline_align, 1); | ||||
| 				txt += String::chr(0xfffc); | ||||
| 				l.char_count++; | ||||
| 				remaining_characters--; | ||||
|  | @ -933,7 +946,13 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o | |||
| 				switch (it->type) { | ||||
| 					case ITEM_IMAGE: { | ||||
| 						ItemImage *img = static_cast<ItemImage *>(it); | ||||
| 						img->image->draw_rect(ci, Rect2(p_ofs + rect.position + off, rect.size), false, img->color); | ||||
| 						if (img->pad) { | ||||
| 							Size2 pad_size = Size2(MIN(rect.size.x, img->image->get_width()), MIN(rect.size.y, img->image->get_height())); | ||||
| 							Vector2 pad_off = (rect.size - pad_size) / 2; | ||||
| 							img->image->draw_rect(ci, Rect2(p_ofs + rect.position + off + pad_off, pad_size), false, img->color); | ||||
| 						} else { | ||||
| 							img->image->draw_rect(ci, Rect2(p_ofs + rect.position + off, rect.size), false, img->color); | ||||
| 						} | ||||
| 					} break; | ||||
| 					case ITEM_TABLE: { | ||||
| 						ItemTable *table = static_cast<ItemTable *>(it); | ||||
|  | @ -2215,11 +2234,15 @@ String RichTextLabel::get_tooltip(const Point2 &p_pos) const { | |||
| 	const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &c_item, nullptr, &outside, true); | ||||
| 
 | ||||
| 	String description; | ||||
| 	if (c_item && !outside && const_cast<RichTextLabel *>(this)->_find_hint(c_item, &description)) { | ||||
| 		return description; | ||||
| 	} else { | ||||
| 		return Control::get_tooltip(p_pos); | ||||
| 	if (c_item && !outside) { | ||||
| 		if (const_cast<RichTextLabel *>(this)->_find_hint(c_item, &description)) { | ||||
| 			return description; | ||||
| 		} else if (c_item->type == ITEM_IMAGE && !static_cast<ItemImage *>(c_item)->tooltip.is_empty()) { | ||||
| 			return static_cast<ItemImage *>(c_item)->tooltip; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return Control::get_tooltip(p_pos); | ||||
| } | ||||
| 
 | ||||
| void RichTextLabel::_find_frame(Item *p_item, ItemFrame **r_frame, int *r_line) { | ||||
|  | @ -3121,7 +3144,46 @@ 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, const Rect2 &p_region) { | ||||
| Size2 RichTextLabel::_get_image_size(const Ref<Texture2D> &p_image, int p_width, int p_height, const Rect2 &p_region) { | ||||
| 	Size2 ret; | ||||
| 	if (p_width > 0) { | ||||
| 		// custom width
 | ||||
| 		ret.width = p_width; | ||||
| 		if (p_height > 0) { | ||||
| 			// custom height
 | ||||
| 			ret.height = p_height; | ||||
| 		} else { | ||||
| 			// calculate height to keep aspect ratio
 | ||||
| 			if (p_region.has_area()) { | ||||
| 				ret.height = p_region.get_size().height * p_width / p_region.get_size().width; | ||||
| 			} else { | ||||
| 				ret.height = p_image->get_height() * p_width / p_image->get_width(); | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		if (p_height > 0) { | ||||
| 			// custom height
 | ||||
| 			ret.height = p_height; | ||||
| 			// calculate width to keep aspect ratio
 | ||||
| 			if (p_region.has_area()) { | ||||
| 				ret.width = p_region.get_size().width * p_height / p_region.get_size().height; | ||||
| 			} else { | ||||
| 				ret.width = p_image->get_width() * p_height / p_image->get_height(); | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (p_region.has_area()) { | ||||
| 				// if the image has a region, keep the region size
 | ||||
| 				ret = p_region.get_size(); | ||||
| 			} else { | ||||
| 				// keep original width and height
 | ||||
| 				ret = p_image->get_size(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void RichTextLabel::add_image(const Ref<Texture2D> &p_image, int p_width, int p_height, const Color &p_color, InlineAlignment p_alignment, const Rect2 &p_region, const Variant &p_key, bool p_pad, const String &p_tooltip, bool p_size_in_percent) { | ||||
| 	_stop_thread(); | ||||
| 	MutexLock data_lock(data_mutex); | ||||
| 
 | ||||
|  | @ -3142,48 +3204,97 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, | |||
| 	} else { | ||||
| 		item->image = p_image; | ||||
| 	} | ||||
| 
 | ||||
| 	item->color = p_color; | ||||
| 	item->inline_align = p_alignment; | ||||
| 
 | ||||
| 	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
 | ||||
| 			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
 | ||||
| 			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 { | ||||
| 			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(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	item->rq_size = Size2(p_width, p_height); | ||||
| 	item->region = p_region; | ||||
| 	item->size = _get_image_size(p_image, p_width, p_height, p_region); | ||||
| 	item->size_in_percent = p_size_in_percent; | ||||
| 	item->pad = p_pad; | ||||
| 	item->key = p_key; | ||||
| 	item->tooltip = p_tooltip; | ||||
| 
 | ||||
| 	_add_item(item, false); | ||||
| } | ||||
| 
 | ||||
| void RichTextLabel::update_image(const Variant &p_key, BitField<ImageUpdateMask> p_mask, const Ref<Texture2D> &p_image, int p_width, int p_height, const Color &p_color, InlineAlignment p_alignment, const Rect2 &p_region, bool p_pad, const String &p_tooltip, bool p_size_in_percent) { | ||||
| 	_stop_thread(); | ||||
| 	MutexLock data_lock(data_mutex); | ||||
| 
 | ||||
| 	if (p_mask & UPDATE_TEXTURE) { | ||||
| 		ERR_FAIL_COND(p_image.is_null()); | ||||
| 		ERR_FAIL_COND(p_image->get_width() == 0); | ||||
| 		ERR_FAIL_COND(p_image->get_height() == 0); | ||||
| 	} | ||||
| 
 | ||||
| 	bool reshape = false; | ||||
| 
 | ||||
| 	Item *it = main; | ||||
| 	while (it) { | ||||
| 		if (it->type == ITEM_IMAGE) { | ||||
| 			ItemImage *it_img = static_cast<ItemImage *>(it); | ||||
| 			if (it_img->key == p_key) { | ||||
| 				ItemImage *item = it_img; | ||||
| 				if (p_mask & UPDATE_REGION) { | ||||
| 					item->region = p_region; | ||||
| 				} | ||||
| 				if (p_mask & UPDATE_TEXTURE) { | ||||
| 					if (item->region.has_area()) { | ||||
| 						Ref<AtlasTexture> atlas_tex = memnew(AtlasTexture); | ||||
| 						atlas_tex->set_atlas(p_image); | ||||
| 						atlas_tex->set_region(item->region); | ||||
| 						item->image = atlas_tex; | ||||
| 					} else { | ||||
| 						item->image = p_image; | ||||
| 					} | ||||
| 				} | ||||
| 				if (p_mask & UPDATE_COLOR) { | ||||
| 					item->color = p_color; | ||||
| 				} | ||||
| 				if (p_mask & UPDATE_TOOLTIP) { | ||||
| 					item->tooltip = p_tooltip; | ||||
| 				} | ||||
| 				if (p_mask & UPDATE_PAD) { | ||||
| 					item->pad = p_pad; | ||||
| 				} | ||||
| 				if (p_mask & UPDATE_ALIGNMENT) { | ||||
| 					if (item->inline_align != p_alignment) { | ||||
| 						reshape = true; | ||||
| 						item->inline_align = p_alignment; | ||||
| 					} | ||||
| 				} | ||||
| 				if (p_mask & UPDATE_WIDTH_IN_PERCENT) { | ||||
| 					if (item->size_in_percent != p_size_in_percent) { | ||||
| 						reshape = true; | ||||
| 						item->size_in_percent = p_size_in_percent; | ||||
| 					} | ||||
| 				} | ||||
| 				if (p_mask & UPDATE_SIZE) { | ||||
| 					if (p_width > 0) { | ||||
| 						item->rq_size.width = p_width; | ||||
| 					} | ||||
| 					if (p_height > 0) { | ||||
| 						item->rq_size.height = p_height; | ||||
| 					} | ||||
| 				} | ||||
| 				if ((p_mask & UPDATE_SIZE) || (p_mask & UPDATE_REGION) || (p_mask & UPDATE_TEXTURE)) { | ||||
| 					Size2 new_size = _get_image_size(item->image, item->rq_size.width, item->rq_size.height, item->region); | ||||
| 					if (item->size != new_size) { | ||||
| 						reshape = true; | ||||
| 						item->size = new_size; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		it = _get_next_item(it, true); | ||||
| 	} | ||||
| 
 | ||||
| 	if (reshape) { | ||||
| 		main->first_invalid_line.store(0); | ||||
| 	} | ||||
| 	queue_redraw(); | ||||
| } | ||||
| 
 | ||||
| void RichTextLabel::add_newline() { | ||||
| 	_stop_thread(); | ||||
| 	MutexLock data_lock(data_mutex); | ||||
|  | @ -4479,6 +4590,9 @@ void RichTextLabel::append_text(const String &p_bbcode) { | |||
| 
 | ||||
| 				int width = 0; | ||||
| 				int height = 0; | ||||
| 				bool pad = false; | ||||
| 				String tooltip; | ||||
| 				bool size_in_percent = false; | ||||
| 				if (!bbcode_value.is_empty()) { | ||||
| 					int sep = bbcode_value.find("x"); | ||||
| 					if (sep == -1) { | ||||
|  | @ -4491,15 +4605,31 @@ void RichTextLabel::append_text(const String &p_bbcode) { | |||
| 					OptionMap::Iterator width_option = bbcode_options.find("width"); | ||||
| 					if (width_option) { | ||||
| 						width = width_option->value.to_int(); | ||||
| 						if (width_option->value.ends_with("%")) { | ||||
| 							size_in_percent = true; | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					OptionMap::Iterator height_option = bbcode_options.find("height"); | ||||
| 					if (height_option) { | ||||
| 						height = height_option->value.to_int(); | ||||
| 						if (height_option->value.ends_with("%")) { | ||||
| 							size_in_percent = true; | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					OptionMap::Iterator tooltip_option = bbcode_options.find("tooltip"); | ||||
| 					if (tooltip_option) { | ||||
| 						tooltip = tooltip_option->value; | ||||
| 					} | ||||
| 
 | ||||
| 					OptionMap::Iterator pad_option = bbcode_options.find("pad"); | ||||
| 					if (pad_option) { | ||||
| 						pad = (pad_option->value == "true"); | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				add_image(texture, width, height, color, (InlineAlignment)alignment, region); | ||||
| 				add_image(texture, width, height, color, (InlineAlignment)alignment, region, Variant(), pad, tooltip, size_in_percent); | ||||
| 			} | ||||
| 
 | ||||
| 			pos = end; | ||||
|  | @ -5624,7 +5754,8 @@ 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", "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("add_image", "image", "width", "height", "color", "inline_align", "region", "key", "pad", "tooltip", "size_in_percent"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(Rect2()), DEFVAL(Variant()), DEFVAL(false), DEFVAL(String()), DEFVAL(false)); | ||||
| 	ClassDB::bind_method(D_METHOD("update_image", "key", "mask", "image", "width", "height", "color", "inline_align", "region", "pad", "tooltip", "size_in_percent"), &RichTextLabel::update_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(Rect2()), DEFVAL(false), DEFVAL(String()), DEFVAL(false)); | ||||
| 	ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline); | ||||
| 	ClassDB::bind_method(D_METHOD("remove_paragraph", "paragraph"), &RichTextLabel::remove_paragraph); | ||||
| 	ClassDB::bind_method(D_METHOD("push_font", "font", "font_size"), &RichTextLabel::push_font, DEFVAL(0)); | ||||
|  | @ -5832,6 +5963,15 @@ void RichTextLabel::_bind_methods() { | |||
| 	BIND_ENUM_CONSTANT(MENU_SELECT_ALL); | ||||
| 	BIND_ENUM_CONSTANT(MENU_MAX); | ||||
| 
 | ||||
| 	BIND_BITFIELD_FLAG(UPDATE_TEXTURE); | ||||
| 	BIND_BITFIELD_FLAG(UPDATE_SIZE); | ||||
| 	BIND_BITFIELD_FLAG(UPDATE_COLOR); | ||||
| 	BIND_BITFIELD_FLAG(UPDATE_ALIGNMENT); | ||||
| 	BIND_BITFIELD_FLAG(UPDATE_REGION); | ||||
| 	BIND_BITFIELD_FLAG(UPDATE_PAD); | ||||
| 	BIND_BITFIELD_FLAG(UPDATE_TOOLTIP); | ||||
| 	BIND_BITFIELD_FLAG(UPDATE_WIDTH_IN_PERCENT); | ||||
| 
 | ||||
| 	BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, RichTextLabel, normal_style, "normal"); | ||||
| 	BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, RichTextLabel, focus_style, "focus"); | ||||
| 	BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, RichTextLabel, progress_bg_style, "background", "ProgressBar"); | ||||
|  |  | |||
|  | @ -98,12 +98,28 @@ public: | |||
| 		CUSTOM_FONT, | ||||
| 	}; | ||||
| 
 | ||||
| 	enum ImageUpdateMask { | ||||
| 		UPDATE_TEXTURE = 1 << 0, | ||||
| 		UPDATE_SIZE = 1 << 1, | ||||
| 		UPDATE_COLOR = 1 << 2, | ||||
| 		UPDATE_ALIGNMENT = 1 << 3, | ||||
| 		UPDATE_REGION = 1 << 4, | ||||
| 		UPDATE_PAD = 1 << 5, | ||||
| 		UPDATE_TOOLTIP = 1 << 6, | ||||
| 		UPDATE_WIDTH_IN_PERCENT = 1 << 7, | ||||
| 	}; | ||||
| 
 | ||||
| protected: | ||||
| 	virtual void _update_theme_item_cache() override; | ||||
| 
 | ||||
| 	void _notification(int p_what); | ||||
| 	static void _bind_methods(); | ||||
| 
 | ||||
| #ifndef DISABLE_DEPRECATED | ||||
| 	void _add_image_bind_compat_80410(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment, const Rect2 &p_region); | ||||
| 	static void _bind_compatibility_methods(); | ||||
| #endif | ||||
| 
 | ||||
| private: | ||||
| 	struct Item; | ||||
| 
 | ||||
|  | @ -189,8 +205,14 @@ private: | |||
| 	struct ItemImage : public Item { | ||||
| 		Ref<Texture2D> image; | ||||
| 		InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER; | ||||
| 		bool pad = false; | ||||
| 		bool size_in_percent = false; | ||||
| 		Rect2 region; | ||||
| 		Size2 size; | ||||
| 		Size2 rq_size; | ||||
| 		Color color; | ||||
| 		Variant key; | ||||
| 		String tooltip; | ||||
| 		ItemImage() { type = ITEM_IMAGE; } | ||||
| 	}; | ||||
| 
 | ||||
|  | @ -544,6 +566,8 @@ private: | |||
| 	Ref<RichTextEffect> _get_custom_effect_by_code(String p_bbcode_identifier); | ||||
| 	virtual Dictionary parse_expressions_for_values(Vector<String> p_expressions); | ||||
| 
 | ||||
| 	Size2 _get_image_size(const Ref<Texture2D> &p_image, int p_width = 0, int p_height = 0, const Rect2 &p_region = Rect2()); | ||||
| 
 | ||||
| 	void _draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item *it_from, Item *it_to, int start, int end, int fbg_flag); | ||||
| #ifndef DISABLE_DEPRECATED | ||||
| 	// Kept for compatibility from 3.x to 4.0.
 | ||||
|  | @ -601,7 +625,8 @@ 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, const Rect2 &p_region = Rect2(0, 0, 0, 0)); | ||||
| 	void add_image(const Ref<Texture2D> &p_image, int p_width = 0, 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(), const Variant &p_key = Variant(), bool p_pad = false, const String &p_tooltip = String(), bool p_size_in_percent = false); | ||||
| 	void update_image(const Variant &p_key, BitField<ImageUpdateMask> p_mask, const Ref<Texture2D> &p_image, int p_width = 0, 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(), bool p_pad = false, const String &p_tooltip = String(), bool p_size_in_percent = false); | ||||
| 	void add_newline(); | ||||
| 	bool remove_paragraph(const int p_paragraph); | ||||
| 	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)); | ||||
|  | @ -779,5 +804,6 @@ public: | |||
| 
 | ||||
| VARIANT_ENUM_CAST(RichTextLabel::ListType); | ||||
| VARIANT_ENUM_CAST(RichTextLabel::MenuItems); | ||||
| VARIANT_BITFIELD_CAST(RichTextLabel::ImageUpdateMask); | ||||
| 
 | ||||
| #endif // RICH_TEXT_LABEL_H
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rémi Verschelde
						Rémi Verschelde