Internals: Columns: Renamed fields. Comments and tweak. Moved a demo block.

This commit is contained in:
omar 2019-05-09 12:56:03 +02:00
parent a4d0b0efa4
commit e29176df53
4 changed files with 58 additions and 55 deletions

View File

@ -1140,7 +1140,7 @@ ImGuiStyle::ImGuiStyle()
ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar
ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar
GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar
@ -5452,6 +5452,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerMainRect.Min.y); window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerMainRect.Min.y);
window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerMainRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize))); window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerMainRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize)));
window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerMainRect.Max.y); window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerMainRect.Max.y);
// Setup drawing context // Setup drawing context
// (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.) // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.)
window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x; window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x;
@ -8434,12 +8435,12 @@ int ImGui::GetColumnsCount()
static float OffsetNormToPixels(const ImGuiColumns* columns, float offset_norm) static float OffsetNormToPixels(const ImGuiColumns* columns, float offset_norm)
{ {
return offset_norm * (columns->MaxX - columns->MinX); return offset_norm * (columns->OffMaxX - columns->OffMinX);
} }
static float PixelsToOffsetNorm(const ImGuiColumns* columns, float offset) static float PixelsToOffsetNorm(const ImGuiColumns* columns, float offset)
{ {
return offset / (columns->MaxX - columns->MinX); return offset / (columns->OffMaxX - columns->OffMinX);
} }
static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f; static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f;
@ -8472,7 +8473,7 @@ float ImGui::GetColumnOffset(int column_index)
IM_ASSERT(column_index < columns->Columns.Size); IM_ASSERT(column_index < columns->Columns.Size);
const float t = columns->Columns[column_index].OffsetNorm; const float t = columns->Columns[column_index].OffsetNorm;
const float x_offset = ImLerp(columns->MinX, columns->MaxX, t); const float x_offset = ImLerp(columns->OffMinX, columns->OffMaxX, t);
return x_offset; return x_offset;
} }
@ -8515,8 +8516,8 @@ void ImGui::SetColumnOffset(int column_index, float offset)
const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f; const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f;
if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow))
offset = ImMin(offset, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index)); offset = ImMin(offset, columns->OffMaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index));
columns->Columns[column_index].OffsetNorm = PixelsToOffsetNorm(columns, offset - columns->MinX); columns->Columns[column_index].OffsetNorm = PixelsToOffsetNorm(columns, offset - columns->OffMinX);
if (preserve_width) if (preserve_width)
SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width));
@ -8551,7 +8552,7 @@ void ImGui::PushColumnsBackground()
ImGuiColumns* columns = window->DC.CurrentColumns; ImGuiColumns* columns = window->DC.CurrentColumns;
window->DrawList->ChannelsSetCurrent(0); window->DrawList->ChannelsSetCurrent(0);
int cmd_size = window->DrawList->CmdBuffer.Size; int cmd_size = window->DrawList->CmdBuffer.Size;
PushClipRect(columns->BackupClipRect.Min, columns->BackupClipRect.Max, false); PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false);
IM_ASSERT(cmd_size == window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd IM_ASSERT(cmd_size == window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd
} }
@ -8597,9 +8598,8 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
IM_ASSERT(columns_count >= 1); IM_ASSERT(columns_count >= 1);
IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported
ImGuiID id = GetColumnsID(str_id, columns_count);
// Acquire storage for the columns set // Acquire storage for the columns set
ImGuiID id = GetColumnsID(str_id, columns_count);
ImGuiColumns* columns = FindOrCreateColumns(window, id); ImGuiColumns* columns = FindOrCreateColumns(window, id);
IM_ASSERT(columns->ID == id); IM_ASSERT(columns->ID == id);
columns->Current = 0; columns->Current = 0;
@ -8609,11 +8609,11 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
// Set state for first column // Set state for first column
const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x); const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x);
columns->MinX = window->DC.Indent.x - g.Style.ItemSpacing.x; // Lock our horizontal range columns->OffMinX = window->DC.Indent.x - g.Style.ItemSpacing.x; // Lock our horizontal range
columns->MaxX = ImMax(content_region_width - window->Scroll.x, columns->MinX + 1.0f); columns->OffMaxX = ImMax(content_region_width - window->Scroll.x, columns->OffMinX + 1.0f);
columns->BackupCursorPosY = window->DC.CursorPos.y; columns->HostCursorPosY = window->DC.CursorPos.y;
columns->BackupCursorMaxPosX = window->DC.CursorMaxPos.x; columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
columns->BackupClipRect = window->ClipRect; columns->HostClipRect = window->ClipRect;
columns->LineMinY = columns->LineMaxY = window->DC.CursorPos.y; columns->LineMinY = columns->LineMaxY = window->DC.CursorPos.y;
window->DC.ColumnsOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
@ -8622,7 +8622,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1) if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1)
columns->Columns.resize(0); columns->Columns.resize(0);
// Initialize defaults // Initialize default widths
columns->IsFirstFrame = (columns->Columns.Size == 0); columns->IsFirstFrame = (columns->Columns.Size == 0);
if (columns->Columns.Size == 0) if (columns->Columns.Size == 0)
{ {
@ -8668,17 +8668,19 @@ void ImGui::EndColumns()
window->DrawList->ChannelsMerge(); window->DrawList->ChannelsMerge();
} }
const ImGuiColumnsFlags flags = columns->Flags;
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y); columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
window->DC.CursorPos.y = columns->LineMaxY; window->DC.CursorPos.y = columns->LineMaxY;
if (!(columns->Flags & ImGuiColumnsFlags_GrowParentContentsSize)) if (!(flags & ImGuiColumnsFlags_GrowParentContentsSize))
window->DC.CursorMaxPos.x = columns->BackupCursorMaxPosX; // Restore cursor max pos, as columns don't grow parent window->DC.CursorMaxPos.x = columns->HostCursorMaxPosX; // Restore cursor max pos, as columns don't grow parent
// Draw columns borders and handle resize // Draw columns borders and handle resize
// The IsBeingResized flag ensure we preserve pre-resize columns width so back-and-forth are not lossy
bool is_being_resized = false; bool is_being_resized = false;
if (!(columns->Flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) if (!(flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems)
{ {
// We clip Y boundaries CPU side because very long triangles are mishandled by some GPU drivers. // We clip Y boundaries CPU side because very long triangles are mishandled by some GPU drivers.
const float y1 = ImMax(columns->BackupCursorPosY, window->ClipRect.Min.y); const float y1 = ImMax(columns->HostCursorPosY, window->ClipRect.Min.y);
const float y2 = ImMin(window->DC.CursorPos.y, window->ClipRect.Max.y); const float y2 = ImMin(window->DC.CursorPos.y, window->ClipRect.Max.y);
int dragging_column = -1; int dragging_column = -1;
for (int n = 1; n < columns->Count; n++) for (int n = 1; n < columns->Count; n++)
@ -8693,7 +8695,7 @@ void ImGui::EndColumns()
continue; continue;
bool hovered = false, held = false; bool hovered = false, held = false;
if (!(columns->Flags & ImGuiColumnsFlags_NoResize)) if (!(flags & ImGuiColumnsFlags_NoResize))
{ {
ButtonBehavior(column_hit_rect, column_id, &hovered, &held); ButtonBehavior(column_hit_rect, column_id, &hovered, &held);
if (hovered || held) if (hovered || held)
@ -8745,6 +8747,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
BeginColumns(id, columns_count, flags); BeginColumns(id, columns_count, flags);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] DRAG AND DROP // [SECTION] DRAG AND DROP
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -9692,7 +9695,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
{ {
if (!ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) if (!ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags))
return; return;
ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX); ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->OffMaxX - columns->OffMinX, columns->OffMinX, columns->OffMaxX);
for (int column_n = 0; column_n < columns->Columns.Size; column_n++) for (int column_n = 0; column_n < columns->Columns.Size; column_n++)
ImGui::BulletText("Column %02d: OffsetNorm %.3f (= %.1f px)", column_n, columns->Columns[column_n].OffsetNorm, OffsetNormToPixels(columns, columns->Columns[column_n].OffsetNorm)); ImGui::BulletText("Column %02d: OffsetNorm %.3f (= %.1f px)", column_n, columns->Columns[column_n].OffsetNorm, OffsetNormToPixels(columns, columns->Columns[column_n].OffsetNorm));
ImGui::TreePop(); ImGui::TreePop();

View File

@ -1293,7 +1293,7 @@ struct ImGuiStyle
ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label). ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label).
ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar. float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar.
float ScrollbarRounding; // Radius of grab corners for scrollbar. float ScrollbarRounding; // Radius of grab corners for scrollbar.
float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar. float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar.

View File

@ -2426,6 +2426,32 @@ static void ShowDemoWindowColumns()
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Borders"))
{
// NB: Future columns API should allow automatic horizontal borders.
static bool h_borders = true;
static bool v_borders = true;
ImGui::Checkbox("horizontal", &h_borders);
ImGui::SameLine();
ImGui::Checkbox("vertical", &v_borders);
ImGui::Columns(4, NULL, v_borders);
for (int i = 0; i < 4 * 3; i++)
{
if (h_borders && ImGui::GetColumnIndex() == 0)
ImGui::Separator();
ImGui::Text("%c%c%c", 'a' + i, 'a' + i, 'a' + i);
ImGui::Text("Width %.2f", ImGui::GetColumnWidth());
ImGui::Text("Offset %.2f", ImGui::GetColumnOffset());
ImGui::Text("Long text that is likely to clip");
ImGui::Button("Button", ImVec2(-1.0f, 0.0f));
ImGui::NextColumn();
}
ImGui::Columns(1);
if (h_borders)
ImGui::Separator();
ImGui::TreePop();
}
// Create multiple items in a same cell before switching to next column // Create multiple items in a same cell before switching to next column
if (ImGui::TreeNode("Mixed items")) if (ImGui::TreeNode("Mixed items"))
{ {
@ -2472,32 +2498,6 @@ static void ShowDemoWindowColumns()
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Borders"))
{
// NB: Future columns API should allow automatic horizontal borders.
static bool h_borders = true;
static bool v_borders = true;
ImGui::Checkbox("horizontal", &h_borders);
ImGui::SameLine();
ImGui::Checkbox("vertical", &v_borders);
ImGui::Columns(4, NULL, v_borders);
for (int i = 0; i < 4*3; i++)
{
if (h_borders && ImGui::GetColumnIndex() == 0)
ImGui::Separator();
ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i);
ImGui::Text("Width %.2f", ImGui::GetColumnWidth());
ImGui::Text("Offset %.2f", ImGui::GetColumnOffset());
ImGui::Text("Long text that is likely to clip");
ImGui::Button("Button", ImVec2(-1.0f, 0.0f));
ImGui::NextColumn();
}
ImGui::Columns(1);
if (h_borders)
ImGui::Separator();
ImGui::TreePop();
}
// Scrolling columns // Scrolling columns
/* /*
if (ImGui::TreeNode("Vertical Scrolling")) if (ImGui::TreeNode("Vertical Scrolling"))

View File

@ -680,11 +680,11 @@ struct ImGuiColumns
bool IsBeingResized; bool IsBeingResized;
int Current; int Current;
int Count; int Count;
float MinX, MaxX; float OffMinX, OffMaxX; // Offsets from HostWorkRect.Min.x
float LineMinY, LineMaxY; float LineMinY, LineMaxY;
float BackupCursorPosY; // Backup of CursorPos at the time of BeginColumns() float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns()
float BackupCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns() float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
ImRect BackupClipRect; ImRect HostClipRect; // Backup of ClipRect at the time of BeginColumns()
ImVector<ImGuiColumnData> Columns; ImVector<ImGuiColumnData> Columns;
ImGuiColumns() { Clear(); } ImGuiColumns() { Clear(); }
@ -696,10 +696,10 @@ struct ImGuiColumns
IsBeingResized = false; IsBeingResized = false;
Current = 0; Current = 0;
Count = 1; Count = 1;
MinX = MaxX = 0.0f; OffMinX = OffMaxX = 0.0f;
LineMinY = LineMaxY = 0.0f; LineMinY = LineMaxY = 0.0f;
BackupCursorPosY = 0.0f; HostCursorPosY = 0.0f;
BackupCursorMaxPosX = 0.0f; HostCursorMaxPosX = 0.0f;
Columns.clear(); Columns.clear();
} }
}; };