diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d6d9f2c3..fca9b189 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -41,6 +41,8 @@ Other Changes: - TreeNode: Fixed bug where BeginDragDropSource() failed when the _OpenOnDoubleClick flag is enabled (bug introduced in 1.76, but pre-1.76 it would also fail unless the _OpenOnArrow flag was also set, and _OpenOnArrow is frequently set along with _OpenOnDoubleClick). +- TreeNode: Fixed bug where dragging a payload over a TreeNode() with either _OpenOnDoubleClick + or _OpenOnArrow would open the node. (#143) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 1161a580..a1cdfe50 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3795,6 +3795,7 @@ void ImGui::NewFrame() g.DragDropAcceptIdCurrRectSurface = FLT_MAX; g.DragDropWithinSource = false; g.DragDropWithinTarget = false; + g.DragDropHoldJustPressedId = 0; // Update keyboard input state // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools diff --git a/imgui_internal.h b/imgui_internal.h index 3f35b8c2..0735d727 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1165,6 +1165,7 @@ struct ImGuiContext ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source + ImGuiID DragDropHoldJustPressedId; // Set when holding a payload just made ButtonBehavior() return a press. ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly, ImGuiPayload only holds pointer+size unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads @@ -1320,6 +1321,7 @@ struct ImGuiContext DragDropAcceptIdCurrRectSurface = 0.0f; DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; DragDropAcceptFrameCount = -1; + DragDropHoldJustPressedId = 0; memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); CurrentTabBar = NULL; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index aca6d796..124e0122 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -500,11 +500,13 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) { + const float DRAG_DROP_HOLD_TIMER = 0.70f; hovered = true; SetHoveredID(id); - if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, 0.70f, 0.00f)) + if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAG_DROP_HOLD_TIMER, 0.00f)) { pressed = true; + g.DragDropHoldJustPressedId = id; FocusWindow(window); } } @@ -5376,7 +5378,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l bool toggled = false; if (!is_leaf) { - if (pressed) + if (pressed && g.DragDropHoldJustPressedId != id) { if ((flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) == 0 || (g.NavActivateId == id)) toggled = true; @@ -5384,8 +5386,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseDoubleClicked[0]) toggled = true; - if (g.DragDropActive && is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again. - toggled = false; + } + else if (pressed && g.DragDropHoldJustPressedId == id) + { + IM_ASSERT(button_flags & ImGuiButtonFlags_PressedOnDragDropHold); + if (!is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again. + toggled = true; } if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Left && is_open)