From c1b9971ad833adb6cfced27c56e9098ac01bd277 Mon Sep 17 00:00:00 2001 From: Paulb23 Date: Fri, 18 Sep 2020 20:45:47 +0100 Subject: [PATCH] Move and expose Code Hint in CodeEdit --- editor/code_editor.cpp | 4 +- editor/editor_settings.cpp | 1 - editor/plugins/script_text_editor.cpp | 4 +- editor/plugins/shader_editor_plugin.cpp | 4 +- scene/gui/code_edit.cpp | 99 +++++++++++++++++++++++-- scene/gui/code_edit.h | 10 +++ scene/gui/text_edit.cpp | 37 --------- scene/gui/text_edit.h | 12 --- 8 files changed, 106 insertions(+), 65 deletions(-) diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 67a2d11670c..be42eab6360 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1564,9 +1564,7 @@ void CodeTextEditor::_on_settings_change() { EDITOR_GET("text_editor/completion/code_complete_delay")); // Call hint settings. - text_editor->set_callhint_settings( - EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line"), - EDITOR_GET("text_editor/completion/callhint_tooltip_offset")); + text_editor->set_code_hint_draw_below(EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line")); idle->set_wait_time(EDITOR_GET("text_editor/completion/idle_parse_delay")); } diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 28b01c0d182..4c21fb4569f 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -571,7 +571,6 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { _initial_set("text_editor/completion/code_complete_delay", 0.3); hints["text_editor/completion/code_complete_delay"] = PropertyInfo(Variant::FLOAT, "text_editor/completion/code_complete_delay", PROPERTY_HINT_RANGE, "0.01, 5, 0.01"); _initial_set("text_editor/completion/put_callhint_tooltip_below_current_line", true); - _initial_set("text_editor/completion/callhint_tooltip_offset", Vector2()); _initial_set("text_editor/completion/complete_file_paths", true); _initial_set("text_editor/completion/add_type_hints", false); _initial_set("text_editor/completion/use_single_quotes", false); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 6836a877ddc..a29e51e8fb7 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1824,9 +1824,7 @@ ScriptTextEditor::ScriptTextEditor() { update_settings(); - code_editor->get_text_editor()->set_callhint_settings( - EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"), - EditorSettings::get_singleton()->get("text_editor/completion/callhint_tooltip_offset")); + code_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line")); code_editor->get_text_editor()->set_select_identifiers_on_hover(true); code_editor->get_text_editor()->set_context_menu_enabled(false); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index c100923167b..3beef78bfcf 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -663,9 +663,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &ShaderEditor::_editor_settings_changed)); ProjectSettingsEditor::get_singleton()->connect("confirmed", callable_mp(this, &ShaderEditor::_project_settings_changed)); - shader_editor->get_text_editor()->set_callhint_settings( - EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"), - EditorSettings::get_singleton()->get("text_editor/completion/callhint_tooltip_offset")); + shader_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line")); shader_editor->get_text_editor()->set_select_identifiers_on_hover(true); shader_editor->get_text_editor()->set_context_menu_enabled(false); diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 83f5a7bfb56..d5000e88d70 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -159,6 +159,57 @@ 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), code_completion_scroll_color); } } + + /* Code hint */ + if (caret_visible && code_hint != "" && (!code_completion_active || (code_completion_below != code_hint_draw_below))) { + const Ref font = cache.font; + const int font_height = font->get_height(cache.font_size); + Ref sb = get_theme_stylebox("panel", "TooltipPanel"); + Color font_color = get_theme_color("font_color", "TooltipLabel"); + + Vector 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, font->get_string_size(code_hint_lines[i], cache.font_size).x); + } + Size2 minsize = sb->get_minimum_size() + Size2(max_width, line_count * font_height + (cache.line_spacing * line_count - 1)); + + int offset = font->get_string_size(code_hint_lines[0].substr(0, code_hint_lines[0].find(String::chr(0xFFFF))), 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 += cache.line_spacing / 2.0f; + } else { + hint_ofs.y -= (minsize.y + row_height) - cache.line_spacing; + } + + draw_style_box(sb, Rect2(hint_ofs, minsize)); + + int line_spacing = 0; + for (int i = 0; i < line_count; i++) { + const String &line = code_hint_lines[i]; + + int begin = 0; + int end = 0; + if (line.find(String::chr(0xFFFF)) != -1) { + begin = font->get_string_size(line.substr(0, line.find(String::chr(0xFFFF))), cache.font_size).x; + end = font->get_string_size(line.substr(0, line.rfind(String::chr(0xFFFF))), cache.font_size).x; + } + + Point2 round_ofs = hint_ofs + sb->get_offset() + Vector2(0, font->get_ascent() + font_height * i + line_spacing); + round_ofs = round_ofs.round(); + draw_string(font, round_ofs, line.replace(String::chr(0xFFFF), ""), HALIGN_LEFT, -1, cache.font_size, font_color); + if (end > 0) { + Vector2 b = hint_ofs + sb->get_offset() + Vector2(begin, font_height + font_height * i + line_spacing - 1); + draw_line(b, b + Vector2(end - begin, 0), font_color); + } + line_spacing += cache.line_spacing; + } + } } break; } } @@ -196,6 +247,7 @@ void CodeEdit::_gui_input(const Ref &p_gui_input) { return; } cancel_code_completion(); + set_code_hint(""); } Ref k = p_gui_input; @@ -205,12 +257,8 @@ void CodeEdit::_gui_input(const Ref &p_gui_input) { return; } - if (!k->is_pressed()) { - return; - } - - // If a modifier has been pressed, and nothing else, return. - if (k->get_keycode() == KEY_CONTROL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT || k->get_keycode() == KEY_META) { + /* If a modifier has been pressed, and nothing else, return. */ + if (!k->is_pressed() || k->get_keycode() == KEY_CTRL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT || k->get_keycode() == KEY_META) { return; } @@ -298,6 +346,29 @@ void CodeEdit::_gui_input(const Ref &p_gui_input) { } } + /* MISC */ + if (k->is_action("ui_cancel", true)) { + set_code_hint(""); + accept_event(); + return; + } + if (allow_unicode_handling && k->get_unicode() == ')') { + set_code_hint(""); + } + + /* Remove shift otherwise actions will not match. */ + k = k->duplicate(); + k->set_shift_pressed(false); + + if (k->is_action("ui_text_caret_up", true) || + k->is_action("ui_text_caret_down", true) || + k->is_action("ui_text_caret_line_start", true) || + k->is_action("ui_text_caret_line_end", true) || + k->is_action("ui_text_caret_page_up", true) || + k->is_action("ui_text_caret_page_down", true)) { + set_code_hint(""); + } + TextEdit::_gui_input(p_gui_input); if (update_code_completion) { @@ -698,6 +769,18 @@ Point2 CodeEdit::get_delimiter_end_position(int p_line, int p_column) const { return end_position; } +/* Code hint */ +void CodeEdit::set_code_hint(const String &p_hint) { + code_hint = p_hint; + code_hint_xpos = -0xFFFF; + update(); +} + +void CodeEdit::set_code_hint_draw_below(bool p_below) { + code_hint_draw_below = p_below; + update(); +} + /* Code Completion */ void CodeEdit::set_code_completion_enabled(bool p_enable) { code_completion_enabled = p_enable; @@ -1041,6 +1124,10 @@ void CodeEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_delimiter_start_postion", "line", "column"), &CodeEdit::get_delimiter_start_position); ClassDB::bind_method(D_METHOD("get_delimiter_end_postion", "line", "column"), &CodeEdit::get_delimiter_end_position); + /* Code hint */ + ClassDB::bind_method(D_METHOD("set_code_hint", "code_hint"), &CodeEdit::set_code_hint); + ClassDB::bind_method(D_METHOD("set_code_hint_draw_below", "draw_below"), &CodeEdit::set_code_hint_draw_below); + /* Code Completion */ BIND_ENUM_CONSTANT(KIND_CLASS); BIND_ENUM_CONSTANT(KIND_FUNCTION); diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h index 6c4b60f4619..6305eacf83a 100644 --- a/scene/gui/code_edit.h +++ b/scene/gui/code_edit.h @@ -160,6 +160,12 @@ private: void _clear_delimiters(DelimiterType p_type); TypedArray _get_delimiters(DelimiterType p_type) const; + /* Code Hint */ + String code_hint = ""; + + bool code_hint_draw_below = true; + int code_hint_xpos = -0xFFFF; + /* Code Completion */ bool code_completion_enabled = false; bool code_completion_forced = false; @@ -262,6 +268,10 @@ public: Point2 get_delimiter_start_position(int p_line, int p_column) const; Point2 get_delimiter_end_position(int p_line, int p_column) const; + /* Code hint */ + void set_code_hint(const String &p_hint); + void set_code_hint_draw_below(bool p_below); + /* Code Completion */ void set_code_completion_enabled(bool p_enable); bool is_code_completion_enabled() const; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index c67231d293e..0a2e08bb6c1 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2210,8 +2210,6 @@ void TextEdit::_move_cursor_up(bool p_select) { if (p_select) { _post_shift_selection(); } - - _cancel_code_hint(); } void TextEdit::_move_cursor_down(bool p_select) { @@ -2234,8 +2232,6 @@ void TextEdit::_move_cursor_down(bool p_select) { if (p_select) { _post_shift_selection(); } - - _cancel_code_hint(); } void TextEdit::_move_cursor_to_line_start(bool p_select) { @@ -2275,8 +2271,6 @@ void TextEdit::_move_cursor_to_line_start(bool p_select) { if (p_select) { _post_shift_selection(); } - - completion_hint = ""; } void TextEdit::_move_cursor_to_line_end(bool p_select) { @@ -2302,7 +2296,6 @@ void TextEdit::_move_cursor_to_line_end(bool p_select) { if (p_select) { _post_shift_selection(); } - completion_hint = ""; } void TextEdit::_move_cursor_page_up(bool p_select) { @@ -2319,8 +2312,6 @@ void TextEdit::_move_cursor_page_up(bool p_select) { if (p_select) { _post_shift_selection(); } - - completion_hint = ""; } void TextEdit::_move_cursor_page_down(bool p_select) { @@ -2337,8 +2328,6 @@ void TextEdit::_move_cursor_page_down(bool p_select) { if (p_select) { _post_shift_selection(); } - - completion_hint = ""; } void TextEdit::_backspace(bool p_word, bool p_all_to_left) { @@ -2488,11 +2477,6 @@ void TextEdit::_handle_unicode_character(uint32_t unicode, bool p_had_selection) const char32_t chr[2] = { (char32_t)unicode, 0 }; - // Clear completion hint when function closed - if (completion_hint != "" && unicode == ')') { - completion_hint = ""; - } - if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { _consume_pair_symbol(chr[0]); } else { @@ -3067,7 +3051,6 @@ void TextEdit::_gui_input(const Ref &p_gui_input) { } // MISC. - if (k->is_action("ui_menu", true)) { if (context_menu_enabled) { menu->set_position(get_screen_transform().xform(_get_cursor_pixel_pos())); @@ -3084,14 +3067,6 @@ void TextEdit::_gui_input(const Ref &p_gui_input) { accept_event(); return; } - if (k->is_action("ui_cancel", true)) { - if (completion_hint != "") { - completion_hint = ""; - update(); - } - accept_event(); - return; - } if (k->is_action("ui_swap_input_direction", true)) { _swap_current_input_direction(); accept_event(); @@ -5510,7 +5485,6 @@ void TextEdit::undo() { if (undo_stack_pos->get().type == TextOperation::TYPE_REMOVE) { cursor_set_line(undo_stack_pos->get().to_line, false); cursor_set_column(undo_stack_pos->get().to_column); - _cancel_code_hint(); } else { cursor_set_line(undo_stack_pos->get().from_line, false); cursor_set_column(undo_stack_pos->get().from_column); @@ -5786,17 +5760,6 @@ float TextEdit::get_v_scroll_speed() const { return v_scroll_speed; } -void TextEdit::_cancel_code_hint() { - completion_hint = ""; - update(); -} - -void TextEdit::set_code_hint(const String &p_hint) { - completion_hint = p_hint; - completion_hint_offset = -0xFFFF; - update(); -} - String TextEdit::get_word_at_pos(const Vector2 &p_pos) const { int row, col; _get_mouse_pos(p_pos, row, col); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 21ae9540cf8..f963e664d1b 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -329,11 +329,6 @@ private: bool next_operation_is_complex = false; - bool callhint_below = false; - Vector2 callhint_offset; - String completion_hint = ""; - int completion_hint_offset = 0; - String search_text; uint32_t search_flags = 0; int search_result_line = 0; @@ -427,7 +422,6 @@ private: PopupMenu *menu_ctl; void _clear(); - void _cancel_code_hint(); int _calculate_spaces_till_next_left_indent(int column); int _calculate_spaces_till_next_right_indent(int column); @@ -666,10 +660,6 @@ public: brace_matching_enabled = p_enabled; update(); } - inline void set_callhint_settings(bool below, Vector2 offset) { - callhint_below = below; - callhint_offset = offset; - } void set_auto_indent(bool p_auto_indent); void center_viewport_to_cursor(); @@ -798,8 +788,6 @@ public: void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata); - void set_code_hint(const String &p_hint); - void set_select_identifiers_on_hover(bool p_enable); bool is_selecting_identifiers_on_hover_enabled() const;