diff options
-rw-r--r-- | editor/debugger/editor_debugger_node.cpp | 1 | ||||
-rw-r--r-- | editor/debugger/script_editor_debugger.cpp | 114 | ||||
-rw-r--r-- | editor/debugger/script_editor_debugger.h | 9 |
3 files changed, 123 insertions, 1 deletions
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 5bc2be60a7..e9d275895f 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -95,6 +95,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { node->connect("stopped", callable_mp(this, &EditorDebuggerNode::_debugger_stopped), varray(id)); node->connect("stack_frame_selected", callable_mp(this, &EditorDebuggerNode::_stack_frame_selected), varray(id)); node->connect("error_selected", callable_mp(this, &EditorDebuggerNode::_error_selected), varray(id)); + node->connect("breakpoint_selected", callable_mp(this, &EditorDebuggerNode::_error_selected), varray(id)); node->connect("clear_execution", callable_mp(this, &EditorDebuggerNode::_clear_execution)); node->connect("breaked", callable_mp(this, &EditorDebuggerNode::_breaked), varray(id)); node->connect("remote_tree_updated", callable_mp(this, &EditorDebuggerNode::_remote_tree_updated), varray(id)); diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index df9f02023a..c38c10cd10 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -788,6 +788,7 @@ void ScriptEditorDebugger::_notification(int p_what) { le_clear->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_live_edit_clear)); error_tree->connect("item_selected", callable_mp(this, &ScriptEditorDebugger::_error_selected)); error_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_error_activated)); + breakpoints_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_breakpoint_tree_clicked)); vmem_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons"))); search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); @@ -895,6 +896,13 @@ void ScriptEditorDebugger::_clear_breakpoints() { emit_signal("clear_breakpoints"); } +void ScriptEditorDebugger::_breakpoint_tree_clicked() { + TreeItem *selected = breakpoints_tree->get_selected(); + if (selected->has_meta("line")) { + emit_signal(SNAME("breakpoint_selected"), selected->get_parent()->get_text(0), int(selected->get_meta("line"))); + } +} + void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) { _clear_errors_list(); stop(); @@ -1353,6 +1361,45 @@ void ScriptEditorDebugger::set_breakpoint(const String &p_path, int p_line, bool msg.push_back(p_line); msg.push_back(p_enabled); _put_msg("breakpoint", msg); + + TreeItem *path_item = breakpoints_tree->search_item_text(p_path); + if (path_item == nullptr) { + if (!p_enabled) { + return; + } + path_item = breakpoints_tree->create_item(); + path_item->set_text(0, p_path); + } + + int idx = 0; + TreeItem *breakpoint_item; + for (breakpoint_item = path_item->get_first_child(); breakpoint_item; breakpoint_item = breakpoint_item->get_next()) { + if ((int)breakpoint_item->get_meta("line") < p_line) { + idx++; + continue; + } + + if ((int)breakpoint_item->get_meta("line") == p_line) { + break; + } + } + + if (breakpoint_item == nullptr) { + if (!p_enabled) { + return; + } + breakpoint_item = breakpoints_tree->create_item(path_item, idx); + breakpoint_item->set_meta("line", p_line); + breakpoint_item->set_text(0, vformat(TTR("Line %d"), p_line)); + return; + } + + if (!p_enabled) { + path_item->remove_child(breakpoint_item); + if (path_item->get_first_child() == nullptr) { + breakpoints_tree->get_root()->remove_child(path_item); + } + } } void ScriptEditorDebugger::reload_scripts() { @@ -1419,6 +1466,23 @@ void ScriptEditorDebugger::_clear_errors_list() { clear_button->set_disabled(true); } +void ScriptEditorDebugger::_breakpoints_item_rmb_selected(const Vector2 &p_pos) { + breakpoints_menu->clear(); + breakpoints_menu->set_size(Size2(1, 1)); + + const TreeItem *selected = breakpoints_tree->get_selected(); + String file = selected->get_text(0); + if (selected->has_meta("line")) { + breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Breakpoint"), ACTION_DELETE_BREAKPOINT); + file = selected->get_parent()->get_text(0); + } + breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete All Breakpoints in: ") + file, ACTION_DELETE_BREAKPOINTS_IN_FILE); + breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete All Breakpoints"), ACTION_DELETE_ALL_BREAKPOINTS); + + breakpoints_menu->set_position(breakpoints_tree->get_global_position() + p_pos); + breakpoints_menu->popup(); +} + // Right click on specific file(s) or folder(s). void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) { item_menu->clear(); @@ -1493,6 +1557,29 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { line_number)); } } break; + case ACTION_DELETE_BREAKPOINT: { + const TreeItem *selected = breakpoints_tree->get_selected(); + _set_breakpoint(selected->get_parent()->get_text(0), selected->get_meta("line"), false); + } break; + case ACTION_DELETE_BREAKPOINTS_IN_FILE: { + TreeItem *file_item = breakpoints_tree->get_selected(); + if (file_item->has_meta("line")) { + file_item = file_item->get_parent(); + } + + // Store first else we will be removing as we loop. + List<int> lines; + for (TreeItem *breakpoint_item = file_item->get_first_child(); breakpoint_item; breakpoint_item = breakpoint_item->get_next()) { + lines.push_back(breakpoint_item->get_meta("line")); + } + + for (const int &line : lines) { + _set_breakpoint(file_item->get_text(0), line, false); + } + } break; + case ACTION_DELETE_ALL_BREAKPOINTS: { + _clear_breakpoints(); + } break; } } @@ -1519,6 +1606,7 @@ void ScriptEditorDebugger::_bind_methods() { ADD_SIGNAL(MethodInfo("stop_requested")); ADD_SIGNAL(MethodInfo("stack_frame_selected", PropertyInfo(Variant::INT, "frame"))); ADD_SIGNAL(MethodInfo("error_selected", PropertyInfo(Variant::INT, "error"))); + ADD_SIGNAL(MethodInfo("breakpoint_selected", PropertyInfo("script"), PropertyInfo(Variant::INT, "line"))); ADD_SIGNAL(MethodInfo("set_execution", PropertyInfo("script"), PropertyInfo(Variant::INT, "line"))); ADD_SIGNAL(MethodInfo("clear_execution", PropertyInfo("script"))); ADD_SIGNAL(MethodInfo("breaked", PropertyInfo(Variant::BOOL, "reallydid"), PropertyInfo(Variant::BOOL, "can_debug"), PropertyInfo(Variant::STRING, "reason"), PropertyInfo(Variant::BOOL, "has_stackdump"))); @@ -1646,9 +1734,15 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { docontinue->set_shortcut(ED_GET_SHORTCUT("debugger/continue")); docontinue->connect("pressed", callable_mp(this, &ScriptEditorDebugger::debug_continue)); + HSplitContainer *parent_sc = memnew(HSplitContainer); + vbc->add_child(parent_sc); + parent_sc->set_v_size_flags(SIZE_EXPAND_FILL); + parent_sc->set_split_offset(500 * EDSCALE); + HSplitContainer *sc = memnew(HSplitContainer); - vbc->add_child(sc); sc->set_v_size_flags(SIZE_EXPAND_FILL); + sc->set_h_size_flags(SIZE_EXPAND_FILL); + parent_sc->add_child(sc); stack_dump = memnew(Tree); stack_dump->set_allow_reselect(true); @@ -1661,6 +1755,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { sc->add_child(stack_dump); VBoxContainer *inspector_vbox = memnew(VBoxContainer); + inspector_vbox->set_h_size_flags(SIZE_EXPAND_FILL); sc->add_child(inspector_vbox); HBoxContainer *tools_hb = memnew(HBoxContainer); @@ -1683,7 +1778,24 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { inspector->register_text_enter(search); inspector->set_use_filter(true); inspector_vbox->add_child(inspector); + sc->add_child(inspector); + + breakpoints_tree = memnew(Tree); + breakpoints_tree->set_h_size_flags(SIZE_EXPAND_FILL); + breakpoints_tree->set_column_titles_visible(true); + breakpoints_tree->set_column_title(0, TTR("Breakpoints")); + breakpoints_tree->set_allow_reselect(true); + breakpoints_tree->set_allow_rmb_select(true); + breakpoints_tree->set_hide_root(true); + breakpoints_tree->connect("item_rmb_selected", callable_mp(this, &ScriptEditorDebugger::_breakpoints_item_rmb_selected)); + breakpoints_tree->create_item(); + + parent_sc->add_child(breakpoints_tree); tabs->add_child(dbg); + + breakpoints_menu = memnew(PopupMenu); + breakpoints_menu->connect("id_pressed", callable_mp(this, &ScriptEditorDebugger::_item_menu_id_pressed)); + breakpoints_tree->add_child(breakpoints_menu); } { //errors diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h index ceb30e4565..c061e7c61e 100644 --- a/editor/debugger/script_editor_debugger.h +++ b/editor/debugger/script_editor_debugger.h @@ -81,6 +81,9 @@ private: enum Actions { ACTION_COPY_ERROR, ACTION_OPEN_SOURCE, + ACTION_DELETE_BREAKPOINT, + ACTION_DELETE_BREAKPOINTS_IN_FILE, + ACTION_DELETE_ALL_BREAKPOINTS, }; AcceptDialog *msgdialog; @@ -99,6 +102,9 @@ private: Button *clear_button; PopupMenu *item_menu; + Tree *breakpoints_tree; + PopupMenu *breakpoints_menu; + EditorFileDialog *file_dialog; enum FileDialogPurpose { SAVE_MONITORS_CSV, @@ -198,6 +204,7 @@ private: void _clear_errors_list(); + void _breakpoints_item_rmb_selected(const Vector2 &p_pos); void _error_tree_item_rmb_selected(const Vector2 &p_pos); void _item_menu_id_pressed(int p_option); void _tab_changed(int p_tab); @@ -211,6 +218,8 @@ private: void _set_breakpoint(const String &p_path, const int &p_line, const bool &p_enabled); void _clear_breakpoints(); + void _breakpoint_tree_clicked(); + protected: void _notification(int p_what); static void _bind_methods(); |