From f41cd8ad523f1b1279ca2de0e81d72c66d199fd6 Mon Sep 17 00:00:00 2001 From: kit Date: Thu, 22 Feb 2024 15:32:12 -0500 Subject: [PATCH] Make Goto line a Popup and allow column input --- editor/code_editor.cpp | 104 +++++++++++++++++++------- editor/code_editor.h | 31 +++++--- editor/plugins/script_text_editor.cpp | 10 ++- editor/plugins/script_text_editor.h | 2 +- editor/plugins/text_editor.cpp | 6 +- editor/plugins/text_editor.h | 2 +- editor/plugins/text_shader_editor.cpp | 6 +- editor/plugins/text_shader_editor.h | 2 +- 8 files changed, 110 insertions(+), 53 deletions(-) diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 88a32b1a6da..0a37b6ff744 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -39,39 +39,72 @@ #include "editor/plugins/script_editor_plugin.h" #include "editor/themes/editor_scale.h" #include "editor/themes/editor_theme_manager.h" +#include "scene/gui/line_edit.h" #include "scene/gui/menu_button.h" #include "scene/gui/separator.h" #include "scene/resources/font.h" -void GotoLineDialog::popup_find_line(CodeEdit *p_edit) { - text_editor = p_edit; +void GotoLinePopup::popup_find_line(CodeTextEditor *p_text_editor) { + text_editor = p_text_editor; - // Add 1 because text_editor->get_caret_line() starts from 0, but the editor user interface starts from 1. - line->set_text(itos(text_editor->get_caret_line() + 1)); - line->select_all(); - popup_centered(Size2(180, 80) * EDSCALE); - line->grab_focus(); + original_state = text_editor->get_navigation_state(); + + // Add 1 because the TextEdit starts from 0, but the editor user interface starts from 1. + TextEdit *text_edit = text_editor->get_text_editor(); + int original_line = text_edit->get_caret_line() + 1; + line_input->set_text(itos(original_line)); + text_editor->set_preview_navigation_change(true); + + Rect2i parent_rect = text_editor->get_global_rect(); + Point2i centered_pos(parent_rect.get_center().x - get_contents_minimum_size().x / 2.0, parent_rect.position.y); + popup_on_parent(Rect2i(centered_pos, Size2())); + reset_size(); + line_input->grab_focus(); } -int GotoLineDialog::get_line() const { - return line->get_text().to_int(); -} - -void GotoLineDialog::ok_pressed() { - // Subtract 1 because the editor user interface starts from 1, but text_editor->set_caret_line(n) starts from 0. - const int line_number = get_line() - 1; - if (line_number < 0 || line_number >= text_editor->get_line_count()) { +void GotoLinePopup::_goto_line() { + if (line_input->get_text().is_empty()) { return; } - text_editor->remove_secondary_carets(); - text_editor->unfold_line(line_number); - text_editor->set_caret_line(line_number); - text_editor->set_code_hint(""); - text_editor->cancel_code_completion(); + + PackedStringArray line_col_strings = line_input->get_text().split(":"); + // Subtract 1 because the editor user interface starts from 1, but the TextEdit starts from 0. + const int line_number = line_col_strings[0].to_int() - 1; + if (line_number < 0 || line_number >= text_editor->get_text_editor()->get_line_count()) { + return; + } + + int column_number = 0; + if (line_col_strings.size() >= 2) { + column_number = line_col_strings[1].to_int() - 1; + } + text_editor->goto_line_centered(line_number, column_number); +} + +void GotoLinePopup::_submit() { + _goto_line(); hide(); } -GotoLineDialog::GotoLineDialog() { +void GotoLinePopup::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible()) { + text_editor->set_preview_navigation_change(false); + } + } break; + } +} + +void GotoLinePopup::_input_from_window(const Ref &p_event) { + if (p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) { + // Cancelled, go back to original state. + text_editor->set_edit_state(original_state); + } + PopupPanel::_input_from_window(p_event); +} + +GotoLinePopup::GotoLinePopup() { set_title(TTR("Go to Line")); VBoxContainer *vbc = memnew(VBoxContainer); @@ -85,14 +118,12 @@ GotoLineDialog::GotoLineDialog() { l->set_text(TTR("Line Number:")); vbc->add_child(l); - line = memnew(LineEdit); - vbc->add_child(line); - register_text_enter(line); - text_editor = nullptr; - - line_label = nullptr; - - set_hide_on_ok(false); + line_input = memnew(LineEdit); + line_input->set_custom_minimum_size(Size2(100, 0) * EDSCALE); + line_input->set_select_all_on_focus(true); + line_input->connect(SceneStringName(text_changed), callable_mp(this, &GotoLinePopup::_goto_line).unbind(1)); + line_input->connect(SceneStringName(text_submitted), callable_mp(this, &GotoLinePopup::_submit).unbind(1)); + vbc->add_child(line_input); } void FindReplaceBar::_notification(int p_what) { @@ -1392,6 +1423,20 @@ void CodeTextEditor::store_previous_state() { previous_state = get_navigation_state(); } +bool CodeTextEditor::is_previewing_navigation_change() const { + return preview_navigation_change; +} + +void CodeTextEditor::set_preview_navigation_change(bool p_preview) { + if (preview_navigation_change == p_preview) { + return; + } + preview_navigation_change = p_preview; + if (!preview_navigation_change) { + emit_signal("navigation_preview_ended"); + } +} + void CodeTextEditor::set_edit_state(const Variant &p_state) { Dictionary state = p_state; @@ -1752,6 +1797,7 @@ void CodeTextEditor::_bind_methods() { ADD_SIGNAL(MethodInfo("load_theme_settings")); ADD_SIGNAL(MethodInfo("show_errors_panel")); ADD_SIGNAL(MethodInfo("show_warnings_panel")); + ADD_SIGNAL(MethodInfo("navigation_preview_ended")); ADD_SIGNAL(MethodInfo("zoomed", PropertyInfo(Variant::FLOAT, "p_zoom_factor"))); } diff --git a/editor/code_editor.h b/editor/code_editor.h index c1c65a2a4a5..3bc0cf30f68 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -37,30 +37,33 @@ #include "scene/gui/code_edit.h" #include "scene/gui/dialogs.h" #include "scene/gui/label.h" -#include "scene/gui/line_edit.h" +#include "scene/gui/popup.h" #include "scene/main/timer.h" class MenuButton; +class CodeTextEditor; +class LineEdit; -class GotoLineDialog : public ConfirmationDialog { - GDCLASS(GotoLineDialog, ConfirmationDialog); +class GotoLinePopup : public PopupPanel { + GDCLASS(GotoLinePopup, PopupPanel); - Label *line_label = nullptr; - LineEdit *line = nullptr; + Variant original_state; + LineEdit *line_input = nullptr; + CodeTextEditor *text_editor = nullptr; - CodeEdit *text_editor = nullptr; + void _goto_line(); + void _submit(); - virtual void ok_pressed() override; +protected: + void _notification(int p_what); + virtual void _input_from_window(const Ref &p_event) override; public: - void popup_find_line(CodeEdit *p_edit); - int get_line() const; + void popup_find_line(CodeTextEditor *p_text_editor); - GotoLineDialog(); + GotoLinePopup(); }; -class CodeTextEditor; - class FindReplaceBar : public HBoxContainer { GDCLASS(FindReplaceBar, HBoxContainer); @@ -184,6 +187,7 @@ class CodeTextEditor : public VBoxContainer { int error_line; int error_column; + bool preview_navigation_change = false; Dictionary previous_state; void _update_text_editor_theme(); @@ -262,6 +266,9 @@ public: Variant get_previous_state(); void store_previous_state(); + bool is_previewing_navigation_change() const; + void set_preview_navigation_change(bool p_preview); + void set_error_count(int p_error_count); void set_warning_count(int p_warning_count); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index b45b30b52ec..de20539f4b8 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -926,6 +926,9 @@ void ScriptTextEditor::_breakpoint_toggled(int p_row) { } void ScriptTextEditor::_on_caret_moved() { + if (code_editor->is_previewing_navigation_change()) { + return; + } int current_line = code_editor->get_text_editor()->get_caret_line(); if (ABS(current_line - previous_line) >= 10) { Dictionary nav_state = get_navigation_state(); @@ -1518,7 +1521,7 @@ void ScriptTextEditor::_edit_option(int p_op) { quick_open->set_title(TTR("Go to Function")); } break; case SEARCH_GOTO_LINE: { - goto_line_dialog->popup_find_line(tx); + goto_line_popup->popup_find_line(code_editor); } break; case BOOKMARK_TOGGLE: { code_editor->toggle_bookmark(); @@ -2272,8 +2275,8 @@ void ScriptTextEditor::_enable_code_editor() { quick_open->connect("goto_line", callable_mp(this, &ScriptTextEditor::_goto_line)); add_child(quick_open); - goto_line_dialog = memnew(GotoLineDialog); - add_child(goto_line_dialog); + goto_line_popup = memnew(GotoLinePopup); + add_child(goto_line_popup); add_child(connection_info_dialog); @@ -2381,6 +2384,7 @@ ScriptTextEditor::ScriptTextEditor() { code_editor->get_text_editor()->set_draw_executing_lines_gutter(true); code_editor->get_text_editor()->connect("breakpoint_toggled", callable_mp(this, &ScriptTextEditor::_breakpoint_toggled)); code_editor->get_text_editor()->connect("caret_changed", callable_mp(this, &ScriptTextEditor::_on_caret_moved)); + code_editor->connect("navigation_preview_ended", callable_mp(this, &ScriptTextEditor::_on_caret_moved)); connection_gutter = 1; code_editor->get_text_editor()->add_gutter(connection_gutter); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 7aa0726479f..618027be255 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -85,7 +85,7 @@ class ScriptTextEditor : public ScriptEditorBase { PopupMenu *highlighter_menu = nullptr; PopupMenu *context_menu = nullptr; - GotoLineDialog *goto_line_dialog = nullptr; + GotoLinePopup *goto_line_popup = nullptr; ScriptEditorQuickOpen *quick_open = nullptr; ConnectionInfoDialog *connection_info_dialog = nullptr; diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 1262fe1ce8a..3097aa96e3d 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -468,7 +468,7 @@ void TextEditor::_edit_option(int p_op) { emit_signal(SNAME("replace_in_files_requested"), selected_text); } break; case SEARCH_GOTO_LINE: { - goto_line_dialog->popup_find_line(tx); + goto_line_popup->popup_find_line(code_editor); } break; case BOOKMARK_TOGGLE: { code_editor->toggle_bookmark(); @@ -706,8 +706,8 @@ TextEditor::TextEditor() { bookmarks_menu->connect("about_to_popup", callable_mp(this, &TextEditor::_update_bookmark_list)); bookmarks_menu->connect("index_pressed", callable_mp(this, &TextEditor::_bookmark_item_pressed)); - goto_line_dialog = memnew(GotoLineDialog); - add_child(goto_line_dialog); + goto_line_popup = memnew(GotoLinePopup); + add_child(goto_line_popup); } TextEditor::~TextEditor() { diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index b6c203f2a28..badeb91817a 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -53,7 +53,7 @@ private: PopupMenu *bookmarks_menu = nullptr; PopupMenu *context_menu = nullptr; - GotoLineDialog *goto_line_dialog = nullptr; + GotoLinePopup *goto_line_popup = nullptr; enum { EDIT_UNDO, diff --git a/editor/plugins/text_shader_editor.cpp b/editor/plugins/text_shader_editor.cpp index 0ff7aaa3fe4..30b259b14a1 100644 --- a/editor/plugins/text_shader_editor.cpp +++ b/editor/plugins/text_shader_editor.cpp @@ -712,7 +712,7 @@ void TextShaderEditor::_menu_option(int p_option) { code_editor->get_find_replace_bar()->popup_replace(); } break; case SEARCH_GOTO_LINE: { - goto_line_dialog->popup_find_line(code_editor->get_text_editor()); + goto_line_popup->popup_find_line(code_editor); } break; case BOOKMARK_TOGGLE: { code_editor->toggle_bookmark(); @@ -1235,8 +1235,8 @@ TextShaderEditor::TextShaderEditor() { editor_box->add_child(warnings_panel); code_editor->set_warnings_panel(warnings_panel); - goto_line_dialog = memnew(GotoLineDialog); - add_child(goto_line_dialog); + goto_line_popup = memnew(GotoLinePopup); + add_child(goto_line_popup); disk_changed = memnew(ConfirmationDialog); diff --git a/editor/plugins/text_shader_editor.h b/editor/plugins/text_shader_editor.h index 55efb4e30ed..afcb03e0589 100644 --- a/editor/plugins/text_shader_editor.h +++ b/editor/plugins/text_shader_editor.h @@ -145,7 +145,7 @@ class TextShaderEditor : public ShaderEditor { RichTextLabel *warnings_panel = nullptr; uint64_t idle = 0; - GotoLineDialog *goto_line_dialog = nullptr; + GotoLinePopup *goto_line_popup = nullptr; ConfirmationDialog *erase_tab_confirm = nullptr; ConfirmationDialog *disk_changed = nullptr;