Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_internal.h
This commit is contained in:
ocornut
2020-12-03 20:05:49 +01:00
17 changed files with 407 additions and 242 deletions

View File

@ -1358,7 +1358,7 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
if (g.GroupStack.Size > 0 && g.GroupStack.back().WindowID == window->ID)
x1 += window->DC.Indent.x;
ImGuiColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL;
ImGuiOldColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL;
if (columns)
PushColumnsBackground();
@ -1597,13 +1597,17 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
char name[16];
ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginPopupStack.Size); // Recycle windows based on depth
// Peak into expected window size so we can position it
// Position the window given a custom constraint (peak into expected window size so we can position it)
// This might be easier to express with an hypothetical SetNextWindowPosConstraints() function.
if (ImGuiWindow* popup_window = FindWindowByName(name))
if (popup_window->WasActive)
{
// Always override 'AutoPosLastDirection' to not leave a chance for a past value to affect us.
ImVec2 size_expected = CalcWindowExpectedSize(popup_window);
if (flags & ImGuiComboFlags_PopupAlignLeft)
popup_window->AutoPosLastDirection = ImGuiDir_Left;
popup_window->AutoPosLastDirection = ImGuiDir_Left; // "Below, Toward Left"
else
popup_window->AutoPosLastDirection = ImGuiDir_Down; // "Below, Toward Right (default)"
ImRect r_outer = GetWindowAllowedExtentRect(popup_window);
ImVec2 pos = FindBestWindowPosForPopupEx(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, r_outer, frame_bb, ImGuiPopupPositionPolicy_ComboBox);
SetNextWindowPos(pos);
@ -3864,9 +3868,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline);
const bool init_make_active = (focus_requested || user_clicked || user_scroll_finish || user_nav_input_start);
const bool init_state = (init_make_active || user_scroll_active);
if (init_state && g.ActiveId != id)
if ((init_state && g.ActiveId != id) || init_changed_specs)
{
// Access state even if we don't own it yet.
state = &g.InputTextState;
@ -3888,7 +3893,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Preserve cursor position and undo/redo stack if we come back to same widget
// FIXME: For non-readonly widgets we might be able to require that TextAIsValid && TextA == buf ? (untested) and discard undo stack if user buffer has changed.
const bool recycle_state = (state->ID == id);
const bool recycle_state = (state->ID == id && !init_changed_specs);
if (recycle_state)
{
// Recycle existing cursor/selection/undo stack but clamp position
@ -8053,19 +8058,19 @@ int ImGui::GetColumnsCount()
return window->DC.CurrentColumns ? window->DC.CurrentColumns->Count : 1;
}
float ImGui::GetColumnOffsetFromNorm(const ImGuiColumns* columns, float offset_norm)
float ImGui::GetColumnOffsetFromNorm(const ImGuiOldColumns* columns, float offset_norm)
{
return offset_norm * (columns->OffMaxX - columns->OffMinX);
}
float ImGui::GetColumnNormFromOffset(const ImGuiColumns* columns, float offset)
float ImGui::GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offset)
{
return offset / (columns->OffMaxX - columns->OffMinX);
}
static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f;
static float GetDraggedColumnOffset(ImGuiColumns* columns, int column_index)
static float GetDraggedColumnOffset(ImGuiOldColumns* 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
// window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
@ -8076,7 +8081,7 @@ static float GetDraggedColumnOffset(ImGuiColumns* columns, int column_index)
float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + COLUMNS_HIT_RECT_HALF_WIDTH - window->Pos.x;
x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing);
if ((columns->Flags & ImGuiColumnsFlags_NoPreserveWidths))
if ((columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths))
x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing);
return x;
@ -8085,7 +8090,7 @@ static float GetDraggedColumnOffset(ImGuiColumns* columns, int column_index)
float ImGui::GetColumnOffset(int column_index)
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
if (columns == NULL)
return 0.0f;
@ -8098,7 +8103,7 @@ float ImGui::GetColumnOffset(int column_index)
return x_offset;
}
static float GetColumnWidthEx(ImGuiColumns* columns, int column_index, bool before_resize = false)
static float GetColumnWidthEx(ImGuiOldColumns* columns, int column_index, bool before_resize = false)
{
if (column_index < 0)
column_index = columns->Current;
@ -8115,7 +8120,7 @@ float ImGui::GetColumnWidth(int column_index)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
if (columns == NULL)
return GetContentRegionAvail().x;
@ -8128,17 +8133,17 @@ void ImGui::SetColumnOffset(int column_index, float offset)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL);
if (column_index < 0)
column_index = columns->Current;
IM_ASSERT(column_index < columns->Columns.Size);
const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count - 1);
const bool preserve_width = !(columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths) && (column_index < columns->Count - 1);
const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f;
if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow))
if (!(columns->Flags & ImGuiOldColumnFlags_NoForceWithinWindow))
offset = ImMin(offset, columns->OffMaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index));
columns->Columns[column_index].OffsetNorm = GetColumnNormFromOffset(columns, offset - columns->OffMinX);
@ -8149,7 +8154,7 @@ void ImGui::SetColumnOffset(int column_index, float offset)
void ImGui::SetColumnWidth(int column_index, float width)
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL);
if (column_index < 0)
@ -8160,11 +8165,11 @@ void ImGui::SetColumnWidth(int column_index, float width)
void ImGui::PushColumnClipRect(int column_index)
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
if (column_index < 0)
column_index = columns->Current;
ImGuiColumnData* column = &columns->Columns[column_index];
ImGuiOldColumnData* column = &columns->Columns[column_index];
PushClipRect(column->ClipRect.Min, column->ClipRect.Max, false);
}
@ -8172,7 +8177,7 @@ void ImGui::PushColumnClipRect(int column_index)
void ImGui::PushColumnsBackground()
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1)
return;
@ -8185,7 +8190,7 @@ void ImGui::PushColumnsBackground()
void ImGui::PopColumnsBackground()
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1)
return;
@ -8194,15 +8199,15 @@ void ImGui::PopColumnsBackground()
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
}
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
ImGuiOldColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
{
// We have few columns per window so for now we don't need bother much with turning this into a faster lookup.
for (int n = 0; n < window->ColumnsStorage.Size; n++)
if (window->ColumnsStorage[n].ID == id)
return &window->ColumnsStorage[n];
window->ColumnsStorage.push_back(ImGuiColumns());
ImGuiColumns* columns = &window->ColumnsStorage.back();
window->ColumnsStorage.push_back(ImGuiOldColumns());
ImGuiOldColumns* columns = &window->ColumnsStorage.back();
columns->ID = id;
return columns;
}
@ -8220,7 +8225,7 @@ ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count)
return id;
}
void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags)
void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiOldColumnFlags flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
@ -8230,7 +8235,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
// Acquire storage for the columns set
ImGuiID id = GetColumnsID(str_id, columns_count);
ImGuiColumns* columns = FindOrCreateColumns(window, id);
ImGuiOldColumns* columns = FindOrCreateColumns(window, id);
IM_ASSERT(columns->ID == id);
columns->Current = 0;
columns->Count = columns_count;
@ -8264,7 +8269,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
columns->Columns.reserve(columns_count + 1);
for (int n = 0; n < columns_count + 1; n++)
{
ImGuiColumnData column;
ImGuiOldColumnData column;
column.OffsetNorm = n / (float)columns_count;
columns->Columns.push_back(column);
}
@ -8273,7 +8278,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
for (int n = 0; n < columns_count; n++)
{
// Compute clipping rectangle
ImGuiColumnData* column = &columns->Columns[n];
ImGuiOldColumnData* column = &columns->Columns[n];
float clip_x1 = IM_ROUND(window->Pos.x + GetColumnOffset(n));
float clip_x2 = IM_ROUND(window->Pos.x + GetColumnOffset(n + 1) - 1.0f);
column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
@ -8304,7 +8309,7 @@ void ImGui::NextColumn()
return;
ImGuiContext& g = *GImGui;
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1)
{
@ -8321,7 +8326,7 @@ void ImGui::NextColumn()
// Optimization: avoid PopClipRect() + SetCurrentChannel() + PushClipRect()
// (which would needlessly attempt to update commands in the wrong channel, then pop or overwrite them),
ImGuiColumnData* column = &columns->Columns[columns->Current];
ImGuiOldColumnData* column = &columns->Columns[columns->Current];
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
@ -8356,7 +8361,7 @@ void ImGui::EndColumns()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL);
PopItemWidth();
@ -8366,16 +8371,16 @@ void ImGui::EndColumns()
columns->Splitter.Merge(window->DrawList);
}
const ImGuiColumnsFlags flags = columns->Flags;
const ImGuiOldColumnFlags flags = columns->Flags;
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
window->DC.CursorPos.y = columns->LineMaxY;
if (!(flags & ImGuiColumnsFlags_GrowParentContentsSize))
if (!(flags & ImGuiOldColumnFlags_GrowParentContentsSize))
window->DC.CursorMaxPos.x = columns->HostCursorMaxPosX; // Restore cursor max pos, as columns don't grow parent
// 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;
if (!(flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems)
if (!(flags & ImGuiOldColumnFlags_NoBorder) && !window->SkipItems)
{
// We clip Y boundaries CPU side because very long triangles are mishandled by some GPU drivers.
const float y1 = ImMax(columns->HostCursorPosY, window->ClipRect.Min.y);
@ -8383,7 +8388,7 @@ void ImGui::EndColumns()
int dragging_column = -1;
for (int n = 1; n < columns->Count; n++)
{
ImGuiColumnData* column = &columns->Columns[n];
ImGuiOldColumnData* column = &columns->Columns[n];
float x = window->Pos.x + GetColumnOffset(n);
const ImGuiID column_id = columns->ID + ImGuiID(n);
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH;
@ -8393,12 +8398,12 @@ void ImGui::EndColumns()
continue;
bool hovered = false, held = false;
if (!(flags & ImGuiColumnsFlags_NoResize))
if (!(flags & ImGuiOldColumnFlags_NoResize))
{
ButtonBehavior(column_hit_rect, column_id, &hovered, &held);
if (hovered || held)
g.MouseCursor = ImGuiMouseCursor_ResizeEW;
if (held && !(column->Flags & ImGuiColumnsFlags_NoResize))
if (held && !(column->Flags & ImGuiOldColumnFlags_NoResize))
dragging_column = n;
}
@ -8428,15 +8433,14 @@ void ImGui::EndColumns()
window->DC.CursorPos.x = IM_FLOOR(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]
void ImGui::Columns(int columns_count, const char* id, bool border)
{
ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(columns_count >= 1);
ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder);
//flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior
ImGuiColumns* columns = window->DC.CurrentColumns;
ImGuiOldColumnFlags flags = (border ? 0 : ImGuiOldColumnFlags_NoBorder);
//flags |= ImGuiOldColumnFlags_NoPreserveWidths; // NB: Legacy behavior
ImGuiOldColumns* columns = window->DC.CurrentColumns;
if (columns != NULL && columns->Count == columns_count && columns->Flags == flags)
return;