Internals: Merged some changes to facilitate 1D->2D transition for some elements, and merging the stack layout PR (#846)

This commit is contained in:
omar 2018-08-28 19:03:08 +02:00
parent 220e6a55b7
commit f9634feb66
2 changed files with 63 additions and 55 deletions

View File

@ -2048,7 +2048,7 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
ImGui::SetCursorPosY(pos_y);
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.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.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.
if (window->DC.ColumnsSet)
window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
}
@ -2379,18 +2379,18 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y)
return;
// Always align ourselves on pixel boundaries
const float line_height = ImMax(window->DC.CurrentLineHeight, size.y);
const float line_height = ImMax(window->DC.CurrentLineSize.y, size.y);
const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y);
//if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG]
window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y);
window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y));
window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y));
window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x);
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y);
//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
window->DC.PrevLineHeight = line_height;
window->DC.PrevLineSize.y = line_height;
window->DC.PrevLineTextBaseOffset = text_base_offset;
window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f;
window->DC.CurrentLineSize.y = window->DC.CurrentLineTextBaseOffset = 0.0f;
// Horizontal layout mode
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
@ -6676,14 +6676,14 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// 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.)
window->DC.IndentX = 0.0f + window->WindowPadding.x - window->Scroll.x;
window->DC.GroupOffsetX = 0.0f;
window->DC.ColumnsOffsetX = 0.0f;
window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.IndentX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y);
window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x;
window->DC.GroupOffset.x = 0.0f;
window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.Indent.x + window->DC.ColumnsOffset.x, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y);
window->DC.CursorPos = window->DC.CursorStartPos;
window->DC.CursorPosPrevLine = window->DC.CursorPos;
window->DC.CursorMaxPos = window->DC.CursorStartPos;
window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f;
window->DC.CurrentLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f;
window->DC.NavHideHighlightOneFrame = false;
window->DC.NavHasScroll = (GetScrollMaxY() > 0.0f);
@ -7856,7 +7856,7 @@ void ImGui::SetScrollHere(float center_y_ratio)
{
ImGuiWindow* window = GetCurrentWindow();
float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space
target_y += (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line.
target_y += (window->DC.PrevLineSize.y * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line.
SetScrollFromPosY(target_y, center_y_ratio);
}
@ -8081,7 +8081,7 @@ void ImGui::AlignTextToFramePadding()
return;
ImGuiContext& g = *GImGui;
window->DC.CurrentLineHeight = ImMax(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y * 2);
window->DC.CurrentLineSize.y = ImMax(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y * 2);
window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y);
}
@ -8672,7 +8672,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
// We vertically grow up to current line height up the typical widget height.
const float text_base_offset_y = ImMax(padding.y, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it
const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2);
const float frame_height = ImMax(ImMin(window->DC.CurrentLineSize.y, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2);
ImRect frame_bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height));
if (display_frame)
{
@ -8997,7 +8997,7 @@ void ImGui::Bullet()
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize);
const float line_height = ImMax(ImMin(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y*2), g.FontSize);
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height));
ItemSize(bb);
if (!ItemAdd(bb, 0))
@ -9025,7 +9025,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
const ImVec2 label_size = CalcTextSize(text_begin, text_end, false);
const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it
const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize);
const float line_height = ImMax(ImMin(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y*2), g.FontSize);
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x*2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding
ItemSize(bb);
if (!ItemAdd(bb, 0))
@ -13095,7 +13095,7 @@ void ImGui::Separator()
float x1 = window->Pos.x;
float x2 = window->Pos.x + window->Size.x;
if (!window->DC.GroupStack.empty())
x1 += window->DC.IndentX;
x1 += window->DC.Indent.x;
const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f));
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.
@ -13126,7 +13126,7 @@ void ImGui::VerticalSeparator()
ImGuiContext& g = *GImGui;
float y1 = window->DC.CursorPos.y;
float y2 = window->DC.CursorPos.y + window->DC.CurrentLineHeight;
float y2 = window->DC.CursorPos.y + window->DC.CurrentLineSize.y;
const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2));
ItemSize(ImVec2(bb.GetWidth(), 0.0f));
if (!ItemAdd(bb, 0))
@ -13236,19 +13236,19 @@ void ImGui::BeginGroup()
ImGuiGroupData& group_data = window->DC.GroupStack.back();
group_data.BackupCursorPos = window->DC.CursorPos;
group_data.BackupCursorMaxPos = window->DC.CursorMaxPos;
group_data.BackupIndentX = window->DC.IndentX;
group_data.BackupGroupOffsetX = window->DC.GroupOffsetX;
group_data.BackupCurrentLineHeight = window->DC.CurrentLineHeight;
group_data.BackupIndent = window->DC.Indent;
group_data.BackupGroupOffset = window->DC.GroupOffset;
group_data.BackupCurrentLineSize = window->DC.CurrentLineSize;
group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset;
group_data.BackupLogLinePosY = window->DC.LogLinePosY;
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive;
group_data.AdvanceCursor = true;
window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX;
window->DC.IndentX = window->DC.GroupOffsetX;
window->DC.GroupOffset.x = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffset.x;
window->DC.Indent = window->DC.GroupOffset;
window->DC.CursorMaxPos = window->DC.CursorPos;
window->DC.CurrentLineHeight = 0.0f;
window->DC.CurrentLineSize = ImVec2(0.0f, 0.0f);
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; // To enforce Log carriage return
}
@ -13265,9 +13265,9 @@ void ImGui::EndGroup()
window->DC.CursorPos = group_data.BackupCursorPos;
window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos);
window->DC.IndentX = group_data.BackupIndentX;
window->DC.GroupOffsetX = group_data.BackupGroupOffsetX;
window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight;
window->DC.Indent = group_data.BackupIndent;
window->DC.GroupOffset = group_data.BackupGroupOffset;
window->DC.CurrentLineSize = group_data.BackupCurrentLineSize;
window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset;
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; // To enforce Log carriage return
@ -13307,7 +13307,7 @@ void ImGui::SameLine(float pos_x, float spacing_w)
if (pos_x != 0.0f)
{
if (spacing_w < 0.0f) spacing_w = 0.0f;
window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w + window->DC.GroupOffsetX + window->DC.ColumnsOffsetX;
window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w + window->DC.GroupOffset.x + window->DC.ColumnsOffset.x;
window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y;
}
else
@ -13316,7 +13316,7 @@ void ImGui::SameLine(float pos_x, float spacing_w)
window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w;
window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y;
}
window->DC.CurrentLineHeight = window->DC.PrevLineHeight;
window->DC.CurrentLineSize = window->DC.PrevLineSize;
window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
}
@ -13329,7 +13329,7 @@ void ImGui::NewLine()
ImGuiContext& g = *GImGui;
const ImGuiLayoutType backup_layout_type = window->DC.LayoutType;
window->DC.LayoutType = ImGuiLayoutType_Vertical;
if (window->DC.CurrentLineHeight > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
if (window->DC.CurrentLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
ItemSize(ImVec2(0,0));
else
ItemSize(ImVec2(0.0f, g.FontSize));
@ -13351,19 +13351,19 @@ void ImGui::NextColumn()
if (++columns->Current < columns->Count)
{
// Columns 1+ cancel out IndentX
window->DC.ColumnsOffsetX = GetColumnOffset(columns->Current) - window->DC.IndentX + g.Style.ItemSpacing.x;
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + g.Style.ItemSpacing.x;
window->DrawList->ChannelsSetCurrent(columns->Current);
}
else
{
window->DC.ColumnsOffsetX = 0.0f;
window->DC.ColumnsOffset.x = 0.0f;
window->DrawList->ChannelsSetCurrent(0);
columns->Current = 0;
columns->LineMinY = columns->LineMaxY;
}
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.Indent.x + window->DC.ColumnsOffset.x);
window->DC.CursorPos.y = columns->LineMinY;
window->DC.CurrentLineHeight = 0.0f;
window->DC.CurrentLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrentLineTextBaseOffset = 0.0f;
PushColumnClipRect();
@ -13529,13 +13529,13 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
// 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);
columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range
columns->MinX = 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->StartPosY = window->DC.CursorPos.y;
columns->StartMaxPosX = window->DC.CursorMaxPos.x;
columns->LineMinY = columns->LineMaxY = window->DC.CursorPos.y;
window->DC.ColumnsOffsetX = 0.0f;
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX);
window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
// Clear data if columns count changed
if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1)
@ -13632,8 +13632,8 @@ void ImGui::EndColumns()
columns->IsBeingResized = is_being_resized;
window->DC.ColumnsSet = NULL;
window->DC.ColumnsOffsetX = 0.0f;
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX);
window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
}
// [2018-03: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing]
@ -13658,16 +13658,16 @@ void ImGui::Indent(float indent_w)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
window->DC.IndentX += (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing;
window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX;
window->DC.Indent.x += (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing;
window->DC.CursorPos.x = window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x;
}
void ImGui::Unindent(float indent_w)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
window->DC.IndentX -= (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing;
window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX;
window->DC.Indent.x -= (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing;
window->DC.CursorPos.x = window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x;
}
void ImGui::TreePush(const char* str_id)

View File

@ -211,6 +211,14 @@ static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs)
// Types
//-----------------------------------------------------------------------------
// 1D vector (this odd construct is used to facilitate the transition between 1D and 2D and maintenance of some patches)
struct ImVec1
{
float x;
ImVec1() { x = 0.0f; }
ImVec1(float _x) { x = _x; }
};
enum ImGuiButtonFlags_
{
ImGuiButtonFlags_None = 0,
@ -406,9 +414,9 @@ struct ImGuiGroupData
{
ImVec2 BackupCursorPos;
ImVec2 BackupCursorMaxPos;
float BackupIndentX;
float BackupGroupOffsetX;
float BackupCurrentLineHeight;
ImVec1 BackupIndent;
ImVec1 BackupGroupOffset;
ImVec2 BackupCurrentLineSize;
float BackupCurrentLineTextBaseOffset;
float BackupLogLinePosY;
ImGuiID BackupActiveIdIsAlive;
@ -894,11 +902,11 @@ struct IMGUI_API ImGuiWindowTempData
{
ImVec2 CursorPos;
ImVec2 CursorPosPrevLine;
ImVec2 CursorStartPos;
ImVec2 CursorStartPos; // Initial position in client area with padding
ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Turned into window->SizeContents at the beginning of next frame
float CurrentLineHeight;
ImVec2 CurrentLineSize;
float CurrentLineTextBaseOffset;
float PrevLineHeight;
ImVec2 PrevLineSize;
float PrevLineTextBaseOffset;
float LogLinePosY;
int TreeDepth;
@ -930,15 +938,15 @@ struct IMGUI_API ImGuiWindowTempData
ImVector<ImGuiGroupData>GroupStack;
int StackSizesBackup[6]; // Store size of various stacks for asserting
float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
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.
ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
ImVec1 GroupOffset;
ImVec1 ColumnsOffset; // 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.
ImGuiColumnsSet* ColumnsSet; // Current columns set
ImGuiWindowTempData()
{
CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f);
CurrentLineHeight = PrevLineHeight = 0.0f;
CurrentLineSize = PrevLineSize = ImVec2(0.0f, 0.0f);
CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f;
LogLinePosY = -1.0f;
TreeDepth = 0;
@ -960,9 +968,9 @@ struct IMGUI_API ImGuiWindowTempData
TextWrapPos = -1.0f;
memset(StackSizesBackup, 0, sizeof(StackSizesBackup));
IndentX = 0.0f;
GroupOffsetX = 0.0f;
ColumnsOffsetX = 0.0f;
Indent = ImVec1(0.0f);
GroupOffset = ImVec1(0.0f);
ColumnsOffset = ImVec1(0.0f);
ColumnsSet = NULL;
}
};