|
@@ -1,4 +1,4 @@
|
|
|
-// dear imgui, v1.61
|
|
|
|
|
|
|
+// dear imgui, v1.62 WIP
|
|
|
// (main code and documentation)
|
|
// (main code and documentation)
|
|
|
|
|
|
|
|
// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code.
|
|
// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code.
|
|
@@ -2254,7 +2254,7 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand)
|
|
|
|
|
|
|
|
// We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items)
|
|
// We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items)
|
|
|
// For example, this ensure that items in one column are not reached when moving vertically from items in another column.
|
|
// For example, this ensure that items in one column are not reached when moving vertically from items in another column.
|
|
|
- NavClampRectToVisibleAreaForMoveDir(g.NavMoveDir, cand, window->ClipRect);
|
|
|
|
|
|
|
+ NavClampRectToVisibleAreaForMoveDir(g.NavMoveClipDir, cand, window->ClipRect);
|
|
|
|
|
|
|
|
// Compute distance between boxes
|
|
// Compute distance between boxes
|
|
|
// FIXME-NAV: Introducing biases for vertical navigation, needs to be removed.
|
|
// FIXME-NAV: Introducing biases for vertical navigation, needs to be removed.
|
|
@@ -3008,39 +3008,35 @@ static void ImGui::NavUpdateWindowing()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// NB: We modify rect_rel by the amount we scrolled for, so it is immediately updated.
|
|
// NB: We modify rect_rel by the amount we scrolled for, so it is immediately updated.
|
|
|
-static void NavScrollToBringItemIntoView(ImGuiWindow* window, ImRect& item_rect_rel)
|
|
|
|
|
|
|
+static void NavScrollToBringItemIntoView(ImGuiWindow* window, const ImRect& item_rect)
|
|
|
{
|
|
{
|
|
|
// Scroll to keep newly navigated item fully into view
|
|
// Scroll to keep newly navigated item fully into view
|
|
|
- ImRect window_rect_rel(window->InnerMainRect.Min - window->Pos - ImVec2(1, 1), window->InnerMainRect.Max - window->Pos + ImVec2(1, 1));
|
|
|
|
|
- //g.OverlayDrawList.AddRect(window->Pos + window_rect_rel.Min, window->Pos + window_rect_rel.Max, IM_COL32_WHITE); // [DEBUG]
|
|
|
|
|
- if (window_rect_rel.Contains(item_rect_rel))
|
|
|
|
|
|
|
+ ImRect window_rect(window->InnerMainRect.Min - ImVec2(1, 1), window->InnerMainRect.Max + ImVec2(1, 1));
|
|
|
|
|
+ //g.OverlayDrawList.AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG]
|
|
|
|
|
+ if (window_rect.Contains(item_rect))
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- if (window->ScrollbarX && item_rect_rel.Min.x < window_rect_rel.Min.x)
|
|
|
|
|
|
|
+ if (window->ScrollbarX && item_rect.Min.x < window_rect.Min.x)
|
|
|
{
|
|
{
|
|
|
- window->ScrollTarget.x = item_rect_rel.Min.x + window->Scroll.x - g.Style.ItemSpacing.x;
|
|
|
|
|
|
|
+ window->ScrollTarget.x = item_rect.Min.x - window->Pos.x + window->Scroll.x - g.Style.ItemSpacing.x;
|
|
|
window->ScrollTargetCenterRatio.x = 0.0f;
|
|
window->ScrollTargetCenterRatio.x = 0.0f;
|
|
|
}
|
|
}
|
|
|
- else if (window->ScrollbarX && item_rect_rel.Max.x >= window_rect_rel.Max.x)
|
|
|
|
|
|
|
+ else if (window->ScrollbarX && item_rect.Max.x >= window_rect.Max.x)
|
|
|
{
|
|
{
|
|
|
- window->ScrollTarget.x = item_rect_rel.Max.x + window->Scroll.x + g.Style.ItemSpacing.x;
|
|
|
|
|
|
|
+ window->ScrollTarget.x = item_rect.Max.x - window->Pos.x + window->Scroll.x + g.Style.ItemSpacing.x;
|
|
|
window->ScrollTargetCenterRatio.x = 1.0f;
|
|
window->ScrollTargetCenterRatio.x = 1.0f;
|
|
|
}
|
|
}
|
|
|
- if (item_rect_rel.Min.y < window_rect_rel.Min.y)
|
|
|
|
|
|
|
+ if (item_rect.Min.y < window_rect.Min.y)
|
|
|
{
|
|
{
|
|
|
- window->ScrollTarget.y = item_rect_rel.Min.y + window->Scroll.y - g.Style.ItemSpacing.y;
|
|
|
|
|
|
|
+ window->ScrollTarget.y = item_rect.Min.y - window->Pos.y + window->Scroll.y - g.Style.ItemSpacing.y;
|
|
|
window->ScrollTargetCenterRatio.y = 0.0f;
|
|
window->ScrollTargetCenterRatio.y = 0.0f;
|
|
|
}
|
|
}
|
|
|
- else if (item_rect_rel.Max.y >= window_rect_rel.Max.y)
|
|
|
|
|
|
|
+ else if (item_rect.Max.y >= window_rect.Max.y)
|
|
|
{
|
|
{
|
|
|
- window->ScrollTarget.y = item_rect_rel.Max.y + window->Scroll.y + g.Style.ItemSpacing.y;
|
|
|
|
|
|
|
+ window->ScrollTarget.y = item_rect.Max.y - window->Pos.y + window->Scroll.y + g.Style.ItemSpacing.y;
|
|
|
window->ScrollTargetCenterRatio.y = 1.0f;
|
|
window->ScrollTargetCenterRatio.y = 1.0f;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // Estimate upcoming scroll so we can offset our relative mouse position so mouse position can be applied immediately after in NavUpdate()
|
|
|
|
|
- ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window, false);
|
|
|
|
|
- item_rect_rel.Translate(window->Scroll - next_scroll);
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void ImGui::NavUpdate()
|
|
static void ImGui::NavUpdate()
|
|
@@ -3104,9 +3100,18 @@ static void ImGui::NavUpdate()
|
|
|
|
|
|
|
|
IM_ASSERT(g.NavWindow && result->Window);
|
|
IM_ASSERT(g.NavWindow && result->Window);
|
|
|
|
|
|
|
|
- // Scroll to keep newly navigated item fully into view
|
|
|
|
|
|
|
+ // Scroll to keep newly navigated item fully into view. Also scroll parent window if necessary.
|
|
|
if (g.NavLayer == 0)
|
|
if (g.NavLayer == 0)
|
|
|
- NavScrollToBringItemIntoView(result->Window, result->RectRel);
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ ImRect rect_abs = ImRect(result->RectRel.Min + result->Window->Pos, result->RectRel.Max + result->Window->Pos);
|
|
|
|
|
+ NavScrollToBringItemIntoView(result->Window, rect_abs);
|
|
|
|
|
+ if (result->Window->Flags & ImGuiWindowFlags_ChildWindow)
|
|
|
|
|
+ NavScrollToBringItemIntoView(result->Window->ParentWindow, rect_abs);
|
|
|
|
|
+
|
|
|
|
|
+ // Estimate upcoming scroll so we can offset our result position so mouse position can be applied immediately after in NavUpdate()
|
|
|
|
|
+ ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(result->Window, false);
|
|
|
|
|
+ result->RectRel.Translate(result->Window->Scroll - next_scroll);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// Apply result from previous frame navigation directional move request
|
|
// Apply result from previous frame navigation directional move request
|
|
|
ClearActiveID();
|
|
ClearActiveID();
|
|
@@ -3225,6 +3230,7 @@ static void ImGui::NavUpdate()
|
|
|
if (g.NavMoveRequestForward == ImGuiNavForward_None)
|
|
if (g.NavMoveRequestForward == ImGuiNavForward_None)
|
|
|
{
|
|
{
|
|
|
g.NavMoveDir = ImGuiDir_None;
|
|
g.NavMoveDir = ImGuiDir_None;
|
|
|
|
|
+ g.NavMoveRequestFlags = 0;
|
|
|
if (g.NavWindow && !g.NavWindowingTarget && allowed_dir_flags && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
if (g.NavWindow && !g.NavWindowingTarget && allowed_dir_flags && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
|
{
|
|
{
|
|
|
if ((allowed_dir_flags & (1<<ImGuiDir_Left)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadLeft, ImGuiNavInput_KeyLeft_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Left;
|
|
if ((allowed_dir_flags & (1<<ImGuiDir_Left)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadLeft, ImGuiNavInput_KeyLeft_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Left;
|
|
@@ -3232,11 +3238,13 @@ static void ImGui::NavUpdate()
|
|
|
if ((allowed_dir_flags & (1<<ImGuiDir_Up)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadUp, ImGuiNavInput_KeyUp_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Up;
|
|
if ((allowed_dir_flags & (1<<ImGuiDir_Up)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadUp, ImGuiNavInput_KeyUp_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Up;
|
|
|
if ((allowed_dir_flags & (1<<ImGuiDir_Down)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadDown, ImGuiNavInput_KeyDown_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Down;
|
|
if ((allowed_dir_flags & (1<<ImGuiDir_Down)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadDown, ImGuiNavInput_KeyDown_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Down;
|
|
|
}
|
|
}
|
|
|
|
|
+ g.NavMoveClipDir = g.NavMoveDir;
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
// Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window)
|
|
// Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window)
|
|
|
- IM_ASSERT(g.NavMoveDir != ImGuiDir_None);
|
|
|
|
|
|
|
+ // (Preserve g.NavMoveRequestFlags, g.NavMoveClipDir which were set by the NavMoveRequestForward() function)
|
|
|
|
|
+ IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
|
|
|
IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_ForwardQueued);
|
|
IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_ForwardQueued);
|
|
|
g.NavMoveRequestForward = ImGuiNavForward_ForwardActive;
|
|
g.NavMoveRequestForward = ImGuiNavForward_ForwardActive;
|
|
|
}
|
|
}
|
|
@@ -4545,9 +4553,11 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
|
|
|
const ImVec2 pos = window->DC.CursorPos;
|
|
const ImVec2 pos = window->DC.CursorPos;
|
|
|
int start = (int)((window->ClipRect.Min.y - pos.y) / items_height);
|
|
int start = (int)((window->ClipRect.Min.y - pos.y) / items_height);
|
|
|
int end = (int)((window->ClipRect.Max.y - pos.y) / items_height);
|
|
int end = (int)((window->ClipRect.Max.y - pos.y) / items_height);
|
|
|
- if (g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Up) // When performing a navigation request, ensure we have one item extra in the direction we are moving to
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // When performing a navigation request, ensure we have one item extra in the direction we are moving to
|
|
|
|
|
+ if (g.NavMoveRequest && g.NavMoveClipDir == ImGuiDir_Up)
|
|
|
start--;
|
|
start--;
|
|
|
- if (g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down)
|
|
|
|
|
|
|
+ if (g.NavMoveRequest && g.NavMoveClipDir == ImGuiDir_Down)
|
|
|
end++;
|
|
end++;
|
|
|
|
|
|
|
|
start = ImClamp(start, 0, items_count);
|
|
start = ImClamp(start, 0, items_count);
|
|
@@ -5099,16 +5109,51 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla
|
|
|
return is_open;
|
|
return is_open;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void NavProcessMoveRequestWrapAround(ImGuiWindow* window)
|
|
|
|
|
|
|
+void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect& bb_rel, ImGuiNavMoveFlags move_flags)
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- if (g.NavWindow == window && NavMoveRequestButNoResultYet())
|
|
|
|
|
- if ((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == 0)
|
|
|
|
|
- {
|
|
|
|
|
- g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
|
|
|
|
|
- ImGui::NavMoveRequestCancel();
|
|
|
|
|
- g.NavWindow->NavRectRel[0].Min.y = g.NavWindow->NavRectRel[0].Max.y = ((g.NavMoveDir == ImGuiDir_Up) ? ImMax(window->SizeFull.y, window->SizeContents.y) : 0.0f) - window->Scroll.y;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None);
|
|
|
|
|
+ ImGui::NavMoveRequestCancel();
|
|
|
|
|
+ g.NavMoveDir = move_dir;
|
|
|
|
|
+ g.NavMoveClipDir = clip_dir;
|
|
|
|
|
+ g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
|
|
|
|
|
+ g.NavMoveRequestFlags = move_flags;
|
|
|
|
|
+ g.NavWindow->NavRectRel[g.NavLayer] = bb_rel;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags)
|
|
|
|
|
+{
|
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
|
+ if (g.NavWindow != window || !NavMoveRequestButNoResultYet() || g.NavMoveRequestForward != ImGuiNavForward_None || g.NavLayer != 0)
|
|
|
|
|
+ return;
|
|
|
|
|
+ IM_ASSERT(move_flags != 0); // No points calling this with no wrapping
|
|
|
|
|
+ ImRect bb_rel = window->NavRectRel[0];
|
|
|
|
|
+
|
|
|
|
|
+ ImGuiDir clip_dir = g.NavMoveDir;
|
|
|
|
|
+ if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
|
|
|
|
|
+ {
|
|
|
|
|
+ bb_rel.Min.x = bb_rel.Max.x = ImMax(window->SizeFull.x, window->SizeContents.x) - window->Scroll.x;
|
|
|
|
|
+ if (move_flags & ImGuiNavMoveFlags_WrapX) { bb_rel.TranslateY(-bb_rel.GetHeight()); clip_dir = ImGuiDir_Up; }
|
|
|
|
|
+ NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
|
|
|
|
|
+ {
|
|
|
|
|
+ bb_rel.Min.x = bb_rel.Max.x = -window->Scroll.x;
|
|
|
|
|
+ if (move_flags & ImGuiNavMoveFlags_WrapX) { bb_rel.TranslateY(+bb_rel.GetHeight()); clip_dir = ImGuiDir_Down; }
|
|
|
|
|
+ NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
|
|
|
|
|
+ {
|
|
|
|
|
+ bb_rel.Min.y = bb_rel.Max.y = ImMax(window->SizeFull.y, window->SizeContents.y) - window->Scroll.y;
|
|
|
|
|
+ if (move_flags & ImGuiNavMoveFlags_WrapY) { bb_rel.TranslateX(-bb_rel.GetWidth()); clip_dir = ImGuiDir_Left; }
|
|
|
|
|
+ NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
|
|
|
|
|
+ {
|
|
|
|
|
+ bb_rel.Min.y = bb_rel.Max.y = -window->Scroll.y;
|
|
|
|
|
+ if (move_flags & ImGuiNavMoveFlags_WrapY) { bb_rel.TranslateX(+bb_rel.GetWidth()); clip_dir = ImGuiDir_Right; }
|
|
|
|
|
+ NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void ImGui::EndPopup()
|
|
void ImGui::EndPopup()
|
|
@@ -5118,7 +5163,7 @@ void ImGui::EndPopup()
|
|
|
IM_ASSERT(g.CurrentPopupStack.Size > 0);
|
|
IM_ASSERT(g.CurrentPopupStack.Size > 0);
|
|
|
|
|
|
|
|
// Make all menus and popups wrap around for now, may need to expose that policy.
|
|
// Make all menus and popups wrap around for now, may need to expose that policy.
|
|
|
- NavProcessMoveRequestWrapAround(g.CurrentWindow);
|
|
|
|
|
|
|
+ NavMoveRequestTryWrapping(g.CurrentWindow, ImGuiNavMoveFlags_LoopY);
|
|
|
|
|
|
|
|
End();
|
|
End();
|
|
|
}
|
|
}
|
|
@@ -6156,7 +6201,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
window->SizeFullAtLastBegin = window->SizeFull;
|
|
window->SizeFullAtLastBegin = window->SizeFull;
|
|
|
|
|
|
|
|
// Update various regions. Variables they depends on are set above in this function.
|
|
// Update various regions. Variables they depends on are set above in this function.
|
|
|
- // FIXME: window->ContentsRegion.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
|
|
|
|
|
|
|
+ // FIXME: window->ContentsRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
|
|
|
window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
|
|
window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
|
|
|
window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight();
|
|
window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight();
|
|
|
window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x));
|
|
window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x));
|
|
@@ -8067,7 +8112,7 @@ void ImGui::LogButtons()
|
|
|
bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
|
|
bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
|
|
|
{
|
|
{
|
|
|
if (flags & ImGuiTreeNodeFlags_Leaf)
|
|
if (flags & ImGuiTreeNodeFlags_Leaf)
|
|
|
- return true;
|
|
|
|
|
|
|
+ return false;
|
|
|
|
|
|
|
|
// We only write to the tree storage if the user clicks (or explicitly use SetNextTreeNode*** functions)
|
|
// We only write to the tree storage if the user clicks (or explicitly use SetNextTreeNode*** functions)
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|