mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-13 18:50:58 +01:00
Internals: ImGuiListClipper using absolute coordinate (instead of relative one). Minor no-op tweaks + ImDrawListSplitter assert
This commit is contained in:
parent
1dd322c6fb
commit
82711251b6
31
imgui.cpp
31
imgui.cpp
@ -2239,7 +2239,8 @@ void ImGuiTextBuffer::appendfv(const char* fmt, va_list args)
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] ImGuiListClipper
|
// [SECTION] ImGuiListClipper
|
||||||
// This is currently not as flexible/powerful as it should be, needs some rework (see TODO)
|
// This is currently not as flexible/powerful as it should be and really confusing/spaghetti, mostly because we changed
|
||||||
|
// the API mid-way through development and support two ways to using the clipper, needs some rework (see TODO)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
||||||
@ -2247,12 +2248,14 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
|||||||
// Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor.
|
// Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor.
|
||||||
// FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue.
|
// FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue.
|
||||||
// The clipper should probably have a 4th step to display the last item in a regular manner.
|
// The clipper should probably have a 4th step to display the last item in a regular manner.
|
||||||
ImGui::SetCursorPosY(pos_y);
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
|
window->DC.CursorPos.y = pos_y;
|
||||||
window->DC.PrevLineSize.y = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
|
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y);
|
||||||
|
window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
|
||||||
|
window->DC.PrevLineSize.y = (line_height - g.Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
|
||||||
if (ImGuiColumns* columns = window->DC.CurrentColumns)
|
if (ImGuiColumns* columns = window->DC.CurrentColumns)
|
||||||
columns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
|
columns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
|
// Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
|
||||||
@ -2260,7 +2263,10 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
|||||||
// FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style.
|
// FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style.
|
||||||
void ImGuiListClipper::Begin(int count, float items_height)
|
void ImGuiListClipper::Begin(int count, float items_height)
|
||||||
{
|
{
|
||||||
StartPosY = ImGui::GetCursorPosY();
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
|
StartPosY = window->DC.CursorPos.y;
|
||||||
ItemsHeight = items_height;
|
ItemsHeight = items_height;
|
||||||
ItemsCount = count;
|
ItemsCount = count;
|
||||||
StepNo = 0;
|
StepNo = 0;
|
||||||
@ -2287,7 +2293,10 @@ void ImGuiListClipper::End()
|
|||||||
|
|
||||||
bool ImGuiListClipper::Step()
|
bool ImGuiListClipper::Step()
|
||||||
{
|
{
|
||||||
if (ItemsCount == 0 || ImGui::GetCurrentWindowRead()->SkipItems)
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
|
if (ItemsCount == 0 || window->SkipItems)
|
||||||
{
|
{
|
||||||
ItemsCount = -1;
|
ItemsCount = -1;
|
||||||
return false;
|
return false;
|
||||||
@ -2296,16 +2305,16 @@ bool ImGuiListClipper::Step()
|
|||||||
{
|
{
|
||||||
DisplayStart = 0;
|
DisplayStart = 0;
|
||||||
DisplayEnd = 1;
|
DisplayEnd = 1;
|
||||||
StartPosY = ImGui::GetCursorPosY();
|
StartPosY = window->DC.CursorPos.y;
|
||||||
StepNo = 1;
|
StepNo = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (StepNo == 1) // Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element.
|
if (StepNo == 1) // Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element.
|
||||||
{
|
{
|
||||||
if (ItemsCount == 1) { ItemsCount = -1; return false; }
|
if (ItemsCount == 1) { ItemsCount = -1; return false; }
|
||||||
float items_height = ImGui::GetCursorPosY() - StartPosY;
|
float items_height = window->DC.CursorPos.y - StartPosY;
|
||||||
IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically
|
IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically
|
||||||
Begin(ItemsCount-1, items_height);
|
Begin(ItemsCount - 1, items_height);
|
||||||
DisplayStart++;
|
DisplayStart++;
|
||||||
DisplayEnd++;
|
DisplayEnd++;
|
||||||
StepNo = 3;
|
StepNo = 3;
|
||||||
|
@ -4022,7 +4022,7 @@ static void ShowExampleAppLongText(bool* p_open)
|
|||||||
static ImGuiTextBuffer log;
|
static ImGuiTextBuffer log;
|
||||||
static int lines = 0;
|
static int lines = 0;
|
||||||
ImGui::Text("Printing unusually long amount of text.");
|
ImGui::Text("Printing unusually long amount of text.");
|
||||||
ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped (slow)\0");
|
ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped\0Multiple calls to Text(), not clipped (slow)\0");
|
||||||
ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size());
|
ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size());
|
||||||
if (ImGui::Button("Clear")) { log.clear(); lines = 0; }
|
if (ImGui::Button("Clear")) { log.clear(); lines = 0; }
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -1304,7 +1304,7 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
|||||||
|
|
||||||
void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
|
void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
|
||||||
{
|
{
|
||||||
IM_ASSERT(idx < _Count);
|
IM_ASSERT(idx >= 0 && idx < _Count);
|
||||||
if (_Current == idx)
|
if (_Current == idx)
|
||||||
return;
|
return;
|
||||||
// Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap()
|
// Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap()
|
||||||
|
Loading…
Reference in New Issue
Block a user