mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-04 01:34:32 +00:00 
			
		
		
		
	Nav: merged SetNavID() and SetNavIDWithRectRel() to improve sanity, moved flags overwrite off them. (#787)
This commit is contained in:
		
							
								
								
									
										59
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -886,6 +886,7 @@ static void             NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb
 | 
			
		||||
static ImVec2           NavCalcPreferredRefPos();
 | 
			
		||||
static void             NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
 | 
			
		||||
static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window);
 | 
			
		||||
static void             NavRestoreLayer(ImGuiNavLayer layer);
 | 
			
		||||
static int              FindWindowFocusIndex(ImGuiWindow* window);
 | 
			
		||||
 | 
			
		||||
// Error Checking
 | 
			
		||||
@@ -8476,9 +8477,8 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
 | 
			
		||||
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
// FIXME-NAV: The existence of SetNavID vs SetNavIDWithRectRel vs SetFocusID is incredibly messy and confusing,
 | 
			
		||||
// and needs some explanation or serious refactoring.
 | 
			
		||||
void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id)
 | 
			
		||||
// FIXME-NAV: The existence of SetNavID vs SetFocusID properly needs to be clarified/reworked.
 | 
			
		||||
void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    IM_ASSERT(g.NavWindow != NULL);
 | 
			
		||||
@@ -8487,16 +8487,9 @@ void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id)
 | 
			
		||||
    g.NavLayer = (ImGuiNavLayer)nav_layer;
 | 
			
		||||
    g.NavFocusScopeId = focus_scope_id;
 | 
			
		||||
    g.NavWindow->NavLastIds[nav_layer] = id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImGui::SetNavIDWithRectRel(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    SetNavID(id, nav_layer, focus_scope_id);
 | 
			
		||||
    g.NavWindow->NavRectRel[nav_layer] = rect_rel;
 | 
			
		||||
    g.NavMousePosDirty = true;
 | 
			
		||||
    g.NavDisableHighlight = false;
 | 
			
		||||
    g.NavDisableMouseHover = true;
 | 
			
		||||
    //g.NavDisableHighlight = false;
 | 
			
		||||
    //g.NavDisableMouseHover = g.NavMousePosDirty = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
 | 
			
		||||
@@ -8810,17 +8803,23 @@ static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window)
 | 
			
		||||
    return window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void NavRestoreLayer(ImGuiNavLayer layer)
 | 
			
		||||
void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    g.NavLayer = layer;
 | 
			
		||||
    if (layer == 0)
 | 
			
		||||
        g.NavWindow = ImGui::NavRestoreLastChildNavWindow(g.NavWindow);
 | 
			
		||||
    if (layer == ImGuiNavLayer_Main)
 | 
			
		||||
        g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow);
 | 
			
		||||
    ImGuiWindow* window = g.NavWindow;
 | 
			
		||||
    if (window->NavLastIds[layer] != 0)
 | 
			
		||||
        ImGui::SetNavIDWithRectRel(window->NavLastIds[layer], layer, 0, g.NavWindow->NavRectRel[layer]);
 | 
			
		||||
    {
 | 
			
		||||
        SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
 | 
			
		||||
        g.NavDisableHighlight = false;
 | 
			
		||||
        g.NavDisableMouseHover = g.NavMousePosDirty = true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        ImGui::NavInitWindow(window, true);
 | 
			
		||||
    {
 | 
			
		||||
        g.NavLayer = layer;
 | 
			
		||||
        NavInitWindow(window, true);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void ImGui::NavUpdateAnyRequestFlag()
 | 
			
		||||
@@ -8843,7 +8842,7 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
 | 
			
		||||
    IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from NavInitWindow(), init_for_nav=%d, window=\"%s\", layer=%d\n", init_for_nav, window->Name, g.NavLayer);
 | 
			
		||||
    if (init_for_nav)
 | 
			
		||||
    {
 | 
			
		||||
        SetNavID(0, g.NavLayer, 0);
 | 
			
		||||
        SetNavID(0, g.NavLayer, 0, ImRect());
 | 
			
		||||
        g.NavInitRequest = true;
 | 
			
		||||
        g.NavInitRequestFromMove = false;
 | 
			
		||||
        g.NavInitResultId = 0;
 | 
			
		||||
@@ -8987,13 +8986,11 @@ static void ImGui::NavUpdate()
 | 
			
		||||
    {
 | 
			
		||||
        // Set mouse position given our knowledge of the navigated item position from last frame
 | 
			
		||||
        if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos))
 | 
			
		||||
        {
 | 
			
		||||
            if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow)
 | 
			
		||||
            {
 | 
			
		||||
                io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos();
 | 
			
		||||
                io.WantSetMousePos = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        g.NavMousePosDirty = false;
 | 
			
		||||
    }
 | 
			
		||||
    g.NavIdIsAlive = false;
 | 
			
		||||
@@ -9028,12 +9025,9 @@ static void ImGui::NavUpdate()
 | 
			
		||||
            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);
 | 
			
		||||
            // Reassigning with same value, we're being explicit here.
 | 
			
		||||
            g.NavIdIsAlive = false;     // -V1048
 | 
			
		||||
            if (g.NavDisableMouseHover)
 | 
			
		||||
                g.NavMousePosDirty = true;
 | 
			
		||||
            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)
 | 
			
		||||
        {
 | 
			
		||||
@@ -9202,11 +9196,12 @@ static void ImGui::NavUpdateInitResult()
 | 
			
		||||
 | 
			
		||||
    // Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called)
 | 
			
		||||
    IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", g.NavInitResultId, g.NavLayer, g.NavWindow->Name);
 | 
			
		||||
    SetNavID(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel);
 | 
			
		||||
    if (g.NavInitRequestFromMove)
 | 
			
		||||
        SetNavIDWithRectRel(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel);
 | 
			
		||||
    else
 | 
			
		||||
        SetNavID(g.NavInitResultId, g.NavLayer, 0);
 | 
			
		||||
    g.NavWindow->NavRectRel[g.NavLayer] = g.NavInitResultRectRel;
 | 
			
		||||
    {
 | 
			
		||||
        g.NavDisableHighlight = false;
 | 
			
		||||
        g.NavDisableMouseHover = g.NavMousePosDirty = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Apply result from previous frame navigation directional move request
 | 
			
		||||
@@ -9269,7 +9264,9 @@ static void ImGui::NavUpdateMoveResult()
 | 
			
		||||
        g.NavJustMovedToKeyMods = g.NavMoveRequestKeyMods;
 | 
			
		||||
    }
 | 
			
		||||
    IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name);
 | 
			
		||||
    SetNavIDWithRectRel(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
 | 
			
		||||
    SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
 | 
			
		||||
    g.NavDisableHighlight = false;
 | 
			
		||||
    g.NavDisableMouseHover = g.NavMousePosDirty = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handle PageUp/PageDown/Home/End keys
 | 
			
		||||
 
 | 
			
		||||
@@ -2313,8 +2313,7 @@ namespace ImGui
 | 
			
		||||
    IMGUI_API ImVec2        GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f);
 | 
			
		||||
    IMGUI_API int           CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);
 | 
			
		||||
    IMGUI_API void          ActivateItem(ImGuiID id);   // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again.
 | 
			
		||||
    IMGUI_API void          SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id);
 | 
			
		||||
    IMGUI_API void          SetNavIDWithRectRel(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
 | 
			
		||||
    IMGUI_API void          SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
 | 
			
		||||
 | 
			
		||||
    // Focus Scope (WIP)
 | 
			
		||||
    // This is generally used to identify a selection set (multiple of which may be in the same window), as selection
 | 
			
		||||
 
 | 
			
		||||
@@ -5913,7 +5913,7 @@ void ImGui::TreePop()
 | 
			
		||||
    if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet())
 | 
			
		||||
        if (g.NavIdIsAlive && (window->DC.TreeJumpToParentOnPopMask & tree_depth_mask))
 | 
			
		||||
        {
 | 
			
		||||
            SetNavID(window->IDStack.back(), g.NavLayer, 0);
 | 
			
		||||
            SetNavID(window->IDStack.back(), g.NavLayer, 0, ImRect());
 | 
			
		||||
            NavMoveRequestCancel();
 | 
			
		||||
        }
 | 
			
		||||
    window->DC.TreeJumpToParentOnPopMask &= tree_depth_mask - 1;
 | 
			
		||||
@@ -6101,8 +6101,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
 | 
			
		||||
    {
 | 
			
		||||
        if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent)
 | 
			
		||||
        {
 | 
			
		||||
            SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, ImRect(bb.Min - window->Pos, bb.Max - window->Pos));
 | 
			
		||||
            g.NavDisableHighlight = true;
 | 
			
		||||
            SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (pressed)
 | 
			
		||||
@@ -6580,8 +6580,9 @@ void ImGui::EndMenuBar()
 | 
			
		||||
            const ImGuiNavLayer layer = ImGuiNavLayer_Menu;
 | 
			
		||||
            IM_ASSERT(window->DC.NavLayerActiveMaskNext & (1 << layer)); // Sanity check
 | 
			
		||||
            FocusWindow(window);
 | 
			
		||||
            SetNavIDWithRectRel(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
 | 
			
		||||
            SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
 | 
			
		||||
            g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection.
 | 
			
		||||
            g.NavDisableMouseHover = g.NavMousePosDirty = true;
 | 
			
		||||
            g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
 | 
			
		||||
            NavMoveRequestCancel();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user