Make it possible to show code hint and code completion at the same time

Make code completion position more consistent

Add whitespace before if
This commit is contained in:
CHM 2023-11-27 23:53:50 +08:00 committed by Yuri Sizov
parent 1f5d4a62e9
commit 3744ef50e4

View File

@ -69,8 +69,68 @@ void CodeEdit::_notification(int p_what) {
} }
} }
bool code_completion_below = false; if (caret_visible) {
if (caret_visible && code_completion_active && code_completion_options.size() > 0) { const bool draw_code_completion = code_completion_active && !code_completion_options.is_empty();
const bool draw_code_hint = !code_hint.is_empty();
/* Code hint */
Size2 code_hint_minsize;
if (draw_code_hint) {
const int font_height = theme_cache.font->get_height(theme_cache.font_size);
Vector<String> code_hint_lines = code_hint.split("\n");
int line_count = code_hint_lines.size();
int max_width = 0;
for (int i = 0; i < line_count; i++) {
max_width = MAX(max_width, theme_cache.font->get_string_size(code_hint_lines[i], HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).x);
}
code_hint_minsize = theme_cache.code_hint_style->get_minimum_size() + Size2(max_width, line_count * font_height + (theme_cache.line_spacing * line_count - 1));
int offset = theme_cache.font->get_string_size(code_hint_lines[0].substr(0, code_hint_lines[0].find(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).x;
if (code_hint_xpos == -0xFFFF) {
code_hint_xpos = get_caret_draw_pos().x - offset;
}
Point2 hint_ofs = Vector2(code_hint_xpos, get_caret_draw_pos().y);
if (code_hint_draw_below) {
hint_ofs.y += theme_cache.line_spacing / 2.0f;
} else {
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));
int yofs = 0;
for (int i = 0; i < line_count; i++) {
const String &line = code_hint_lines[i];
int begin = 0;
int end = 0;
if (line.contains(String::chr(0xFFFF))) {
begin = theme_cache.font->get_string_size(line.substr(0, line.find(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).x;
end = theme_cache.font->get_string_size(line.substr(0, line.rfind(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).x;
}
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);
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);
// 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));
}
yofs += theme_cache.line_spacing;
}
}
/* Code completion */
if (draw_code_completion) {
const int code_completion_options_count = code_completion_options.size(); const int code_completion_options_count = code_completion_options.size();
const int lines = MIN(code_completion_options_count, theme_cache.code_completion_max_lines); const int lines = MIN(code_completion_options_count, theme_cache.code_completion_max_lines);
const Size2 icon_area_size(row_height, row_height); const Size2 icon_area_size(row_height, row_height);
@ -80,13 +140,28 @@ void CodeEdit::_notification(int p_what) {
const Point2 caret_pos = get_caret_draw_pos(); const Point2 caret_pos = get_caret_draw_pos();
const int total_height = theme_cache.code_completion_style->get_minimum_size().y + code_completion_rect.size.height; const int total_height = theme_cache.code_completion_style->get_minimum_size().y + code_completion_rect.size.height;
const bool can_fit_completion_above = (caret_pos.y - row_height > total_height); int min_y = caret_pos.y - row_height;
const bool can_fit_completion_below = (caret_pos.y + row_height + total_height <= get_size().height); int max_y = caret_pos.y + row_height + total_height;
if (draw_code_hint) {
if (code_hint_draw_below) {
max_y += code_hint_minsize.y;
} else {
min_y -= code_hint_minsize.y;
}
}
const bool can_fit_completion_above = (min_y > total_height);
const bool can_fit_completion_below = (max_y <= get_size().height);
if (!can_fit_completion_below && can_fit_completion_above) { if (!can_fit_completion_below && can_fit_completion_above) {
code_completion_rect.position.y = (caret_pos.y - total_height - row_height) + theme_cache.line_spacing; code_completion_rect.position.y = (caret_pos.y - total_height - row_height) + theme_cache.line_spacing;
if (draw_code_hint && !code_hint_draw_below) {
code_completion_rect.position.y -= code_hint_minsize.y;
}
} else { } else {
code_completion_rect.position.y = caret_pos.y + (theme_cache.line_spacing / 2.0f); code_completion_rect.position.y = caret_pos.y + (theme_cache.line_spacing / 2.0f);
code_completion_below = true; if (draw_code_hint && code_hint_draw_below) {
code_completion_rect.position.y += code_hint_minsize.y;
}
} }
const int scroll_width = code_completion_options_count > theme_cache.code_completion_max_lines ? theme_cache.code_completion_scroll_width : 0; const int scroll_width = code_completion_options_count > theme_cache.code_completion_max_lines ? theme_cache.code_completion_scroll_width : 0;
@ -162,60 +237,6 @@ void CodeEdit::_notification(int p_what) {
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); 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);
} }
} }
/* Code hint */
if (caret_visible && !code_hint.is_empty() && (!code_completion_active || (code_completion_below != code_hint_draw_below))) {
const int font_height = theme_cache.font->get_height(theme_cache.font_size);
Vector<String> code_hint_lines = code_hint.split("\n");
int line_count = code_hint_lines.size();
int max_width = 0;
for (int i = 0; i < line_count; i++) {
max_width = MAX(max_width, theme_cache.font->get_string_size(code_hint_lines[i], HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).x);
}
Size2 minsize = theme_cache.code_hint_style->get_minimum_size() + Size2(max_width, line_count * font_height + (theme_cache.line_spacing * line_count - 1));
int offset = theme_cache.font->get_string_size(code_hint_lines[0].substr(0, code_hint_lines[0].find(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).x;
if (code_hint_xpos == -0xFFFF) {
code_hint_xpos = get_caret_draw_pos().x - offset;
}
Point2 hint_ofs = Vector2(code_hint_xpos, get_caret_draw_pos().y);
if (code_hint_draw_below) {
hint_ofs.y += theme_cache.line_spacing / 2.0f;
} else {
hint_ofs.y -= (minsize.y + row_height) - theme_cache.line_spacing;
}
draw_style_box(theme_cache.code_hint_style, Rect2(hint_ofs, minsize));
int yofs = 0;
for (int i = 0; i < line_count; i++) {
const String &line = code_hint_lines[i];
int begin = 0;
int end = 0;
if (line.contains(String::chr(0xFFFF))) {
begin = theme_cache.font->get_string_size(line.substr(0, line.find(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).x;
end = theme_cache.font->get_string_size(line.substr(0, line.rfind(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).x;
}
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);
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);
// 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));
}
yofs += theme_cache.line_spacing;
}
} }
} break; } break;