Skip to content

Commit 747c3de

Browse files
committed
TextEdit::scroll_fit_content_* is now maximum size aware
If `Control::get_combined_maximum_size()` returns a size smaller than `get_minimum_size()` in the target axis, scrollbars are shown.
1 parent 653fed3 commit 747c3de

3 files changed

Lines changed: 51 additions & 4 deletions

File tree

doc/classes/TextEdit.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,10 +1375,10 @@
13751375
Text shown when the [TextEdit] is empty. It is [b]not[/b] the [TextEdit]'s default value (see [member text]).
13761376
</member>
13771377
<member name="scroll_fit_content_height" type="bool" setter="set_fit_content_height_enabled" getter="is_fit_content_height_enabled" default="false">
1378-
If [code]true[/code], [TextEdit] will disable vertical scroll and fit minimum height to the number of visible lines. When both this property and [member scroll_fit_content_width] are [code]true[/code], no scrollbars will be displayed.
1378+
If [code]true[/code], [TextEdit] fits its minimum height to the number of visible lines instead of scrolling vertically. If a maximum height is set (for example via [member Control.custom_maximum_size]) and content exceeds it, a vertical scrollbar is shown.
13791379
</member>
13801380
<member name="scroll_fit_content_width" type="bool" setter="set_fit_content_width_enabled" getter="is_fit_content_width_enabled" default="false">
1381-
If [code]true[/code], [TextEdit] will disable horizontal scroll and fit minimum width to the widest line in the text. When both this property and [member scroll_fit_content_height] are [code]true[/code], no scrollbars will be displayed.
1381+
If [code]true[/code], [TextEdit] fits its minimum width to the widest line instead of scrolling horizontally. If a maximum width is set (for example via [member Control.custom_maximum_size]) and content exceeds it, a horizontal scrollbar is shown.
13821382
</member>
13831383
<member name="scroll_horizontal" type="int" setter="set_h_scroll" getter="get_h_scroll" default="0">
13841384
If there is a horizontal scrollbar, this determines the current horizontal scroll value in pixels.

scene/gui/text_edit.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8678,9 +8678,16 @@ void TextEdit::_update_scrollbars() {
86788678
update_minimum_size();
86798679
}
86808680

8681+
const Size2 combined_maximum_size = get_combined_maximum_size();
8682+
const Size2 style_minimum_size = style->get_minimum_size();
8683+
const bool fit_content_height_exceeds_maximum = fit_content_height && combined_maximum_size.y >= 0 &&
8684+
style_minimum_size.y + content_size_cache.y > combined_maximum_size.y;
8685+
const bool fit_content_width_exceeds_maximum = fit_content_width && combined_maximum_size.x >= 0 &&
8686+
style_minimum_size.x + content_size_cache.x > combined_maximum_size.x;
8687+
86818688
updating_scrolls = true;
86828689

8683-
if (!fit_content_height && total_rows > visible_rows) {
8690+
if ((!fit_content_height || fit_content_height_exceeds_maximum) && total_rows > visible_rows) {
86848691
double visible_rows_exact = (double)_get_control_height() / (double)get_line_height();
86858692
double fractional_visible_rows = visible_rows_exact - (double)visible_rows;
86868693
fractional_visible_rows = CLAMP(fractional_visible_rows, 0.0, 1.0);
@@ -8696,7 +8703,7 @@ void TextEdit::_update_scrollbars() {
86968703
v_scroll->hide();
86978704
}
86988705

8699-
if (total_width > visible_width) {
8706+
if ((!fit_content_width || fit_content_width_exceeds_maximum) && total_width > visible_width) {
87008707
h_scroll->show();
87018708
h_scroll->set_max(total_width);
87028709
h_scroll->set_page(visible_width);

tests/scene/test_text_edit.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8045,6 +8045,46 @@ TEST_CASE("[SceneTree][TextEdit] small height value") {
80458045
memdelete(text_edit);
80468046
}
80478047

8048+
TEST_CASE("[SceneTree][TextEdit] fit content scrollbar behavior") {
8049+
TextEdit *text_edit = memnew(TextEdit);
8050+
SceneTree::get_singleton()->get_root()->add_child(text_edit);
8051+
8052+
text_edit->set_line_wrapping_mode(TextEdit::LineWrappingMode::LINE_WRAPPING_NONE);
8053+
text_edit->set_fit_content_width_enabled(true);
8054+
text_edit->set_fit_content_height_enabled(true);
8055+
8056+
const String long_line = "0123456789012345678901234567890123456789012345678901234567890123456789";
8057+
String content;
8058+
for (int i = 0; i < 40; i++) {
8059+
if (i > 0) {
8060+
content += "\n";
8061+
}
8062+
content += long_line;
8063+
}
8064+
text_edit->set_text(content);
8065+
MessageQueue::get_singleton()->flush();
8066+
8067+
SUBCASE("[TextEdit] fit content without maximum size") {
8068+
text_edit->set_custom_maximum_size(Size2(-1, -1));
8069+
text_edit->set_size(text_edit->get_combined_minimum_size());
8070+
MessageQueue::get_singleton()->flush();
8071+
8072+
CHECK_FALSE(text_edit->get_h_scroll_bar()->is_visible());
8073+
CHECK_FALSE(text_edit->get_v_scroll_bar()->is_visible());
8074+
}
8075+
8076+
SUBCASE("[TextEdit] fit content with maximum size") {
8077+
text_edit->set_custom_maximum_size(Size2(180, 120));
8078+
text_edit->set_size(text_edit->get_combined_maximum_size());
8079+
MessageQueue::get_singleton()->flush();
8080+
8081+
CHECK(text_edit->get_h_scroll_bar()->is_visible());
8082+
CHECK(text_edit->get_v_scroll_bar()->is_visible());
8083+
}
8084+
8085+
memdelete(text_edit);
8086+
}
8087+
80488088
TEST_CASE("[SceneTree][TextEdit] setter getters") {
80498089
TextEdit *text_edit = memnew(TextEdit);
80508090
SceneTree::get_singleton()->get_root()->add_child(text_edit);

0 commit comments

Comments
 (0)