diff options
30 files changed, 383 insertions, 21 deletions
diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp index 1b59508abf..eeaae96754 100644 --- a/core/core_string_names.cpp +++ b/core/core_string_names.cpp @@ -44,6 +44,7 @@ CoreStringNames::CoreStringNames() : _iter_next(StaticCString::create("_iter_next")), _iter_get(StaticCString::create("_iter_get")), get_rid(StaticCString::create("get_rid")), + _to_string(StaticCString::create("_to_string")), #ifdef TOOLS_ENABLED _sections_unfolded(StaticCString::create("_sections_unfolded")), #endif diff --git a/core/core_string_names.h b/core/core_string_names.h index 6fea40e1b2..85f8bb7f62 100644 --- a/core/core_string_names.h +++ b/core/core_string_names.h @@ -62,6 +62,7 @@ public: StringName _iter_next; StringName _iter_get; StringName get_rid; + StringName _to_string; #ifdef TOOLS_ENABLED StringName _sections_unfolded; #endif diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 81b3829ffc..d1b6b82cf0 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -1231,11 +1231,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo buf += 4; PoolVector<uint8_t>::Read r = data.read(); copymem(buf, &r[0], datalen * datasize); + buf += datalen * datasize; } r_len += 4 + datalen * datasize; - while (r_len % 4) + while (r_len % 4) { r_len++; + if (buf) + *(buf++) = 0; + } } break; case Variant::POOL_INT_ARRAY: { diff --git a/core/object.cpp b/core/object.cpp index 2a4ab93a6d..64f55f08a9 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -954,6 +954,16 @@ void Object::notification(int p_notification, bool p_reversed) { } } +String Object::to_string() { + if (script_instance) { + bool valid; + String ret = script_instance->to_string(&valid); + if (valid) + return ret; + } + return "[" + get_class() + ":" + itos(get_instance_id()) + "]"; +} + void Object::_changed_callback(Object *p_changed, const char *p_prop) { } @@ -1687,6 +1697,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("get_property_list"), &Object::_get_property_list_bind); ClassDB::bind_method(D_METHOD("get_method_list"), &Object::_get_method_list_bind); ClassDB::bind_method(D_METHOD("notification", "what", "reversed"), &Object::notification, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("to_string"), &Object::to_string); ClassDB::bind_method(D_METHOD("get_instance_id"), &Object::get_instance_id); ClassDB::bind_method(D_METHOD("set_script", "script"), &Object::set_script); @@ -1774,6 +1785,7 @@ void Object::_bind_methods() { #endif BIND_VMETHOD(MethodInfo("_init")); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_to_string")); BIND_CONSTANT(NOTIFICATION_POSTINITIALIZE); BIND_CONSTANT(NOTIFICATION_PREDELETE); diff --git a/core/object.h b/core/object.h index 57ebb32392..4394c1c3da 100644 --- a/core/object.h +++ b/core/object.h @@ -659,6 +659,7 @@ public: void call_multilevel(const StringName &p_name, VARIANT_ARG_LIST); // C++ helper void notification(int p_notification, bool p_reversed = false); + String to_string(); //used mainly by script, get and set all INCLUDING string virtual Variant getvar(const Variant &p_key, bool *r_valid = NULL) const; diff --git a/core/script_language.cpp b/core/script_language.cpp index 4a6f904f9d..97758ced66 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -30,6 +30,7 @@ #include "script_language.h" +#include "core/core_string_names.h" #include "core/project_settings.h" ScriptLanguage *ScriptServer::_languages[MAX_LANGUAGES]; diff --git a/core/script_language.h b/core/script_language.h index 005e21e2cc..b2dab666c4 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -173,6 +173,11 @@ public: virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount); virtual void notification(int p_notification) = 0; + virtual String to_string(bool *r_valid) { + if (r_valid) + *r_valid = false; + return String(); + } //this is used by script languages that keep a reference counter of their own //you can make make Ref<> not die when it reaches zero, so deleting the reference diff --git a/core/variant.cpp b/core/variant.cpp index 1bc3cff505..6eadf59fce 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1601,7 +1601,7 @@ String Variant::stringify(List<const void *> &stack) const { }; }; #endif - return "[" + _get_obj().obj->get_class() + ":" + itos(_get_obj().obj->get_instance_id()) + "]"; + return _get_obj().obj->to_string(); } else return "[Object:null]"; diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 9c2a65ce5b..0350162792 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -57,6 +57,22 @@ Sets a property. Returns [code]true[/code] if the [code]property[/code] exists. </description> </method> + <method name="_to_string" qualifiers="virtual"> + <return type="String"> + </return> + <description> + Returns a [String] representing the object. Default is [code]"[ClassName:RID]"[/code]. + Override this method to customize the [String] representation of the object when it's being converted to a string, for example: [code]print(obj)[/code]. + </description> + </method> + <method name="to_string"> + <return type="String"> + </return> + <description> + Returns a [String] representing the object. Default is [code]"[ClassName:RID]"[/code]. + Override the method [method _to_string] to customize the [String] representation. + </description> + </method> <method name="add_user_signal"> <return type="void"> </return> diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 7fd7b8dac3..695560ca34 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -765,6 +765,7 @@ void CodeTextEditor::update_editor_settings() { text_editor->set_highlight_current_line(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_current_line")); text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink")); text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); + text_editor->set_bookmark_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_bookmark_gutter")); text_editor->set_breakpoint_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter")); text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding")); text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding")); @@ -1204,6 +1205,7 @@ Variant CodeTextEditor::get_edit_state() { state["folded_lines"] = text_editor->get_folded_lines(); state["breakpoints"] = text_editor->get_breakpoints_array(); + state["bookmarks"] = text_editor->get_bookmarks_array(); state["syntax_highlighter"] = TTR("Standard"); SyntaxHighlighter *syntax_highlighter = text_editor->_get_syntax_highlighting(); @@ -1241,6 +1243,13 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) { } } + if (state.has("bookmarks")) { + Array bookmarks = state["bookmarks"]; + for (int i = 0; i < bookmarks.size(); i++) { + text_editor->set_line_as_bookmark(bookmarks[i], true); + } + } + text_editor->grab_focus(); } @@ -1358,6 +1367,70 @@ void CodeTextEditor::set_warning_nb(int p_warning_nb) { _set_show_warnings_panel(false); } +void CodeTextEditor::toggle_bookmark() { + + int line = text_editor->cursor_get_line(); + text_editor->set_line_as_bookmark(line, !text_editor->is_line_set_as_bookmark(line)); +} + +void CodeTextEditor::goto_next_bookmark() { + + List<int> bmarks; + text_editor->get_bookmarks(&bmarks); + if (bmarks.size() <= 0) { + return; + } + + int line = text_editor->cursor_get_line(); + if (line >= bmarks[bmarks.size() - 1]) { + text_editor->unfold_line(bmarks[0]); + text_editor->cursor_set_line(bmarks[0]); + } else { + for (List<int>::Element *E = bmarks.front(); E; E = E->next()) { + int bline = E->get(); + if (bline > line) { + text_editor->unfold_line(bline); + text_editor->cursor_set_line(bline); + return; + } + } + } +} + +void CodeTextEditor::goto_prev_bookmark() { + + List<int> bmarks; + text_editor->get_bookmarks(&bmarks); + if (bmarks.size() <= 0) { + return; + } + + int line = text_editor->cursor_get_line(); + if (line <= bmarks[0]) { + text_editor->unfold_line(bmarks[bmarks.size() - 1]); + text_editor->cursor_set_line(bmarks[bmarks.size() - 1]); + } else { + for (List<int>::Element *E = bmarks.back(); E; E = E->prev()) { + int bline = E->get(); + if (bline < line) { + text_editor->unfold_line(bline); + text_editor->cursor_set_line(bline); + return; + } + } + } +} + +void CodeTextEditor::remove_all_bookmarks() { + + List<int> bmarks; + text_editor->get_bookmarks(&bmarks); + + for (List<int>::Element *E = bmarks.front(); E; E = E->next()) { + text_editor->set_line_as_bookmark(E->get(), false); + } +} + void CodeTextEditor::_bind_methods() { ClassDB::bind_method("_text_editor_gui_input", &CodeTextEditor::_text_editor_gui_input); diff --git a/editor/code_editor.h b/editor/code_editor.h index b98af377ce..5c6b54ae44 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -234,6 +234,11 @@ public: virtual void apply_code() {} void goto_error(); + void toggle_bookmark(); + void goto_next_bookmark(); + void goto_prev_bookmark(); + void remove_all_bookmarks(); + void set_code_complete_func(CodeTextEditorCodeCompleteFunc p_code_complete_func, void *p_ud); CodeTextEditor(); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 356964cd90..cb40926ce3 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -430,6 +430,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { // Line numbers _initial_set("text_editor/line_numbers/show_line_numbers", true); _initial_set("text_editor/line_numbers/line_numbers_zero_padded", false); + _initial_set("text_editor/line_numbers/show_bookmark_gutter", true); _initial_set("text_editor/line_numbers/show_breakpoint_gutter", true); _initial_set("text_editor/line_numbers/show_info_gutter", true); _initial_set("text_editor/line_numbers/code_folding", true); @@ -647,6 +648,7 @@ void EditorSettings::_load_default_text_editor_theme() { _initial_set("text_editor/highlighting/function_color", Color::html("66a2ce")); _initial_set("text_editor/highlighting/member_variable_color", Color::html("e64e59")); _initial_set("text_editor/highlighting/mark_color", Color(1.0, 0.4, 0.4, 0.4)); + _initial_set("text_editor/highlighting/bookmark_color", Color(0.08, 0.49, 0.98)); _initial_set("text_editor/highlighting/breakpoint_color", Color(0.8, 0.8, 0.4, 0.2)); _initial_set("text_editor/highlighting/executing_line_color", Color(0.2, 0.8, 0.2, 0.4)); _initial_set("text_editor/highlighting/code_folding_color", Color(0.8, 0.8, 0.8, 0.8)); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index ba4dd9d7e2..ff38b4b650 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -1118,6 +1118,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color function_color = main_color; const Color member_variable_color = main_color.linear_interpolate(mono_color, 0.6); const Color mark_color = Color(error_color.r, error_color.g, error_color.b, 0.3); + const Color bookmark_color = Color(0.08, 0.49, 0.98); const Color breakpoint_color = error_color; const Color executing_line_color = Color(0.2, 0.8, 0.2, 0.4); const Color code_folding_color = alpha3; @@ -1154,6 +1155,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { setting->set_initial_value("text_editor/highlighting/function_color", function_color, true); setting->set_initial_value("text_editor/highlighting/member_variable_color", member_variable_color, true); setting->set_initial_value("text_editor/highlighting/mark_color", mark_color, true); + setting->set_initial_value("text_editor/highlighting/bookmark_color", bookmark_color, true); setting->set_initial_value("text_editor/highlighting/breakpoint_color", breakpoint_color, true); setting->set_initial_value("text_editor/highlighting/executing_line_color", executing_line_color, true); setting->set_initial_value("text_editor/highlighting/code_folding_color", code_folding_color, true); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index eaba48fa05..ff0959c8a1 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -213,6 +213,7 @@ void ScriptTextEditor::_load_theme_settings() { Color function_color = EDITOR_GET("text_editor/highlighting/function_color"); Color member_variable_color = EDITOR_GET("text_editor/highlighting/member_variable_color"); Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color"); + Color bookmark_color = EDITOR_GET("text_editor/highlighting/bookmark_color"); Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color"); Color executing_line_color = EDITOR_GET("text_editor/highlighting/executing_line_color"); Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color"); @@ -245,6 +246,7 @@ void ScriptTextEditor::_load_theme_settings() { text_edit->add_color_override("number_color", number_color); text_edit->add_color_override("function_color", function_color); text_edit->add_color_override("member_variable_color", member_variable_color); + text_edit->add_color_override("bookmark_color", bookmark_color); text_edit->add_color_override("breakpoint_color", breakpoint_color); text_edit->add_color_override("executing_line_color", executing_line_color); text_edit->add_color_override("mark_color", mark_color); @@ -376,7 +378,6 @@ void ScriptTextEditor::reload_text() { int v = te->get_v_scroll(); te->set_text(script->get_source_code()); - te->clear_undo_history(); te->cursor_set_line(row); te->cursor_set_column(column); te->set_h_scroll(h); @@ -1066,6 +1067,22 @@ void ScriptTextEditor::_edit_option(int p_op) { goto_line_dialog->popup_find_line(tx); } break; + case BOOKMARK_TOGGLE: { + + code_editor->toggle_bookmark(); + } break; + case BOOKMARK_GOTO_NEXT: { + + code_editor->goto_next_bookmark(); + } break; + case BOOKMARK_GOTO_PREV: { + + code_editor->goto_prev_bookmark(); + } break; + case BOOKMARK_REMOVE_ALL: { + + code_editor->remove_all_bookmarks(); + } break; case DEBUG_TOGGLE_BREAKPOINT: { int line = tx->cursor_get_line(); @@ -1500,6 +1517,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); if (p_selection) { context_menu->add_separator(); @@ -1652,6 +1670,16 @@ ScriptTextEditor::ScriptTextEditor() { search_menu->get_popup()->connect("id_pressed", this, "_edit_option"); + PopupMenu *bookmarks = memnew(PopupMenu); + bookmarks->set_name("bookmarks"); + edit_menu->get_popup()->add_child(bookmarks); + edit_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "bookmarks"); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); + bookmarks->connect("id_pressed", this, "_edit_option"); + edit_hb->add_child(edit_menu); quick_open = memnew(ScriptEditorQuickOpen); @@ -1693,6 +1721,10 @@ void ScriptTextEditor::register_editor() { ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), 0); ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0); ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD | KEY_K); + ED_SHORTCUT("script_text_editor/toggle_bookmark", TTR("Toggle Bookmark"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_B); + ED_SHORTCUT("script_text_editor/goto_next_bookmark", TTR("Go to Next Bookmark"), KEY_MASK_CMD | KEY_B); + ED_SHORTCUT("script_text_editor/goto_previous_bookmark", TTR("Go to Previous Bookmark"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B); + ED_SHORTCUT("script_text_editor/remove_all_bookmarks", TTR("Remove All Bookmarks"), 0); ED_SHORTCUT("script_text_editor/toggle_fold_line", TTR("Fold/Unfold Line"), KEY_MASK_ALT | KEY_F); ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), 0); ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0); @@ -1700,7 +1732,7 @@ void ScriptTextEditor::register_editor() { ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C); ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE); #else - ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_B); + ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D); ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE); #endif ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 0dbc884594..bdfdf18d45 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -128,6 +128,10 @@ class ScriptTextEditor : public ScriptEditorBase { SEARCH_LOCATE_FUNCTION, SEARCH_GOTO_LINE, SEARCH_IN_FILES, + BOOKMARK_TOGGLE, + BOOKMARK_GOTO_NEXT, + BOOKMARK_GOTO_PREV, + BOOKMARK_REMOVE_ALL, DEBUG_TOGGLE_BREAKPOINT, DEBUG_REMOVE_ALL_BREAKPOINTS, DEBUG_GOTO_NEXT_BREAKPOINT, diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 31660a9e19..a795405dfc 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -84,6 +84,7 @@ void ShaderTextEditor::_load_theme_settings() { Color function_color = EDITOR_GET("text_editor/highlighting/function_color"); Color member_variable_color = EDITOR_GET("text_editor/highlighting/member_variable_color"); Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color"); + Color bookmark_color = EDITOR_GET("text_editor/highlighting/bookmark_color"); Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color"); Color executing_line_color = EDITOR_GET("text_editor/highlighting/executing_line_color"); Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color"); @@ -113,6 +114,7 @@ void ShaderTextEditor::_load_theme_settings() { get_text_edit()->add_color_override("function_color", function_color); get_text_edit()->add_color_override("member_variable_color", member_variable_color); get_text_edit()->add_color_override("mark_color", mark_color); + get_text_edit()->add_color_override("bookmark_color", bookmark_color); get_text_edit()->add_color_override("breakpoint_color", breakpoint_color); get_text_edit()->add_color_override("executing_line_color", executing_line_color); get_text_edit()->add_color_override("code_folding_color", code_folding_color); @@ -304,6 +306,22 @@ void ShaderEditor::_menu_option(int p_option) { goto_line_dialog->popup_find_line(shader_editor->get_text_edit()); } break; + case BOOKMARK_TOGGLE: { + + shader_editor->toggle_bookmark(); + } break; + case BOOKMARK_GOTO_NEXT: { + + shader_editor->goto_next_bookmark(); + } break; + case BOOKMARK_GOTO_PREV: { + + shader_editor->goto_prev_bookmark(); + } break; + case BOOKMARK_REMOVE_ALL: { + + shader_editor->remove_all_bookmarks(); + } break; } if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) { shader_editor->get_text_edit()->call_deferred("grab_focus"); @@ -535,6 +553,16 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE); search_menu->get_popup()->connect("id_pressed", this, "_menu_option"); + PopupMenu *bookmarks = memnew(PopupMenu); + bookmarks->set_name("bookmarks"); + edit_menu->get_popup()->add_child(bookmarks); + edit_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "bookmarks"); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); + bookmarks->connect("id_pressed", this, "_edit_option"); + add_child(main_container); main_container->add_child(hbc); hbc->add_child(search_menu); diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index 46c78c1d33..28ac9faaa5 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -88,6 +88,10 @@ class ShaderEditor : public PanelContainer { SEARCH_FIND_PREV, SEARCH_REPLACE, SEARCH_GOTO_LINE, + BOOKMARK_TOGGLE, + BOOKMARK_GOTO_NEXT, + BOOKMARK_GOTO_PREV, + BOOKMARK_REMOVE_ALL, }; diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index becaae3567..a0f3c253d1 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -93,6 +93,7 @@ void TextEditor::_load_theme_settings() { Color function_color = EDITOR_GET("text_editor/highlighting/function_color"); Color member_variable_color = EDITOR_GET("text_editor/highlighting/member_variable_color"); Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color"); + Color bookmark_color = EDITOR_GET("text_editor/highlighting/bookmark_color"); Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color"); Color executing_line_color = EDITOR_GET("text_editor/highlighting/executing_line_color"); Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color"); @@ -127,6 +128,7 @@ void TextEditor::_load_theme_settings() { text_edit->add_color_override("breakpoint_color", breakpoint_color); text_edit->add_color_override("executing_line_color", executing_line_color); text_edit->add_color_override("mark_color", mark_color); + text_edit->add_color_override("bookmark_color", bookmark_color); text_edit->add_color_override("code_folding_color", code_folding_color); text_edit->add_color_override("search_result_color", search_result_color); text_edit->add_color_override("search_result_border_color", search_result_border_color); @@ -202,7 +204,6 @@ void TextEditor::reload_text() { int v = te->get_v_scroll(); te->set_text(text_file->get_text()); - te->clear_undo_history(); te->cursor_set_line(row); te->cursor_set_column(column); te->set_h_scroll(h); @@ -438,6 +439,22 @@ void TextEditor::_edit_option(int p_op) { goto_line_dialog->popup_find_line(tx); } break; + case BOOKMARK_TOGGLE: { + + code_editor->toggle_bookmark(); + } break; + case BOOKMARK_GOTO_NEXT: { + + code_editor->goto_next_bookmark(); + } break; + case BOOKMARK_GOTO_PREV: { + + code_editor->goto_prev_bookmark(); + } break; + case BOOKMARK_REMOVE_ALL: { + + code_editor->remove_all_bookmarks(); + } break; } } @@ -620,5 +637,15 @@ TextEditor::TextEditor() { highlighter_menu->add_radio_check_item(TTR("Standard")); highlighter_menu->connect("id_pressed", this, "_change_syntax_highlighter"); + PopupMenu *bookmarks = memnew(PopupMenu); + bookmarks->set_name("bookmarks"); + edit_menu->get_popup()->add_child(bookmarks); + edit_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "bookmarks"); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); + bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); + bookmarks->connect("id_pressed", this, "_edit_option"); + code_editor->get_text_edit()->set_drag_forwarding(this); } diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index 767001e2f6..2da7474793 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -87,6 +87,10 @@ private: SEARCH_FIND_PREV, SEARCH_REPLACE, SEARCH_GOTO_LINE, + BOOKMARK_TOGGLE, + BOOKMARK_GOTO_NEXT, + BOOKMARK_GOTO_PREV, + BOOKMARK_REMOVE_ALL, }; protected: diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index c2aa8427b4..f30c9da4c1 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -32,6 +32,7 @@ #include "gdnative/gdnative.h" +#include "core/core_string_names.h" #include "core/global_constants.h" #include "core/io/file_access_encrypted.h" #include "core/os/file_access.h" @@ -771,6 +772,27 @@ void NativeScriptInstance::notification(int p_notification) { call_multilevel("_notification", args, 1); } +String NativeScriptInstance::to_string(bool *r_valid) { + if (has_method(CoreStringNames::get_singleton()->_to_string)) { + Variant::CallError ce; + Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce); + if (ce.error == Variant::CallError::CALL_OK) { + if (ret.get_type() != Variant::STRING) { + if (r_valid) + *r_valid = false; + ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String."); + ERR_FAIL_V(String()); + } + if (r_valid) + *r_valid = true; + return ret.operator String(); + } + } + if (r_valid) + *r_valid = false; + return String(); +} + void NativeScriptInstance::refcount_incremented() { Variant::CallError err; call("_refcount_incremented", NULL, 0, err); diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index a6865c6243..be1c499714 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -208,6 +208,7 @@ public: virtual bool has_method(const StringName &p_method) const; virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); virtual void notification(int p_notification); + String to_string(bool *r_valid); virtual Ref<Script> get_script() const; virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index d7a809eb5f..3fb9268702 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -30,6 +30,7 @@ #include "gdscript.h" +#include "core/core_string_names.h" #include "core/engine.h" #include "core/global_constants.h" #include "core/io/file_access_encrypted.h" @@ -1234,6 +1235,27 @@ void GDScriptInstance::notification(int p_notification) { } } +String GDScriptInstance::to_string(bool *r_valid) { + if (has_method(CoreStringNames::get_singleton()->_to_string)) { + Variant::CallError ce; + Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce); + if (ce.error == Variant::CallError::CALL_OK) { + if (ret.get_type() != Variant::STRING) { + if (r_valid) + *r_valid = false; + ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String."); + ERR_FAIL_V(String()); + } + if (r_valid) + *r_valid = true; + return ret.operator String(); + } + } + if (r_valid) + *r_valid = false; + return String(); +} + Ref<Script> GDScriptInstance::get_script() const { return script; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 38009b878d..716f536e89 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -251,6 +251,7 @@ public: Variant debug_get_member_by_index(int p_idx) const { return members[p_idx]; } virtual void notification(int p_notification); + String to_string(bool *r_valid); virtual Ref<Script> get_script() const; diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 581809fec9..8f311d11f4 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -30,6 +30,7 @@ #include "visual_script.h" +#include "core/core_string_names.h" #include "core/os/os.h" #include "core/project_settings.h" #include "scene/main/node.h" @@ -1976,6 +1977,27 @@ void VisualScriptInstance::notification(int p_notification) { call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); //do as call } +String VisualScriptInstance::to_string(bool *r_valid) { + if (has_method(CoreStringNames::get_singleton()->_to_string)) { + Variant::CallError ce; + Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce); + if (ce.error == Variant::CallError::CALL_OK) { + if (ret.get_type() != Variant::STRING) { + if (r_valid) + *r_valid = false; + ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String."); + ERR_FAIL_V(String()); + } + if (r_valid) + *r_valid = true; + return ret.operator String(); + } + } + if (r_valid) + *r_valid = false; + return String(); +} + Ref<Script> VisualScriptInstance::get_script() const { return script; diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 0171b8e6f1..91748d077b 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -405,6 +405,7 @@ public: virtual bool has_method(const StringName &p_method) const; virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); virtual void notification(int p_notification); + String to_string(bool *r_valid); bool set_variable(const StringName &p_variable, const Variant &p_value) { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 11fb92a946..4f71ae63c3 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -289,7 +289,7 @@ void Control::_update_minimum_size() { Size2 minsize = get_combined_minimum_size(); if (minsize.x > data.size_cache.x || minsize.y > data.size_cache.y) { - _size_changed(); + set_size(data.size_cache); } data.updating_last_minimum_size = false; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 8acd28a2f4..1a000d8da5 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -292,6 +292,7 @@ void TextEdit::Text::insert(int p_at, const String &p_text) { line.marked = false; line.safe = false; line.breakpoint = false; + line.bookmark = false; line.hidden = false; line.width_cache = -1; line.wrap_amount_cache = -1; @@ -346,7 +347,7 @@ void TextEdit::_update_scrollbars() { if (line_numbers) total_width += cache.line_number_w; - if (draw_breakpoint_gutter) { + if (draw_breakpoint_gutter || draw_bookmark_gutter) { total_width += cache.breakpoint_gutter_width; } @@ -605,7 +606,7 @@ void TextEdit::_notification(int p_what) { draw_caret = false; } - if (draw_breakpoint_gutter) { + if (draw_breakpoint_gutter || draw_bookmark_gutter) { breakpoint_gutter_width = (get_row_height() * 55) / 100; cache.breakpoint_gutter_width = breakpoint_gutter_width; } else { @@ -954,6 +955,16 @@ void TextEdit::_notification(int p_what) { #endif } + // draw bookmark marker + if (text.is_bookmark(line)) { + if (draw_bookmark_gutter) { + int vertical_gap = (get_row_height() * 40) / 100; + int horizontal_gap = (cache.breakpoint_gutter_width * 30) / 100; + int marker_radius = get_row_height() - (vertical_gap * 2); + VisualServer::get_singleton()->canvas_item_add_circle(ci, Point2(cache.style_normal->get_margin(MARGIN_LEFT) + horizontal_gap - 2 + marker_radius / 2, ofs_y + vertical_gap + marker_radius / 2), marker_radius, Color(cache.bookmark_color.r, cache.bookmark_color.g, cache.bookmark_color.b)); + } + } + // draw breakpoint marker if (text.is_breakpoint(line)) { if (draw_breakpoint_gutter) { @@ -4303,17 +4314,22 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const { void TextEdit::set_text(String p_text) { setting_text = true; - _clear(); - _insert_text_at_cursor(p_text); - clear_undo_history(); - cursor.column = 0; - cursor.line = 0; - cursor.x_ofs = 0; - cursor.line_ofs = 0; - cursor.wrap_ofs = 0; - cursor.last_fit_x = 0; - cursor_set_line(0); - cursor_set_column(0); + if (!undo_enabled) { + _clear(); + _insert_text_at_cursor(p_text); + } + + if (undo_enabled) { + cursor_set_line(0); + cursor_set_column(0); + + begin_complex_operation(); + _remove_text(0, 0, MAX(0, get_line_count() - 1), MAX(get_line(MAX(get_line_count() - 1, 0)).size() - 1, 0)); + _insert_text_at_cursor(p_text); + end_complex_operation(); + selection.active = false; + } + update(); setting_text = false; @@ -4499,6 +4515,7 @@ void TextEdit::_update_caches() { cache.mark_color = get_color("mark_color"); cache.current_line_color = get_color("current_line_color"); cache.line_length_guideline_color = get_color("line_length_guideline_color"); + cache.bookmark_color = get_color("bookmark_color"); cache.breakpoint_color = get_color("breakpoint_color"); cache.executing_line_color = get_color("executing_line_color"); cache.code_folding_color = get_color("code_folding_color"); @@ -5096,6 +5113,37 @@ void TextEdit::clear_executing_line() { update(); } +bool TextEdit::is_line_set_as_bookmark(int p_line) const { + + ERR_FAIL_INDEX_V(p_line, text.size(), false); + return text.is_bookmark(p_line); +} + +void TextEdit::set_line_as_bookmark(int p_line, bool p_bookmark) { + + ERR_FAIL_INDEX(p_line, text.size()); + text.set_bookmark(p_line, p_bookmark); + update(); +} + +void TextEdit::get_bookmarks(List<int> *p_bookmarks) const { + + for (int i = 0; i < text.size(); i++) { + if (text.is_bookmark(i)) + p_bookmarks->push_back(i); + } +} + +Array TextEdit::get_bookmarks_array() const { + + Array arr; + for (int i = 0; i < text.size(); i++) { + if (text.is_bookmark(i)) + arr.append(i); + } + return arr; +} + bool TextEdit::is_line_set_as_breakpoint(int p_line) const { ERR_FAIL_INDEX_V(p_line, text.size(), false); @@ -6183,6 +6231,15 @@ void TextEdit::set_line_length_guideline_column(int p_column) { update(); } +void TextEdit::set_bookmark_gutter_enabled(bool p_draw) { + draw_bookmark_gutter = p_draw; + update(); +} + +bool TextEdit::is_bookmark_gutter_enabled() const { + return draw_bookmark_gutter; +} + void TextEdit::set_breakpoint_gutter_enabled(bool p_draw) { draw_breakpoint_gutter = p_draw; update(); @@ -6579,6 +6636,7 @@ TextEdit::TextEdit() { line_numbers_zero_padded = false; line_length_guideline = false; line_length_guideline_col = 80; + draw_bookmark_gutter = false; draw_breakpoint_gutter = false; draw_fold_gutter = false; draw_info_gutter = false; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index eb9fb2cf57..3f83c9975e 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -75,6 +75,7 @@ public: int width_cache : 24; bool marked : 1; bool breakpoint : 1; + bool bookmark : 1; bool hidden : 1; bool safe : 1; int wrap_amount_cache : 24; @@ -105,6 +106,8 @@ public: void set(int p_line, const String &p_text); void set_marked(int p_line, bool p_marked) { text.write[p_line].marked = p_marked; } bool is_marked(int p_line) const { return text[p_line].marked; } + void set_bookmark(int p_line, bool p_bookmark) { text.write[p_line].bookmark = p_bookmark; } + bool is_bookmark(int p_line) const { return text[p_line].bookmark; } void set_breakpoint(int p_line, bool p_breakpoint) { text.write[p_line].breakpoint = p_breakpoint; } bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; } void set_hidden(int p_line, bool p_hidden) { text.write[p_line].hidden = p_hidden; } @@ -188,6 +191,7 @@ private: Color member_variable_color; Color selection_color; Color mark_color; + Color bookmark_color; Color breakpoint_color; Color executing_line_color; Color code_folding_color; @@ -300,6 +304,7 @@ private: bool line_numbers_zero_padded; bool line_length_guideline; int line_length_guideline_col; + bool draw_bookmark_gutter; bool draw_breakpoint_gutter; int breakpoint_gutter_width; bool draw_fold_gutter; @@ -490,6 +495,10 @@ public: void insert_at(const String &p_text, int at); int get_line_count() const; void set_line_as_marked(int p_line, bool p_marked); + void set_line_as_bookmark(int p_line, bool p_bookmark); + bool is_line_set_as_bookmark(int p_line) const; + void get_bookmarks(List<int> *p_bookmarks) const; + Array get_bookmarks_array() const; void set_line_as_breakpoint(int p_line, bool p_breakpoint); bool is_line_set_as_breakpoint(int p_line) const; void set_executing_line(int p_line); @@ -664,6 +673,9 @@ public: void set_show_line_length_guideline(bool p_show); void set_line_length_guideline_column(int p_column); + void set_bookmark_gutter_enabled(bool p_draw); + bool is_bookmark_gutter_enabled() const; + void set_breakpoint_gutter_enabled(bool p_draw); bool is_breakpoint_gutter_enabled() const; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index f22fe5b6a5..049cae9dd9 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -2266,7 +2266,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { next = _n; } else { - return; + break; } } if (next == selected_item) @@ -2304,7 +2304,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { prev = _n; } else { - return; + break; } } if (prev == selected_item) diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 0b88763300..bdb6c78782 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -441,6 +441,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color_selected", "TextEdit", Color(0, 0, 0)); theme->set_color("selection_color", "TextEdit", font_color_selection); theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4)); + theme->set_color("bookmark_color", "TextEdit", Color(0.08, 0.49, 0.98)); theme->set_color("breakpoint_color", "TextEdit", Color(0.8, 0.8, 0.4, 0.2)); theme->set_color("executing_line_color", "TextEdit", Color(0.2, 0.8, 0.2, 0.4)); theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8)); |