Skip to content

Instantly share code, notes, and snippets.

@unpacklo
Last active April 12, 2018 04:35
Show Gist options
  • Save unpacklo/f4af1d688237a7d367f9 to your computer and use it in GitHub Desktop.
Save unpacklo/f4af1d688237a7d367f9 to your computer and use it in GitHub Desktop.
imgui drag reordering
void **editResources = gui->editResources;
float itemHeight = ImGui::GetTextLineHeightWithSpacing();
int displayStart = 0, displayEnd = gui->numEditResources;
int listItemHovered = -1;
ImGui::CalcListClipping(gui->numEditResources, itemHeight, &displayStart, &displayEnd);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (displayStart * itemHeight));
ImVec4 dirtyColor(1.0f, 0.5f, 0.5f, 1.0f), normalColor(1.0f, 1.0f, 1.0f, 1.0f);
for (int i = displayStart; i < displayEnd; ++i)
{
char buffer[128];
const char *path = GetResourcePath(editResources[i]);
snprintf(buffer, sizeof(buffer), !IsResourceDirty(editResources[i]) ? "%d. %s" : "%d. * %s", i + 1, path);
ImGui::PushID(i);
ImGui::PushStyleColor(ImGuiCol_Text, IsResourceDirty(gui->editResources[i]) ? dirtyColor : normalColor);
if (ImGui::Selectable(buffer, gui->selected == i))
{
ResourceEditGuiSetSelected(gui, i);
}
ImGui::PopStyleColor();
if (ImGui::IsItemHoveredRect())
{
listItemHovered = i;
}
ImGui::PopID();
}
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ((gui->numEditResources - displayEnd) * itemHeight));
ImGui::EndChild();
ImGui::NextColumn();
if (0 <= listItemHovered)
{
if (ImGui::IsMouseClicked(2))
{
ResourceEditGuiMarkResourceForRemoval(gui, listItemHovered);
}
ImGui::SetTooltip(GetResourcePath(editResources[listItemHovered]));
if (ImGui::IsMouseDragging() && gui->dragEditResourceCopy)
{
// Reorder the list.
void *dragging = gui->dragEditResourceCopy[gui->dragIndex];
memmove(gui->editResources, gui->dragEditResourceCopy, SIZEOF_ARRAY(gui->editResources, gui->numEditResources));
if (listItemHovered < gui->dragIndex)
{
int numMoving = gui->dragIndex - listItemHovered;
void **src = gui->editResources + listItemHovered;
void **dest = gui->editResources + listItemHovered + 1;
memmove(dest, src, SIZEOF_ARRAY(gui->editResources, numMoving));
gui->editResources[listItemHovered] = dragging;
}
else
{
int numMoving = listItemHovered - gui->dragIndex;
void **src = gui->editResources + gui->dragIndex + 1;
void **dest = gui->editResources + gui->dragIndex;
memmove(dest, src, SIZEOF_ARRAY(gui->editResources, numMoving));
gui->editResources[listItemHovered] = dragging;
}
// Terrible linear search to reset the selected item.
for (int i = 0; i < gui->numEditResources; ++i)
{
if (gui->editResources[i] == gui->selectedAtDragStart)
{
ResourceEditGuiSetSelected(gui, i);
break;
}
}
}
else if (leftPressed)
{
// Begin drag and drop logic.
gui->dragIndex = listItemHovered;
gui->selectedAtDragStart = ResourceEditGuiGetSelectedResource(gui);
gui->dragEditResourceCopy = PushArrayFront(&gui->guiMemory, void *, gui->numEditResources);
memmove(gui->dragEditResourceCopy, gui->editResources, SIZEOF_ARRAY(gui->editResources, gui->numEditResources));
}
}
else
{
if (ImGui::IsMouseDragging() && gui->dragEditResourceCopy)
{
// Restore the original order if we're hovering off the list.
memmove(gui->editResources, gui->dragEditResourceCopy, SIZEOF_ARRAY(gui->editResources, gui->numEditResources));
// Terrible linear search to reset the selected item.
for (int i = 0; i < gui->numEditResources; ++i)
{
if (gui->editResources[i] == gui->selectedAtDragStart)
{
ResourceEditGuiSetSelected(gui, i);
break;
}
}
}
}
if (leftReleased && gui->dragEditResourceCopy)
{
gui->dragIndex = -1;
gui->selectedAtDragStart = NULL;
gui->dragEditResourceCopy = NULL;
PopArrayFront(&gui->guiMemory, void *, gui->numEditResources);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment