Skip to content

Commit 1aabcb9

Browse files
committed
Merge pull request godotengine#118306 from StarryWorm/text-edit-max-size
Make `TextEdit`'s `scroll_fit_content_*` properties work properly with maximum sizes
2 parents b5c9064 + 747c3de commit 1aabcb9

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
@@ -8686,9 +8686,16 @@ void TextEdit::_update_scrollbars() {
86868686
update_minimum_size();
86878687
}
86888688

8689+
const Size2 combined_maximum_size = get_combined_maximum_size();
8690+
const Size2 style_minimum_size = style->get_minimum_size();
8691+
const bool fit_content_height_exceeds_maximum = fit_content_height && combined_maximum_size.y >= 0 &&
8692+
style_minimum_size.y + content_size_cache.y > combined_maximum_size.y;
8693+
const bool fit_content_width_exceeds_maximum = fit_content_width && combined_maximum_size.x >= 0 &&
8694+
style_minimum_size.x + content_size_cache.x > combined_maximum_size.x;
8695+
86898696
updating_scrolls = true;
86908697

8691-
if (!fit_content_height && total_rows > visible_rows) {
8698+
if ((!fit_content_height || fit_content_height_exceeds_maximum) && total_rows > visible_rows) {
86928699
double visible_rows_exact = (double)_get_control_height() / (double)get_line_height();
86938700
double fractional_visible_rows = visible_rows_exact - (double)visible_rows;
86948701
fractional_visible_rows = CLAMP(fractional_visible_rows, 0.0, 1.0);
@@ -8704,7 +8711,7 @@ void TextEdit::_update_scrollbars() {
87048711
v_scroll->hide();
87058712
}
87068713

8707-
if (total_width > visible_width) {
8714+
if ((!fit_content_width || fit_content_width_exceeds_maximum) && total_width > visible_width) {
87088715
h_scroll->show();
87098716
h_scroll->set_max(total_width);
87108717
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)