From 3b8afcd10c60a54356c4a2b15a45e4ef9a7b3e04 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sun, 17 Mar 2024 16:19:17 -0700 Subject: [PATCH] Implement fit content width in TextEdit Co-authored-by: Kit Bishop --- doc/classes/TextEdit.xml | 5 +++- scene/gui/text_edit.cpp | 55 +++++++++++++++++++++++++++------------- scene/gui/text_edit.h | 30 ++++++++++++---------- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index f71601f9ae1..6505e48fb9a 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -1327,7 +1327,10 @@ Text shown when the [TextEdit] is empty. It is [b]not[/b] the [TextEdit]'s default value (see [member text]). - If [code]true[/code], [TextEdit] will disable vertical scroll and fit minimum height to the number of visible lines. + 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. + + + 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. If there is a horizontal scrollbar, this determines the current horizontal scroll value in pixels. diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index ac6ebd5cc1f..f3f90ee0661 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2928,7 +2928,10 @@ void TextEdit::_update_ime_text() { Size2 TextEdit::get_minimum_size() const { Size2 size = theme_cache.style_normal->get_minimum_size(); if (fit_content_height) { - size.y += content_height_cache; + size.y += content_size_cache.y; + } + if (fit_content_width) { + size.x += content_size_cache.x; } return size; } @@ -3098,7 +3101,7 @@ void TextEdit::apply_ime() { insert_text_at_caret(insert_ime_text); } -void TextEdit::set_editable(const bool p_editable) { +void TextEdit::set_editable(bool p_editable) { if (editable == p_editable) { return; } @@ -3223,7 +3226,7 @@ bool TextEdit::is_indent_wrapped_lines() const { } // User controls -void TextEdit::set_overtype_mode_enabled(const bool p_enabled) { +void TextEdit::set_overtype_mode_enabled(bool p_enabled) { if (overtype_mode == p_enabled) { return; } @@ -4486,7 +4489,7 @@ TextEdit::CaretType TextEdit::get_caret_type() const { return caret_type; } -void TextEdit::set_caret_blink_enabled(const bool p_enabled) { +void TextEdit::set_caret_blink_enabled(bool p_enabled) { if (caret_blink_enabled == p_enabled) { return; } @@ -4528,7 +4531,7 @@ bool TextEdit::is_drawing_caret_when_editable_disabled() const { return draw_caret_when_editable_disabled; } -void TextEdit::set_move_caret_on_right_click_enabled(const bool p_enabled) { +void TextEdit::set_move_caret_on_right_click_enabled(bool p_enabled) { move_caret_on_right_click = p_enabled; } @@ -4536,7 +4539,7 @@ bool TextEdit::is_move_caret_on_right_click_enabled() const { return move_caret_on_right_click; } -void TextEdit::set_caret_mid_grapheme_enabled(const bool p_enabled) { +void TextEdit::set_caret_mid_grapheme_enabled(bool p_enabled) { caret_mid_grapheme_enabled = p_enabled; } @@ -4646,7 +4649,7 @@ void TextEdit::add_caret_at_carets(bool p_below) { for (int i = 0; i < num_carets; i++) { const int caret_line = get_caret_line(i); const int caret_column = get_caret_column(i); - const bool is_selected = has_selection(i) || carets[i].last_fit_x != carets[i].selection.origin_last_fit_x; + bool is_selected = has_selection(i) || carets[i].last_fit_x != carets[i].selection.origin_last_fit_x; const int selection_origin_line = get_selection_origin_line(i); const int selection_origin_column = get_selection_origin_column(i); const int caret_wrap_index = get_caret_wrap_index(i); @@ -5111,7 +5114,7 @@ String TextEdit::get_word_under_caret(int p_caret) const { } /* Selection. */ -void TextEdit::set_selecting_enabled(const bool p_enabled) { +void TextEdit::set_selecting_enabled(bool p_enabled) { if (selecting_enabled == p_enabled) { return; } @@ -5127,7 +5130,7 @@ bool TextEdit::is_selecting_enabled() const { return selecting_enabled; } -void TextEdit::set_deselect_on_focus_loss_enabled(const bool p_enabled) { +void TextEdit::set_deselect_on_focus_loss_enabled(bool p_enabled) { if (deselect_on_focus_loss_enabled == p_enabled) { return; } @@ -5142,7 +5145,7 @@ bool TextEdit::is_deselect_on_focus_loss_enabled() const { return deselect_on_focus_loss_enabled; } -void TextEdit::set_drag_and_drop_selection_enabled(const bool p_enabled) { +void TextEdit::set_drag_and_drop_selection_enabled(bool p_enabled) { drag_and_drop_selection_enabled = p_enabled; } @@ -5702,7 +5705,7 @@ Vector TextEdit::get_line_wrapped_text(int p_line) const { /* Viewport */ // Scrolling. -void TextEdit::set_smooth_scroll_enabled(const bool p_enabled) { +void TextEdit::set_smooth_scroll_enabled(bool p_enabled) { v_scroll->set_smooth_scroll_enabled(p_enabled); smooth_scroll_enabled = p_enabled; } @@ -5711,7 +5714,7 @@ bool TextEdit::is_smooth_scroll_enabled() const { return smooth_scroll_enabled; } -void TextEdit::set_scroll_past_end_of_file_enabled(const bool p_enabled) { +void TextEdit::set_scroll_past_end_of_file_enabled(bool p_enabled) { if (scroll_past_end_of_file_enabled == p_enabled) { return; } @@ -5765,7 +5768,7 @@ float TextEdit::get_v_scroll_speed() const { return v_scroll_speed; } -void TextEdit::set_fit_content_height_enabled(const bool p_enabled) { +void TextEdit::set_fit_content_height_enabled(bool p_enabled) { if (fit_content_height == p_enabled) { return; } @@ -5777,6 +5780,18 @@ bool TextEdit::is_fit_content_height_enabled() const { return fit_content_height; } +void TextEdit::set_fit_content_width_enabled(bool p_enabled) { + if (fit_content_width == p_enabled) { + return; + } + fit_content_width = p_enabled; + update_minimum_size(); +} + +bool TextEdit::is_fit_content_width_enabled() const { + return fit_content_width; +} + double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const { ERR_FAIL_INDEX_V(p_line, text.size(), 0); ERR_FAIL_COND_V(p_wrap_index < 0, 0); @@ -6330,7 +6345,7 @@ bool TextEdit::is_highlight_current_line_enabled() const { return highlight_current_line; } -void TextEdit::set_highlight_all_occurrences(const bool p_enabled) { +void TextEdit::set_highlight_all_occurrences(bool p_enabled) { if (highlight_all_occurrences == p_enabled) { return; } @@ -6748,6 +6763,9 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fit_content_height_enabled", "enabled"), &TextEdit::set_fit_content_height_enabled); ClassDB::bind_method(D_METHOD("is_fit_content_height_enabled"), &TextEdit::is_fit_content_height_enabled); + ClassDB::bind_method(D_METHOD("set_fit_content_width_enabled", "enabled"), &TextEdit::set_fit_content_width_enabled); + ClassDB::bind_method(D_METHOD("is_fit_content_width_enabled"), &TextEdit::is_fit_content_width_enabled); + ClassDB::bind_method(D_METHOD("get_scroll_pos_for_line", "line", "wrap_index"), &TextEdit::get_scroll_pos_for_line, DEFVAL(0)); // Visible lines. @@ -6872,6 +6890,7 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scroll_vertical", PROPERTY_HINT_NONE, "suffix:lines"), "set_v_scroll", "get_v_scroll"); ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal", PROPERTY_HINT_NONE, "suffix:px"), "set_h_scroll", "get_h_scroll"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_fit_content_height"), "set_fit_content_height_enabled", "is_fit_content_height_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_fit_content_width"), "set_fit_content_width_enabled", "is_fit_content_width_enabled"); ADD_GROUP("Minimap", "minimap_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "minimap_draw"), "set_draw_minimap", "is_drawing_minimap"); @@ -7859,8 +7878,8 @@ void TextEdit::_update_scrollbars() { total_width += minimap_width; } - content_height_cache = MAX(total_rows, 1) * get_line_height(); - if (fit_content_height) { + content_size_cache = Vector2i(total_width + 10, MAX(total_rows, 1) * get_line_height()); + if (fit_content_height || fit_content_width) { update_minimum_size(); } @@ -8067,7 +8086,7 @@ void TextEdit::_update_minimap_hover() { const Point2 mp = get_local_mouse_pos(); const int xmargin_end = get_size().width - theme_cache.style_normal->get_margin(SIDE_RIGHT); - const bool hovering_sidebar = mp.x > xmargin_end - minimap_width && mp.x < xmargin_end; + bool hovering_sidebar = mp.x > xmargin_end - minimap_width && mp.x < xmargin_end; if (!hovering_sidebar) { if (hovering_minimap) { // Only redraw if the hovering status changed. @@ -8081,7 +8100,7 @@ void TextEdit::_update_minimap_hover() { const int row = get_minimap_line_at_pos(mp); - const bool new_hovering_minimap = row >= get_first_visible_line() && row <= get_last_full_visible_line(); + bool new_hovering_minimap = row >= get_first_visible_line() && row <= get_last_full_visible_line(); if (new_hovering_minimap != hovering_minimap) { // Only redraw if the hovering status changed. hovering_minimap = new_hovering_minimap; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index c8cd7b0e4d5..1f2fd6619a3 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -505,8 +505,9 @@ private: HScrollBar *h_scroll = nullptr; VScrollBar *v_scroll = nullptr; - float content_height_cache = 0.0; + Vector2i content_size_cache; bool fit_content_height = false; + bool fit_content_width = false; bool scroll_past_end_of_file_enabled = false; // Smooth scrolling. @@ -734,7 +735,7 @@ public: void cancel_ime(); void apply_ime(); - void set_editable(const bool p_editable); + void set_editable(bool p_editable); bool is_editable() const; void set_text_direction(TextDirection p_text_direction); @@ -755,7 +756,7 @@ public: bool is_indent_wrapped_lines() const; // User controls - void set_overtype_mode_enabled(const bool p_enabled); + void set_overtype_mode_enabled(bool p_enabled); bool is_overtype_mode_enabled() const; void set_context_menu_enabled(bool p_enabled); @@ -862,7 +863,7 @@ public: void set_caret_type(CaretType p_type); CaretType get_caret_type() const; - void set_caret_blink_enabled(const bool p_enabled); + void set_caret_blink_enabled(bool p_enabled); bool is_caret_blink_enabled() const; void set_caret_blink_interval(const float p_interval); @@ -871,10 +872,10 @@ public: void set_draw_caret_when_editable_disabled(bool p_enable); bool is_drawing_caret_when_editable_disabled() const; - void set_move_caret_on_right_click_enabled(const bool p_enabled); + void set_move_caret_on_right_click_enabled(bool p_enabled); bool is_move_caret_on_right_click_enabled() const; - void set_caret_mid_grapheme_enabled(const bool p_enabled); + void set_caret_mid_grapheme_enabled(bool p_enabled); bool is_caret_mid_grapheme_enabled() const; void set_multiple_carets_enabled(bool p_enabled); @@ -910,13 +911,13 @@ public: String get_word_under_caret(int p_caret = -1) const; /* Selection. */ - void set_selecting_enabled(const bool p_enabled); + void set_selecting_enabled(bool p_enabled); bool is_selecting_enabled() const; - void set_deselect_on_focus_loss_enabled(const bool p_enabled); + void set_deselect_on_focus_loss_enabled(bool p_enabled); bool is_deselect_on_focus_loss_enabled() const; - void set_drag_and_drop_selection_enabled(const bool p_enabled); + void set_drag_and_drop_selection_enabled(bool p_enabled); bool is_drag_and_drop_selection_enabled() const; void set_selection_mode(SelectionMode p_mode); @@ -965,10 +966,10 @@ public: /* Viewport. */ // Scrolling. - void set_smooth_scroll_enabled(const bool p_enabled); + void set_smooth_scroll_enabled(bool p_enabled); bool is_smooth_scroll_enabled() const; - void set_scroll_past_end_of_file_enabled(const bool p_enabled); + void set_scroll_past_end_of_file_enabled(bool p_enabled); bool is_scroll_past_end_of_file_enabled() const; VScrollBar *get_v_scroll_bar() const; @@ -983,9 +984,12 @@ public: void set_v_scroll_speed(float p_speed); float get_v_scroll_speed() const; - void set_fit_content_height_enabled(const bool p_enabled); + void set_fit_content_height_enabled(bool p_enabled); bool is_fit_content_height_enabled() const; + void set_fit_content_width_enabled(bool p_enabled); + bool is_fit_content_width_enabled() const; + double get_scroll_pos_for_line(int p_line, int p_wrap_index = 0) const; // Visible lines. @@ -1071,7 +1075,7 @@ public: void set_highlight_current_line(bool p_enabled); bool is_highlight_current_line_enabled() const; - void set_highlight_all_occurrences(const bool p_enabled); + void set_highlight_all_occurrences(bool p_enabled); bool is_highlight_all_occurrences_enabled() const; void set_draw_control_chars(bool p_enabled);