Skip to content

Instantly share code, notes, and snippets.

@unpacklo
Last active August 29, 2015 14:15
Show Gist options
  • Save unpacklo/a7469c63552365671b3d to your computer and use it in GitHub Desktop.
Save unpacklo/a7469c63552365671b3d to your computer and use it in GitHub Desktop.
imgui column header and sorting
static void GetColumnOffsetsFromImGui(PackFileGui *gui)
{
for (int i = 1; i < ARRAY_ELEMENTS(gui->displayColumnOffsets); ++i)
{
gui->displayColumnOffsets[i] = ImGui::GetColumnOffset(i);
}
}
static void SendColumnOffsetsToImGui(PackFileGui *gui)
{
// Pixels to offset the column headers by to make sure we line up with the contents.
const float COLUMN_HEADER_OFFSET = 8.0f;
for (int i = 1; i < ARRAY_ELEMENTS(gui->displayColumnOffsets); ++i)
{
ImGui::SetColumnOffset(i, gui->displayColumnOffsets[i] + COLUMN_HEADER_OFFSET);
}
}
static const char *GetSortDirectionLabel(bool sortSelected, bool descending)
{
if (!sortSelected)
{
return "";
}
if (descending)
{
return "v";
}
else
{
return "^";
}
}
void PackFileGuiInit(PackFileGui *gui)
{
memset(gui, 0, sizeof(*gui));
gui->selectedTab = -1;
gui->displayComp = indexCompare;
gui->rowSelected = -1;
// Initial column offsets for pleasing spacing.
gui->displayColumnOffsets[1] = 60.0f;
gui->displayColumnOffsets[2] = 254.430542f;
gui->displayColumnOffsets[3] = 954.982666f;
gui->displayColumnOffsets[4] = 1059.500488f;
}
ImGui::Columns(5, "header");
SendColumnOffsetsToImGui(gui);
bool sortSelected = (gui->displayComp == indexCompare);
if (ImGuiSelectable(false, false, "Index %s", GetSortDirectionLabel(sortSelected, gui->displayDescending)))
{
gui->displayDescending ^= sortSelected ? true : gui->displayDescending;
gui->displayComp = indexCompare;
}
ImGui::Separator();
ImGui::NextColumn();
sortSelected = (gui->displayComp == typeCompare);
if (ImGuiSelectable(false, false, "Type %s", GetSortDirectionLabel(sortSelected, gui->displayDescending)))
{
gui->displayDescending ^= sortSelected ? true : gui->displayDescending;
gui->displayComp = typeCompare;
}
ImGui::Separator();
ImGui::NextColumn();
sortSelected = (gui->displayComp == pathCompare);
if (ImGuiSelectable(false, false, "Path %s", GetSortDirectionLabel(sortSelected, gui->displayDescending)))
{
gui->displayDescending ^= sortSelected ? true : gui->displayDescending;
gui->displayComp = pathCompare;
}
ImGui::Separator();
ImGui::NextColumn();
sortSelected = (gui->displayComp == offsetCompare);
if (ImGuiSelectable(false, false, "Offset %s", GetSortDirectionLabel(sortSelected, gui->displayDescending)))
{
gui->displayDescending ^= sortSelected ? true : gui->displayDescending;
gui->displayComp = offsetCompare;
}
ImGui::Separator();
ImGui::NextColumn();
sortSelected = (gui->displayComp == byteCompare);
if (ImGuiSelectable(false, false, "Bytes %s", GetSortDirectionLabel(sortSelected, gui->displayDescending)))
{
gui->displayDescending ^= sortSelected ? true : gui->displayDescending;
gui->displayComp = byteCompare;
}
ImGui::Separator();
ImGui::NextColumn();
ImGui::Columns(1);
ImGui::BeginChild("##scrolling", ImVec2(0.0f, 500.0f));
ImGui::Columns(5, "contents");
if (!gui->displayColumnsInitialized)
{
SendColumnOffsetsToImGui(gui);
gui->displayColumnsInitialized = true;
}
GetColumnOffsetsFromImGui(gui);
int numItems = gui->pack.manifest->numPaths;
DisplayIndex *displayIndices = PushArrayFront(&gui->imguiMemory, DisplayIndex, numItems);
// Set up the display indices for sorting.
for (int i = 0; i < numItems; ++i)
{
displayIndices[i].manifest = gui->pack.manifest;
displayIndices[i].index = i;
}
qsort(displayIndices, numItems, SIZEOF_ARRAY_ELEMENT(displayIndices), gui->displayComp);
if (gui->displayDescending)
{
int lo = 0, hi = numItems - 1;
while (lo < hi)
{
DisplayIndex temp = displayIndices[lo];
displayIndices[lo] = displayIndices[hi];
displayIndices[hi] = temp;
++lo;
--hi;
}
}
float itemHeight = ImGui::GetTextLineHeightWithSpacing();
int displayStart = 0, displayEnd = numItems;
ImGui::CalcListClipping(numItems, itemHeight, &displayStart, &displayEnd);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (displayStart * itemHeight));
for (int i = displayStart; i < displayEnd; ++i)
{
int indexSelected = displayIndices[i].index;
ImGui::PushID(i);
if (ImGuiSelectable(false, i == gui->rowSelected, "%d", indexSelected))
{
gui->rowSelected = i;
gui->selectedResource = PackFileRead(&gui->pack, gui->pack.manifest->paths[indexSelected], gui->onLoaded, gui->callbackData);
printf("\n");
}
ImGui::PopID();
}
ImGui::NextColumn();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (displayStart * itemHeight));
for (int i = displayStart; i < displayEnd; ++i)
{
int indexSelected = displayIndices[i].index;
ImGui::PushID(i);
if (ImGuiSelectable(false, i == gui->rowSelected, "%s", ResourceTypeToStr[gui->pack.manifest->types[indexSelected]]))
{
gui->rowSelected = i;
gui->selectedResource = PackFileRead(&gui->pack, gui->pack.manifest->paths[indexSelected], gui->onLoaded, gui->callbackData);
printf("\n");
}
ImGui::PopID();
}
ImGui::NextColumn();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (displayStart * itemHeight));
for (int i = displayStart; i < displayEnd; ++i)
{
int indexSelected = displayIndices[i].index;
ImGui::PushID(i);
if (ImGuiSelectable(false, i == gui->rowSelected, gui->pack.manifest->paths[indexSelected]))
{
gui->rowSelected = i;
gui->selectedResource = PackFileRead(&gui->pack, gui->pack.manifest->paths[indexSelected], gui->onLoaded, gui->callbackData);
printf("\n");
}
ImGui::PopID();
}
ImGui::NextColumn();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (displayStart * itemHeight));
for (int i = displayStart; i < displayEnd; ++i)
{
int indexSelected = displayIndices[i].index;
ImGui::PushID(i);
if (ImGuiSelectable(false, i == gui->rowSelected, FMT_SIZET, gui->pack.manifest->offsets[indexSelected]))
{
gui->rowSelected = i;
gui->selectedResource = PackFileRead(&gui->pack, gui->pack.manifest->paths[indexSelected], gui->onLoaded, gui->callbackData);
printf("\n");
}
ImGui::PopID();
}
ImGui::NextColumn();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (displayStart * itemHeight));
for (int i = displayStart; i < displayEnd; ++i)
{
int indexSelected = displayIndices[i].index;
ImGui::PushID(i);
if (ImGuiSelectable(false, i == gui->rowSelected, FMT_SIZET " (%f MB)", gui->pack.manifest->bytes[indexSelected], (double)gui->pack.manifest->bytes[indexSelected] / ((double)MEGABYTES(1))))
{
gui->rowSelected = i;
gui->selectedResource = PackFileRead(&gui->pack, gui->pack.manifest->paths[indexSelected], gui->onLoaded, gui->callbackData);
printf("\n");
}
ImGui::PopID();
}
ImGui::Columns(1);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ((gui->pack.manifest->numPaths - displayEnd) * itemHeight));
ImGui::EndChild();
PopArrayFront(&gui->imguiMemory, DisplayIndex, numItems);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment