From f0bf4032544e82a6203f0791247bc7c1c94e21aa Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Fri, 20 Feb 2026 02:08:16 -0800 Subject: [PATCH] Add a delete button to the highlighted element. PiperOrigin-RevId: 872795277 Change-Id: I63afa9c87b425ebed5d20126e9909ad95532d559 --- src/experimental/studio/app.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/experimental/studio/app.cc b/src/experimental/studio/app.cc index 30a2166e..2454821f 100644 --- a/src/experimental/studio/app.cc +++ b/src/experimental/studio/app.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -1130,7 +1131,8 @@ void App::SpecExplorerGui() { const ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_Framed; - auto display_group = [this](mjtObj type, const std::string& prefix) { + auto display_group = [this](mjtObj type, const std::string& prefix, + std::function delete_callback = {}) { mjsElement* element = mjs_firstElement(spec(), type); while (element) { const int id = mjs_getId(element); @@ -1142,17 +1144,28 @@ void App::SpecExplorerGui() { } const bool selected = (tmp_.element == element); - if (ImGui::Selectable(label.c_str(), selected)) { + if (ImGui::Selectable(label.c_str(), selected, + ImGuiSelectableFlags_AllowOverlap)) { tmp_.element = element; tmp_.element_id = id; } + if (selected && delete_callback) { + // Right-align the delete button. + const float button_width = ImGui::CalcTextSize(ICON_DELETE).x + + ImGui::GetStyle().FramePadding.x * 2.0f; + ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - button_width); + if (ImGui::SmallButton(ICON_DELETE)) { + delete_callback(); + } + } + element = mjs_nextElement(spec(), element); } }; if (ImGui::TreeNodeEx("Bodies", flags)) { - display_group(mjOBJ_BODY, "Body"); + display_group(mjOBJ_BODY, "Body", [this] { SpecDeleteSelectedElement(); }); ImGui::TreePop(); }