Fix TextEdit styles and disable clipping.

Co-Authored-By: kit <kitbdev@gmail.com>
This commit is contained in:
Mounir Tohami 2025-08-20 13:06:27 +03:00
parent 149a4b4ca1
commit b25e35cf58
5 changed files with 119 additions and 64 deletions

View file

@ -1309,7 +1309,6 @@
<member name="caret_type" type="int" setter="set_caret_type" getter="get_caret_type" enum="TextEdit.CaretType" default="0">
Set the type of caret to draw.
</member>
<member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="context_menu_enabled" type="bool" setter="set_context_menu_enabled" getter="is_context_menu_enabled" default="true">
If [code]true[/code], a right-click displays the context menu.
</member>

View file

@ -523,9 +523,10 @@ void ScriptTextEditor::_inline_object_draw(const Dictionary &p_info, const Rect2
if (color_alpha_texture.is_null()) {
color_alpha_texture = inline_color_picker->get_theme_icon("sample_bg", "ColorPicker");
}
code_editor->get_text_editor()->draw_texture_rect(color_alpha_texture, col_rect, false);
code_editor->get_text_editor()->draw_rect(col_rect, Color(p_info["color"]));
code_editor->get_text_editor()->draw_rect(col_rect, Color(1, 1, 1), false, 1);
RID text_ci = code_editor->get_text_editor()->get_text_canvas_item();
RS::get_singleton()->canvas_item_add_rect(text_ci, p_rect.grow(-3), Color(1, 1, 1));
color_alpha_texture->draw_rect(text_ci, col_rect);
RS::get_singleton()->canvas_item_add_rect(text_ci, col_rect, Color(p_info["color"]));
}
}

View file

@ -69,7 +69,7 @@ void CodeEdit::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
RID ci = get_canvas_item();
RID ci = get_text_canvas_item();
const bool caret_visible = is_caret_visible();
const bool rtl = is_layout_rtl();
const int row_height = get_line_height();
@ -103,7 +103,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++) {
@ -118,17 +118,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.remove_char(0xFFFF), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size, theme_cache.code_hint_color);
theme_cache.font->draw_string(ci, round_ofs, line.remove_char(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);
RS::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));
RS::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;
}
@ -177,7 +177,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);
}
@ -211,7 +211,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);
RS::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 {
@ -219,10 +219,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);
theme_cache.completion_color_bg->draw_rect(ci, rect, true);
}
draw_rect(rect, color);
RS::get_singleton()->canvas_item_add_rect(ci, rect, color);
}
tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
}
@ -234,7 +234,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);
RS::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);
}
@ -245,7 +245,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);
RS::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);
}
}
}
@ -1341,6 +1341,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);
@ -1355,7 +1356,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);
}
}
@ -1374,7 +1375,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);
}
}
@ -1385,7 +1386,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);
}
}
@ -1546,7 +1547,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() {
@ -1575,6 +1576,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;
@ -1588,17 +1590,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 */

View file

@ -932,7 +932,14 @@ void TextEdit::_notification(int p_what) {
_update_scrollbars();
RS::get_singleton()->canvas_item_clear(text_ci);
RS::get_singleton()->canvas_item_set_custom_rect(text_ci, !is_visibility_clip_disabled(), Rect2(Point2(0, 0), size));
RS::get_singleton()->canvas_item_set_clip(text_ci, true);
RS::get_singleton()->canvas_item_set_visibility_layer(text_ci, get_visibility_layer());
RS::get_singleton()->canvas_item_set_default_texture_filter(text_ci, RS::CanvasItemTextureFilter(get_texture_filter_in_tree()));
RID ci = get_canvas_item();
int xmargin_beg = Math::ceil(theme_cache.style_normal->get_margin(SIDE_LEFT)) + gutters_width + gutter_padding;
int xmargin_end = size.width - Math::ceil(theme_cache.style_normal->get_margin(SIDE_RIGHT));
@ -952,7 +959,7 @@ void TextEdit::_notification(int p_what) {
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);
RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(Point2i(), get_size()), theme_cache.background_color);
}
Vector<BraceMatchingData> brace_matching;
@ -1157,9 +1164,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);
RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - (xmargin_end + 2) - 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);
RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2((xmargin_end + 2), viewport_offset_y, minimap_width, viewport_height), viewport_color);
}
for (int i = 0; i < minimap_draw_amount; i++) {
@ -1222,15 +1229,15 @@ void TextEdit::_notification(int p_what) {
if (highlight_current_line && highlighted_lines.has(Pair<int, int>(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);
RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, i * 3, minimap_width, 2), 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);
RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), 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);
RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, i * 3, minimap_width, 2), line_background_color);
} else {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), line_background_color);
RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2((xmargin_end + 2), i * 3, minimap_width, 2), line_background_color);
}
}
@ -1280,9 +1287,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);
RS::get_singleton()->canvas_item_add_rect(text_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);
} 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);
RS::get_singleton()->canvas_item_add_rect(text_ci, Rect2(Point2(xpos, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color);
}
}
@ -1407,18 +1414,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 - ofs_x - 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_x, 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<int, int>(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 - ofs_x - xmargin_end, ofs_y, xmargin_end, 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(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
}
}
@ -1448,9 +1455,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 + ofs_x, 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 + ofs_x, yofs), get_line_gutter_item_color(line, g));
} break;
case GUTTER_TYPE_ICON: {
const Ref<Texture2D> icon = get_line_gutter_icon(line, g);
@ -1478,7 +1485,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()) {
@ -1555,7 +1562,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);
}
}
}
@ -1577,8 +1584,8 @@ 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);
draw_rect(rect, theme_cache.search_result_border_color, false);
RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.search_result_color);
_draw_rect_unfilled(text_ci, rect, theme_cache.search_result_border_color);
}
search_text_col = _get_column_pos_of_word(search_text, str, search_flags, search_text_col + search_text_len);
@ -1601,7 +1608,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);
@ -1628,7 +1635,7 @@ void TextEdit::_notification(int p_what) {
}
rect.position.y += std::ceil(TS->shaped_text_get_ascent(rid)) + std::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);
@ -1652,7 +1659,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 + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, theme_cache.outline_color);
}
}
char_ofs += glyphs[j].advance;
@ -1708,7 +1715,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) ||
@ -1717,18 +1724,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);
}
}
@ -1736,10 +1743,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 + ofs_x + 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 + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color);
had_glyphs_drawn = true;
}
}
@ -1770,7 +1777,7 @@ void TextEdit::_notification(int p_what) {
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);
}
}
@ -1822,17 +1829,21 @@ void TextEdit::_notification(int p_what) {
ts_caret.t_caret.size.y = h;
}
ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y);
draw_rect(ts_caret.t_caret, theme_cache.caret_color, overtype_mode);
if (overtype_mode) {
RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.t_caret, theme_cache.caret_color);
} else {
_draw_rect_unfilled(text_ci, ts_caret.t_caret, theme_cache.caret_color);
}
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.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) {
@ -1857,7 +1868,11 @@ void TextEdit::_notification(int p_what) {
if (ts_caret.l_dir == TextServer::DIRECTION_RTL) {
ts_caret.l_caret.position.x -= ts_caret.l_caret.size.x;
}
draw_rect(ts_caret.l_caret, theme_cache.caret_color, overtype_mode);
if (overtype_mode) {
RS::get_singleton()->canvas_item_add_rect(text_ci, ts_caret.l_caret, theme_cache.caret_color);
} else {
_draw_rect_unfilled(text_ci, ts_caret.l_caret, theme_cache.caret_color);
}
}
} else {
// Normal caret.
@ -1865,28 +1880,28 @@ void TextEdit::_notification(int p_what) {
// 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);
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);
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);
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.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.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);
}
}
}
@ -1907,7 +1922,7 @@ void TextEdit::_notification(int p_what) {
rect.size.x = xmargin_end - rect.position.x;
}
rect.size.y = caret_width;
draw_rect(rect, theme_cache.caret_color);
RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.caret_color);
carets.write[c].draw_pos.x = rect.position.x;
}
}
@ -1926,7 +1941,7 @@ void TextEdit::_notification(int p_what) {
rect.size.x = xmargin_end - rect.position.x;
}
rect.size.y = caret_width * 3;
draw_rect(rect, theme_cache.caret_color);
RS::get_singleton()->canvas_item_add_rect(text_ci, rect, theme_cache.caret_color);
carets.write[c].draw_pos.x = rect.position.x;
}
}
@ -6446,6 +6461,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;
}
@ -9232,6 +9251,26 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
emit_signal(SNAME("lines_edited_from"), p_to_line, p_from_line);
}
void TextEdit::_draw_rect_unfilled(RID p_canvas_item, const Rect2 &p_rect, const Color &p_color, real_t p_width, bool p_antialiased) const {
Rect2 rect = p_rect.abs();
if (p_width >= rect.size.width || p_width >= rect.size.height) {
RS::get_singleton()->canvas_item_add_rect(p_canvas_item, rect.grow(0.5f * p_width), p_color, p_antialiased);
} else {
Vector<Vector2> points;
points.resize(5);
points.write[0] = rect.position;
points.write[1] = rect.position + Vector2(rect.size.x, 0);
points.write[2] = rect.position + rect.size;
points.write[3] = rect.position + Vector2(0, rect.size.y);
points.write[4] = rect.position;
Vector<Color> colors = { p_color };
RS::get_singleton()->canvas_item_add_polyline(p_canvas_item, points, colors, p_width, p_antialiased);
}
}
TextEdit::TextEdit(const String &p_placeholder) {
placeholder_data_buf.instantiate();
carets.push_back(Caret());
@ -9243,6 +9282,10 @@ TextEdit::TextEdit(const String &p_placeholder) {
text.set_tab_size(text.get_tab_size());
text_ci = RS::get_singleton()->canvas_item_create();
RS::get_singleton()->canvas_item_set_parent(text_ci, get_canvas_item());
RS::get_singleton()->canvas_item_set_use_parent_material(text_ci, true);
h_scroll = memnew(HScrollBar);
v_scroll = memnew(VScrollBar);
@ -9277,6 +9320,9 @@ TextEdit::TextEdit(const String &p_placeholder) {
set_placeholder(p_placeholder);
set_clip_contents(true);
set_editable(true);
}
TextEdit::~TextEdit() {
RS::get_singleton()->free(text_ci);
}

View file

@ -288,6 +288,7 @@ private:
/* Text */
Text text;
RID text_ci;
bool setting_text = false;
enum AltInputMode {
@ -657,6 +658,9 @@ private:
RID accessibility_text_root_element_nl;
// FIXME: Helper method to draw unfilled rects, should be moved to RenderingServer.
void _draw_rect_unfilled(RID p_canvas_item, const Rect2 &p_rect, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false) const;
/*** Super internal Core API. Everything builds on it. ***/
bool text_changed_dirty = false;
void _text_changed();
@ -783,6 +787,8 @@ public:
/* Text */
// Text properties.
RID get_text_canvas_item() const;
bool has_ime_text() const;
void cancel_ime();
void apply_ime();
@ -1188,6 +1194,7 @@ public:
#endif
TextEdit(const String &p_placeholder = String());
~TextEdit();
};
VARIANT_ENUM_CAST(TextEdit::EditAction);