|
@@ -1,4 +1,4 @@
|
|
-// dear imgui, v1.84
|
|
|
|
|
|
+// dear imgui, v1.85 WIP
|
|
// (main code and documentation)
|
|
// (main code and documentation)
|
|
|
|
|
|
// Help:
|
|
// Help:
|
|
@@ -15,7 +15,10 @@
|
|
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
|
|
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
|
|
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
|
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
|
// - Issues & support https://github.com/ocornut/imgui/issues
|
|
// - Issues & support https://github.com/ocornut/imgui/issues
|
|
-// - Discussions https://github.com/ocornut/imgui/discussions
|
|
|
|
|
|
+
|
|
|
|
+// Getting Started?
|
|
|
|
+// - For first-time users having issues compiling/linking/running or issues loading fonts:
|
|
|
|
+// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
|
|
|
|
|
|
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
|
|
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
|
|
// See LICENSE.txt for copyright and licensing details (standard MIT License).
|
|
// See LICENSE.txt for copyright and licensing details (standard MIT License).
|
|
@@ -386,6 +389,7 @@ CODE
|
|
- 2021/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
|
|
- 2021/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
|
|
|
|
|
|
|
|
|
|
|
|
+ - 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead.
|
|
- 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019):
|
|
- 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019):
|
|
- ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList()
|
|
- ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList()
|
|
- ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder
|
|
- ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder
|
|
@@ -919,8 +923,9 @@ namespace ImGui
|
|
static void NavUpdate();
|
|
static void NavUpdate();
|
|
static void NavUpdateWindowing();
|
|
static void NavUpdateWindowing();
|
|
static void NavUpdateWindowingOverlay();
|
|
static void NavUpdateWindowingOverlay();
|
|
-static void NavUpdateMoveResult();
|
|
|
|
static void NavUpdateInitResult();
|
|
static void NavUpdateInitResult();
|
|
|
|
+static void NavUpdateCancelRequest();
|
|
|
|
+static void NavUpdateCreateMoveRequest();
|
|
static float NavUpdatePageUpPageDown();
|
|
static float NavUpdatePageUpPageDown();
|
|
static inline void NavUpdateAnyRequestFlag();
|
|
static inline void NavUpdateAnyRequestFlag();
|
|
static void NavEndFrame();
|
|
static void NavEndFrame();
|
|
@@ -4004,6 +4009,7 @@ void ImGui::UpdateTabFocus()
|
|
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
|
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiIO& io = g.IO;
|
|
g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING));
|
|
g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING));
|
|
|
|
|
|
// Find the window hovered by mouse:
|
|
// Find the window hovered by mouse:
|
|
@@ -4020,48 +4026,61 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
|
clear_hovered_windows = true;
|
|
clear_hovered_windows = true;
|
|
|
|
|
|
// Disabled mouse?
|
|
// Disabled mouse?
|
|
- if (g.IO.ConfigFlags & ImGuiConfigFlags_NoMouse)
|
|
|
|
|
|
+ if (io.ConfigFlags & ImGuiConfigFlags_NoMouse)
|
|
clear_hovered_windows = true;
|
|
clear_hovered_windows = true;
|
|
|
|
|
|
- // We track click ownership. When clicked outside of a window the click is owned by the application and won't report hovering nor request capture even while dragging over our windows afterward.
|
|
|
|
- int mouse_earliest_button_down = -1;
|
|
|
|
|
|
+ // We track click ownership. When clicked outside of a window the click is owned by the application and
|
|
|
|
+ // won't report hovering nor request capture even while dragging over our windows afterward.
|
|
|
|
+ const bool has_open_popup = (g.OpenPopupStack.Size > 0);
|
|
|
|
+ const bool has_open_modal = (modal_window != NULL);
|
|
|
|
+ int mouse_earliest_down = -1;
|
|
bool mouse_any_down = false;
|
|
bool mouse_any_down = false;
|
|
- for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
|
|
|
|
|
|
+ for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
|
{
|
|
{
|
|
- if (g.IO.MouseClicked[i])
|
|
|
|
- g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (g.OpenPopupStack.Size > 0);
|
|
|
|
- mouse_any_down |= g.IO.MouseDown[i];
|
|
|
|
- if (g.IO.MouseDown[i])
|
|
|
|
- if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down])
|
|
|
|
- mouse_earliest_button_down = i;
|
|
|
|
|
|
+ if (io.MouseClicked[i])
|
|
|
|
+ {
|
|
|
|
+ io.MouseDownOwned[i] = (g.HoveredWindow != NULL) || has_open_popup;
|
|
|
|
+ io.MouseDownOwnedUnlessPopupClose[i] = (g.HoveredWindow != NULL) || has_open_modal;
|
|
|
|
+ }
|
|
|
|
+ mouse_any_down |= io.MouseDown[i];
|
|
|
|
+ if (io.MouseDown[i])
|
|
|
|
+ if (mouse_earliest_down == -1 || io.MouseClickedTime[i] < io.MouseClickedTime[mouse_earliest_down])
|
|
|
|
+ mouse_earliest_down = i;
|
|
}
|
|
}
|
|
- const bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down];
|
|
|
|
|
|
+ const bool mouse_avail = (mouse_earliest_down == -1) || io.MouseDownOwned[mouse_earliest_down];
|
|
|
|
+ const bool mouse_avail_unless_popup_close = (mouse_earliest_down == -1) || io.MouseDownOwnedUnlessPopupClose[mouse_earliest_down];
|
|
|
|
|
|
// If mouse was first clicked outside of ImGui bounds we also cancel out hovering.
|
|
// If mouse was first clicked outside of ImGui bounds we also cancel out hovering.
|
|
// FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02)
|
|
// FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02)
|
|
const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
|
|
const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
|
|
- if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload)
|
|
|
|
|
|
+ if (!mouse_avail && !mouse_dragging_extern_payload)
|
|
clear_hovered_windows = true;
|
|
clear_hovered_windows = true;
|
|
|
|
|
|
if (clear_hovered_windows)
|
|
if (clear_hovered_windows)
|
|
g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
|
g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
|
|
|
|
|
- // Update io.WantCaptureMouse for the user application (true = dispatch mouse info to imgui, false = dispatch mouse info to Dear ImGui + app)
|
|
|
|
|
|
+ // Update io.WantCaptureMouse for the user application (true = dispatch mouse info to Dear ImGui only, false = dispatch mouse to Dear ImGui + underlying app)
|
|
|
|
+ // Update io.WantCaptureMouseAllowPopupClose (experimental) to give a chance for app to react to popup closure with a drag
|
|
if (g.WantCaptureMouseNextFrame != -1)
|
|
if (g.WantCaptureMouseNextFrame != -1)
|
|
- g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
|
|
|
|
|
|
+ {
|
|
|
|
+ io.WantCaptureMouse = io.WantCaptureMouseUnlessPopupClose = (g.WantCaptureMouseNextFrame != 0);
|
|
|
|
+ }
|
|
else
|
|
else
|
|
- g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.OpenPopupStack.Size > 0);
|
|
|
|
|
|
+ {
|
|
|
|
+ io.WantCaptureMouse = (mouse_avail && (g.HoveredWindow != NULL || mouse_any_down)) || has_open_popup;
|
|
|
|
+ io.WantCaptureMouseUnlessPopupClose = (mouse_avail_unless_popup_close && (g.HoveredWindow != NULL || mouse_any_down)) || has_open_modal;
|
|
|
|
+ }
|
|
|
|
|
|
- // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to Dear ImGui + app)
|
|
|
|
|
|
+ // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to Dear ImGui only, false = dispatch keyboard info to Dear ImGui + underlying app)
|
|
if (g.WantCaptureKeyboardNextFrame != -1)
|
|
if (g.WantCaptureKeyboardNextFrame != -1)
|
|
- g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0);
|
|
|
|
|
|
+ io.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0);
|
|
else
|
|
else
|
|
- g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL);
|
|
|
|
- if (g.IO.NavActive && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard))
|
|
|
|
- g.IO.WantCaptureKeyboard = true;
|
|
|
|
|
|
+ io.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL);
|
|
|
|
+ if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard))
|
|
|
|
+ io.WantCaptureKeyboard = true;
|
|
|
|
|
|
// Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible
|
|
// Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible
|
|
- g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false;
|
|
|
|
|
|
+ io.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false;
|
|
}
|
|
}
|
|
|
|
|
|
ImGuiKeyModFlags ImGui::GetMergedKeyModFlags()
|
|
ImGuiKeyModFlags ImGui::GetMergedKeyModFlags()
|
|
@@ -6687,18 +6706,23 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding);
|
|
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding);
|
|
}
|
|
}
|
|
|
|
|
|
- // Since 1.71, child window can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call.
|
|
|
|
|
|
+ // Child windows can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call (since 1.71)
|
|
// When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order.
|
|
// When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order.
|
|
- // We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping child.
|
|
|
|
- // We also disabled this when we have dimming overlay behind this specific one child.
|
|
|
|
- // FIXME: More code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected.
|
|
|
|
|
|
+ // FIXME: User code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected (github #4493)
|
|
const bool is_undocked_or_docked_visible = !window->DockIsActive || window->DockTabIsVisible;
|
|
const bool is_undocked_or_docked_visible = !window->DockIsActive || window->DockTabIsVisible;
|
|
if (is_undocked_or_docked_visible)
|
|
if (is_undocked_or_docked_visible)
|
|
{
|
|
{
|
|
bool render_decorations_in_parent = false;
|
|
bool render_decorations_in_parent = false;
|
|
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip)
|
|
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip)
|
|
- if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_window->DrawList->VtxBuffer.Size > 0)
|
|
|
|
|
|
+ {
|
|
|
|
+ // - We test overlap with the previous child window only (testing all would end up being O(log N) not a good investment here)
|
|
|
|
+ // - We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping childs
|
|
|
|
+ ImGuiWindow* previous_child = parent_window->DC.ChildWindows.Size >= 2 ? parent_window->DC.ChildWindows[parent_window->DC.ChildWindows.Size - 2] : NULL;
|
|
|
|
+ bool previous_child_overlapping = previous_child ? previous_child->Rect().Overlaps(window->Rect()) : false;
|
|
|
|
+ bool parent_is_empty = parent_window->DrawList->VtxBuffer.Size > 0;
|
|
|
|
+ if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_is_empty && !previous_child_overlapping)
|
|
render_decorations_in_parent = true;
|
|
render_decorations_in_parent = true;
|
|
|
|
+ }
|
|
if (render_decorations_in_parent)
|
|
if (render_decorations_in_parent)
|
|
window->DrawList = parent_window->DrawList;
|
|
window->DrawList = parent_window->DrawList;
|
|
|
|
|
|
@@ -7162,7 +7186,7 @@ void ImGui::PopItemFlag()
|
|
}
|
|
}
|
|
|
|
|
|
// BeginDisabled()/EndDisabled()
|
|
// BeginDisabled()/EndDisabled()
|
|
-// - Those can be nested but this cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep things disabled)
|
|
|
|
|
|
+// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)
|
|
// - Visually this is currently altering alpha, but it is expected that in a future styling system this would work differently.
|
|
// - Visually this is currently altering alpha, but it is expected that in a future styling system this would work differently.
|
|
// - Feedback welcome at https://github.com/ocornut/imgui/issues/211
|
|
// - Feedback welcome at https://github.com/ocornut/imgui/issues/211
|
|
// - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it.
|
|
// - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it.
|
|
@@ -7173,7 +7197,10 @@ void ImGui::BeginDisabled(bool disabled)
|
|
bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
|
bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
|
g.DisabledAlphaBackup = g.Style.Alpha;
|
|
g.DisabledAlphaBackup = g.Style.Alpha;
|
|
if (!was_disabled && disabled)
|
|
if (!was_disabled && disabled)
|
|
|
|
+ {
|
|
|
|
+ g.DisabledAlphaBackup = g.Style.Alpha;
|
|
g.Style.Alpha *= g.Style.DisabledAlpha; // PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * g.Style.DisabledAlpha);
|
|
g.Style.Alpha *= g.Style.DisabledAlpha; // PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * g.Style.DisabledAlpha);
|
|
|
|
+ }
|
|
if (was_disabled || disabled)
|
|
if (was_disabled || disabled)
|
|
g.CurrentItemFlags |= ImGuiItemFlags_Disabled;
|
|
g.CurrentItemFlags |= ImGuiItemFlags_Disabled;
|
|
g.ItemFlagsStack.push_back(g.CurrentItemFlags);
|
|
g.ItemFlagsStack.push_back(g.CurrentItemFlags);
|
|
@@ -7185,7 +7212,7 @@ void ImGui::EndDisabled()
|
|
bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
|
bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
|
//PopItemFlag();
|
|
//PopItemFlag();
|
|
g.ItemFlagsStack.pop_back();
|
|
g.ItemFlagsStack.pop_back();
|
|
- g.CurrentItemFlags &= ~ImGuiItemFlags_Disabled;
|
|
|
|
|
|
+ g.CurrentItemFlags = g.ItemFlagsStack.back();
|
|
if (was_disabled && (g.CurrentItemFlags & ImGuiItemFlags_Disabled) == 0)
|
|
if (was_disabled && (g.CurrentItemFlags & ImGuiItemFlags_Disabled) == 0)
|
|
g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar();
|
|
g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar();
|
|
}
|
|
}
|
|
@@ -8048,7 +8075,6 @@ void ImGuiStackSizes::CompareWithCurrentState()
|
|
// - GetContentRegionMaxAbs() [Internal]
|
|
// - GetContentRegionMaxAbs() [Internal]
|
|
// - GetContentRegionAvail(),
|
|
// - GetContentRegionAvail(),
|
|
// - GetWindowContentRegionMin(), GetWindowContentRegionMax()
|
|
// - GetWindowContentRegionMin(), GetWindowContentRegionMax()
|
|
-// - GetWindowContentRegionWidth()
|
|
|
|
// - BeginGroup()
|
|
// - BeginGroup()
|
|
// - EndGroup()
|
|
// - EndGroup()
|
|
// Also see in imgui_widgets: tab bars, columns.
|
|
// Also see in imgui_widgets: tab bars, columns.
|
|
@@ -8416,12 +8442,6 @@ ImVec2 ImGui::GetWindowContentRegionMax()
|
|
return window->ContentRegionRect.Max - window->Pos;
|
|
return window->ContentRegionRect.Max - window->Pos;
|
|
}
|
|
}
|
|
|
|
|
|
-float ImGui::GetWindowContentRegionWidth()
|
|
|
|
-{
|
|
|
|
- ImGuiWindow* window = GImGui->CurrentWindow;
|
|
|
|
- return window->ContentRegionRect.GetWidth();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
// Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.)
|
|
// Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.)
|
|
// Groups are currently a mishmash of functionalities which should perhaps be clarified and separated.
|
|
// Groups are currently a mishmash of functionalities which should perhaps be clarified and separated.
|
|
void ImGui::BeginGroup()
|
|
void ImGui::BeginGroup()
|
|
@@ -9074,7 +9094,7 @@ void ImGui::EndPopup()
|
|
IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls
|
|
IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls
|
|
IM_ASSERT(g.BeginPopupStack.Size > 0);
|
|
IM_ASSERT(g.BeginPopupStack.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 (e.g. focus scope could include wrap/loop policy flags used by new move requests)
|
|
if (g.NavWindow == window)
|
|
if (g.NavWindow == window)
|
|
NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_LoopY);
|
|
NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_LoopY);
|
|
|
|
|
|
@@ -9587,26 +9607,26 @@ void ImGui::NavMoveRequestCancel()
|
|
NavUpdateAnyRequestFlag();
|
|
NavUpdateAnyRequestFlag();
|
|
}
|
|
}
|
|
|
|
|
|
-void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect& bb_rel, ImGuiNavMoveFlags move_flags)
|
|
|
|
|
|
+// Forward will reuse the move request again on the next frame (generally with modifications done to it)
|
|
|
|
+void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
- IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None);
|
|
|
|
|
|
+ IM_ASSERT(g.NavMoveRequestForwardToNextFrame == false);
|
|
NavMoveRequestCancel();
|
|
NavMoveRequestCancel();
|
|
|
|
+ g.NavMoveRequestForwardToNextFrame = true;
|
|
g.NavMoveDir = move_dir;
|
|
g.NavMoveDir = move_dir;
|
|
g.NavMoveClipDir = clip_dir;
|
|
g.NavMoveClipDir = clip_dir;
|
|
- g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
|
|
|
|
- g.NavMoveRequestFlags = move_flags;
|
|
|
|
- g.NavWindow->NavRectRel[g.NavLayer] = bb_rel;
|
|
|
|
|
|
+ g.NavMoveRequestFlags = move_flags | ImGuiNavMoveFlags_Forwarded;
|
|
}
|
|
}
|
|
|
|
|
|
-void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags)
|
|
|
|
|
|
+// Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire
|
|
|
|
+// popup is assembled and in case of appended popups it is not clear which EndPopup() call is final.
|
|
|
|
+void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags wrap_flags)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
-
|
|
|
|
- // Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire
|
|
|
|
- // popup is assembled and in case of appended popups it is not clear which EndPopup() call is final.
|
|
|
|
- g.NavWrapRequestWindow = window;
|
|
|
|
- g.NavWrapRequestFlags = move_flags;
|
|
|
|
|
|
+ IM_ASSERT(wrap_flags != 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY
|
|
|
|
+ if (g.NavWindow == window && g.NavMoveRequest && g.NavLayer == ImGuiNavLayer_Main)
|
|
|
|
+ g.NavMoveRequestFlags |= wrap_flags;
|
|
}
|
|
}
|
|
|
|
|
|
// FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0).
|
|
// FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0).
|
|
@@ -9756,16 +9776,14 @@ static void ImGui::NavUpdate()
|
|
ImGuiIO& io = g.IO;
|
|
ImGuiIO& io = g.IO;
|
|
|
|
|
|
io.WantSetMousePos = false;
|
|
io.WantSetMousePos = false;
|
|
- g.NavWrapRequestWindow = NULL;
|
|
|
|
- g.NavWrapRequestFlags = ImGuiNavMoveFlags_None;
|
|
|
|
#if 0
|
|
#if 0
|
|
if (g.NavScoringCount > 0) IMGUI_DEBUG_LOG("NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest);
|
|
if (g.NavScoringCount > 0) IMGUI_DEBUG_LOG("NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
// Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard)
|
|
// Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard)
|
|
// (do it before we map Keyboard input!)
|
|
// (do it before we map Keyboard input!)
|
|
- bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
|
|
|
- bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
|
|
|
|
|
+ const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
|
|
|
+ const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
|
if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad)
|
|
if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad)
|
|
{
|
|
{
|
|
if (io.NavInputs[ImGuiNavInput_Activate] > 0.0f || io.NavInputs[ImGuiNavInput_Input] > 0.0f || io.NavInputs[ImGuiNavInput_Cancel] > 0.0f || io.NavInputs[ImGuiNavInput_Menu] > 0.0f
|
|
if (io.NavInputs[ImGuiNavInput_Activate] > 0.0f || io.NavInputs[ImGuiNavInput_Input] > 0.0f || io.NavInputs[ImGuiNavInput_Cancel] > 0.0f || io.NavInputs[ImGuiNavInput_Menu] > 0.0f
|
|
@@ -9804,16 +9822,8 @@ static void ImGui::NavUpdate()
|
|
|
|
|
|
// Process navigation move request
|
|
// Process navigation move request
|
|
if (g.NavMoveRequest)
|
|
if (g.NavMoveRequest)
|
|
- NavUpdateMoveResult();
|
|
|
|
-
|
|
|
|
- // When a forwarded move request failed, we restore the highlight that we disabled during the forward frame
|
|
|
|
- if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive)
|
|
|
|
- {
|
|
|
|
- IM_ASSERT(g.NavMoveRequest);
|
|
|
|
- if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0)
|
|
|
|
- g.NavDisableHighlight = false;
|
|
|
|
- g.NavMoveRequestForward = ImGuiNavForward_None;
|
|
|
|
- }
|
|
|
|
|
|
+ NavMoveRequestApplyResult();
|
|
|
|
+ g.NavMoveRequest = false;
|
|
|
|
|
|
// Apply application mouse position movement, after we had a chance to process move request result.
|
|
// Apply application mouse position movement, after we had a chance to process move request result.
|
|
if (g.NavMousePosDirty && g.NavIdIsAlive)
|
|
if (g.NavMousePosDirty && g.NavIdIsAlive)
|
|
@@ -9831,7 +9841,7 @@ static void ImGui::NavUpdate()
|
|
g.NavJustTabbedId = 0;
|
|
g.NavJustTabbedId = 0;
|
|
IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1);
|
|
IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1);
|
|
|
|
|
|
- // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0
|
|
|
|
|
|
+ // Store our return window (for returning from Menu Layer to Main Layer) and clear it as soon as we step back in our own Layer 0
|
|
if (g.NavWindow)
|
|
if (g.NavWindow)
|
|
NavSaveLastChildNavWindowIntoParent(g.NavWindow);
|
|
NavSaveLastChildNavWindowIntoParent(g.NavWindow);
|
|
if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == ImGuiNavLayer_Main)
|
|
if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == ImGuiNavLayer_Main)
|
|
@@ -9845,43 +9855,7 @@ static void ImGui::NavUpdate()
|
|
io.NavVisible = (io.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL);
|
|
io.NavVisible = (io.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL);
|
|
|
|
|
|
// Process NavCancel input (to close a popup, get back to parent, clear focus)
|
|
// Process NavCancel input (to close a popup, get back to parent, clear focus)
|
|
- if (IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed))
|
|
|
|
- {
|
|
|
|
- IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n");
|
|
|
|
- if (g.ActiveId != 0)
|
|
|
|
- {
|
|
|
|
- if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel))
|
|
|
|
- ClearActiveID();
|
|
|
|
- }
|
|
|
|
- else if (g.NavLayer != ImGuiNavLayer_Main)
|
|
|
|
- {
|
|
|
|
- // Leave the "menu" layer
|
|
|
|
- NavRestoreLayer(ImGuiNavLayer_Main);
|
|
|
|
- }
|
|
|
|
- else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow)
|
|
|
|
- {
|
|
|
|
- // Exit child window
|
|
|
|
- ImGuiWindow* child_window = g.NavWindow;
|
|
|
|
- ImGuiWindow* parent_window = g.NavWindow->ParentWindow;
|
|
|
|
- IM_ASSERT(child_window->ChildId != 0);
|
|
|
|
- ImRect child_rect = child_window->Rect();
|
|
|
|
- FocusWindow(parent_window);
|
|
|
|
- SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, ImRect(child_rect.Min - parent_window->Pos, child_rect.Max - parent_window->Pos));
|
|
|
|
- }
|
|
|
|
- else if (g.OpenPopupStack.Size > 0)
|
|
|
|
- {
|
|
|
|
- // Close open popup/menu
|
|
|
|
- if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
|
|
|
|
- ClosePopupToLevel(g.OpenPopupStack.Size - 1, true);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were
|
|
|
|
- if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow)))
|
|
|
|
- g.NavWindow->NavLastIds[0] = 0;
|
|
|
|
- g.NavId = g.NavFocusScopeId = 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ NavUpdateCancelRequest();
|
|
|
|
|
|
// Process manual activation request
|
|
// Process manual activation request
|
|
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0;
|
|
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0;
|
|
@@ -9902,59 +9876,14 @@ static void ImGui::NavUpdate()
|
|
g.NavDisableHighlight = true;
|
|
g.NavDisableHighlight = true;
|
|
if (g.NavActivateId != 0)
|
|
if (g.NavActivateId != 0)
|
|
IM_ASSERT(g.NavActivateDownId == g.NavActivateId);
|
|
IM_ASSERT(g.NavActivateDownId == g.NavActivateId);
|
|
- g.NavMoveRequest = false;
|
|
|
|
|
|
|
|
// Process programmatic activation request
|
|
// Process programmatic activation request
|
|
if (g.NavNextActivateId != 0)
|
|
if (g.NavNextActivateId != 0)
|
|
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId;
|
|
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId;
|
|
g.NavNextActivateId = 0;
|
|
g.NavNextActivateId = 0;
|
|
|
|
|
|
- // Initiate directional inputs request
|
|
|
|
- if (g.NavMoveRequestForward == ImGuiNavForward_None)
|
|
|
|
- {
|
|
|
|
- g.NavMoveDir = ImGuiDir_None;
|
|
|
|
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_None;
|
|
|
|
- if (g.NavWindow && !g.NavWindowingTarget && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
|
|
- {
|
|
|
|
- const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat;
|
|
|
|
- if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; }
|
|
|
|
- if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; }
|
|
|
|
- if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; }
|
|
|
|
- if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && (IsNavInputTest(ImGuiNavInput_DpadDown, read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_, read_mode))) { g.NavMoveDir = ImGuiDir_Down; }
|
|
|
|
- }
|
|
|
|
- g.NavMoveClipDir = g.NavMoveDir;
|
|
|
|
- }
|
|
|
|
- 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)
|
|
|
|
- // (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);
|
|
|
|
- IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
|
|
|
|
- g.NavMoveRequestForward = ImGuiNavForward_ForwardActive;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Update PageUp/PageDown/Home/End scroll
|
|
|
|
- // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag?
|
|
|
|
- float nav_scoring_rect_offset_y = 0.0f;
|
|
|
|
- if (nav_keyboard_active)
|
|
|
|
- nav_scoring_rect_offset_y = NavUpdatePageUpPageDown();
|
|
|
|
-
|
|
|
|
- // If we initiate a movement request and have no current NavId, we initiate a InitDefautRequest that will be used as a fallback if the direction fails to find a match
|
|
|
|
- if (g.NavMoveDir != ImGuiDir_None)
|
|
|
|
- {
|
|
|
|
- g.NavMoveRequest = true;
|
|
|
|
- g.NavMoveRequestKeyMods = io.KeyMods;
|
|
|
|
- g.NavMoveDirLast = g.NavMoveDir;
|
|
|
|
- }
|
|
|
|
- if (g.NavMoveRequest && g.NavId == 0)
|
|
|
|
- {
|
|
|
|
- IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer);
|
|
|
|
- g.NavInitRequest = g.NavInitRequestFromMove = true;
|
|
|
|
- // Reassigning with same value, we're being explicit here.
|
|
|
|
- g.NavInitResultId = 0; // -V1048
|
|
|
|
- g.NavDisableHighlight = false;
|
|
|
|
- }
|
|
|
|
|
|
+ // Process move requests
|
|
|
|
+ NavUpdateCreateMoveRequest();
|
|
NavUpdateAnyRequestFlag();
|
|
NavUpdateAnyRequestFlag();
|
|
|
|
|
|
// Scrolling
|
|
// Scrolling
|
|
@@ -9963,7 +9892,7 @@ static void ImGui::NavUpdate()
|
|
// *Fallback* manual-scroll with Nav directional keys when window has no navigable item
|
|
// *Fallback* manual-scroll with Nav directional keys when window has no navigable item
|
|
ImGuiWindow* window = g.NavWindow;
|
|
ImGuiWindow* window = g.NavWindow;
|
|
const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
|
|
const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
|
|
- if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest)
|
|
|
|
|
|
+ if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest) //-V560
|
|
{
|
|
{
|
|
if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right)
|
|
if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right)
|
|
SetScrollX(window, ImFloor(window->Scroll.x + ((g.NavMoveDir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed));
|
|
SetScrollX(window, ImFloor(window->Scroll.x + ((g.NavMoveDir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed));
|
|
@@ -9980,36 +9909,7 @@ static void ImGui::NavUpdate()
|
|
SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed));
|
|
SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed));
|
|
}
|
|
}
|
|
|
|
|
|
- // Reset search results
|
|
|
|
- g.NavMoveResultLocal.Clear();
|
|
|
|
- g.NavMoveResultLocalVisibleSet.Clear();
|
|
|
|
- g.NavMoveResultOther.Clear();
|
|
|
|
-
|
|
|
|
- // When using gamepad, we project the reference nav bounding box into window visible area.
|
|
|
|
- // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad every movements are relative
|
|
|
|
- // (can't focus a visible object like we can with the mouse).
|
|
|
|
- if (g.NavMoveRequest && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main)
|
|
|
|
- {
|
|
|
|
- ImGuiWindow* window = g.NavWindow;
|
|
|
|
- ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1));
|
|
|
|
- if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
|
|
|
|
- {
|
|
|
|
- IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel\n");
|
|
|
|
- float pad = window->CalcFontSize() * 0.5f;
|
|
|
|
- window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item
|
|
|
|
- window->NavRectRel[g.NavLayer].ClipWithFull(window_rect_rel);
|
|
|
|
- g.NavId = g.NavFocusScopeId = 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items)
|
|
|
|
- ImRect nav_rect_rel = (g.NavWindow && !g.NavWindow->NavRectRel[g.NavLayer].IsInverted()) ? g.NavWindow->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0);
|
|
|
|
- g.NavScoringRect = g.NavWindow ? ImRect(g.NavWindow->Pos + nav_rect_rel.Min, g.NavWindow->Pos + nav_rect_rel.Max) : ImRect(0, 0, 0, 0);
|
|
|
|
- g.NavScoringRect.TranslateY(nav_scoring_rect_offset_y);
|
|
|
|
- g.NavScoringRect.Min.x = ImMin(g.NavScoringRect.Min.x + 1.0f, g.NavScoringRect.Max.x);
|
|
|
|
- g.NavScoringRect.Max.x = g.NavScoringRect.Min.x;
|
|
|
|
- IM_ASSERT(!g.NavScoringRect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem().
|
|
|
|
- //GetForegroundDrawList()->AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG]
|
|
|
|
|
|
+ // [DEBUG]
|
|
g.NavScoringCount = 0;
|
|
g.NavScoringCount = 0;
|
|
#if IMGUI_DEBUG_NAV_RECTS
|
|
#if IMGUI_DEBUG_NAV_RECTS
|
|
if (g.NavWindow)
|
|
if (g.NavWindow)
|
|
@@ -10039,10 +9939,100 @@ static void ImGui::NavUpdateInitResult()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-// Apply result from previous frame navigation directional move request
|
|
|
|
-static void ImGui::NavUpdateMoveResult()
|
|
|
|
|
|
+void ImGui::NavUpdateCreateMoveRequest()
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiIO& io = g.IO;
|
|
|
|
+ ImGuiWindow* window = g.NavWindow;
|
|
|
|
+
|
|
|
|
+ if (g.NavMoveRequestForwardToNextFrame)
|
|
|
|
+ {
|
|
|
|
+ // 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)
|
|
|
|
+ // (preserve most state, which were already set by the NavMoveRequestForward() function)
|
|
|
|
+ IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
|
|
|
|
+ IM_ASSERT(g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded);
|
|
|
|
+ IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
|
|
|
|
+ g.NavMoveRequestForwardToNextFrame = false;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // Initiate directional inputs request
|
|
|
|
+ g.NavMoveDir = ImGuiDir_None;
|
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_None;
|
|
|
|
+ if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
|
|
+ {
|
|
|
|
+ const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat;
|
|
|
|
+ if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; }
|
|
|
|
+ if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; }
|
|
|
|
+ if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; }
|
|
|
|
+ if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && (IsNavInputTest(ImGuiNavInput_DpadDown, read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_, read_mode))) { g.NavMoveDir = ImGuiDir_Down; }
|
|
|
|
+ }
|
|
|
|
+ g.NavMoveClipDir = g.NavMoveDir;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Update PageUp/PageDown/Home/End scroll
|
|
|
|
+ // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag?
|
|
|
|
+ const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
|
|
|
+ float nav_scoring_rect_offset_y = 0.0f;
|
|
|
|
+ if (nav_keyboard_active)
|
|
|
|
+ nav_scoring_rect_offset_y = NavUpdatePageUpPageDown();
|
|
|
|
+
|
|
|
|
+ // If we initiate a movement request and have no current NavId, we initiate a InitDefaultRequest that will be used as a fallback if the direction fails to find a match
|
|
|
|
+ if (g.NavMoveDir != ImGuiDir_None)
|
|
|
|
+ {
|
|
|
|
+ IM_ASSERT(window != NULL);
|
|
|
|
+ g.NavMoveRequest = true;
|
|
|
|
+ g.NavMoveRequestKeyMods = io.KeyMods;
|
|
|
|
+ g.NavMoveDirLast = g.NavMoveDir;
|
|
|
|
+ g.NavMoveResultLocal.Clear();
|
|
|
|
+ g.NavMoveResultLocalVisibleSet.Clear();
|
|
|
|
+ g.NavMoveResultOther.Clear();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Moving with no reference triggers a init request
|
|
|
|
+ if (g.NavMoveRequest && g.NavId == 0)
|
|
|
|
+ {
|
|
|
|
+ IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer);
|
|
|
|
+ g.NavInitRequest = g.NavInitRequestFromMove = true;
|
|
|
|
+ g.NavInitResultId = 0;
|
|
|
|
+ g.NavDisableHighlight = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // When using gamepad, we project the reference nav bounding box into window visible area.
|
|
|
|
+ // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad every movements are relative
|
|
|
|
+ // (can't focus a visible object like we can with the mouse).
|
|
|
|
+ if (g.NavMoveRequest && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main && window != NULL)
|
|
|
|
+ {
|
|
|
|
+ ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1));
|
|
|
|
+ if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
|
|
|
|
+ {
|
|
|
|
+ IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel\n");
|
|
|
|
+ float pad = window->CalcFontSize() * 0.5f;
|
|
|
|
+ window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item
|
|
|
|
+ window->NavRectRel[g.NavLayer].ClipWithFull(window_rect_rel);
|
|
|
|
+ g.NavId = g.NavFocusScopeId = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items)
|
|
|
|
+ g.NavScoringRect = ImRect();
|
|
|
|
+ if (window)
|
|
|
|
+ {
|
|
|
|
+ ImRect nav_rect_rel = !window->NavRectRel[g.NavLayer].IsInverted() ? window->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0);
|
|
|
|
+ g.NavScoringRect = ImRect(window->Pos + nav_rect_rel.Min, window->Pos + nav_rect_rel.Max);
|
|
|
|
+ g.NavScoringRect.TranslateY(nav_scoring_rect_offset_y);
|
|
|
|
+ g.NavScoringRect.Min.x = ImMin(g.NavScoringRect.Min.x + 1.0f, g.NavScoringRect.Max.x);
|
|
|
|
+ g.NavScoringRect.Max.x = g.NavScoringRect.Min.x;
|
|
|
|
+ IM_ASSERT(!g.NavScoringRect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem().
|
|
|
|
+ //GetForegroundDrawList()->AddRect(g.NavScoringRect.Min, g.NavScoringRect.Max, IM_COL32(255,200,0,255)); // [DEBUG]
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Apply result from previous frame navigation directional move request. Always called from NavUpdate()
|
|
|
|
+void ImGui::NavMoveRequestApplyResult()
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+
|
|
if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0)
|
|
if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0)
|
|
{
|
|
{
|
|
// In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result)
|
|
// In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result)
|
|
@@ -10104,7 +10094,54 @@ static void ImGui::NavUpdateMoveResult()
|
|
g.NavDisableMouseHover = g.NavMousePosDirty = true;
|
|
g.NavDisableMouseHover = g.NavMousePosDirty = true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Process NavCancel input (to close a popup, get back to parent, clear focus)
|
|
|
|
+// FIXME: In order to support e.g. Escape to clear a selection we'll need:
|
|
|
|
+// - either to store the equivalent of ActiveIdUsingKeyInputMask for a FocusScope and test for it.
|
|
|
|
+// - either to move most/all of those tests to the epilogue/end functions of the scope they are dealing with (e.g. exit child window in EndChild()) or in EndFrame(), to allow an earlier intercept
|
|
|
|
+static void ImGui::NavUpdateCancelRequest()
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ if (!IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n");
|
|
|
|
+ if (g.ActiveId != 0)
|
|
|
|
+ {
|
|
|
|
+ if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel))
|
|
|
|
+ ClearActiveID();
|
|
|
|
+ }
|
|
|
|
+ else if (g.NavLayer != ImGuiNavLayer_Main)
|
|
|
|
+ {
|
|
|
|
+ // Leave the "menu" layer
|
|
|
|
+ NavRestoreLayer(ImGuiNavLayer_Main);
|
|
|
|
+ }
|
|
|
|
+ else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow)
|
|
|
|
+ {
|
|
|
|
+ // Exit child window
|
|
|
|
+ ImGuiWindow* child_window = g.NavWindow;
|
|
|
|
+ ImGuiWindow* parent_window = g.NavWindow->ParentWindow;
|
|
|
|
+ IM_ASSERT(child_window->ChildId != 0);
|
|
|
|
+ ImRect child_rect = child_window->Rect();
|
|
|
|
+ FocusWindow(parent_window);
|
|
|
|
+ SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, ImRect(child_rect.Min - parent_window->Pos, child_rect.Max - parent_window->Pos));
|
|
|
|
+ }
|
|
|
|
+ else if (g.OpenPopupStack.Size > 0)
|
|
|
|
+ {
|
|
|
|
+ // Close open popup/menu
|
|
|
|
+ if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
|
|
|
|
+ ClosePopupToLevel(g.OpenPopupStack.Size - 1, true);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were
|
|
|
|
+ if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow)))
|
|
|
|
+ g.NavWindow->NavLastIds[0] = 0;
|
|
|
|
+ g.NavId = g.NavFocusScopeId = 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// Handle PageUp/PageDown/Home/End keys
|
|
// Handle PageUp/PageDown/Home/End keys
|
|
|
|
+// FIXME-NAV: how to get Home/End to aim at the beginning/end of a 2D grid?
|
|
static float ImGui::NavUpdatePageUpPageDown()
|
|
static float ImGui::NavUpdatePageUpPageDown()
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -10120,60 +10157,60 @@ static float ImGui::NavUpdatePageUpPageDown()
|
|
const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown);
|
|
const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown);
|
|
const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home);
|
|
const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home);
|
|
const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End);
|
|
const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End);
|
|
- if (page_up_held != page_down_held || home_pressed != end_pressed) // If either (not both) are pressed
|
|
|
|
|
|
+ if (page_up_held == page_down_held && home_pressed == end_pressed) // Proceed if either (not both) are pressed, otherwise early out
|
|
|
|
+ return 0.0f;
|
|
|
|
+
|
|
|
|
+ if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll)
|
|
{
|
|
{
|
|
- if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll)
|
|
|
|
|
|
+ // Fallback manual-scroll when window has no navigable item
|
|
|
|
+ if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
|
|
|
|
+ SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight());
|
|
|
|
+ else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
|
|
|
|
+ SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight());
|
|
|
|
+ else if (home_pressed)
|
|
|
|
+ SetScrollY(window, 0.0f);
|
|
|
|
+ else if (end_pressed)
|
|
|
|
+ SetScrollY(window, window->ScrollMax.y);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
|
|
|
|
+ const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
|
|
|
|
+ float nav_scoring_rect_offset_y = 0.0f;
|
|
|
|
+ if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
|
|
{
|
|
{
|
|
- // Fallback manual-scroll when window has no navigable item
|
|
|
|
- if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
|
|
|
|
- SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight());
|
|
|
|
- else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
|
|
|
|
- SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight());
|
|
|
|
- else if (home_pressed)
|
|
|
|
- SetScrollY(window, 0.0f);
|
|
|
|
- else if (end_pressed)
|
|
|
|
- SetScrollY(window, window->ScrollMax.y);
|
|
|
|
|
|
+ nav_scoring_rect_offset_y = -page_offset_y;
|
|
|
|
+ g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item)
|
|
|
|
+ g.NavMoveClipDir = ImGuiDir_Up;
|
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
|
|
{
|
|
{
|
|
- ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
|
|
|
|
- const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
|
|
|
|
- float nav_scoring_rect_offset_y = 0.0f;
|
|
|
|
- if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
|
|
|
|
- {
|
|
|
|
- nav_scoring_rect_offset_y = -page_offset_y;
|
|
|
|
- g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item)
|
|
|
|
- g.NavMoveClipDir = ImGuiDir_Up;
|
|
|
|
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
|
- }
|
|
|
|
- else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
|
|
|
|
- {
|
|
|
|
- nav_scoring_rect_offset_y = +page_offset_y;
|
|
|
|
- g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item)
|
|
|
|
- g.NavMoveClipDir = ImGuiDir_Down;
|
|
|
|
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
|
- }
|
|
|
|
- else if (home_pressed)
|
|
|
|
- {
|
|
|
|
- // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y
|
|
|
|
- // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result.
|
|
|
|
- // Preserve current horizontal position if we have any.
|
|
|
|
- nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y;
|
|
|
|
- if (nav_rect_rel.IsInverted())
|
|
|
|
- nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
|
- g.NavMoveDir = ImGuiDir_Down;
|
|
|
|
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
|
- }
|
|
|
|
- else if (end_pressed)
|
|
|
|
- {
|
|
|
|
- nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
|
|
|
|
- if (nav_rect_rel.IsInverted())
|
|
|
|
- nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
|
- g.NavMoveDir = ImGuiDir_Up;
|
|
|
|
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
|
- }
|
|
|
|
- return nav_scoring_rect_offset_y;
|
|
|
|
|
|
+ nav_scoring_rect_offset_y = +page_offset_y;
|
|
|
|
+ g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item)
|
|
|
|
+ g.NavMoveClipDir = ImGuiDir_Down;
|
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
|
+ }
|
|
|
|
+ else if (home_pressed)
|
|
|
|
+ {
|
|
|
|
+ // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y
|
|
|
|
+ // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result.
|
|
|
|
+ // Preserve current horizontal position if we have any.
|
|
|
|
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y;
|
|
|
|
+ if (nav_rect_rel.IsInverted())
|
|
|
|
+ nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
|
+ g.NavMoveDir = ImGuiDir_Down;
|
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
}
|
|
}
|
|
|
|
+ else if (end_pressed)
|
|
|
|
+ {
|
|
|
|
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
|
|
|
|
+ if (nav_rect_rel.IsInverted())
|
|
|
|
+ nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
|
+ g.NavMoveDir = ImGuiDir_Up;
|
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
|
+ }
|
|
|
|
+ return nav_scoring_rect_offset_y;
|
|
}
|
|
}
|
|
return 0.0f;
|
|
return 0.0f;
|
|
}
|
|
}
|
|
@@ -10187,13 +10224,14 @@ static void ImGui::NavEndFrame()
|
|
NavUpdateWindowingOverlay();
|
|
NavUpdateWindowingOverlay();
|
|
|
|
|
|
// Perform wrap-around in menus
|
|
// Perform wrap-around in menus
|
|
- ImGuiWindow* window = g.NavWrapRequestWindow;
|
|
|
|
- ImGuiNavMoveFlags move_flags = g.NavWrapRequestFlags;
|
|
|
|
- if (window != NULL && g.NavWindow == window && NavMoveRequestButNoResultYet() && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == ImGuiNavLayer_Main)
|
|
|
|
|
|
+ // FIXME-NAV: Wrap (not Loop) support could be handled by the scoring function and then WrapX would function without an extra frame.
|
|
|
|
+ ImGuiWindow* window = g.NavWindow;
|
|
|
|
+ const ImGuiNavMoveFlags move_flags = g.NavMoveRequestFlags;
|
|
|
|
+ const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY;
|
|
|
|
+ if (window && NavMoveRequestButNoResultYet() && (g.NavMoveRequestFlags & wanted_flags) && (g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded) == 0)
|
|
{
|
|
{
|
|
- IM_ASSERT(move_flags != 0); // No points calling this with no wrapping
|
|
|
|
- ImRect bb_rel = window->NavRectRel[0];
|
|
|
|
-
|
|
|
|
|
|
+ bool do_forward = false;
|
|
|
|
+ ImRect bb_rel = window->NavRectRel[g.NavLayer];
|
|
ImGuiDir clip_dir = g.NavMoveDir;
|
|
ImGuiDir clip_dir = g.NavMoveDir;
|
|
if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
|
|
if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
|
|
{
|
|
{
|
|
@@ -10204,7 +10242,7 @@ static void ImGui::NavEndFrame()
|
|
bb_rel.TranslateY(-bb_rel.GetHeight());
|
|
bb_rel.TranslateY(-bb_rel.GetHeight());
|
|
clip_dir = ImGuiDir_Up;
|
|
clip_dir = ImGuiDir_Up;
|
|
}
|
|
}
|
|
- NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
|
|
|
|
|
|
+ do_forward = true;
|
|
}
|
|
}
|
|
if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
|
|
if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
|
|
{
|
|
{
|
|
@@ -10214,7 +10252,7 @@ static void ImGui::NavEndFrame()
|
|
bb_rel.TranslateY(+bb_rel.GetHeight());
|
|
bb_rel.TranslateY(+bb_rel.GetHeight());
|
|
clip_dir = ImGuiDir_Down;
|
|
clip_dir = ImGuiDir_Down;
|
|
}
|
|
}
|
|
- NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
|
|
|
|
|
|
+ do_forward = true;
|
|
}
|
|
}
|
|
if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
|
|
if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
|
|
{
|
|
{
|
|
@@ -10225,7 +10263,7 @@ static void ImGui::NavEndFrame()
|
|
bb_rel.TranslateX(-bb_rel.GetWidth());
|
|
bb_rel.TranslateX(-bb_rel.GetWidth());
|
|
clip_dir = ImGuiDir_Left;
|
|
clip_dir = ImGuiDir_Left;
|
|
}
|
|
}
|
|
- NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
|
|
|
|
|
|
+ do_forward = true;
|
|
}
|
|
}
|
|
if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
|
|
if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
|
|
{
|
|
{
|
|
@@ -10235,7 +10273,12 @@ static void ImGui::NavEndFrame()
|
|
bb_rel.TranslateX(+bb_rel.GetWidth());
|
|
bb_rel.TranslateX(+bb_rel.GetWidth());
|
|
clip_dir = ImGuiDir_Right;
|
|
clip_dir = ImGuiDir_Right;
|
|
}
|
|
}
|
|
- NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
|
|
|
|
|
|
+ do_forward = true;
|
|
|
|
+ }
|
|
|
|
+ if (do_forward)
|
|
|
|
+ {
|
|
|
|
+ window->NavRectRel[g.NavLayer] = bb_rel;
|
|
|
|
+ NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|