From 018008ce81036fe7fffd2734b35a6588560d64a6 Mon Sep 17 00:00:00 2001 From: PouleyKetchoupp Date: Mon, 15 Feb 2021 10:47:38 -0700 Subject: [PATCH] TextEdit respects content margin from StyleBox Backport from PR #45858 on master. --- scene/gui/text_edit.cpp | 84 +++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 5ede5fbd070..bc70755b4dd 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1052,6 +1052,16 @@ void TextEdit::_notification(int p_what) { } } + int top_limit_y = 0; + int bottom_limit_y = get_size().height; + if (readonly) { + top_limit_y += cache.style_readonly->get_margin(MARGIN_BOTTOM); + bottom_limit_y -= cache.style_readonly->get_margin(MARGIN_BOTTOM); + } else { + top_limit_y += cache.style_normal->get_margin(MARGIN_TOP); + bottom_limit_y -= cache.style_normal->get_margin(MARGIN_TOP); + } + // draw main text int line = first_visible_line; for (int i = 0; i < draw_amount; i++) { @@ -1106,17 +1116,33 @@ void TextEdit::_notification(int p_what) { char_margin += indent_px; int char_ofs = 0; - int ofs_readonly = 0; int ofs_x = 0; + int ofs_y = 0; if (readonly) { - ofs_readonly = cache.style_readonly->get_offset().y / 2; ofs_x = cache.style_readonly->get_offset().x / 2; + ofs_x -= cache.style_normal->get_offset().x / 2; + ofs_y = cache.style_readonly->get_offset().y / 2; + } else { + ofs_y = cache.style_normal->get_offset().y / 2; } - int ofs_y = (i * get_row_height() + cache.line_spacing / 2) + ofs_readonly; + ofs_y += (i * get_row_height() + cache.line_spacing / 2); ofs_y -= cursor.wrap_ofs * get_row_height(); ofs_y -= get_v_scroll_offset() * get_row_height(); + bool clipped = false; + if (ofs_y + get_row_height() < top_limit_y) { + // Line is outside the top margin, clip current line. + // Still need to go through the process to prepare color changes for next lines. + clipped = true; + } + + if (ofs_y > bottom_limit_y) { + // Line is outside the bottom margin, clip any remaining text. + i = draw_amount; + break; + } + // Check if line contains highlighted word. int highlighted_text_col = -1; int search_text_col = -1; @@ -1316,7 +1342,7 @@ void TextEdit::_notification(int p_what) { // Current line highlighting. bool in_selection = (selection.active && line >= selection.from_line && line <= selection.to_line && (line > selection.from_line || last_wrap_column + j >= selection.from_column) && (line < selection.to_line || last_wrap_column + j < selection.to_column)); - if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) { + if (!clipped && line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) { // Draw the wrap indent offset highlight. if (line_wrap_index != 0 && j == 0) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + ofs_x - indent_px, ofs_y, indent_px, get_row_height()), cache.current_line_color); @@ -1331,11 +1357,11 @@ void TextEdit::_notification(int p_what) { } } - if (in_selection) { + if (!clipped && in_selection) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + ofs_x, ofs_y), Size2i(char_w, get_row_height())), cache.selection_color); } - if (in_search_result) { + if (!clipped && in_search_result) { Color border_color = (line == search_result_line && j >= search_result_col && j < search_result_col + search_text.length()) ? cache.font_color : cache.search_result_border_color; VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + ofs_x, ofs_y), Size2i(char_w, 1)), border_color); @@ -1347,7 +1373,7 @@ void TextEdit::_notification(int p_what) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + char_w + ofs_x - 1, ofs_y), Size2i(1, get_row_height())), border_color); } - if (highlight_all_occurrences && !only_whitespaces_highlighted) { + if (!clipped && highlight_all_occurrences && !only_whitespaces_highlighted) { if (highlighted_text_col != -1) { // If we are at the end check for new word on same line. @@ -1394,7 +1420,7 @@ void TextEdit::_notification(int p_what) { } } - if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index) { + if (!clipped && cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index) { is_cursor_visible = true; cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y); @@ -1454,31 +1480,33 @@ void TextEdit::_notification(int p_what) { } } - if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index && block_caret && draw_caret && !insert_mode) { - color = cache.caret_background_color; - } else if (!syntax_coloring && block_caret) { - color = readonly ? cache.font_color_readonly : cache.font_color; - } + if (!clipped) { + if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index && block_caret && draw_caret && !insert_mode) { + color = cache.caret_background_color; + } else if (!syntax_coloring && block_caret) { + color = readonly ? cache.font_color_readonly : cache.font_color; + } - if (str[j] >= 32) { - int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2; - int w = drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), str[j], str[j + 1], in_selection && override_selected_font_color ? cache.font_color_selected : color); - if (underlined) { - float line_width = 1.0; + if (str[j] >= 32) { + int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2; + int w = drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), str[j], str[j + 1], in_selection && override_selected_font_color ? cache.font_color_selected : color); + if (underlined) { + float line_width = 1.0; #ifdef TOOLS_ENABLED - line_width *= EDSCALE; + line_width *= EDSCALE; #endif - draw_rect(Rect2(char_ofs + char_margin + ofs_x, yofs + ascent + 2, w, line_width), in_selection && override_selected_font_color ? cache.font_color_selected : color); + draw_rect(Rect2(char_ofs + char_margin + ofs_x, yofs + ascent + 2, w, line_width), in_selection && override_selected_font_color ? cache.font_color_selected : color); + } + } else if (draw_tabs && str[j] == '\t') { + int yofs = (get_row_height() - cache.tab_icon->get_height()) / 2; + cache.tab_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_color_selected : color); } - } else if (draw_tabs && str[j] == '\t') { - int yofs = (get_row_height() - cache.tab_icon->get_height()) / 2; - cache.tab_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_color_selected : color); - } - if (draw_spaces && str[j] == ' ') { - int yofs = (get_row_height() - cache.space_icon->get_height()) / 2; - cache.space_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_color_selected : color); + if (draw_spaces && str[j] == ' ') { + int yofs = (get_row_height() - cache.space_icon->get_height()) / 2; + cache.space_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_color_selected : color); + } } char_ofs += char_w; @@ -1492,7 +1520,7 @@ void TextEdit::_notification(int p_what) { } } - if (cursor.column == (last_wrap_column + j) && cursor.line == line && cursor_wrap_index == line_wrap_index && (char_ofs + char_margin) >= xmargin_beg) { + if (!clipped && cursor.column == (last_wrap_column + j) && cursor.line == line && cursor_wrap_index == line_wrap_index && (char_ofs + char_margin) >= xmargin_beg) { is_cursor_visible = true; cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y);