mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Columns: Refactor: Moved columns data into their own data structure. Minimum changes now to ease diffing. (#125, #1499)
This commit is contained in:
parent
027ffd91ea
commit
78320aa633
214
imgui.cpp
214
imgui.cpp
@ -627,8 +627,6 @@
|
|||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
static float GetDraggedColumnOffset(int column_index);
|
|
||||||
|
|
||||||
static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true);
|
static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true);
|
||||||
|
|
||||||
static ImFont* GetDefaultFont();
|
static ImFont* GetDefaultFont();
|
||||||
@ -1744,8 +1742,8 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
|||||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage.
|
window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage.
|
||||||
window->DC.PrevLineHeight = (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.PrevLineHeight = (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.
|
||||||
if (window->DC.ColumnsCount > 1)
|
if (window->DC.ColumnsSet)
|
||||||
window->DC.ColumnsCellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
|
window->DC.ColumnsSet->ColumnsCellMinY = 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
|
||||||
@ -4833,11 +4831,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
window->DC.ItemFlagsStack.resize(0);
|
window->DC.ItemFlagsStack.resize(0);
|
||||||
window->DC.ItemWidthStack.resize(0);
|
window->DC.ItemWidthStack.resize(0);
|
||||||
window->DC.TextWrapPosStack.resize(0);
|
window->DC.TextWrapPosStack.resize(0);
|
||||||
window->DC.ColumnsCurrent = 0;
|
window->DC.ColumnsSet = NULL;
|
||||||
window->DC.ColumnsCount = 1;
|
|
||||||
window->DC.ColumnsStartPosY = window->DC.CursorPos.y;
|
|
||||||
window->DC.ColumnsStartMaxPosX = window->DC.CursorMaxPos.x;
|
|
||||||
window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.ColumnsStartPosY;
|
|
||||||
window->DC.TreeDepth = 0;
|
window->DC.TreeDepth = 0;
|
||||||
window->DC.StateStorage = &window->StateStorage;
|
window->DC.StateStorage = &window->StateStorage;
|
||||||
window->DC.GroupStack.resize(0);
|
window->DC.GroupStack.resize(0);
|
||||||
@ -4990,7 +4984,7 @@ void ImGui::End()
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
if (window->DC.ColumnsCount != 1) // close columns set if any is open
|
if (window->DC.ColumnsSet != NULL)
|
||||||
EndColumns();
|
EndColumns();
|
||||||
PopClipRect(); // inner window clip rectangle
|
PopClipRect(); // inner window clip rectangle
|
||||||
|
|
||||||
@ -5736,8 +5730,8 @@ ImVec2 ImGui::GetContentRegionMax()
|
|||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindowRead();
|
ImGuiWindow* window = GetCurrentWindowRead();
|
||||||
ImVec2 mx = window->ContentsRegionRect.Max;
|
ImVec2 mx = window->ContentsRegionRect.Max;
|
||||||
if (window->DC.ColumnsCount != 1)
|
if (window->DC.ColumnsSet)
|
||||||
mx.x = GetColumnOffset(window->DC.ColumnsCurrent + 1) - window->WindowPadding.x;
|
mx.x = GetColumnOffset(window->DC.ColumnsSet->ColumnsCurrent + 1) - window->WindowPadding.x;
|
||||||
return mx;
|
return mx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9347,7 +9341,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
|
|
||||||
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) // FIXME-OPT: Avoid if vertically clipped.
|
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) // FIXME-OPT: Avoid if vertically clipped.
|
||||||
PopClipRect();
|
PopClipRect();
|
||||||
|
|
||||||
ImGuiID id = window->GetID(label);
|
ImGuiID id = window->GetID(label);
|
||||||
@ -9378,7 +9372,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
bb_with_spacing.Max.y += spacing_D;
|
bb_with_spacing.Max.y += spacing_D;
|
||||||
if (!ItemAdd(bb_with_spacing, id))
|
if (!ItemAdd(bb_with_spacing, id))
|
||||||
{
|
{
|
||||||
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
|
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet)
|
||||||
PushColumnClipRect();
|
PushColumnClipRect();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -9400,7 +9394,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f);
|
RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1)
|
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet)
|
||||||
{
|
{
|
||||||
PushColumnClipRect();
|
PushColumnClipRect();
|
||||||
bb_with_spacing.Max.x -= (GetContentRegionMax().x - max_x);
|
bb_with_spacing.Max.x -= (GetContentRegionMax().x - max_x);
|
||||||
@ -10552,7 +10546,7 @@ void ImGui::Separator()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Horizontal Separator
|
// Horizontal Separator
|
||||||
if (window->DC.ColumnsCount > 1)
|
if (window->DC.ColumnsSet)
|
||||||
PopClipRect();
|
PopClipRect();
|
||||||
|
|
||||||
float x1 = window->Pos.x;
|
float x1 = window->Pos.x;
|
||||||
@ -10564,7 +10558,7 @@ void ImGui::Separator()
|
|||||||
ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout.
|
ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout.
|
||||||
if (!ItemAdd(bb, 0))
|
if (!ItemAdd(bb, 0))
|
||||||
{
|
{
|
||||||
if (window->DC.ColumnsCount > 1)
|
if (window->DC.ColumnsSet)
|
||||||
PushColumnClipRect();
|
PushColumnClipRect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -10574,10 +10568,10 @@ void ImGui::Separator()
|
|||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogRenderedText(NULL, IM_NEWLINE "--------------------------------");
|
LogRenderedText(NULL, IM_NEWLINE "--------------------------------");
|
||||||
|
|
||||||
if (window->DC.ColumnsCount > 1)
|
if (window->DC.ColumnsSet)
|
||||||
{
|
{
|
||||||
PushColumnClipRect();
|
PushColumnClipRect();
|
||||||
window->DC.ColumnsCellMinY = window->DC.CursorPos.y;
|
window->DC.ColumnsSet->ColumnsCellMinY = window->DC.CursorPos.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10790,29 +10784,30 @@ void ImGui::NewLine()
|
|||||||
void ImGui::NextColumn()
|
void ImGui::NextColumn()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems || window->DC.ColumnsCount <= 1)
|
if (window->SkipItems || window->DC.ColumnsSet == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
PopItemWidth();
|
PopItemWidth();
|
||||||
PopClipRect();
|
PopClipRect();
|
||||||
|
|
||||||
window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y);
|
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
|
||||||
if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount)
|
columns->ColumnsCellMaxY = ImMax(columns->ColumnsCellMaxY, window->DC.CursorPos.y);
|
||||||
|
if (++columns->ColumnsCurrent < columns->ColumnsCount)
|
||||||
{
|
{
|
||||||
// Columns 1+ cancel out IndentX
|
// Columns 1+ cancel out IndentX
|
||||||
window->DC.ColumnsOffsetX = GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x;
|
window->DC.ColumnsOffsetX = GetColumnOffset(columns->ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x;
|
||||||
window->DrawList->ChannelsSetCurrent(window->DC.ColumnsCurrent);
|
window->DrawList->ChannelsSetCurrent(columns->ColumnsCurrent);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
window->DC.ColumnsCurrent = 0;
|
|
||||||
window->DC.ColumnsOffsetX = 0.0f;
|
window->DC.ColumnsOffsetX = 0.0f;
|
||||||
window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY;
|
columns->ColumnsCurrent = 0;
|
||||||
|
columns->ColumnsCellMinY = columns->ColumnsCellMaxY;
|
||||||
window->DrawList->ChannelsSetCurrent(0);
|
window->DrawList->ChannelsSetCurrent(0);
|
||||||
}
|
}
|
||||||
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX);
|
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX);
|
||||||
window->DC.CursorPos.y = window->DC.ColumnsCellMinY;
|
window->DC.CursorPos.y = columns->ColumnsCellMinY;
|
||||||
window->DC.CurrentLineHeight = 0.0f;
|
window->DC.CurrentLineHeight = 0.0f;
|
||||||
window->DC.CurrentLineTextBaseOffset = 0.0f;
|
window->DC.CurrentLineTextBaseOffset = 0.0f;
|
||||||
|
|
||||||
@ -10823,37 +10818,37 @@ void ImGui::NextColumn()
|
|||||||
int ImGui::GetColumnIndex()
|
int ImGui::GetColumnIndex()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindowRead();
|
ImGuiWindow* window = GetCurrentWindowRead();
|
||||||
return window->DC.ColumnsCurrent;
|
return window->DC.ColumnsSet ? window->DC.ColumnsSet->ColumnsCurrent : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImGui::GetColumnsCount()
|
int ImGui::GetColumnsCount()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindowRead();
|
ImGuiWindow* window = GetCurrentWindowRead();
|
||||||
return window->DC.ColumnsCount;
|
return window->DC.ColumnsSet ? window->DC.ColumnsSet->ColumnsCount : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float OffsetNormToPixels(ImGuiWindow* window, float offset_norm)
|
static float OffsetNormToPixels(const ImGuiColumnsSet* columns, float offset_norm)
|
||||||
{
|
{
|
||||||
return offset_norm * (window->DC.ColumnsMaxX - window->DC.ColumnsMinX);
|
return offset_norm * (columns->ColumnsMaxX - columns->ColumnsMinX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float PixelsToOffsetNorm(ImGuiWindow* window, float offset)
|
static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset)
|
||||||
{
|
{
|
||||||
return (offset - window->DC.ColumnsMinX) / (window->DC.ColumnsMaxX - window->DC.ColumnsMinX);
|
return (offset - columns->ColumnsMinX) / (columns->ColumnsMaxX - columns->ColumnsMinX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float GetDraggedColumnOffset(int column_index)
|
static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index)
|
||||||
{
|
{
|
||||||
// Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
|
// Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
|
||||||
// window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
|
// window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets.
|
IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets.
|
||||||
IM_ASSERT(g.ActiveId == window->DC.ColumnsSetId + ImGuiID(column_index));
|
IM_ASSERT(g.ActiveId == columns->ColumnsSetId + ImGuiID(column_index));
|
||||||
|
|
||||||
float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x;
|
float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x;
|
||||||
x = ImMax(x, ImGui::GetColumnOffset(column_index-1) + g.Style.ColumnsMinSpacing);
|
x = ImMax(x, ImGui::GetColumnOffset(column_index-1) + g.Style.ColumnsMinSpacing);
|
||||||
if ((window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths))
|
if ((columns->ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths))
|
||||||
x = ImMin(x, ImGui::GetColumnOffset(column_index+1) - g.Style.ColumnsMinSpacing);
|
x = ImMin(x, ImGui::GetColumnOffset(column_index+1) - g.Style.ColumnsMinSpacing);
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
@ -10862,44 +10857,50 @@ static float GetDraggedColumnOffset(int column_index)
|
|||||||
float ImGui::GetColumnOffset(int column_index)
|
float ImGui::GetColumnOffset(int column_index)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindowRead();
|
ImGuiWindow* window = GetCurrentWindowRead();
|
||||||
|
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
|
||||||
|
IM_ASSERT(columns != NULL);
|
||||||
|
|
||||||
if (column_index < 0)
|
if (column_index < 0)
|
||||||
column_index = window->DC.ColumnsCurrent;
|
column_index = columns->ColumnsCurrent;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (g.ActiveId)
|
if (g.ActiveId)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index);
|
const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index);
|
||||||
if (g.ActiveId == column_id)
|
if (g.ActiveId == column_id)
|
||||||
return GetDraggedColumnOffset(column_index);
|
return GetDraggedColumnOffset(columns, column_index);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IM_ASSERT(column_index < window->DC.ColumnsData.Size);
|
IM_ASSERT(column_index < columns->ColumnsData.Size);
|
||||||
const float t = window->DC.ColumnsData[column_index].OffsetNorm;
|
const float t = columns->ColumnsData[column_index].OffsetNorm;
|
||||||
const float x_offset = ImLerp(window->DC.ColumnsMinX, window->DC.ColumnsMaxX, t);
|
const float x_offset = ImLerp(columns->ColumnsMinX, columns->ColumnsMaxX, t);
|
||||||
return x_offset;
|
return x_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::SetColumnOffset(int column_index, float offset)
|
void ImGui::SetColumnOffset(int column_index, float offset)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
|
||||||
|
IM_ASSERT(columns != NULL);
|
||||||
|
|
||||||
if (column_index < 0)
|
if (column_index < 0)
|
||||||
column_index = window->DC.ColumnsCurrent;
|
column_index = columns->ColumnsCurrent;
|
||||||
|
|
||||||
IM_ASSERT(column_index < window->DC.ColumnsData.Size);
|
IM_ASSERT(column_index < columns->ColumnsData.Size);
|
||||||
|
|
||||||
const bool preserve_width = !(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < window->DC.ColumnsCount-1);
|
const bool preserve_width = !(columns->ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->ColumnsCount-1);
|
||||||
const float width = preserve_width ? GetColumnWidth(column_index) : 0.0f;
|
const float width = preserve_width ? GetColumnWidth(column_index) : 0.0f;
|
||||||
|
|
||||||
if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow))
|
if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow))
|
||||||
offset = ImMin(offset, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index));
|
offset = ImMin(offset, columns->ColumnsMaxX - g.Style.ColumnsMinSpacing * (columns->ColumnsCount - column_index));
|
||||||
const float offset_norm = PixelsToOffsetNorm(window, offset);
|
const float offset_norm = PixelsToOffsetNorm(columns, offset);
|
||||||
|
|
||||||
const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index);
|
const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index);
|
||||||
window->DC.StateStorage->SetFloat(column_id, offset_norm);
|
window->DC.StateStorage->SetFloat(column_id, offset_norm);
|
||||||
window->DC.ColumnsData[column_index].OffsetNorm = offset_norm;
|
columns->ColumnsData[column_index].OffsetNorm = offset_norm;
|
||||||
|
|
||||||
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));
|
||||||
@ -10908,70 +10909,91 @@ void ImGui::SetColumnOffset(int column_index, float offset)
|
|||||||
float ImGui::GetColumnWidth(int column_index)
|
float ImGui::GetColumnWidth(int column_index)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindowRead();
|
ImGuiWindow* window = GetCurrentWindowRead();
|
||||||
if (column_index < 0)
|
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
|
||||||
column_index = window->DC.ColumnsCurrent;
|
IM_ASSERT(columns != NULL);
|
||||||
|
|
||||||
return OffsetNormToPixels(window, window->DC.ColumnsData[column_index+1].OffsetNorm - window->DC.ColumnsData[column_index].OffsetNorm);
|
if (column_index < 0)
|
||||||
|
column_index = columns->ColumnsCurrent;
|
||||||
|
return OffsetNormToPixels(columns, columns->ColumnsData[column_index+1].OffsetNorm - columns->ColumnsData[column_index].OffsetNorm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::SetColumnWidth(int column_index, float width)
|
void ImGui::SetColumnWidth(int column_index, float width)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindowRead();
|
ImGuiWindow* window = GetCurrentWindowRead();
|
||||||
if (column_index < 0)
|
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
|
||||||
column_index = window->DC.ColumnsCurrent;
|
IM_ASSERT(columns != NULL);
|
||||||
|
|
||||||
|
if (column_index < 0)
|
||||||
|
column_index = columns->ColumnsCurrent;
|
||||||
SetColumnOffset(column_index+1, GetColumnOffset(column_index) + width);
|
SetColumnOffset(column_index+1, GetColumnOffset(column_index) + width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::PushColumnClipRect(int column_index)
|
void ImGui::PushColumnClipRect(int column_index)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindowRead();
|
ImGuiWindow* window = GetCurrentWindowRead();
|
||||||
|
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
|
||||||
if (column_index < 0)
|
if (column_index < 0)
|
||||||
column_index = window->DC.ColumnsCurrent;
|
column_index = columns->ColumnsCurrent;
|
||||||
|
|
||||||
PushClipRect(window->DC.ColumnsData[column_index].ClipRect.Min, window->DC.ColumnsData[column_index].ClipRect.Max, false);
|
PushClipRect(columns->ColumnsData[column_index].ClipRect.Min, columns->ColumnsData[column_index].ClipRect.Max, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags flags)
|
static ImGuiColumnsSet* FindOrAddColumnsSet(ImGuiWindow* window, ImGuiID id)
|
||||||
|
{
|
||||||
|
for (int n = 0; n < window->DC.ColumnsSets.Size; n++)
|
||||||
|
if (window->DC.ColumnsSets[n].ColumnsSetId == id)
|
||||||
|
return &window->DC.ColumnsSets[n];
|
||||||
|
|
||||||
|
window->DC.ColumnsSets.push_back(ImGuiColumnsSet());
|
||||||
|
ImGuiColumnsSet* columns = &window->DC.ColumnsSets.back();
|
||||||
|
columns->ColumnsSetId = id;
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
|
||||||
IM_ASSERT(columns_count > 1);
|
IM_ASSERT(columns_count > 1);
|
||||||
IM_ASSERT(window->DC.ColumnsCount == 1); // Nested columns are currently not supported
|
IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported
|
||||||
|
|
||||||
// Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
|
// Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
|
||||||
// In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
|
// In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
|
||||||
PushID(0x11223347 + (id ? 0 : columns_count));
|
PushID(0x11223347 + (str_id ? 0 : columns_count));
|
||||||
window->DC.ColumnsSetId = window->GetID(id ? id : "columns");
|
ImGuiID id = window->GetID(str_id ? str_id : "columns");
|
||||||
PopID();
|
PopID();
|
||||||
|
|
||||||
|
ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id);
|
||||||
|
IM_ASSERT(columns->ColumnsSetId == id);
|
||||||
|
window->DC.ColumnsSet = columns;
|
||||||
|
|
||||||
// Set state for first column
|
// Set state for first column
|
||||||
window->DC.ColumnsCurrent = 0;
|
columns->ColumnsCurrent = 0;
|
||||||
window->DC.ColumnsCount = columns_count;
|
columns->ColumnsCount = columns_count;
|
||||||
window->DC.ColumnsFlags = flags;
|
columns->ColumnsFlags = flags;
|
||||||
|
|
||||||
const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x);
|
const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x);
|
||||||
window->DC.ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range
|
columns->ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range
|
||||||
//window->DC.ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x;
|
//column->ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x;
|
||||||
window->DC.ColumnsMaxX = content_region_width - window->Scroll.x;
|
columns->ColumnsMaxX = content_region_width - window->Scroll.x;
|
||||||
window->DC.ColumnsStartPosY = window->DC.CursorPos.y;
|
columns->ColumnsStartPosY = window->DC.CursorPos.y;
|
||||||
window->DC.ColumnsStartMaxPosX = window->DC.CursorMaxPos.x;
|
columns->ColumnsStartMaxPosX = window->DC.CursorMaxPos.x;
|
||||||
window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y;
|
columns->ColumnsCellMinY = columns->ColumnsCellMaxY = window->DC.CursorPos.y;
|
||||||
window->DC.ColumnsOffsetX = 0.0f;
|
window->DC.ColumnsOffsetX = 0.0f;
|
||||||
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX);
|
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX);
|
||||||
|
|
||||||
// Cache column offsets
|
// Cache column offsets
|
||||||
window->DC.ColumnsData.resize(columns_count + 1);
|
columns->ColumnsData.resize(columns_count + 1);
|
||||||
for (int column_index = 0; column_index < columns_count + 1; column_index++)
|
for (int column_index = 0; column_index < columns_count + 1; column_index++)
|
||||||
{
|
{
|
||||||
const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index);
|
const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index);
|
||||||
KeepAliveID(column_id);
|
KeepAliveID(column_id);
|
||||||
const float default_t = column_index / (float)window->DC.ColumnsCount;
|
const float default_t = column_index / (float)columns_count;
|
||||||
float t = window->DC.StateStorage->GetFloat(column_id, default_t);
|
float t = window->DC.StateStorage->GetFloat(column_id, default_t);
|
||||||
if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow))
|
if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow))
|
||||||
t = ImMin(t, PixelsToOffsetNorm(window, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index)));
|
t = ImMin(t, PixelsToOffsetNorm(columns, columns->ColumnsMaxX - g.Style.ColumnsMinSpacing * (columns->ColumnsCount - column_index)));
|
||||||
window->DC.ColumnsData[column_index].OffsetNorm = t;
|
columns->ColumnsData[column_index].OffsetNorm = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache clipping rectangles
|
// Cache clipping rectangles
|
||||||
@ -10979,11 +11001,11 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl
|
|||||||
{
|
{
|
||||||
float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f);
|
float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f);
|
||||||
float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f);
|
float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f);
|
||||||
window->DC.ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
|
columns->ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
|
||||||
window->DC.ColumnsData[column_index].ClipRect.ClipWith(window->ClipRect);
|
columns->ColumnsData[column_index].ClipRect.ClipWith(window->ClipRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
window->DrawList->ChannelsSplit(window->DC.ColumnsCount);
|
window->DrawList->ChannelsSplit(columns->ColumnsCount);
|
||||||
PushColumnClipRect();
|
PushColumnClipRect();
|
||||||
PushItemWidth(GetColumnWidth() * 0.65f);
|
PushItemWidth(GetColumnWidth() * 0.65f);
|
||||||
}
|
}
|
||||||
@ -10992,34 +11014,35 @@ void ImGui::EndColumns()
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
IM_ASSERT(window->DC.ColumnsCount > 1);
|
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
|
||||||
|
IM_ASSERT(columns != NULL);
|
||||||
|
|
||||||
PopItemWidth();
|
PopItemWidth();
|
||||||
PopClipRect();
|
PopClipRect();
|
||||||
window->DrawList->ChannelsMerge();
|
window->DrawList->ChannelsMerge();
|
||||||
|
|
||||||
window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y);
|
columns->ColumnsCellMaxY = ImMax(columns->ColumnsCellMaxY, window->DC.CursorPos.y);
|
||||||
window->DC.CursorPos.y = window->DC.ColumnsCellMaxY;
|
window->DC.CursorPos.y = columns->ColumnsCellMaxY;
|
||||||
if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_GrowParentContentsSize))
|
if (!(columns->ColumnsFlags & ImGuiColumnsFlags_GrowParentContentsSize))
|
||||||
window->DC.CursorMaxPos.x = ImMax(window->DC.ColumnsStartMaxPosX, window->DC.ColumnsMaxX); // Restore cursor max pos, as columns don't grow parent
|
window->DC.CursorMaxPos.x = ImMax(columns->ColumnsStartMaxPosX, columns->ColumnsMaxX); // Restore cursor max pos, as columns don't grow parent
|
||||||
|
|
||||||
// Draw columns borders and handle resize
|
// Draw columns borders and handle resize
|
||||||
if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems)
|
if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems)
|
||||||
{
|
{
|
||||||
const float y1 = window->DC.ColumnsStartPosY;
|
const float y1 = columns->ColumnsStartPosY;
|
||||||
const float y2 = window->DC.CursorPos.y;
|
const float y2 = window->DC.CursorPos.y;
|
||||||
int dragging_column = -1;
|
int dragging_column = -1;
|
||||||
for (int i = 1; i < window->DC.ColumnsCount; i++)
|
for (int i = 1; i < columns->ColumnsCount; i++)
|
||||||
{
|
{
|
||||||
float x = window->Pos.x + GetColumnOffset(i);
|
float x = window->Pos.x + GetColumnOffset(i);
|
||||||
const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i);
|
const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(i);
|
||||||
const float column_hw = 4.0f; // Half-width for interaction
|
const float column_hw = 4.0f; // Half-width for interaction
|
||||||
const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2));
|
const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2));
|
||||||
if (IsClippedEx(column_rect, column_id, false))
|
if (IsClippedEx(column_rect, column_id, false))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool hovered = false, held = false;
|
bool hovered = false, held = false;
|
||||||
if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoResize))
|
if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoResize))
|
||||||
{
|
{
|
||||||
ButtonBehavior(column_rect, column_id, &hovered, &held);
|
ButtonBehavior(column_rect, column_id, &hovered, &held);
|
||||||
if (hovered || held)
|
if (hovered || held)
|
||||||
@ -11040,16 +11063,13 @@ void ImGui::EndColumns()
|
|||||||
// Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame.
|
// Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame.
|
||||||
if (dragging_column != -1)
|
if (dragging_column != -1)
|
||||||
{
|
{
|
||||||
float x = GetDraggedColumnOffset(dragging_column);
|
float x = GetDraggedColumnOffset(columns, dragging_column);
|
||||||
SetColumnOffset(dragging_column, x);
|
SetColumnOffset(dragging_column, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window->DC.ColumnsSetId = 0;
|
columns->ColumnsData.resize(0);
|
||||||
window->DC.ColumnsCurrent = 0;
|
window->DC.ColumnsSet = NULL;
|
||||||
window->DC.ColumnsCount = 1;
|
|
||||||
window->DC.ColumnsFlags = 0;
|
|
||||||
window->DC.ColumnsData.resize(0);
|
|
||||||
window->DC.ColumnsOffsetX = 0.0f;
|
window->DC.ColumnsOffsetX = 0.0f;
|
||||||
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX);
|
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX);
|
||||||
}
|
}
|
||||||
@ -11060,7 +11080,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
|
|||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
IM_ASSERT(columns_count >= 1);
|
IM_ASSERT(columns_count >= 1);
|
||||||
|
|
||||||
if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1)
|
if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->ColumnsCount != columns_count)
|
||||||
EndColumns();
|
EndColumns();
|
||||||
|
|
||||||
ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder);
|
ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder);
|
||||||
|
@ -331,14 +331,6 @@ struct ImGuiGroupData
|
|||||||
bool AdvanceCursor;
|
bool AdvanceCursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Per column data for Columns()
|
|
||||||
struct ImGuiColumnData
|
|
||||||
{
|
|
||||||
float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right)
|
|
||||||
ImRect ClipRect;
|
|
||||||
//float IndentX;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper.
|
// Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper.
|
||||||
struct IMGUI_API ImGuiSimpleColumns
|
struct IMGUI_API ImGuiSimpleColumns
|
||||||
{
|
{
|
||||||
@ -420,6 +412,42 @@ struct ImGuiPopupRef
|
|||||||
ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; }
|
ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Per column data for Columns()
|
||||||
|
struct ImGuiColumnData
|
||||||
|
{
|
||||||
|
float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right)
|
||||||
|
ImRect ClipRect;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImGuiColumnsSet
|
||||||
|
{
|
||||||
|
int ColumnsCurrent;
|
||||||
|
int ColumnsCount;
|
||||||
|
float ColumnsMinX;
|
||||||
|
float ColumnsMaxX;
|
||||||
|
float ColumnsStartPosY;
|
||||||
|
float ColumnsStartMaxPosX; // Backup of CursorMaxPos
|
||||||
|
float ColumnsCellMinY;
|
||||||
|
float ColumnsCellMaxY;
|
||||||
|
ImGuiColumnsFlags ColumnsFlags;
|
||||||
|
ImGuiID ColumnsSetId;
|
||||||
|
ImVector<ImGuiColumnData> ColumnsData;
|
||||||
|
|
||||||
|
ImGuiColumnsSet() { Clear(); }
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
ColumnsCurrent = 0;
|
||||||
|
ColumnsCount = 1;
|
||||||
|
ColumnsMinX = ColumnsMaxX = 0.0f;
|
||||||
|
ColumnsStartPosY = 0.0f;
|
||||||
|
ColumnsStartMaxPosX = 0.0f;
|
||||||
|
ColumnsCellMinY = ColumnsCellMaxY = 0.0f;
|
||||||
|
ColumnsFlags = 0;
|
||||||
|
ColumnsSetId = 0;
|
||||||
|
ColumnsData.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Main state for ImGui
|
// Main state for ImGui
|
||||||
struct ImGuiContext
|
struct ImGuiContext
|
||||||
{
|
{
|
||||||
@ -674,17 +702,8 @@ struct IMGUI_API ImGuiDrawContext
|
|||||||
float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
|
float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
|
||||||
float GroupOffsetX;
|
float GroupOffsetX;
|
||||||
float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
|
float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
|
||||||
int ColumnsCurrent;
|
ImGuiColumnsSet* ColumnsSet;
|
||||||
int ColumnsCount;
|
ImVector<ImGuiColumnsSet> ColumnsSets;
|
||||||
float ColumnsMinX;
|
|
||||||
float ColumnsMaxX;
|
|
||||||
float ColumnsStartPosY;
|
|
||||||
float ColumnsStartMaxPosX; // Backup of CursorMaxPos
|
|
||||||
float ColumnsCellMinY;
|
|
||||||
float ColumnsCellMaxY;
|
|
||||||
ImGuiColumnsFlags ColumnsFlags;
|
|
||||||
ImGuiID ColumnsSetId;
|
|
||||||
ImVector<ImGuiColumnData> ColumnsData;
|
|
||||||
|
|
||||||
ImGuiDrawContext()
|
ImGuiDrawContext()
|
||||||
{
|
{
|
||||||
@ -708,14 +727,7 @@ struct IMGUI_API ImGuiDrawContext
|
|||||||
IndentX = 0.0f;
|
IndentX = 0.0f;
|
||||||
GroupOffsetX = 0.0f;
|
GroupOffsetX = 0.0f;
|
||||||
ColumnsOffsetX = 0.0f;
|
ColumnsOffsetX = 0.0f;
|
||||||
ColumnsCurrent = 0;
|
ColumnsSet = NULL;
|
||||||
ColumnsCount = 1;
|
|
||||||
ColumnsMinX = ColumnsMaxX = 0.0f;
|
|
||||||
ColumnsStartPosY = 0.0f;
|
|
||||||
ColumnsStartMaxPosX = 0.0f;
|
|
||||||
ColumnsCellMinY = ColumnsCellMaxY = 0.0f;
|
|
||||||
ColumnsFlags = 0;
|
|
||||||
ColumnsSetId = 0;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -877,7 +889,7 @@ namespace ImGui
|
|||||||
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
||||||
|
|
||||||
// FIXME-WIP: New Columns API
|
// FIXME-WIP: New Columns API
|
||||||
IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
|
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
|
||||||
IMGUI_API void EndColumns(); // close columns
|
IMGUI_API void EndColumns(); // close columns
|
||||||
IMGUI_API void PushColumnClipRect(int column_index = -1);
|
IMGUI_API void PushColumnClipRect(int column_index = -1);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user