diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 9fada9db35eb..e3c76bf716f6 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -1274,7 +1274,6 @@
Set the type of caret to draw.
-
If [code]true[/code], a right-click displays the context menu.
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index c3287035ffce..8661e3d47dd9 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -55,15 +55,16 @@ void CodeEdit::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
- RID ci = get_canvas_item();
+ RID ci = _get_text_canvas_item();
const Size2 size = get_size();
const bool caret_visible = is_caret_visible();
const bool rtl = is_layout_rtl();
const int row_height = get_line_height();
if (line_length_guideline_columns.size() > 0) {
+ HScrollBar *v_scroll_bar = get_v_scroll_bar();
const int xmargin_beg = theme_cache.style_normal->get_margin(SIDE_LEFT) + get_total_gutter_width();
- const int xmargin_end = size.width - theme_cache.style_normal->get_margin(SIDE_RIGHT) - (is_drawing_minimap() ? get_minimap_width() : 0);
+ const int xmargin_end = size.width - theme_cache.style_normal->get_margin(SIDE_RIGHT) - (is_drawing_minimap() ? get_minimap_width() : 0) - (v_scroll_bar->is_visible_in_tree() ? v_scroll_bar->get_combined_minimum_size().width : 0);
const float char_size = theme_cache.font->get_char_size('0', theme_cache.font_size).width;
for (int i = 0; i < line_length_guideline_columns.size(); i++) {
@@ -108,7 +109,7 @@ void CodeEdit::_notification(int p_what) {
hint_ofs.y -= (code_hint_minsize.y + row_height) - theme_cache.line_spacing;
}
- draw_style_box(theme_cache.code_hint_style, Rect2(hint_ofs, code_hint_minsize));
+ theme_cache.code_hint_style->draw(ci, Rect2(hint_ofs, code_hint_minsize));
int yofs = 0;
for (int i = 0; i < line_count; i++) {
@@ -123,17 +124,17 @@ void CodeEdit::_notification(int p_what) {
Point2 round_ofs = hint_ofs + theme_cache.code_hint_style->get_offset() + Vector2(0, theme_cache.font->get_ascent(theme_cache.font_size) + font_height * i + yofs);
round_ofs = round_ofs.round();
- draw_string(theme_cache.font, round_ofs, line.replace(String::chr(0xFFFF), ""), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size, theme_cache.code_hint_color);
+ theme_cache.font->draw_string(ci, round_ofs, line.replace(String::chr(0xFFFF), ""), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size, theme_cache.code_hint_color);
if (end > 0) {
// Draw an underline for the currently edited function parameter.
const Vector2 b = hint_ofs + theme_cache.code_hint_style->get_offset() + Vector2(begin, font_height + font_height * i + yofs);
- draw_line(b, b + Vector2(end - begin, 0), theme_cache.code_hint_color, 2);
+ RenderingServer::get_singleton()->canvas_item_add_line(ci, b, b + Vector2(end - begin, 0), theme_cache.code_hint_color, 2);
// Draw a translucent text highlight as well.
const Rect2 highlight_rect = Rect2(
b - Vector2(0, font_height),
Vector2(end - begin, font_height));
- draw_rect(highlight_rect, theme_cache.code_hint_color * Color(1, 1, 1, 0.2));
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, highlight_rect, theme_cache.code_hint_color * Color(1, 1, 1, 0.2));
}
yofs += theme_cache.line_spacing;
}
@@ -182,7 +183,7 @@ void CodeEdit::_notification(int p_what) {
code_completion_rect.position.x = caret_pos.x - code_completion_base_width;
}
- draw_style_box(theme_cache.code_completion_style, Rect2(code_completion_rect.position - theme_cache.code_completion_style->get_offset(), code_completion_rect.size + theme_cache.code_completion_style->get_minimum_size() + Size2(scroll_width, 0)));
+ theme_cache.code_completion_style->draw(ci, Rect2(code_completion_rect.position - theme_cache.code_completion_style->get_offset(), code_completion_rect.size + theme_cache.code_completion_style->get_minimum_size() + Size2(scroll_width, 0)));
if (theme_cache.code_completion_background_color.a > 0.01) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(code_completion_rect.position, code_completion_rect.size + Size2(scroll_width, 0)), theme_cache.code_completion_background_color);
}
@@ -216,7 +217,7 @@ void CodeEdit::_notification(int p_what) {
tl->set_width(code_completion_rect.size.width - (icon_area_size.x + theme_cache.code_completion_icon_separation));
if (rtl) {
if (code_completion_options[l].default_value.get_type() == Variant::COLOR) {
- draw_rect(Rect2(Point2(code_completion_rect.position.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value);
}
tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
} else {
@@ -224,10 +225,10 @@ void CodeEdit::_notification(int p_what) {
const Color color = code_completion_options[l].default_value;
const Rect2 rect = Rect2(Point2(code_completion_rect.position.x + code_completion_rect.size.width - icon_area_size.x, icon_area.position.y), icon_area_size);
if (color.a < 1.0) {
- draw_texture_rect(theme_cache.completion_color_bg, rect, true);
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect(ci, rect, theme_cache.completion_color_bg->get_rid(), true);
}
- draw_rect(rect, color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, color);
}
tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
}
@@ -239,7 +240,7 @@ void CodeEdit::_notification(int p_what) {
int match_offset = theme_cache.font->get_string_size(code_completion_options[l].display.substr(0, match_segment.first), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).width;
int match_len = theme_cache.font->get_string_size(code_completion_options[l].display.substr(match_segment.first, match_segment.second), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).width;
- draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), theme_cache.code_completion_existing_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), theme_cache.code_completion_existing_color);
}
tl->draw(ci, title_pos, code_completion_options[l].font_color);
}
@@ -250,7 +251,7 @@ void CodeEdit::_notification(int p_what) {
float r = (float)theme_cache.code_completion_max_lines / code_completion_options_count;
float o = (float)code_completion_line_ofs / code_completion_options_count;
- draw_rect(Rect2(code_completion_rect.position.x + code_completion_rect.size.width, code_completion_rect.position.y + o * code_completion_rect.size.y, scroll_width, code_completion_rect.size.y * r), scroll_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(code_completion_rect.position.x + code_completion_rect.size.width, code_completion_rect.position.y + o * code_completion_rect.size.y, scroll_width, code_completion_rect.size.y * r), scroll_color);
}
}
}
@@ -1298,6 +1299,7 @@ bool CodeEdit::is_drawing_executing_lines_gutter() const {
void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) {
bool hovering = get_hovered_gutter() == Vector2i(main_gutter, p_line);
+ RID ci = _get_text_canvas_item();
if (draw_breakpoints && theme_cache.breakpoint_icon.is_valid()) {
bool breakpointed = is_line_breakpointed(p_line);
bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT);
@@ -1312,7 +1314,7 @@ void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2
Rect2 icon_region = p_region;
icon_region.position += Point2(padding, padding);
icon_region.size -= Point2(padding, padding) * 2;
- theme_cache.breakpoint_icon->draw_rect(get_canvas_item(), icon_region, false, use_color);
+ theme_cache.breakpoint_icon->draw_rect(ci, icon_region, false, use_color);
}
}
@@ -1331,7 +1333,7 @@ void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2
Rect2 icon_region = p_region;
icon_region.position += Point2(horizontal_padding, 0);
icon_region.size -= Point2(horizontal_padding * 1.1, vertical_padding);
- theme_cache.bookmark_icon->draw_rect(get_canvas_item(), icon_region, false, use_color);
+ theme_cache.bookmark_icon->draw_rect(ci, icon_region, false, use_color);
}
}
@@ -1342,7 +1344,7 @@ void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2
Rect2 icon_region = p_region;
icon_region.position += Point2(horizontal_padding, vertical_padding);
icon_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
- theme_cache.executing_line_icon->draw_rect(get_canvas_item(), icon_region, false, theme_cache.executing_line_color);
+ theme_cache.executing_line_icon->draw_rect(ci, icon_region, false, theme_cache.executing_line_color);
}
}
@@ -1503,7 +1505,7 @@ void CodeEdit::_line_number_draw_callback(int p_line, int p_gutter, const Rect2
number_color = theme_cache.line_number_color;
}
- TS->shaped_text_draw(text_rid, get_canvas_item(), ofs, -1, -1, number_color);
+ TS->shaped_text_draw(text_rid, _get_text_canvas_item(), ofs, -1, -1, number_color);
}
void CodeEdit::_clear_line_number_text_cache() {
@@ -1532,6 +1534,7 @@ void CodeEdit::_fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_regi
return;
}
set_line_gutter_clickable(p_line, fold_gutter, true);
+ RID ci = _get_text_canvas_item();
int horizontal_padding = p_region.size.x / 10;
int vertical_padding = p_region.size.y / 6;
@@ -1545,17 +1548,17 @@ void CodeEdit::_fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_regi
Color region_icon_color = theme_cache.folded_code_region_color;
region_icon_color.a = MAX(region_icon_color.a, 0.4f);
if (can_fold) {
- theme_cache.can_fold_code_region_icon->draw_rect(get_canvas_item(), p_region, false, region_icon_color);
+ theme_cache.can_fold_code_region_icon->draw_rect(ci, p_region, false, region_icon_color);
} else {
- theme_cache.folded_code_region_icon->draw_rect(get_canvas_item(), p_region, false, region_icon_color);
+ theme_cache.folded_code_region_icon->draw_rect(ci, p_region, false, region_icon_color);
}
return;
}
if (can_fold) {
- theme_cache.can_fold_icon->draw_rect(get_canvas_item(), p_region, false, theme_cache.code_folding_color);
+ theme_cache.can_fold_icon->draw_rect(ci, p_region, false, theme_cache.code_folding_color);
return;
}
- theme_cache.folded_icon->draw_rect(get_canvas_item(), p_region, false, theme_cache.code_folding_color);
+ theme_cache.folded_icon->draw_rect(ci, p_region, false, theme_cache.code_folding_color);
}
/* Line Folding */
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 687ca4d4d423..d67eb50f9233 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -605,6 +605,10 @@ void TextEdit::_notification(int p_what) {
first_draw = false;
}
+ RID ci = get_canvas_item();
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ style->draw(ci, Rect2(Point2(), get_size()));
+
/* Prevent the resource getting lost between the editor and game. */
if (Engine::get_singleton()->is_editor_hint()) {
if (syntax_highlighter.is_valid() && syntax_highlighter->get_text_edit() != this) {
@@ -620,27 +624,29 @@ void TextEdit::_notification(int p_what) {
_update_scrollbars();
- RID ci = get_canvas_item();
- int xmargin_beg = theme_cache.style_normal->get_margin(SIDE_LEFT) + gutters_width + gutter_padding;
-
- int xmargin_end = size.width - theme_cache.style_normal->get_margin(SIDE_RIGHT);
- if (draw_minimap) {
- xmargin_end -= minimap_width;
+ if (v_scroll->is_visible_in_tree()) {
+ size.width -= v_scroll->get_combined_minimum_size().width;
+ }
+ if (h_scroll->is_visible_in_tree()) {
+ size.height -= h_scroll->get_combined_minimum_size().height;
}
- // Let's do it easy for now.
- theme_cache.style_normal->draw(ci, Rect2(Point2(), size));
+
+ RenderingServer::get_singleton()->canvas_item_clear(text_ci);
+ RenderingServer::get_singleton()->canvas_item_set_custom_rect(text_ci, !is_visibility_clip_disabled(), Rect2(style->get_offset(), size - style->get_minimum_size()));
+ RenderingServer::get_singleton()->canvas_item_set_clip(text_ci, true);
+ RenderingServer::get_singleton()->canvas_item_set_visibility_layer(text_ci, get_visibility_layer());
+
+ int xmargin_beg = style->get_margin(SIDE_LEFT) + gutters_width + gutter_padding;
+ int xmargin_end = size.width - style->get_margin(SIDE_RIGHT);
+
if (!editable) {
- theme_cache.style_readonly->draw(ci, Rect2(Point2(), size));
draw_caret = is_drawing_caret_when_editable_disabled();
}
- if (has_focus()) {
- theme_cache.style_focus->draw(ci, Rect2(Point2(), size));
- }
int visible_rows = get_visible_line_count() + 1;
if (theme_cache.background_color.a > 0.01) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(), get_size()), theme_cache.background_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(Point2i(), get_size()), theme_cache.background_color);
}
Vector brace_matching;
@@ -809,11 +815,12 @@ void TextEdit::_notification(int p_what) {
}
int first_vis_line = get_first_visible_line() - 1;
- int draw_amount = visible_rows + (smooth_scroll_enabled ? 1 : 0);
+ int draw_amount = visible_rows + Math::ceil(_get_v_scroll_offset());
draw_amount += draw_placeholder ? placeholder_wraped_rows.size() - 1 : get_line_wrap_count(first_vis_line + 1);
// Draw minimap.
if (draw_minimap) {
+ xmargin_end -= minimap_width;
int minimap_visible_lines = get_minimap_visible_lines();
int minimap_line_height = (minimap_char_size.y + minimap_line_spacing);
int tab_size = text.get_tab_size();
@@ -822,13 +829,14 @@ void TextEdit::_notification(int p_what) {
int viewport_height = (draw_amount - 1) * minimap_line_height;
int control_height = _get_control_height() - viewport_height;
int viewport_offset_y = round(get_scroll_pos_for_line(first_vis_line + 1) * control_height) / ((v_scroll->get_max() <= minimap_visible_lines) ? (minimap_visible_lines - draw_amount) : (v_scroll->get_max() - draw_amount));
+ viewport_offset_y += style->get_margin(SIDE_TOP);
// Calculate the first line.
int num_lines_before = round((viewport_offset_y) / minimap_line_height);
int minimap_line = (v_scroll->get_max() <= minimap_visible_lines) ? -1 : first_vis_line;
if (minimap_line >= 0) {
minimap_line -= get_next_visible_line_index_offset_from(first_vis_line, 0, -num_lines_before).x;
- minimap_line -= (minimap_line > 0 && smooth_scroll_enabled ? 1 : 0);
+ minimap_line -= (minimap_line > 0 && Math::ceil(_get_v_scroll_offset()) > 0 ? 1 : 0);
}
int minimap_draw_amount = minimap_visible_lines + get_line_wrap_count(minimap_line + 1);
@@ -845,9 +853,9 @@ void TextEdit::_notification(int p_what) {
}
if (rtl) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, viewport_offset_y, minimap_width, viewport_height), viewport_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - xmargin_end - minimap_width, viewport_offset_y, minimap_width, viewport_height), viewport_color);
} else {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), viewport_offset_y, minimap_width, viewport_height), viewport_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(xmargin_end, viewport_offset_y, minimap_width, viewport_height), viewport_color);
}
for (int i = 0; i < minimap_draw_amount; i++) {
@@ -906,22 +914,22 @@ void TextEdit::_notification(int p_what) {
if (highlight_current_line && highlighted_lines.has(Pair(minimap_line, line_wrap_index))) {
if (rtl) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, i * 3, minimap_width, 2), theme_cache.current_line_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - xmargin_end - minimap_width, (i * minimap_line_height) + style->get_margin(SIDE_TOP), minimap_width, minimap_char_size.y), theme_cache.current_line_color);
} else {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), theme_cache.current_line_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(xmargin_end, (i * minimap_line_height) + style->get_margin(SIDE_TOP), minimap_width, minimap_char_size.y), theme_cache.current_line_color);
}
} else if (line_background_color.a > 0) {
if (rtl) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, i * 3, minimap_width, 2), line_background_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - xmargin_end - minimap_width, (i * minimap_line_height) + style->get_margin(SIDE_TOP), minimap_width, minimap_char_size.y), line_background_color);
} else {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), line_background_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(xmargin_end, (i * minimap_line_height) + style->get_margin(SIDE_TOP), minimap_width, minimap_char_size.y), line_background_color);
}
}
Color next_color = current_color;
int characters = 0;
int tab_alignment = 0;
- int xpos = xmargin_end + 2 + indent_px;
+ int xpos = xmargin_end + indent_px;
for (int j = 0; j < str.length(); j++) {
bool next_is_whitespace = false;
bool next_is_tab = false;
@@ -964,9 +972,9 @@ void TextEdit::_notification(int p_what) {
if (characters > 0) {
if (rtl) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(size.width - xpos - minimap_char_size.x * characters, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(Point2(size.width - xpos - minimap_char_size.x * characters, (minimap_line_height * i) + style->get_margin(SIDE_TOP)), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color);
} else {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(xpos, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(text_ci, Rect2(Point2(xpos, (minimap_line_height * i) + style->get_margin(SIDE_TOP)), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color);
}
}
@@ -995,15 +1003,8 @@ void TextEdit::_notification(int p_what) {
}
}
- int top_limit_y = 0;
- int bottom_limit_y = get_size().height;
- if (!editable) {
- top_limit_y += theme_cache.style_readonly->get_margin(SIDE_TOP);
- bottom_limit_y -= theme_cache.style_readonly->get_margin(SIDE_BOTTOM);
- } else {
- top_limit_y += theme_cache.style_normal->get_margin(SIDE_TOP);
- bottom_limit_y -= theme_cache.style_normal->get_margin(SIDE_BOTTOM);
- }
+ int top_limit_y = style->get_margin(SIDE_TOP);
+ int bottom_limit_y = get_size().height - style->get_margin(SIDE_BOTTOM);
// Draw main text.
line_drawing_cache.clear();
@@ -1053,17 +1054,8 @@ void TextEdit::_notification(int p_what) {
const String &str = wrap_rows[line_wrap_index];
int char_margin = xmargin_beg - first_visible_col;
- int ofs_x = 0;
- int ofs_y = 0;
- if (!editable) {
- ofs_x = theme_cache.style_readonly->get_offset().x / 2;
- ofs_x -= theme_cache.style_normal->get_offset().x / 2;
- ofs_y = theme_cache.style_readonly->get_offset().y / 2;
- } else {
- ofs_y = theme_cache.style_normal->get_offset().y / 2;
- }
-
- ofs_y += i * row_height + theme_cache.line_spacing / 2;
+ int ofs_y = style->get_margin(SIDE_TOP);
+ ofs_y += i * row_height;
ofs_y -= first_visible_line_wrap_ofs * row_height;
ofs_y -= _get_v_scroll_offset() * row_height;
@@ -1082,18 +1074,18 @@ void TextEdit::_notification(int p_what) {
if (text.get_line_background_color(line).a > 0.0) {
if (rtl) {
- RS::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line));
+ RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line));
} else {
- RS::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line));
+ RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(xmargin_beg, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line));
}
}
// Draw current line highlight.
if (highlight_current_line && highlighted_lines.has(Pair(line, line_wrap_index))) {
if (rtl) {
- RS::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), theme_cache.current_line_color);
} else {
- RS::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(xmargin_beg, ofs_y, xmargin_end - xmargin_beg, row_height), theme_cache.current_line_color);
}
}
@@ -1102,7 +1094,7 @@ void TextEdit::_notification(int p_what) {
cache_entry.y_offset = ofs_y;
- int gutter_offset = theme_cache.style_normal->get_margin(SIDE_LEFT);
+ int gutter_offset = style->get_margin(SIDE_LEFT);
for (int g = 0; g < gutters.size(); g++) {
const GutterInfo &gutter = gutters[g];
@@ -1123,9 +1115,9 @@ void TextEdit::_notification(int p_what) {
int yofs = ofs_y + (row_height - tl->get_size().y) / 2;
if (theme_cache.outline_size > 0 && theme_cache.outline_color.a > 0) {
- tl->draw_outline(ci, Point2(gutter_offset + ofs_x, yofs), theme_cache.outline_size, theme_cache.outline_color);
+ tl->draw_outline(text_ci, Point2(gutter_offset, yofs), theme_cache.outline_size, theme_cache.outline_color);
}
- tl->draw(ci, Point2(gutter_offset + ofs_x, yofs), get_line_gutter_item_color(line, g));
+ tl->draw(text_ci, Point2(gutter_offset, yofs), get_line_gutter_item_color(line, g));
} break;
case GUTTER_TYPE_ICON: {
const Ref icon = get_line_gutter_icon(line, g);
@@ -1153,7 +1145,7 @@ void TextEdit::_notification(int p_what) {
gutter_rect.position.x = size.width - gutter_rect.position.x - gutter_rect.size.x;
}
- icon->draw_rect(ci, gutter_rect, false, get_line_gutter_item_color(line, g));
+ icon->draw_rect(text_ci, gutter_rect, false, get_line_gutter_item_color(line, g));
} break;
case GUTTER_TYPE_CUSTOM: {
if (gutter.custom_draw_callback.is_valid()) {
@@ -1200,7 +1192,7 @@ void TextEdit::_notification(int p_what) {
}
for (int j = 0; j < sel.size(); j++) {
- Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, Math::ceil(sel[j].y) - sel[j].x, row_height);
+ Rect2 rect = Rect2(sel[j].x + char_margin, ofs_y, Math::ceil(sel[j].y) - sel[j].x, row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
continue;
}
@@ -1211,7 +1203,7 @@ void TextEdit::_notification(int p_what) {
if (rect.position.x + rect.size.x > xmargin_end) {
rect.size.x = xmargin_end - rect.position.x;
}
- RS::get_singleton()->canvas_item_add_rect(ci, rect, theme_cache.selection_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.selection_color);
}
}
}
@@ -1223,7 +1215,7 @@ void TextEdit::_notification(int p_what) {
while (search_text_col != -1) {
const Vector sel = TS->shaped_text_get_selection(rid, search_text_col + start, search_text_col + search_text_len + start);
for (int j = 0; j < sel.size(); j++) {
- Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, row_height);
+ Rect2 rect = Rect2(sel[j].x + char_margin, ofs_y, sel[j].y - sel[j].x, row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
continue;
}
@@ -1233,7 +1225,7 @@ void TextEdit::_notification(int p_what) {
} else if (rect.position.x + rect.size.x > xmargin_end) {
rect.size.x = xmargin_end - rect.position.x;
}
- RS::get_singleton()->canvas_item_add_rect(ci, rect, theme_cache.search_result_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.search_result_color);
draw_rect(rect, theme_cache.search_result_border_color, false);
}
@@ -1247,7 +1239,7 @@ void TextEdit::_notification(int p_what) {
while (highlighted_text_col != -1) {
const Vector sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text_len + start);
for (int j = 0; j < sel.size(); j++) {
- Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, row_height);
+ Rect2 rect = Rect2(sel[j].x + char_margin, ofs_y, sel[j].y - sel[j].x, row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
continue;
}
@@ -1257,7 +1249,7 @@ void TextEdit::_notification(int p_what) {
} else if (rect.position.x + rect.size.x > xmargin_end) {
rect.size.x = xmargin_end - rect.position.x;
}
- RS::get_singleton()->canvas_item_add_rect(ci, rect, theme_cache.word_highlighted_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.word_highlighted_color);
}
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_text_col + highlighted_text_len);
@@ -1272,7 +1264,7 @@ void TextEdit::_notification(int p_what) {
while (lookup_symbol_word_col != -1) {
const Vector sel = TS->shaped_text_get_selection(rid, lookup_symbol_word_col + start, lookup_symbol_word_col + lookup_symbol_word_len + start);
for (int j = 0; j < sel.size(); j++) {
- Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y + (theme_cache.line_spacing / 2), sel[j].y - sel[j].x, row_height);
+ Rect2 rect = Rect2(sel[j].x + char_margin, ofs_y + (theme_cache.line_spacing / 2), sel[j].y - sel[j].x, row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
continue;
}
@@ -1284,7 +1276,7 @@ void TextEdit::_notification(int p_what) {
}
rect.position.y += ceil(TS->shaped_text_get_ascent(rid)) + ceil(theme_cache.font->get_underline_position(theme_cache.font_size));
rect.size.y = MAX(1, theme_cache.font->get_underline_thickness(theme_cache.font_size));
- RS::get_singleton()->canvas_item_add_rect(ci, rect, highlight_underline_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, rect, highlight_underline_color);
}
lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, lookup_symbol_word_col + lookup_symbol_word_len);
@@ -1308,7 +1300,7 @@ void TextEdit::_notification(int p_what) {
for (int k = 0; k < glyphs[j].repeat; k++) {
if ((char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) {
if (glyphs[j].font_rid != RID()) {
- TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, theme_cache.outline_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, theme_cache.outline_color);
+ TS->font_draw_glyph_outline(glyphs[j].font_rid, text_ci, glyphs[j].font_size, theme_cache.outline_size, Vector2(char_margin + char_ofs + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, theme_cache.outline_color);
}
}
char_ofs += glyphs[j].advance;
@@ -1343,7 +1335,7 @@ void TextEdit::_notification(int p_what) {
}
}
- float char_pos = char_ofs + char_margin + ofs_x;
+ float char_pos = char_ofs + char_margin;
if (char_pos >= xmargin_beg) {
if (highlight_matching_braces_enabled) {
for (int c = 0; c < get_caret_count(); c++) {
@@ -1354,7 +1346,7 @@ void TextEdit::_notification(int p_what) {
gl_color = _get_brace_mismatch_color();
}
Rect2 rect = Rect2(char_pos, ofs_y + theme_cache.font->get_underline_position(theme_cache.font_size), glyphs[j].advance * glyphs[j].repeat, MAX(theme_cache.font->get_underline_thickness(theme_cache.font_size) * theme_cache.base_scale, 1));
- RS::get_singleton()->canvas_item_add_rect(ci, rect, gl_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, rect, gl_color);
}
if ((brace_match.close_match_line == line && brace_match.close_match_column == glyphs[j].start) ||
@@ -1363,18 +1355,18 @@ void TextEdit::_notification(int p_what) {
gl_color = _get_brace_mismatch_color();
}
Rect2 rect = Rect2(char_pos, ofs_y + theme_cache.font->get_underline_position(theme_cache.font_size), glyphs[j].advance * glyphs[j].repeat, MAX(theme_cache.font->get_underline_thickness(theme_cache.font_size) * theme_cache.base_scale, 1));
- RS::get_singleton()->canvas_item_add_rect(ci, rect, gl_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, rect, gl_color);
}
}
}
if (draw_tabs && ((glyphs[j].flags & TextServer::GRAPHEME_IS_TAB) == TextServer::GRAPHEME_IS_TAB)) {
int yofs = (text_height - theme_cache.tab_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
- theme_cache.tab_icon->draw(ci, Point2(char_pos, ofs_y + yofs), gl_color);
+ theme_cache.tab_icon->draw(text_ci, Point2(char_pos, ofs_y + yofs), gl_color);
} else if (draw_spaces && ((glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE) && ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL)) {
int yofs = (text_height - theme_cache.space_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
int xofs = (glyphs[j].advance * glyphs[j].repeat - theme_cache.space_icon->get_width()) / 2;
- theme_cache.space_icon->draw(ci, Point2(char_pos + xofs, ofs_y + yofs), gl_color);
+ theme_cache.space_icon->draw(text_ci, Point2(char_pos + xofs, ofs_y + yofs), gl_color);
}
}
@@ -1382,10 +1374,10 @@ void TextEdit::_notification(int p_what) {
for (int k = 0; k < glyphs[j].repeat; k++) {
if (!clipped && (char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) {
if (glyphs[j].font_rid != RID()) {
- TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color);
+ TS->font_draw_glyph(glyphs[j].font_rid, text_ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color);
had_glyphs_drawn = true;
} else if (((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) && ((glyphs[j].flags & TextServer::GRAPHEME_IS_EMBEDDED_OBJECT) != TextServer::GRAPHEME_IS_EMBEDDED_OBJECT)) {
- TS->draw_hex_code_box(ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color);
+ TS->draw_hex_code_box(text_ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color);
had_glyphs_drawn = true;
}
}
@@ -1411,12 +1403,12 @@ void TextEdit::_notification(int p_what) {
// is_line_folded
if (line_wrap_index == line_wrap_amount && line < text.size() - 1 && _is_line_hidden(line + 1)) {
- int xofs = char_ofs + char_margin + ofs_x + (_get_folded_eol_icon()->get_width() / 2);
+ int xofs = char_ofs + char_margin + (_get_folded_eol_icon()->get_width() / 2);
if (xofs >= xmargin_beg && xofs < xmargin_end) {
int yofs = (text_height - _get_folded_eol_icon()->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
Color eol_color = _get_code_folding_color();
eol_color.a = 1;
- _get_folded_eol_icon()->draw(ci, Point2(xofs, ofs_y + yofs), eol_color);
+ _get_folded_eol_icon()->draw(text_ci, Point2(xofs, ofs_y + yofs), eol_color);
}
}
@@ -1439,7 +1431,7 @@ void TextEdit::_notification(int p_what) {
int h = theme_cache.font->get_height(theme_cache.font_size);
if (rtl) {
ts_caret.l_dir = TextServer::DIRECTION_RTL;
- ts_caret.l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(caret_width * 4, h));
+ ts_caret.l_caret = Rect2(Vector2(xmargin_end - char_margin, -h / 2), Size2(caret_width * 4, h));
} else {
ts_caret.l_dir = TextServer::DIRECTION_LTR;
ts_caret.l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(caret_width * 4, h));
@@ -1447,9 +1439,9 @@ void TextEdit::_notification(int p_what) {
}
if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) {
- carets.write[c].draw_pos.x = char_margin + ofs_x + ts_caret.l_caret.position.x;
+ carets.write[c].draw_pos.x = char_margin + ts_caret.l_caret.position.x;
} else {
- carets.write[c].draw_pos.x = char_margin + ofs_x + ts_caret.t_caret.position.x;
+ carets.write[c].draw_pos.x = char_margin + ts_caret.t_caret.position.x;
}
if (get_caret_draw_pos(c).x >= xmargin_beg && get_caret_draw_pos(c).x < xmargin_end) {
@@ -1467,18 +1459,18 @@ void TextEdit::_notification(int p_what) {
ts_caret.t_caret.position.y = -TS->shaped_text_get_ascent(rid);
ts_caret.t_caret.size.y = h;
}
- ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y);
+ ts_caret.t_caret.position += Vector2(char_margin, ofs_y);
draw_rect(ts_caret.t_caret, theme_cache.caret_color, overtype_mode);
if (ts_caret.l_caret != Rect2() && ts_caret.l_dir != ts_caret.t_dir) {
// Draw split caret (leading part).
- ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
+ ts_caret.l_caret.position += Vector2(char_margin, ofs_y);
ts_caret.l_caret.size.x = caret_width;
- RS::get_singleton()->canvas_item_add_rect(ci, ts_caret.l_caret, theme_cache.caret_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.l_caret, theme_cache.caret_color);
// Draw extra direction marker on top of split caret.
float d = (ts_caret.l_dir == TextServer::DIRECTION_LTR) ? 0.5 : -3;
Rect2 trect = Rect2(ts_caret.l_caret.position.x + d * caret_width, ts_caret.l_caret.position.y + ts_caret.l_caret.size.y - caret_width, 3 * caret_width, caret_width);
- RS::get_singleton()->canvas_item_add_rect(ci, trect, theme_cache.caret_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, trect, theme_cache.caret_color);
}
} else { // End of the line.
if (gl_size > 0) {
@@ -1499,7 +1491,7 @@ void TextEdit::_notification(int p_what) {
} else {
ts_caret.l_caret.size.x = 3 * caret_width;
}
- ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
+ ts_caret.l_caret.position += Vector2(char_margin, ofs_y);
if (ts_caret.l_dir == TextServer::DIRECTION_RTL) {
ts_caret.l_caret.position.x -= ts_caret.l_caret.size.x;
}
@@ -1510,29 +1502,29 @@ void TextEdit::_notification(int p_what) {
if (ts_caret.l_caret != Rect2() && ts_caret.l_dir == TextServer::DIRECTION_AUTO) {
// Draw extra marker on top of mid caret.
Rect2 trect = Rect2(ts_caret.l_caret.position.x - 2.5 * caret_width, ts_caret.l_caret.position.y, 6 * caret_width, caret_width);
- trect.position += Vector2(char_margin + ofs_x, ofs_y);
- RS::get_singleton()->canvas_item_add_rect(ci, trect, theme_cache.caret_color);
+ trect.position += Vector2(char_margin, ofs_y);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, trect, theme_cache.caret_color);
} else if (ts_caret.l_caret != Rect2() && ts_caret.t_caret != Rect2() && ts_caret.l_dir != ts_caret.t_dir) {
// Draw extra direction marker on top of split caret.
float d = (ts_caret.l_dir == TextServer::DIRECTION_LTR) ? 0.5 : -3;
Rect2 trect = Rect2(ts_caret.l_caret.position.x + d * caret_width, ts_caret.l_caret.position.y + ts_caret.l_caret.size.y - caret_width, 3 * caret_width, caret_width);
- trect.position += Vector2(char_margin + ofs_x, ofs_y);
- RS::get_singleton()->canvas_item_add_rect(ci, trect, theme_cache.caret_color);
+ trect.position += Vector2(char_margin, ofs_y);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, trect, theme_cache.caret_color);
d = (ts_caret.t_dir == TextServer::DIRECTION_LTR) ? 0.5 : -3;
trect = Rect2(ts_caret.t_caret.position.x + d * caret_width, ts_caret.t_caret.position.y, 3 * caret_width, caret_width);
- trect.position += Vector2(char_margin + ofs_x, ofs_y);
- RS::get_singleton()->canvas_item_add_rect(ci, trect, theme_cache.caret_color);
+ trect.position += Vector2(char_margin, ofs_y);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, trect, theme_cache.caret_color);
}
- ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
+ ts_caret.l_caret.position += Vector2(char_margin, ofs_y);
ts_caret.l_caret.size.x = caret_width;
- RS::get_singleton()->canvas_item_add_rect(ci, ts_caret.l_caret, theme_cache.caret_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.l_caret, theme_cache.caret_color);
- ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y);
+ ts_caret.t_caret.position += Vector2(char_margin, ofs_y);
ts_caret.t_caret.size.x = caret_width;
- RS::get_singleton()->canvas_item_add_rect(ci, ts_caret.t_caret, theme_cache.caret_color);
+ RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.t_caret, theme_cache.caret_color);
}
}
}
@@ -1542,7 +1534,7 @@ void TextEdit::_notification(int p_what) {
// IME Intermediate text range.
const Vector sel = TS->shaped_text_get_selection(rid, get_caret_column(c), get_caret_column(c) + ime_text.length());
for (int j = 0; j < sel.size(); j++) {
- Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, text_height);
+ Rect2 rect = Rect2(sel[j].x + char_margin, ofs_y, sel[j].y - sel[j].x, text_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
continue;
}
@@ -1561,7 +1553,7 @@ void TextEdit::_notification(int p_what) {
// IME caret.
const Vector sel = TS->shaped_text_get_selection(rid, get_caret_column(c) + ime_selection.x, get_caret_column(c) + ime_selection.x + ime_selection.y);
for (int j = 0; j < sel.size(); j++) {
- Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, text_height);
+ Rect2 rect = Rect2(sel[j].x + char_margin, ofs_y, sel[j].y - sel[j].x, text_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
continue;
}
@@ -1587,6 +1579,7 @@ void TextEdit::_notification(int p_what) {
}
if (has_focus()) {
+ theme_cache.style_focus->draw(ci, Rect2(Point2(), get_size()));
_update_ime_window_position();
}
} break;
@@ -1833,8 +1826,9 @@ void TextEdit::gui_input(const Ref &p_gui_input) {
int line = pos.y;
int col = pos.x;
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
// Gutters.
- int left_margin = theme_cache.style_normal->get_margin(SIDE_LEFT);
+ int left_margin = style->get_margin(SIDE_LEFT);
for (int i = 0; i < gutters.size(); i++) {
if (!gutters[i].draw || gutters[i].width <= 0) {
continue;
@@ -2057,8 +2051,8 @@ void TextEdit::gui_input(const Ref &p_gui_input) {
// Check if user is hovering a different gutter, and update if yes.
Vector2i current_hovered_gutter = Vector2i(-1, -1);
-
- int left_margin = theme_cache.style_normal->get_margin(SIDE_LEFT);
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ int left_margin = style->get_margin(SIDE_LEFT);
if (mpos.x <= left_margin + gutters_width + gutter_padding) {
int hovered_row = get_line_column_at_pos(mpos).y;
for (int i = 0; i < gutters.size(); i++) {
@@ -3011,14 +3005,20 @@ void TextEdit::_show_virtual_keyboard() {
/* General overrides. */
Size2 TextEdit::get_minimum_size() const {
- Size2 size = theme_cache.style_normal->get_minimum_size();
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ Size2 size = style->get_minimum_size();
+ Size2 ms = Size2();
if (fit_content_height) {
- size.y += content_size_cache.y;
+ size.height += content_size_cache.height;
+ } else if (v_scroll->is_visible_in_tree()) {
+ ms = v_scroll->get_combined_minimum_size();
}
if (fit_content_width) {
- size.x += content_size_cache.x;
+ size.width += content_size_cache.width;
+ } else if (h_scroll->is_visible_in_tree()) {
+ ms = ms.max(h_scroll->get_combined_minimum_size());
}
- return size;
+ return size + ms;
}
bool TextEdit::is_text_field() const {
@@ -3105,8 +3105,9 @@ void TextEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
Point2i pos = get_line_column_at_pos(p_pos);
int row = pos.y;
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
- int left_margin = theme_cache.style_normal->get_margin(SIDE_LEFT);
+ int left_margin = style->get_margin(SIDE_LEFT);
int gutter = left_margin + gutters_width;
if (p_pos.x < gutter) {
for (int i = 0; i < gutters.size(); i++) {
@@ -3124,7 +3125,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
return CURSOR_ARROW;
}
- int xmargin_end = get_size().width - theme_cache.style_normal->get_margin(SIDE_RIGHT);
+ int xmargin_end = get_size().width - style->get_margin(SIDE_RIGHT);
if (draw_minimap && p_pos.x > xmargin_end - minimap_width && p_pos.x <= xmargin_end) {
return CURSOR_ARROW;
}
@@ -4395,11 +4396,8 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
}
Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_of_bounds) const {
- float rows = p_pos.y - theme_cache.style_normal->get_margin(SIDE_TOP);
- if (!editable) {
- rows -= theme_cache.style_readonly->get_offset().y / 2;
- rows += theme_cache.style_normal->get_offset().y / 2;
- }
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ float rows = p_pos.y - style->get_margin(SIDE_TOP);
rows /= get_line_height();
rows += _get_v_scroll_offset();
int first_vis_line = get_first_visible_line();
@@ -4427,12 +4425,8 @@ Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_
return Point2i(text[row].length(), row);
}
- int colx = p_pos.x - (theme_cache.style_normal->get_margin(SIDE_LEFT) + gutters_width + gutter_padding);
+ int colx = p_pos.x - (style->get_margin(SIDE_LEFT) + gutters_width + gutter_padding);
colx += first_visible_col;
- if (!editable) {
- colx -= theme_cache.style_readonly->get_offset().x / 2;
- colx += theme_cache.style_normal->get_offset().x / 2;
- }
RID text_rid = text.get_line_data(row)->get_line_rid(wrap_index);
float wrap_indent = (text.is_indent_wrapped_lines() && wrap_index > 0) ? get_indent_level(row) * theme_cache.font->get_char_size(' ', theme_cache.font_size).width : 0.0;
@@ -4483,9 +4477,10 @@ Rect2i TextEdit::get_rect_at_line_column(int p_line, int p_column) const {
return Rect2i(-1, -1, 0, 0);
}
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
Point2i pos, size;
pos.y = cache_entry.y_offset + get_line_height() * wrap_index;
- pos.x = get_total_gutter_width() + theme_cache.style_normal->get_margin(SIDE_LEFT) - get_h_scroll();
+ pos.x = get_total_gutter_width() + style->get_margin(SIDE_LEFT) - get_h_scroll();
RID text_rid = text.get_line_data(p_line)->get_line_rid(wrap_index);
Vector2 col_bounds = TS->shaped_text_get_grapheme_bounds(text_rid, p_column);
@@ -4507,7 +4502,7 @@ int TextEdit::get_minimap_line_at_pos(const Point2i &p_pos) const {
int minimap_visible_lines = get_minimap_visible_lines();
int visible_rows = get_visible_line_count() + 1;
int first_vis_line = get_first_visible_line() - 1;
- int draw_amount = visible_rows + (smooth_scroll_enabled ? 1 : 0);
+ int draw_amount = visible_rows + Math::ceil(_get_v_scroll_offset());
draw_amount += get_line_wrap_count(first_vis_line + 1);
int minimap_line_height = (minimap_char_size.y + minimap_line_spacing);
@@ -4515,13 +4510,14 @@ int TextEdit::get_minimap_line_at_pos(const Point2i &p_pos) const {
int viewport_height = (draw_amount - 1) * minimap_line_height;
int control_height = _get_control_height() - viewport_height;
int viewport_offset_y = round(get_scroll_pos_for_line(first_vis_line + 1) * control_height) / ((v_scroll->get_max() <= minimap_visible_lines) ? (minimap_visible_lines - draw_amount) : (v_scroll->get_max() - draw_amount));
+ viewport_offset_y += editable ? theme_cache.style_normal->get_margin(SIDE_TOP) : theme_cache.style_readonly->get_margin(SIDE_TOP);
// Calculate the first line.
int num_lines_before = round((viewport_offset_y) / minimap_line_height);
int minimap_line = (v_scroll->get_max() <= minimap_visible_lines) ? -1 : first_vis_line;
if (first_vis_line > 0 && minimap_line >= 0) {
minimap_line -= get_next_visible_line_index_offset_from(first_vis_line, 0, -num_lines_before).x;
- minimap_line -= (minimap_line > 0 && smooth_scroll_enabled ? 1 : 0);
+ minimap_line -= (minimap_line > 0 && Math::ceil(_get_v_scroll_offset()) > 0 ? 1 : 0);
}
if (minimap_line < 0) {
@@ -5810,6 +5806,10 @@ bool TextEdit::is_scroll_past_end_of_file_enabled() const {
return scroll_past_end_of_file_enabled;
}
+RID TextEdit::_get_text_canvas_item() const {
+ return text_ci;
+}
+
VScrollBar *TextEdit::get_v_scroll_bar() const {
return v_scroll;
}
@@ -6006,7 +6006,8 @@ void TextEdit::adjust_viewport_to_caret(int p_caret) {
set_line_as_last_visible(cur_line, cur_wrap);
}
- int visible_width = get_size().width - theme_cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding;
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ int visible_width = get_size().width - style->get_minimum_size().width - gutters_width - gutter_padding;
if (draw_minimap) {
visible_width -= minimap_width;
}
@@ -6060,7 +6061,8 @@ void TextEdit::center_viewport_to_caret(int p_caret) {
minimap_clicked = false;
set_line_as_center_visible(get_caret_line(p_caret), get_caret_wrap_index(p_caret));
- int visible_width = get_size().width - theme_cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding;
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ int visible_width = get_size().width - style->get_minimum_size().width - gutters_width - gutter_padding;
if (draw_minimap) {
visible_width -= minimap_width;
}
@@ -7887,7 +7889,8 @@ bool TextEdit::_selection_contains(int p_caret, int p_line, int p_column, bool p
/* Line Wrapping */
void TextEdit::_update_wrap_at_column(bool p_force) {
- int new_wrap_at = get_size().width - theme_cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding;
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ int new_wrap_at = get_size().width - style->get_minimum_size().width - gutters_width - gutter_padding;
if (draw_minimap) {
new_wrap_at -= minimap_width;
}
@@ -7937,14 +7940,6 @@ void TextEdit::_update_wrap_at_column(bool p_force) {
/* Viewport. */
void TextEdit::_update_scrollbars() {
Size2 size = get_size();
- Size2 hmin = h_scroll->get_combined_minimum_size();
- Size2 vmin = v_scroll->get_combined_minimum_size();
-
- v_scroll->set_begin(Point2(size.width - vmin.width, theme_cache.style_normal->get_margin(SIDE_TOP)));
- v_scroll->set_end(Point2(size.width, size.height - theme_cache.style_normal->get_margin(SIDE_TOP) - theme_cache.style_normal->get_margin(SIDE_BOTTOM)));
-
- h_scroll->set_begin(Point2(0, size.height - hmin.height));
- h_scroll->set_end(Point2(size.width - vmin.width, size.height));
bool draw_placeholder = _using_placeholder();
@@ -7954,25 +7949,23 @@ void TextEdit::_update_scrollbars() {
total_rows += visible_rows - 1;
}
- int visible_width = size.width - theme_cache.style_normal->get_minimum_size().width;
- int total_width = (draw_placeholder ? placeholder_max_width : text.get_max_width()) + gutters_width + gutter_padding;
-
- if (draw_minimap) {
- total_width += minimap_width;
- }
+ updating_scrolls = true;
+ bool update_min_size = false;
- content_size_cache = Vector2i(total_width + 10, MAX(total_rows, 1) * get_line_height());
- if (fit_content_height || fit_content_width) {
- update_minimum_size();
- }
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ int visible_width = size.width - style->get_minimum_size().width;
+ int total_width = (draw_placeholder ? placeholder_max_width : text.get_max_width()) + gutters_width + gutter_padding;
- updating_scrolls = true;
+ int hmin = h_scroll->get_combined_minimum_size().height;
+ int vmin = v_scroll->get_combined_minimum_size().width;
if (!fit_content_height && total_rows > visible_rows) {
v_scroll->show();
+ total_width += vmin;
v_scroll->set_max(total_rows + _get_visible_lines_offset());
v_scroll->set_page(visible_rows + _get_visible_lines_offset());
set_v_scroll(get_v_scroll());
+ update_min_size = true;
} else {
first_visible_line = 0;
@@ -7980,6 +7973,11 @@ void TextEdit::_update_scrollbars() {
v_scroll->set_value(0);
v_scroll->set_max(0);
v_scroll->hide();
+ update_min_size = true;
+ }
+
+ if (draw_minimap) {
+ total_width += minimap_width;
}
if (total_width > visible_width) {
@@ -7992,20 +7990,39 @@ void TextEdit::_update_scrollbars() {
if (fabs(h_scroll->get_value() - (double)first_visible_col) >= 1) {
h_scroll->set_value(first_visible_col);
}
+ update_min_size = true;
} else {
first_visible_col = 0;
h_scroll->set_value(0);
h_scroll->set_max(0);
h_scroll->hide();
+ update_min_size = true;
+ }
+
+ h_scroll->set_begin(Point2(style->get_margin(SIDE_LEFT), size.height - style->get_margin(SIDE_BOTTOM) - hmin));
+ v_scroll->set_begin(Point2(size.width - style->get_margin(SIDE_RIGHT) - vmin, style->get_margin(SIDE_TOP)));
+
+ Point2 h_scroll_end = Point2(size.width - style->get_margin(SIDE_RIGHT), size.height - style->get_margin(SIDE_BOTTOM));
+ Point2 v_scroll_end = Point2(size.width - style->get_margin(SIDE_RIGHT), size.height - style->get_margin(SIDE_BOTTOM));
+ if (h_scroll->is_visible_in_tree() && v_scroll->is_visible_in_tree()) {
+ h_scroll_end.width -= vmin;
+ v_scroll_end.height -= hmin;
+ }
+ h_scroll->set_end(h_scroll_end);
+ v_scroll->set_end(v_scroll_end);
+
+ content_size_cache = Vector2i(total_width + 10, MAX(total_rows, 1) * get_line_height());
+ if (update_min_size || fit_content_height || fit_content_width) {
+ update_minimum_size();
}
updating_scrolls = false;
}
int TextEdit::_get_control_height() const {
- int control_height = get_size().height;
- control_height -= theme_cache.style_normal->get_minimum_size().height;
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ int control_height = get_size().height - style->get_minimum_size().height;
if (h_scroll->is_visible_in_tree()) {
control_height -= h_scroll->get_size().height;
}
@@ -8167,7 +8184,8 @@ void TextEdit::_scroll_lines_down() {
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);
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
+ const int xmargin_end = get_size().width - style->get_margin(SIDE_RIGHT);
bool hovering_sidebar = mp.x > xmargin_end - minimap_width && mp.x < xmargin_end;
if (!hovering_sidebar) {
@@ -8193,8 +8211,9 @@ void TextEdit::_update_minimap_hover() {
void TextEdit::_update_minimap_click() {
Point2 mp = get_local_mouse_pos();
+ Ref style = editable ? theme_cache.style_normal : theme_cache.style_readonly;
- int xmargin_end = get_size().width - theme_cache.style_normal->get_margin(SIDE_RIGHT);
+ int xmargin_end = get_size().width - style->get_margin(SIDE_RIGHT);
if (!dragging_minimap && (mp.x < xmargin_end - minimap_width || mp.x > xmargin_end)) {
minimap_clicked = false;
return;
@@ -8204,7 +8223,7 @@ void TextEdit::_update_minimap_click() {
int row = get_minimap_line_at_pos(mp);
- if (row >= get_first_visible_line() && (row < get_last_full_visible_line() || row >= (text.size() - 1))) {
+ if (row >= get_first_visible_line() && (row <= get_last_full_visible_line() || row >= (text.size() - 1))) {
minimap_scroll_ratio = v_scroll->get_as_ratio();
minimap_scroll_click_pos = mp.y;
can_drag_minimap = true;
@@ -8514,6 +8533,10 @@ TextEdit::TextEdit(const String &p_placeholder) {
text.set_tab_size(text.get_tab_size());
+ text_ci = RenderingServer::get_singleton()->canvas_item_create();
+ RenderingServer::get_singleton()->canvas_item_set_parent(text_ci, get_canvas_item());
+ RenderingServer::get_singleton()->canvas_item_set_use_parent_material(text_ci, true);
+
h_scroll = memnew(HScrollBar);
v_scroll = memnew(VScrollBar);
@@ -8548,6 +8571,9 @@ TextEdit::TextEdit(const String &p_placeholder) {
set_placeholder(p_placeholder);
- set_clip_contents(true);
set_editable(true);
}
+
+TextEdit::~TextEdit() {
+ RenderingServer::get_singleton()->free(text_ci);
+}
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index c5f838020bd5..d9adcced0ad5 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -272,6 +272,7 @@ class TextEdit : public Control {
/* Text */
Text text;
+ RID text_ci;
bool setting_text = false;
@@ -678,6 +679,8 @@ class TextEdit : public Control {
// Line hiding.
bool hiding_enabled = false;
+ RID _get_text_canvas_item() const;
+
void _set_hiding_enabled(bool p_enabled);
bool _is_hiding_enabled() const;
@@ -1112,6 +1115,7 @@ class TextEdit : public Control {
#endif
TextEdit(const String &p_placeholder = String());
+ ~TextEdit();
};
VARIANT_ENUM_CAST(TextEdit::EditAction);
diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h
index 46a5046b21cc..2ef5f349a3da 100644
--- a/tests/scene/test_text_edit.h
+++ b/tests/scene/test_text_edit.h
@@ -7717,7 +7717,7 @@ TEST_CASE("[SceneTree][TextEdit] viewport") {
CHECK(text_edit->get_h_scroll() == 0);
text_edit->set_h_scroll(10000000);
- CHECK(text_edit->get_h_scroll() == 306);
+ CHECK(text_edit->get_h_scroll() == 298 + text_edit->get_combined_minimum_size().width);
CHECK(text_edit->get_h_scroll_bar()->get_combined_minimum_size().x == 8);
text_edit->set_h_scroll(-100);