From 7c4afdbca4b182e38cf47855043afc9dc556eb51 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 01:22:44 -0700 Subject: [PATCH] feat(editor): double-click in NPC/object list flies camera to entry Single-click selects, double-click also flies to. Removes the trip back to the side panel to hit the Fly To button when navigating long lists. --- tools/editor/editor_ui.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index 6ee08a6a..3eecf50d 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -1592,6 +1592,7 @@ void EditorUI::renderObjectPanel(EditorApp& app) { ImGui::Separator(); ImGui::Text("Placed: %zu objects (open format: WOM)", placer.objectCount()); if (placer.objectCount() > 0 && ImGui::CollapsingHeader("Object List")) { + ImGui::TextDisabled("Click to select, double-click to fly to"); ImGui::BeginChild("ObjPlacedList", ImVec2(0, 100), true); for (int i = 0; i < static_cast(placer.objectCount()); i++) { auto& o = const_cast&>(placer.getObjects())[i]; @@ -1601,13 +1602,15 @@ void EditorUI::renderObjectPanel(EditorApp& app) { char lbl[128]; std::snprintf(lbl, sizeof(lbl), "%s (%.0f,%.0f,%.0f)##obj%d", disp.c_str(), o.position.x, o.position.y, o.position.z, i); - if (ImGui::Selectable(lbl, o.selected)) { + if (ImGui::Selectable(lbl, o.selected, ImGuiSelectableFlags_AllowDoubleClick)) { placer.clearSelection(); // Select by creating a ray through the object position rendering::Ray r; r.origin = o.position + glm::vec3(0, 0, 1); r.direction = glm::vec3(0, 0, -1); placer.selectAt(r, 1000.0f); + if (ImGui::IsMouseDoubleClicked(0)) + app.flyToSelected(); } } ImGui::EndChild(); @@ -1907,7 +1910,7 @@ void EditorUI::renderNpcPanel(EditorApp& app) { // ---- Spawned list ---- if (ImGui::CollapsingHeader("Spawned Creatures", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::Text("%zu placed", spawner.spawnCount()); + ImGui::Text("%zu placed (double-click to fly to)", spawner.spawnCount()); ImGui::BeginChild("SpawnList", ImVec2(0, 100), true); for (int i = 0; i < static_cast(spawner.spawnCount()); i++) { auto& s = spawner.getSpawns()[i]; @@ -1916,8 +1919,11 @@ void EditorUI::renderNpcPanel(EditorApp& app) { std::snprintf(label, sizeof(label), "%s Lv%u (%.0f,%.0f,%.0f)", s.name.c_str(), s.level, s.position.x, s.position.y, s.position.z); - if (ImGui::Selectable(label, sel)) + if (ImGui::Selectable(label, sel, ImGuiSelectableFlags_AllowDoubleClick)) { spawner.selectAt(s.position, 10000.0f); + if (ImGui::IsMouseDoubleClicked(0)) + app.flyToSelected(); + } } ImGui::EndChild(); }