ImGuiListClipper new version, detect height automatically, fix compatibility with SetScrollPosHere (#662)

This commit is contained in:
ocornut
2016-05-16 19:22:51 +02:00
parent fa5ae60bce
commit 7a28f5bb81
3 changed files with 156 additions and 74 deletions

View File

@ -2014,24 +2014,33 @@ struct ExampleAppConsole
ImGui::PopStyleVar();
ImGui::Separator();
// Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
// NB- if you have thousands of entries this approach may be too inefficient. You can seek and display only the lines that are visible - CalcListClipping() is a helper to compute this information.
// If your items are of variable size you may want to implement code similar to what CalcListClipping() does. Or split your data into fixed height items to allow random-seeking into your list.
ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar);
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::Selectable("Clear")) ClearLog();
ImGui::EndPopup();
}
// Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
// NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping to only process visible items.
// You can seek and display only the lines that are visible using the ImGuiListClipper helper, if your elements are evenly spaced and you have cheap random access to the elements.
// To use the clipper we could replace the 'for (int i = 0; i < Items.Size; i++)' loop with:
// ImGuiListClipper clipper(Items.Size);
// while (clipper.Step())
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
// However take note that you can not use this code as is if a filter is active because it breaks the 'cheap random-access' property. We would need random-access on the post-filtered list.
// A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices that passed the filtering test, recomputing this array when user changes the filter,
// and appending newly elements as they are inserted. This is left as a task to the user until we can manage to improve this example code!
// If your items are of variable size you may want to implement code similar to what ImGuiListClipper does. Or split your data into fixed height items to allow random-seeking into your list.
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing
for (int i = 0; i < Items.Size; i++)
{
const char* item = Items[i];
if (!filter.PassFilter(item))
continue;
ImVec4 col = ImColor(255,255,255); // A better implementation may store a type per-item. For the sample let's just parse the text.
if (strstr(item, "[error]")) col = ImColor(255,100,100);
else if (strncmp(item, "# ", 2) == 0) col = ImColor(255,200,150);
ImVec4 col = ImVec4(1.0f,1.0f,1.0f,1.0f); // A better implementation may store a type per-item. For the sample let's just parse the text.
if (strstr(item, "[error]")) col = ImColor(1.0f,0.4f,0.4f,1.0f);
else if (strncmp(item, "# ", 2) == 0) col = ImColor(1.0f,0.78f,0.58f,1.0f);
ImGui::PushStyleColor(ImGuiCol_Text, col);
ImGui::TextUnformatted(item);
ImGui::PopStyleColor();
@ -2441,10 +2450,10 @@ static void ShowExampleAppLongText(bool* p_open)
{
// Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper.
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
ImGuiListClipper clipper(lines, ImGui::GetTextLineHeightWithSpacing()); // Here we changed spacing is zero anyway so we could use GetTextLineHeight(), but _WithSpacing() is typically more correct
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i);
clipper.End();
ImGuiListClipper clipper(lines);
while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog", i);
ImGui::PopStyleVar();
break;
}
@ -2452,7 +2461,7 @@ static void ShowExampleAppLongText(bool* p_open)
// Multiple calls to Text(), not clipped (slow)
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
for (int i = 0; i < lines; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i);
ImGui::Text("%i The quick brown fox jumps over the lazy dog", i);
ImGui::PopStyleVar();
break;
}