Updated ImGui.

This commit is contained in:
Бранимир Караџић 2020-08-06 17:55:49 -07:00
parent a3c3997e69
commit 0a4099b13c
5 changed files with 132 additions and 68 deletions

View File

@ -807,7 +807,7 @@ static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock
static void SetCurrentWindow(ImGuiWindow* window); static void SetCurrentWindow(ImGuiWindow* window);
static void FindHoveredWindow(); static void FindHoveredWindow();
static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags); static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags);
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window);
static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list); static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window); static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window);
@ -3375,8 +3375,8 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0])) if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
g.MovingWindow = NULL; g.MovingWindow = NULL;
// Cancel moving if clicked over an item which was disabled or inhibited by popups // Cancel moving if clicked over an item which was disabled or inhibited by popups (note that we know HoveredId == 0 already)
if (g.HoveredId == 0 && g.HoveredIdDisabled) if (g.HoveredIdDisabled)
g.MovingWindow = NULL; g.MovingWindow = NULL;
} }
else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL) else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
@ -5821,7 +5821,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->ScrollMax.y = ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight()); window->ScrollMax.y = ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight());
// Apply scrolling // Apply scrolling
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true); window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window);
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
// DRAWING // DRAWING
@ -5900,6 +5900,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize)); window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize));
window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x; window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x;
window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y; window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
window->ParentWorkRect = window->WorkRect;
// [LEGACY] Content Region // [LEGACY] Content Region
// FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it. // FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
@ -7327,30 +7328,20 @@ void ImGui::EndGroup()
// [SECTION] SCROLLING // [SECTION] SCROLLING
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges) static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
{ {
ImGuiContext& g = *GImGui;
ImVec2 scroll = window->Scroll; ImVec2 scroll = window->Scroll;
if (window->ScrollTarget.x < FLT_MAX) if (window->ScrollTarget.x < FLT_MAX)
{ {
float cr_x = window->ScrollTargetCenterRatio.x; float cr_x = window->ScrollTargetCenterRatio.x;
float target_x = window->ScrollTarget.x; float target_x = window->ScrollTarget.x;
if (snap_on_edges && cr_x <= 0.0f && target_x <= window->WindowPadding.x)
target_x = 0.0f;
else if (snap_on_edges && cr_x >= 1.0f && target_x >= window->ContentSize.x + window->WindowPadding.x + g.Style.ItemSpacing.x)
target_x = window->ContentSize.x + window->WindowPadding.x * 2.0f;
scroll.x = target_x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x); scroll.x = target_x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x);
} }
if (window->ScrollTarget.y < FLT_MAX) if (window->ScrollTarget.y < FLT_MAX)
{ {
// 'snap_on_edges' allows for a discontinuity at the edge of scrolling limits to take account of WindowPadding so that scrolling to make the last item visible scroll far enough to see the padding.
float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
float cr_y = window->ScrollTargetCenterRatio.y; float cr_y = window->ScrollTargetCenterRatio.y;
float target_y = window->ScrollTarget.y; float target_y = window->ScrollTarget.y;
if (snap_on_edges && cr_y <= 0.0f && target_y <= window->WindowPadding.y)
target_y = 0.0f;
if (snap_on_edges && cr_y >= 1.0f && target_y >= window->ContentSize.y + window->WindowPadding.y + g.Style.ItemSpacing.y)
target_y = window->ContentSize.y + window->WindowPadding.y * 2.0f;
scroll.y = target_y - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y - decoration_up_height); scroll.y = target_y - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y - decoration_up_height);
} }
scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f)); scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f));
@ -7382,7 +7373,7 @@ ImVec2 ImGui::ScrollToBringRectIntoView(ImGuiWindow* window, const ImRect& item_
else if (item_rect.Max.y >= window_rect.Max.y) else if (item_rect.Max.y >= window_rect.Max.y)
SetScrollFromPosY(window, item_rect.Max.y - window->Pos.y + g.Style.ItemSpacing.y, 1.0f); SetScrollFromPosY(window, item_rect.Max.y - window->Pos.y + g.Style.ItemSpacing.y, 1.0f);
ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window, false); ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window);
delta_scroll = next_scroll - window->Scroll; delta_scroll = next_scroll - window->Scroll;
} }
@ -7443,10 +7434,10 @@ void ImGui::SetScrollY(ImGuiWindow* window, float new_scroll_y)
window->ScrollTargetCenterRatio.y = 0.0f; window->ScrollTargetCenterRatio.y = 0.0f;
} }
// Note that a local position will vary depending on initial scroll value
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio) void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio)
{ {
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f); IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f);
window->ScrollTarget.x = IM_FLOOR(local_x + window->Scroll.x); window->ScrollTarget.x = IM_FLOOR(local_x + window->Scroll.x);
window->ScrollTargetCenterRatio.x = center_x_ratio; window->ScrollTargetCenterRatio.x = center_x_ratio;
@ -7454,10 +7445,8 @@ void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x
void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio) void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio)
{ {
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); local_y -= window->TitleBarHeight() + window->MenuBarHeight(); // FIXME: Would be nice to have a more standardized access to our scrollable/client rect
local_y -= decoration_up_height;
window->ScrollTarget.y = IM_FLOOR(local_y + window->Scroll.y); window->ScrollTarget.y = IM_FLOOR(local_y + window->Scroll.y);
window->ScrollTargetCenterRatio.y = center_y_ratio; window->ScrollTargetCenterRatio.y = center_y_ratio;
} }
@ -7474,15 +7463,34 @@ void ImGui::SetScrollFromPosY(float local_y, float center_y_ratio)
SetScrollFromPosY(g.CurrentWindow, local_y, center_y_ratio); SetScrollFromPosY(g.CurrentWindow, local_y, center_y_ratio);
} }
// Tweak: snap on edges when aiming at an item very close to the edge,
// So the difference between WindowPadding and ItemSpacing will be in the visible area after scrolling.
// When we refactor the scrolling API this may be configurable with a flag?
// Note that the effect for this won't be visible on X axis with default Style settings as WindowPadding.x == ItemSpacing.x by default.
static float CalcScrollSnap(float target, float snap_min, float snap_max, float snap_threshold, float center_ratio)
{
if (target <= snap_min + snap_threshold)
return ImLerp(snap_min, target, center_ratio);
if (target >= snap_max - snap_threshold)
return ImLerp(target, snap_max, center_ratio);
return target;
}
// center_x_ratio: 0.0f left of last item, 0.5f horizontal center of last item, 1.0f right of last item. // center_x_ratio: 0.0f left of last item, 0.5f horizontal center of last item, 1.0f right of last item.
void ImGui::SetScrollHereX(float center_x_ratio) void ImGui::SetScrollHereX(float center_x_ratio)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
float target_x = window->DC.LastItemRect.Min.x - window->Pos.x; // Left of last item, in window space float spacing_x = g.Style.ItemSpacing.x;
float last_item_width = window->DC.LastItemRect.GetWidth(); float target_x = ImLerp(window->DC.LastItemRect.Min.x - spacing_x, window->DC.LastItemRect.Max.x + spacing_x, center_x_ratio);
target_x += (last_item_width * center_x_ratio) + (g.Style.ItemSpacing.x * (center_x_ratio - 0.5f) * 2.0f); // Precisely aim before, in the middle or after the last item.
SetScrollFromPosX(target_x, center_x_ratio); // Tweak: snap on edges when aiming at an item very close to the edge
const float snap_x_threshold = ImMax(0.0f, window->WindowPadding.x - spacing_x);
const float snap_x_min = window->DC.CursorStartPos.x - window->WindowPadding.x;
const float snap_x_max = window->DC.CursorStartPos.x + window->ContentSize.x + window->WindowPadding.x;
target_x = CalcScrollSnap(target_x, snap_x_min, snap_x_max, snap_x_threshold, center_x_ratio);
SetScrollFromPosX(window, target_x - window->Pos.x, center_x_ratio);
} }
// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item. // center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
@ -7490,9 +7498,16 @@ void ImGui::SetScrollHereY(float center_y_ratio)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space float spacing_y = g.Style.ItemSpacing.y;
target_y += (window->DC.PrevLineSize.y * center_y_ratio) + (g.Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line. float target_y = ImLerp(window->DC.CursorPosPrevLine.y - spacing_y, window->DC.CursorPosPrevLine.y + window->DC.PrevLineSize.y + spacing_y, center_y_ratio);
SetScrollFromPosY(target_y, center_y_ratio);
// Tweak: snap on edges when aiming at an item very close to the edge
const float snap_y_threshold = ImMax(0.0f, window->WindowPadding.y - spacing_y);
const float snap_y_min = window->DC.CursorStartPos.y - window->WindowPadding.y;
const float snap_y_max = window->DC.CursorStartPos.y + window->ContentSize.y + window->WindowPadding.y;
target_y = CalcScrollSnap(target_y, snap_y_min, snap_y_max, snap_y_threshold, center_y_ratio);
SetScrollFromPosY(window, target_y - window->Pos.y, center_y_ratio);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -333,8 +333,8 @@ namespace ImGui
// Windows Scrolling // Windows Scrolling
IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()] IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()]
IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()] IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()]
IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.X - WindowSize.X IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.x - WindowSize.x
IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.Y - WindowSize.Y IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.y - WindowSize.y
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()] IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()]
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()]
IMGUI_API void SetScrollHereX(float center_x_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_x_ratio=0.0: left, 0.5: center, 1.0: right. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead. IMGUI_API void SetScrollHereX(float center_x_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_x_ratio=0.0: left, 0.5: center, 1.0: right. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.

View File

@ -1960,7 +1960,7 @@ static void ShowDemoWindowWidgets()
static void ShowDemoWindowLayout() static void ShowDemoWindowLayout()
{ {
if (!ImGui::CollapsingHeader("Layout")) if (!ImGui::CollapsingHeader("Layout & Scrolling"))
return; return;
if (ImGui::TreeNode("Child windows")) if (ImGui::TreeNode("Child windows"))
@ -2490,11 +2490,9 @@ static void ShowDemoWindowLayout()
ImGui::Spacing(); ImGui::Spacing();
HelpMarker( HelpMarker(
"Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\n" "Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\n"
"Using the \"Scroll To Pos\" button above will make the discontinuity at edges visible: " "Because the clipping rectangle of most window hides half worth of WindowPadding on the "
"scrolling to the top/bottom/left/right-most item will add an additional WindowPadding to reflect " "left/right, using SetScrollFromPosX(+1) will usually result in clipped text whereas the "
"on reaching the edge of the list.\n\nBecause the clipping rectangle of most window hides half " "equivalent SetScrollFromPosY(+1) wouldn't.");
"worth of WindowPadding on the left/right, using SetScrollFromPosX(+1) will usually result in "
"clipped text whereas the equivalent SetScrollFromPosY(+1) wouldn't.");
ImGui::PushID("##HorizontalScrolling"); ImGui::PushID("##HorizontalScrolling");
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
@ -2684,23 +2682,66 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Clipping")) if (ImGui::TreeNode("Clipping"))
{ {
static ImVec2 size(100, 100), offset(50, 20); static ImVec2 size(100.0f, 100.0f);
ImGui::TextWrapped( static ImVec2 offset(30.0f, 30.0f);
"On a per-widget basis we are occasionally clipping text CPU-side if it won't fit in its frame. "
"Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. "
"The system is designed to try minimizing both execution and CPU/GPU rendering cost.");
ImGui::DragFloat2("size", (float*)&size, 0.5f, 1.0f, 200.0f, "%.0f"); ImGui::DragFloat2("size", (float*)&size, 0.5f, 1.0f, 200.0f, "%.0f");
ImGui::TextWrapped("(Click and drag)"); ImGui::TextWrapped("(Click and drag to scroll)");
ImVec2 pos = ImGui::GetCursorScreenPos();
ImVec4 clip_rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y); for (int n = 0; n < 3; n++)
{
if (n > 0)
ImGui::SameLine();
ImGui::PushID(n);
ImGui::BeginGroup(); // Lock X position
ImGui::InvisibleButton("##empty", size); ImGui::InvisibleButton("##empty", size);
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0)) if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left))
{ {
offset.x += ImGui::GetIO().MouseDelta.x; offset.x += ImGui::GetIO().MouseDelta.x;
offset.y += ImGui::GetIO().MouseDelta.y; offset.y += ImGui::GetIO().MouseDelta.y;
} }
ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + size.y), IM_COL32(90, 90, 120, 255)); const ImVec2 p0 = ImGui::GetItemRectMin();
ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x + offset.x, pos.y + offset.y), IM_COL32_WHITE, "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); const ImVec2 p1 = ImGui::GetItemRectMax();
const char* text_str = "Line 1 hello\nLine 2 clip me!";
const ImVec2 text_pos = ImVec2(p0.x + offset.x, p0.y + offset.y);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
switch (n)
{
case 0:
HelpMarker(
"Using ImGui::PushClipRect():\n"
"Will alter ImGui hit-testing logic + ImDrawList rendering.\n"
"(use this if you want your clipping rectangle to affect interactions)");
ImGui::PushClipRect(p0, p1, true);
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
draw_list->AddText(text_pos, IM_COL32_WHITE, text_str);
ImGui::PopClipRect();
break;
case 1:
HelpMarker(
"Using ImDrawList::PushClipRect():\n"
"Will alter ImDrawList rendering only.\n"
"(use this as a shortcut if you are only using ImDrawList calls)");
draw_list->PushClipRect(p0, p1, true);
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
draw_list->AddText(text_pos, IM_COL32_WHITE, text_str);
draw_list->PopClipRect();
break;
case 2:
HelpMarker(
"Using ImDrawList::AddText() with a fine ClipRect:\n"
"Will alter only this specific ImDrawList::AddText() rendering.\n"
"(this is often used internally to avoid altering the clipping rectangle and minimize draw calls)");
ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert.
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, &clip_rect);
break;
}
ImGui::EndGroup();
ImGui::PopID();
}
ImGui::TreePop(); ImGui::TreePop();
} }
} }
@ -4952,8 +4993,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
if (ImGui::BeginTabItem("Canvas")) if (ImGui::BeginTabItem("Canvas"))
{ {
struct ItemLine { ImVec2 p0, p1; ItemLine(const ImVec2& _p0, const ImVec2& _p1) { p0 = _p0; p1 = _p1; } }; static ImVector<ImVec2> points;
static ImVector<ItemLine> lines;
static ImVec2 scrolling(0.0f, 0.0f); static ImVec2 scrolling(0.0f, 0.0f);
static bool opt_enable_grid = true; static bool opt_enable_grid = true;
static bool opt_enable_context_menu = true; static bool opt_enable_context_menu = true;
@ -4997,12 +5037,13 @@ static void ShowExampleAppCustomRendering(bool* p_open)
// Add first and second point // Add first and second point
if (is_hovered && !adding_line && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) if (is_hovered && !adding_line && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{ {
lines.push_back(ItemLine(mouse_pos_in_canvas, mouse_pos_in_canvas)); points.push_back(mouse_pos_in_canvas);
points.push_back(mouse_pos_in_canvas);
adding_line = true; adding_line = true;
} }
if (adding_line) if (adding_line)
{ {
lines.back().p1 = mouse_pos_in_canvas; points.back() = mouse_pos_in_canvas;
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) if (!ImGui::IsMouseDown(ImGuiMouseButton_Left))
adding_line = false; adding_line = false;
} }
@ -5023,10 +5064,10 @@ static void ShowExampleAppCustomRendering(bool* p_open)
if (ImGui::BeginPopup("context")) if (ImGui::BeginPopup("context"))
{ {
if (adding_line) if (adding_line)
lines.pop_back(); points.resize(points.size() - 2);
adding_line = false; adding_line = false;
if (ImGui::MenuItem("Remove one", NULL, false, lines.Size > 0)) { lines.pop_back(); } if (ImGui::MenuItem("Remove one", NULL, false, points.Size > 0)) { points.resize(points.size() - 2); }
if (ImGui::MenuItem("Remove all", NULL, false, lines.Size > 0)) { lines.clear(); } if (ImGui::MenuItem("Remove all", NULL, false, points.Size > 0)) { points.clear(); }
ImGui::EndPopup(); ImGui::EndPopup();
} }
@ -5040,8 +5081,8 @@ static void ShowExampleAppCustomRendering(bool* p_open)
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP) for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40)); draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40));
} }
for (int n = 0; n < lines.Size; n++) for (int n = 0; n < points.Size; n += 2)
draw_list->AddLine(ImVec2(origin.x + lines[n].p0.x, origin.y + lines[n].p0.y), ImVec2(origin.x + lines[n].p1.x, origin.y + lines[n].p1.y), IM_COL32(255, 255, 0, 255), 2.0f); draw_list->AddLine(ImVec2(origin.x + points[n].x, origin.y + points[n].y), ImVec2(origin.x + points[n + 1].x, origin.y + points[n + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
draw_list->PopClipRect(); draw_list->PopClipRect();
ImGui::EndTabItem(); ImGui::EndTabItem();

View File

@ -1015,7 +1015,7 @@ struct ImGuiColumns
float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns() float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns() ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns()
ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground() ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground()
ImRect HostWorkRect; // Backup of WorkRect at the time of BeginColumns() ImRect HostBackupParentWorkRect;//Backup of WorkRect at the time of BeginColumns()
ImVector<ImGuiColumnData> Columns; ImVector<ImGuiColumnData> Columns;
ImDrawListSplitter Splitter; ImDrawListSplitter Splitter;
@ -1612,7 +1612,8 @@ struct IMGUI_API ImGuiWindow
ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window. ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window.
ImRect InnerRect; // Inner rectangle (omit title bar, menu bar, scroll bar) ImRect InnerRect; // Inner rectangle (omit title bar, menu bar, scroll bar)
ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect. ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect.
ImRect WorkRect; // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward). ImRect WorkRect; // Initially covers the whole scrolling region. Reduced by containers e.g columns/tables when active. Shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward).
ImRect ParentWorkRect; // Backup of WorkRect before entering a container such as columns/tables. Used by e.g. SpanAllColumns functions to easily access. Stacked containers are responsible for maintaining this. // FIXME-WORKRECT: Could be a stack?
ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back(). ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back().
ImRect ContentRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on. ImRect ContentRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on.
ImVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window. ImVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window.

View File

@ -5719,8 +5719,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
ItemSize(size, 0.0f); ItemSize(size, 0.0f);
// Fill horizontal space // Fill horizontal space
const float min_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ContentRegionRect.Min.x : pos.x; const float min_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ParentWorkRect.Min.x : pos.x;
const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ContentRegionRect.Max.x : GetContentRegionMaxAbs().x; const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x;
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth)) if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
size.x = ImMax(label_size.x, max_x - min_x); size.x = ImMax(label_size.x, max_x - min_x);
@ -6672,9 +6672,9 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
tab_bar->CurrFrameVisible = g.FrameCount; tab_bar->CurrFrameVisible = g.FrameCount;
tab_bar->FramePadding = g.Style.FramePadding; tab_bar->FramePadding = g.Style.FramePadding;
// Layout // Set cursor pos in a way which only be used in the off-chance the user erroneously submits item before BeginTabItem(): items will overlap
ItemSize(ImVec2(tab_bar->OffsetMaxIdeal, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
window->DC.CursorPos.x = tab_bar->BarRect.Min.x; window->DC.CursorPos.x = tab_bar->BarRect.Min.x;
window->DC.CursorPos.y = tab_bar->BarRect.Max.y + g.Style.ItemSpacing.y;
// Draw separator // Draw separator
const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive); const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive);
@ -6700,7 +6700,7 @@ void ImGui::EndTabBar()
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Mismatched BeginTabBar()/EndTabBar()!"); IM_ASSERT_USER_ERROR(tab_bar != NULL, "Mismatched BeginTabBar()/EndTabBar()!");
return; return;
} }
if (tab_bar->WantLayout) if (tab_bar->WantLayout) // Fallback in case no TabItem have been submitted
TabBarLayout(tab_bar); TabBarLayout(tab_bar);
// Restore the last visible height if no tab is visible, this reduce vertical flicker/movement when a tabs gets removed without calling SetTabItemClosed(). // Restore the last visible height if no tab is visible, this reduce vertical flicker/movement when a tabs gets removed without calling SetTabItemClosed().
@ -6886,6 +6886,11 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
// Clear name buffers // Clear name buffers
if ((tab_bar->Flags & ImGuiTabBarFlags_DockNode) == 0) if ((tab_bar->Flags & ImGuiTabBarFlags_DockNode) == 0)
tab_bar->TabsNames.Buf.resize(0); tab_bar->TabsNames.Buf.resize(0);
// Actual layout in host window (we don't do it in BeginTabBar() so as not to waste an extra frame)
ImGuiWindow* window = g.CurrentWindow;
window->DC.CursorPos = tab_bar->BarRect.Min;
ItemSize(ImVec2(tab_bar->OffsetMaxIdeal, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
} }
// Dockables uses Name/ID in the global namespace. Non-dockable items use the ID stack. // Dockables uses Name/ID in the global namespace. Non-dockable items use the ID stack.
@ -7680,7 +7685,8 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
columns->HostCursorPosY = window->DC.CursorPos.y; columns->HostCursorPosY = window->DC.CursorPos.y;
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x; columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
columns->HostInitialClipRect = window->ClipRect; columns->HostInitialClipRect = window->ClipRect;
columns->HostWorkRect = window->WorkRect; columns->HostBackupParentWorkRect = window->ParentWorkRect;
window->ParentWorkRect = window->WorkRect;
// Set state for first column // Set state for first column
// We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect // We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect
@ -7860,7 +7866,8 @@ void ImGui::EndColumns()
} }
columns->IsBeingResized = is_being_resized; columns->IsBeingResized = is_being_resized;
window->WorkRect = columns->HostWorkRect; window->WorkRect = window->ParentWorkRect;
window->ParentWorkRect = columns->HostBackupParentWorkRect;
window->DC.CurrentColumns = NULL; window->DC.CurrentColumns = NULL;
window->DC.ColumnsOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);