This commit is contained in:
Rokas Kupstys 2025-04-03 09:51:09 +02:00 committed by GitHub
commit c060dd55d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 111 additions and 0 deletions

View file

@ -14346,6 +14346,55 @@ void ImGui::EndDragDropTarget()
ClearDragDrop();
}
//-----------------------------------------------------------------------------
// [SECTION] REORDERING
//-----------------------------------------------------------------------------
int ImGui::ItemReorder(ImGuiID id, bool vertical)
{
ImGuiContext& g = *GImGui;
if (!g.IO.MouseDown[0] && g.LastItemData.ID == g.ActiveIdPreviousFrame)
{
g.ReorderScopeId = 0;
g.ReorderResult = 0;
}
else if (g.ActiveId && g.ActiveId == g.LastItemData.ID)
{
g.ActiveIdAllowOverlap = true; // Enable IsItemHovered() while current item is active
g.ReorderScopeId = id;
g.ReorderItemRect = g.LastItemData.Rect;
if (g.ReorderResult != 0)
{
int result = g.ReorderResult;
g.ReorderScopeId = 0;
g.ReorderResult = 0;
return result;
}
}
else if (g.IO.MouseDown[0] && IsItemHovered() && g.ReorderScopeId == id)
{
ImGuiAxis axis = (ImGuiAxis)vertical;
if (g.IO.MousePos[axis] > g.ReorderItemRect.Max[axis])
g.ReorderResult = +1;
else if (g.IO.MousePos[axis] < g.ReorderItemRect.Min[axis])
g.ReorderResult = -1;
}
return 0;
}
int ImGui::ItemReorder(const char* id, bool vertical)
{
ImGuiContext& g = *GImGui;
return ItemReorder(g.CurrentWindow->GetID(id), vertical);
}
int ImGui::ItemReorder(bool vertical)
{
ImGuiContext& g = *GImGui;
return ItemReorder(g.CurrentWindow->IDStack.back(), vertical);
}
//-----------------------------------------------------------------------------
// [SECTION] LOGGING/CAPTURING
//-----------------------------------------------------------------------------

View file

@ -891,6 +891,15 @@ namespace ImGui
IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true!
IMGUI_API const ImGuiPayload* GetDragDropPayload(); // peek directly into the current payload from anywhere. returns NULL when drag and drop is finished or inactive. use ImGuiPayload::IsDataType() to test for the payload type.
// Reordering
// - Call after each item that can be reordered.
// - Returns -1/+1 if item should be swapped with the previous/next one, or 0 for no action.
// - Only items within current or specified id scope participate in item reorder.
// FIXME: "bool vertical" should be replaced with "ImGuiAxis axis", but ImGuiAxis is in imgui_internal.h
IMGUI_API int ItemReorder(ImGuiID id, bool vertical);
IMGUI_API int ItemReorder(const char* id, bool vertical);
IMGUI_API int ItemReorder(bool vertical);
// Disabling [BETA API]
// - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors)
// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)

View file

@ -1664,6 +1664,54 @@ static void DemoWindowWidgetsDragAndDrop()
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Widgets/Drag and Drop/Drag to reorder items (api)");
if (ImGui::TreeNode("Drag to reorder items (api)"))
{
HelpMarker("Drag items to reorder them.");
static const char* item_names[] = { "Item One", "Item Two", "Item Three", "Item Four", "Item Five" };
static bool vertical = true;
ImGui::Checkbox("Vertical", &vertical);
int swap_n = 0;
int swap_d = 0;
for (int n = 0; n < IM_ARRAYSIZE(item_names); n++)
{
const char* item = item_names[n];
if (vertical)
{
ImGui::Selectable(item);
}
else
{
ImGui::Button(item);
if (n + 1 < IM_ARRAYSIZE(item_names))
ImGui::SameLine();
}
// Called after reorderable item. "SomeId" is optional in this simple example, but may be used to
// avoid mixing multiple distinct reorderable lists when they exist in same id scope.
if (int swap_direction = ImGui::ItemReorder("SomeId", vertical))
{
swap_n = n;
swap_d = swap_direction;
}
}
// Defer swap after rendering in order to avoid rendering glitches when items of different length are
// swapped in a horizontal list.
if (swap_d != 0)
{
const char* item = item_names[swap_n];
int next_n = swap_n + swap_d;
if (next_n >= 0 && next_n < IM_ARRAYSIZE(item_names))
{
item_names[swap_n] = item_names[next_n];
item_names[next_n] = item;
}
}
ImGui::TreePop();
}
ImGui::TreePop();
}
}

View file

@ -2277,6 +2277,11 @@ struct ImGuiContext
ImVector<unsigned char> DragDropPayloadBufHeap; // We don't expose the ImVector<> directly, ImGuiPayload only holds pointer+size
unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads
// Reorder
ImGuiID ReorderScopeId;
ImRect ReorderItemRect; // Rect of item that initiated reorder operation
int ReorderResult; // Reorder response
// Clipper
int ClipperTempDataStacked;
ImVector<ImGuiListClipperData> ClipperTempData;