From 3a068b97196ea2b98dc28f3f5adfecbf44b0e004 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Mon, 8 Jan 2024 10:56:53 +0100 Subject: [PATCH] impr: Use ImGui's built-in drag n drop support for bookmarks --- .../include/content/views/view_bookmarks.hpp | 1 - .../source/content/tools/color_picker.cpp | 2 +- .../source/content/views/view_bookmarks.cpp | 58 +++++++++++++------ 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/plugins/builtin/include/content/views/view_bookmarks.hpp b/plugins/builtin/include/content/views/view_bookmarks.hpp index a126a2fd1..8874a0b21 100644 --- a/plugins/builtin/include/content/views/view_bookmarks.hpp +++ b/plugins/builtin/include/content/views/view_bookmarks.hpp @@ -28,7 +28,6 @@ namespace hex::plugin::builtin { TextEditor editor; }; - std::list::iterator m_dragStartIterator; PerProvider> m_bookmarks; PerProvider m_currBookmarkId; }; diff --git a/plugins/builtin/source/content/tools/color_picker.cpp b/plugins/builtin/source/content/tools/color_picker.cpp index 05b24bd0f..d1851dbd6 100644 --- a/plugins/builtin/source/content/tools/color_picker.cpp +++ b/plugins/builtin/source/content/tools/color_picker.cpp @@ -86,7 +86,7 @@ namespace hex::plugin::builtin { drawBitsSlider(&bitValue); // Configure drag and drop source and target - if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) { + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoPreviewTooltip)) { // Set the current slider index as the payload ImGui::SetDragDropPayload("BIT_VALUE", &index, sizeof(u32)); diff --git a/plugins/builtin/source/content/views/view_bookmarks.cpp b/plugins/builtin/source/content/views/view_bookmarks.cpp index 53633199a..2b9cf8b71 100644 --- a/plugins/builtin/source/content/views/view_bookmarks.cpp +++ b/plugins/builtin/source/content/views/view_bookmarks.cpp @@ -253,7 +253,6 @@ namespace hex::plugin::builtin { ImGuiExt::TextFormattedCentered("hex.builtin.view.bookmarks.no_bookmarks"_lang); } - int id = 1; auto bookmarkToRemove = m_bookmarks->end(); // Draw all bookmarks @@ -272,34 +271,58 @@ namespace hex::plugin::builtin { hoverColor.Value.w *= 1.3F; // Draw bookmark header in the same color as the bookmark was set to - ImGui::PushID(id); + ImGui::PushID(bookmarkId); ImGui::PushStyleColor(ImGuiCol_Header, color); ImGui::PushStyleColor(ImGuiCol_HeaderActive, color); ImGui::PushStyleColor(ImGuiCol_HeaderHovered, u32(hoverColor)); ON_SCOPE_EXIT { - ImGui::PopID(); ImGui::PopStyleColor(3); - id++; + ImGui::PopID(); }; bool open = true; if (!ImGui::CollapsingHeader(hex::format("{}###bookmark", name).c_str(), locked ? nullptr : &open)) { // Handle dragging bookmarks up and down when they're collapsed - // Set the currently held bookmark as the one being dragged - if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && m_dragStartIterator == m_bookmarks->end()) - m_dragStartIterator = it; + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) { + // Set the payload to the bookmark id + ImGui::SetDragDropPayload("BOOKMARK_PAYLOAD", &bookmarkId, sizeof(bookmarkId)); - // When the mouse moved away from the current bookmark, swap the dragged bookmark with the current one - if (ImGui::IsItemHovered() && m_dragStartIterator != m_bookmarks->end()) { - std::iter_swap(it, m_dragStartIterator); - m_dragStartIterator = it; + // Draw drag and drop tooltip + ImGui::ColorButton("##color", headerColor.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoAlpha); + ImGui::SameLine(); + ImGuiExt::TextFormatted("{}", name); + ImGui::Separator(); + + if (!comment.empty()) { + ImGui::PushTextWrapPos(300_scaled); + ImGuiExt::TextFormatted("{}", comment); + ImGui::PopTextWrapPos(); + } + + ImGui::EndDragDropSource(); } - // When the mouse is released, reset the dragged bookmark - if (!ImGui::IsMouseDown(0)) - m_dragStartIterator = m_bookmarks->end(); + if (ImGui::BeginDragDropTarget()) { + + if (auto payload = ImGui::AcceptDragDropPayload("BOOKMARK_PAYLOAD"); payload != nullptr) { + // Receive the bookmark id from the payload + u64 droppedBookmarkId = *static_cast(payload->Data); + + // Find the correct bookmark with that id + auto droppedIter = std::ranges::find_if(m_bookmarks->begin(), m_bookmarks->end(), [droppedBookmarkId](const auto &bookmark) { + return bookmark.entry.id == droppedBookmarkId; + }); + + // Swap the two bookmarks + if (droppedIter != m_bookmarks->end()) { + std::iter_swap(it, droppedIter); + } + } + + ImGui::EndDragDropTarget(); + } } else { const auto rowHeight = ImGui::GetTextLineHeightWithSpacing() + 2 * ImGui::GetStyle().FramePadding.y; if (ImGui::BeginTable("##bookmark_table", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit)) { @@ -465,15 +488,14 @@ namespace hex::plugin::builtin { .comment = bookmark["comment"], .color = bookmark["color"], .locked = bookmark["locked"], - .id = bookmark.contains("id") ? bookmark["id"].get() : *m_currBookmarkId + .id = bookmark.contains("id") ? bookmark["id"].get() : m_currBookmarkId.get(provider) }, editor }); - if (bookmark.contains("id")) - m_currBookmarkId = std::max(m_currBookmarkId, bookmark["id"].get() + 1); + m_currBookmarkId.get(provider) = std::max(m_currBookmarkId.get(provider), bookmark["id"].get() + 1); else - m_currBookmarkId += 1; + m_currBookmarkId.get(provider) += 1; } return true;