Skip to content

Instantly share code, notes, and snippets.

@inolen
Last active September 27, 2017 20:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inolen/b460ae06d05f55390c6dde4709888657 to your computer and use it in GitHub Desktop.
Save inolen/b460ae06d05f55390c6dde4709888657 to your computer and use it in GitHub Desktop.
diff --git a/imgui.cpp b/imgui.cpp
index 3dd3d3f..0a0e467 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -2037,6 +2037,7 @@ static bool NavScoreItem(ImRect cand)
// FIXME-NAVIGATION: Introducing various biases toward typical imgui uses cases, but we don't have any rigorous proof of their effect now.
float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x);
float dby = NavScoreItemDistInterval(ImLerp(cand.Min.y, cand.Max.y, 0.2f), ImLerp(cand.Min.y, cand.Max.y, 0.8f), ImLerp(curr.Min.y, curr.Max.y, 0.2f), ImLerp(curr.Min.y, curr.Max.y, 0.8f)); // Clamp down on Y to keep using box-distance for vertically touching items
+
if (dby && dbx)
dbx = (dbx/1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f);
float dist_box = fabsf(dbx) + fabsf(dby);
@@ -2166,6 +2167,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id, const ImRect* nav_bb_ar
{
const ImRect& nav_bb = nav_bb_arg ? *nav_bb_arg : bb;
const ImRect nav_bb_rel(nav_bb.Min - g.NavWindow->Pos, nav_bb.Max - g.NavWindow->Pos);
+
if (g.NavInitDefaultRequest && g.NavLayer == window->DC.NavLayerCurrent)
{
// Even if 'ImGuiItemFlags_AllowNavDefaultFocus' is off (typically collapse/close button) we record the first ResultId so they can be used as fallback
@@ -2186,6 +2188,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id, const ImRect* nav_bb_ar
{
g.NavMoveResultId = *id;
g.NavMoveResultRectRel = nav_bb_rel;
+ g.NavMoveResultWindow = window;
}
}
@@ -2538,35 +2541,37 @@ static void NavUpdate()
{
IM_ASSERT(g.NavWindow);
+ ImGuiWindow* moveWindow = g.NavMoveResultWindow;
+
// Scroll to keep newly navigated item fully into view
- ImRect window_rect_rel(g.NavWindow->InnerRect.Min - g.NavWindow->Pos - ImVec2(1,1), g.NavWindow->InnerRect.Max - g.NavWindow->Pos + ImVec2(1,1));
- //g.OverlayDrawList.AddRect(g.NavWindow->Pos + window_rect_rel.Min, g.NavWindow->Pos + window_rect_rel.Max, IM_COL32_WHITE); // [DEBUG]
+ ImRect window_rect_rel(moveWindow->InnerRect.Min - moveWindow->Pos - ImVec2(1,1), moveWindow->InnerRect.Max - moveWindow->Pos + ImVec2(1,1));
+ //g.OverlayDrawList.AddRect(moveWindow->Pos + window_rect_rel.Min, moveWindow->Pos + window_rect_rel.Max, IM_COL32_WHITE); // [DEBUG]
if (g.NavLayer == 0 && !window_rect_rel.Contains(g.NavMoveResultRectRel))
{
- if (g.NavWindow->ScrollbarX && g.NavMoveResultRectRel.Min.x < window_rect_rel.Min.x)
+ if (g.NavMoveResultRectRel.Min.x < window_rect_rel.Min.x)
{
- g.NavWindow->ScrollTarget.x = g.NavMoveResultRectRel.Min.x + g.NavWindow->Scroll.x - g.Style.ItemSpacing.x;
- g.NavWindow->ScrollTargetCenterRatio.x = 0.0f;
+ moveWindow->ScrollTarget.x = g.NavMoveResultRectRel.Min.x + moveWindow->Scroll.x - g.Style.ItemSpacing.x;
+ moveWindow->ScrollTargetCenterRatio.x = 0.0f;
}
- else if (g.NavWindow->ScrollbarX && g.NavMoveResultRectRel.Max.x >= window_rect_rel.Max.x)
+ else if (g.NavMoveResultRectRel.Max.x >= window_rect_rel.Max.x)
{
- g.NavWindow->ScrollTarget.x = g.NavMoveResultRectRel.Max.x + g.NavWindow->Scroll.x + g.Style.ItemSpacing.x;
- g.NavWindow->ScrollTargetCenterRatio.x = 1.0f;
+ moveWindow->ScrollTarget.x = g.NavMoveResultRectRel.Max.x + moveWindow->Scroll.x + g.Style.ItemSpacing.x;
+ moveWindow->ScrollTargetCenterRatio.x = 1.0f;
}
if (g.NavMoveResultRectRel.Min.y < window_rect_rel.Min.y)
{
- g.NavWindow->ScrollTarget.y = g.NavMoveResultRectRel.Min.y + g.NavWindow->Scroll.y - g.Style.ItemSpacing.y;
- g.NavWindow->ScrollTargetCenterRatio.y = 0.0f;
+ moveWindow->ScrollTarget.y = g.NavMoveResultRectRel.Min.y + moveWindow->Scroll.y - g.Style.ItemSpacing.y;
+ moveWindow->ScrollTargetCenterRatio.y = 0.0f;
}
else if (g.NavMoveResultRectRel.Max.y >= window_rect_rel.Max.y)
{
- g.NavWindow->ScrollTarget.y = g.NavMoveResultRectRel.Max.y + g.NavWindow->Scroll.y + g.Style.ItemSpacing.y;
- g.NavWindow->ScrollTargetCenterRatio.y = 1.0f;
+ moveWindow->ScrollTarget.y = g.NavMoveResultRectRel.Max.y + moveWindow->Scroll.y + g.Style.ItemSpacing.y;
+ moveWindow->ScrollTargetCenterRatio.y = 1.0f;
}
// Estimate upcoming scroll so we can offset our relative mouse position so mouse position can be applied immediately (under this block)
- ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(g.NavWindow);
- g.NavMoveResultRectRel.Translate(g.NavWindow->Scroll - next_scroll);
+ ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(moveWindow);
+ g.NavMoveResultRectRel.Translate(moveWindow->Scroll - next_scroll);
}
// Apply result from previous frame navigation directional move request
@@ -4424,7 +4429,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
child_window->Flags &= ~ImGuiWindowFlags_ShowBorders;
// Process navigation-in immediately so NavInit can run on first frame
- if (/*!(flags & ImGuiWindowFlags_NavFlattened) &&*/ (child_window->DC.NavLayerActiveFlags != 0 || child_window->DC.NavHasScroll) && GImGui->NavActivateId == id)
+ if (!(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayerActiveFlags != 0 || child_window->DC.NavHasScroll) && GImGui->NavActivateId == id)
{
ImGui::FocusWindow(child_window);
NavInitWindow(child_window, false);
@@ -4468,7 +4473,7 @@ void ImGui::EndChild()
ImGuiWindow* parent_window = GetCurrentWindow();
ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz);
ItemSize(sz);
- if (/*!(window->Flags & ImGuiWindowFlags_NavFlattened) &&*/ (window->DC.NavLayerActiveFlags != 0 || window->DC.NavHasScroll))
+ if (!(window->Flags & ImGuiWindowFlags_NavFlattened) && (window->DC.NavLayerActiveFlags != 0 || window->DC.NavHasScroll))
{
ItemAdd(bb, &window->ChildId);
RenderNavHighlight(bb, window->ChildId);
@@ -4686,8 +4691,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if (flags & ImGuiWindowFlags_NoInputs)
flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
- //if (flags & ImGuiWindowFlags_NavFlattened)
- // IM_ASSERT(flags & ImGuiWindowFlags_ChildWindow);
+ if (flags & ImGuiWindowFlags_NavFlattened)
+ IM_ASSERT(flags & ImGuiWindowFlags_ChildWindow);
// Find or create
bool window_is_new = false;
@@ -4788,8 +4793,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
window->RootWindow = g.CurrentWindowStack[root_idx];
window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // Used to display TitleBgActive color and for selecting which window to use for NavWindowing
window->RootNavWindow = window;
- //while (window->RootNavWindow->Flags & ImGuiWindowFlags_NavFlattened)
- // window->RootNavWindow = window->RootNavWindow->ParentWindow;
+ while (window->RootNavWindow->Flags & ImGuiWindowFlags_NavFlattened)
+ window->RootNavWindow = window->RootNavWindow->ParentWindow;
// When reusing window again multiple times a frame, just append content (don't need to setup again)
if (first_begin_of_the_frame)
diff --git a/imgui.h b/imgui.h
index b32fd7b..2aacd89 100644
--- a/imgui.h
+++ b/imgui.h
@@ -527,7 +527,7 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient)
ImGuiWindowFlags_NoNavFocus = 1 << 17, // No focusing of this window with gamepad/keyboard navigation
ImGuiWindowFlags_NoNavInputs = 1 << 18, // No gamepad/keyboard navigation within the window
- //ImGuiWindowFlags_NavFlattened = 1 << 19, // Allow gamepad/keyboard navigation to cross over parent border to this child (only use on child that have no scrolling!)
+ ImGuiWindowFlags_NavFlattened = 1 << 19, // Allow gamepad/keyboard navigation to cross over parent border to this child (only use on child that have no scrolling!)
// [Internal]
ImGuiWindowFlags_ChildWindow = 1 << 22, // Don't use! For internal use by BeginChild()
ImGuiWindowFlags_ComboBox = 1 << 23, // Don't use! For internal use by ComboBox()
diff --git a/imgui_internal.h b/imgui_internal.h
index 3716ab2..1b8abe9 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -473,6 +473,7 @@ struct ImGuiContext
float NavMoveResultDistCenter; // Best move request candidate center distance to current NavId
float NavMoveResultDistAxial;
ImRect NavMoveResultRectRel; // Best move request candidate bounding box in window relative space
+ ImGuiWindow* NavMoveResultWindow;
// Storage for SetNexWindow** and SetNextTreeNode*** functions
ImVec2 SetNextWindowPosVal;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment