Browse Source

Option in RichTextLabel for height to fit content

(cherry picked from commit ad8081216c73b8a0ace555eeb96c1d4fbcb3e50e)
PouleyKetchoupp 5 years ago
parent
commit
b3af0b2a39
3 changed files with 40 additions and 4 deletions
  1. 4 0
      doc/classes/RichTextLabel.xml
  2. 30 3
      scene/gui/rich_text_label.cpp
  3. 6 1
      scene/gui/rich_text_label.h

+ 4 - 0
doc/classes/RichTextLabel.xml

@@ -292,6 +292,10 @@
 			The currently installed custom effects. This is an array of [RichTextEffect]s.
 			To add a custom effect, it's more convenient to use [method install_effect].
 		</member>
+		<member name="fit_content_height" type="bool" setter="set_fit_content_height" getter="is_fit_content_height_enabled" default="false">
+			If [code]true[/code], the label's height will be automatically updated to fit its content.
+			[b]Note:[/b] This property is used as a workaround to fix issues with [RichTextLabel] in [Container]s, but it's unreliable in some cases and will be removed in future versions.
+		</member>
 		<member name="meta_underlined" type="bool" setter="set_meta_underline" getter="is_meta_underlined" default="true">
 			If [code]true[/code], the label underlines meta tags such as [code][url]{text}[/url][/code].
 		</member>

+ 30 - 3
scene/gui/rich_text_label.cpp

@@ -1556,6 +1556,10 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
 		vscroll->set_value(total_height - size.height);
 
 	updating_scroll = false;
+
+	if (fit_content_height) {
+		minimum_size_changed();
+	}
 }
 
 void RichTextLabel::_invalidate_current_line(ItemFrame *p_frame) {
@@ -1985,6 +1989,17 @@ int RichTextLabel::get_tab_size() const {
 	return tab_size;
 }
 
+void RichTextLabel::set_fit_content_height(bool p_enabled) {
+	if (p_enabled != fit_content_height) {
+		fit_content_height = p_enabled;
+		minimum_size_changed();
+	}
+}
+
+bool RichTextLabel::is_fit_content_height_enabled() const {
+	return fit_content_height;
+}
+
 void RichTextLabel::set_meta_underline(bool p_underline) {
 
 	underline_meta = p_underline;
@@ -2702,7 +2717,7 @@ void RichTextLabel::install_effect(const Variant effect) {
 	}
 }
 
-int RichTextLabel::get_content_height() {
+int RichTextLabel::get_content_height() const {
 	int total_height = 0;
 	if (main->lines.size())
 		total_height = main->lines[main->lines.size() - 1].height_accum_cache + get_stylebox("normal")->get_minimum_size().height;
@@ -2758,6 +2773,9 @@ void RichTextLabel::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_tab_size", "spaces"), &RichTextLabel::set_tab_size);
 	ClassDB::bind_method(D_METHOD("get_tab_size"), &RichTextLabel::get_tab_size);
 
+	ClassDB::bind_method(D_METHOD("set_fit_content_height", "enabled"), &RichTextLabel::set_fit_content_height);
+	ClassDB::bind_method(D_METHOD("is_fit_content_height_enabled"), &RichTextLabel::is_fit_content_height_enabled);
+
 	ClassDB::bind_method(D_METHOD("set_selection_enabled", "enabled"), &RichTextLabel::set_selection_enabled);
 	ClassDB::bind_method(D_METHOD("is_selection_enabled"), &RichTextLabel::is_selection_enabled);
 
@@ -2800,6 +2818,8 @@ void RichTextLabel::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_size", PROPERTY_HINT_RANGE, "0,24,1"), "set_tab_size", "get_tab_size");
 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text");
 
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fit_content_height"), "set_fit_content_height", "is_fit_content_height_enabled");
+
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_active"), "set_scroll_active", "is_scroll_active");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_following"), "set_scroll_follow", "is_scroll_following");
 
@@ -2866,12 +2886,17 @@ void RichTextLabel::set_fixed_size_to_width(int p_width) {
 
 Size2 RichTextLabel::get_minimum_size() const {
 
+	Size2 size(0, 0);
 	if (fixed_width != -1) {
+		size.x = fixed_width;
+	}
+
+	if (fixed_width != -1 || fit_content_height) {
 		const_cast<RichTextLabel *>(this)->_validate_line_caches(main);
-		return Size2(fixed_width, const_cast<RichTextLabel *>(this)->get_content_height());
+		size.y = get_content_height();
 	}
 
-	return Size2();
+	return size;
 }
 
 Ref<RichTextEffect> RichTextLabel::_get_custom_effect_by_code(String p_bbcode_identifier) {
@@ -2989,6 +3014,8 @@ RichTextLabel::RichTextLabel() {
 	visible_line_count = 0;
 
 	fixed_width = -1;
+	fit_content_height = false;
+
 	set_clip_contents(true);
 }
 

+ 6 - 1
scene/gui/rich_text_label.h

@@ -401,6 +401,8 @@ private:
 
 	int fixed_width;
 
+	bool fit_content_height;
+
 protected:
 	void _notification(int p_what);
 
@@ -454,13 +456,16 @@ public:
 	void set_tab_size(int p_spaces);
 	int get_tab_size() const;
 
+	void set_fit_content_height(bool p_enabled);
+	bool is_fit_content_height_enabled() const;
+
 	bool search(const String &p_string, bool p_from_selection = false, bool p_search_previous = false);
 
 	void scroll_to_line(int p_line);
 	int get_line_count() const;
 	int get_visible_line_count() const;
 
-	int get_content_height();
+	int get_content_height() const;
 
 	VScrollBar *get_v_scroll() { return vscroll; }