mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-03 22:51:06 +01:00 
			
		
		
		
	Nav: Rectangle rectangle stored per window and per layer as well. Makes things simpler, allows enable us to visualize more data.
This commit is contained in:
		
							
								
								
									
										31
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -1839,7 +1839,6 @@ ImGuiWindow::ImGuiWindow(const char* name)
 | 
				
			|||||||
    Appearing = false;
 | 
					    Appearing = false;
 | 
				
			||||||
    BeginCount = 0;
 | 
					    BeginCount = 0;
 | 
				
			||||||
    PopupId = 0;
 | 
					    PopupId = 0;
 | 
				
			||||||
    NavLastIds[0] = NavLastIds[1] = 0;
 | 
					 | 
				
			||||||
    AutoFitFramesX = AutoFitFramesY = -1;
 | 
					    AutoFitFramesX = AutoFitFramesY = -1;
 | 
				
			||||||
    AutoFitOnlyGrows = false;
 | 
					    AutoFitOnlyGrows = false;
 | 
				
			||||||
    AutoFitChildAxises = 0x00;
 | 
					    AutoFitChildAxises = 0x00;
 | 
				
			||||||
@@ -1848,6 +1847,9 @@ ImGuiWindow::ImGuiWindow(const char* name)
 | 
				
			|||||||
    SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
 | 
					    SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
 | 
				
			||||||
    SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
 | 
					    SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NavLastIds[0] = NavLastIds[1] = 0;
 | 
				
			||||||
 | 
					    NavRefRectRel[0] = NavRefRectRel[1] = ImRect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LastFrameActive = -1;
 | 
					    LastFrameActive = -1;
 | 
				
			||||||
    ItemWidthDefault = 0.0f;
 | 
					    ItemWidthDefault = 0.0f;
 | 
				
			||||||
    FontWindowScale = 1.0f;
 | 
					    FontWindowScale = 1.0f;
 | 
				
			||||||
@@ -2223,7 +2225,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id, const ImRect* nav_bb_ar
 | 
				
			|||||||
                // Update window-relative bounding box of navigated item
 | 
					                // Update window-relative bounding box of navigated item
 | 
				
			||||||
                if (g.NavId == *id)
 | 
					                if (g.NavId == *id)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    g.NavRefRectRel = nav_bb_rel;
 | 
					                    window->NavRefRectRel[window->DC.NavLayerCurrent] = nav_bb_rel;
 | 
				
			||||||
                    g.NavIdIsAlive = true;
 | 
					                    g.NavIdIsAlive = true;
 | 
				
			||||||
                    g.NavIdTabCounter = window->FocusIdxTabCounter;
 | 
					                    g.NavIdTabCounter = window->FocusIdxTabCounter;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -2459,7 +2461,7 @@ static void SetNavIdAndMoveMouse(ImGuiID id, int nav_layer, const ImRect& rect_r
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
    SetNavId(id, nav_layer);
 | 
					    SetNavId(id, nav_layer);
 | 
				
			||||||
    g.NavRefRectRel = rect_rel;
 | 
					    g.NavWindow->NavRefRectRel[nav_layer] = rect_rel;
 | 
				
			||||||
    g.NavMousePosDirty = true;
 | 
					    g.NavMousePosDirty = true;
 | 
				
			||||||
    g.NavDisableHighlight = false;
 | 
					    g.NavDisableHighlight = false;
 | 
				
			||||||
    g.NavDisableMouseHover = true;
 | 
					    g.NavDisableMouseHover = true;
 | 
				
			||||||
@@ -2487,11 +2489,13 @@ static void NavInitWindow(ImGuiWindow* window, bool force_reinit)
 | 
				
			|||||||
static ImVec2 NavCalcPreferredMousePos()
 | 
					static ImVec2 NavCalcPreferredMousePos()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
    if (!g.NavWindow)
 | 
					    ImGuiWindow* window = g.NavWindow;
 | 
				
			||||||
 | 
					    if (!window)
 | 
				
			||||||
        return g.IO.MousePos;
 | 
					        return g.IO.MousePos;
 | 
				
			||||||
    ImVec2 p = g.NavWindow->Pos + ImVec2(g.NavRefRectRel.Min.x + ImMin(g.Style.FramePadding.x*4, g.NavRefRectRel.GetWidth()), g.NavRefRectRel.Max.y - ImMin(g.Style.FramePadding.y, g.NavRefRectRel.GetHeight()));
 | 
					    const ImRect& ref_rect_rel = window->NavRefRectRel[g.NavLayer];
 | 
				
			||||||
    ImRect r = GetVisibleRect();
 | 
					    ImVec2 pos = g.NavWindow->Pos + ImVec2(ref_rect_rel.Min.x + ImMin(g.Style.FramePadding.x*4, ref_rect_rel.GetWidth()), ref_rect_rel.Max.y - ImMin(g.Style.FramePadding.y, ref_rect_rel.GetHeight()));
 | 
				
			||||||
    return ImFloor(ImClamp(p, r.Min, r.Max));   // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta.
 | 
					    ImRect visible_rect = GetVisibleRect();
 | 
				
			||||||
 | 
					    return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max));   // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int FindWindowIndex(ImGuiWindow* window) // FIXME-OPT O(N)
 | 
					static int FindWindowIndex(ImGuiWindow* window) // FIXME-OPT O(N)
 | 
				
			||||||
@@ -2580,7 +2584,7 @@ static void NavUpdate()
 | 
				
			|||||||
        // Apply result from previous navigation init request (typically select the first item, unless SetItemDefaultFocus() has been called)
 | 
					        // Apply result from previous navigation init request (typically select the first item, unless SetItemDefaultFocus() has been called)
 | 
				
			||||||
        IM_ASSERT(g.NavWindow);
 | 
					        IM_ASSERT(g.NavWindow);
 | 
				
			||||||
        SetNavId(g.NavInitDefaultResultId, g.NavLayer);
 | 
					        SetNavId(g.NavInitDefaultResultId, g.NavLayer);
 | 
				
			||||||
        g.NavRefRectRel = g.NavInitDefaultResultRectRel;
 | 
					        g.NavWindow->NavRefRectRel[g.NavLayer] = g.NavInitDefaultResultRectRel;
 | 
				
			||||||
        if (g.NavDisableMouseHover)
 | 
					        if (g.NavDisableMouseHover)
 | 
				
			||||||
            g.NavMousePosDirty = true;
 | 
					            g.NavMousePosDirty = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -2834,21 +2838,22 @@ static void NavUpdate()
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        // When we have manually scrolled and NavId is out of bounds, we clamp its bounding box (used for search) to the visible area to restart navigation within visible items
 | 
					        // When we have manually scrolled and NavId is out of bounds, we clamp its bounding box (used for search) to the visible area to restart navigation within visible items
 | 
				
			||||||
        ImRect window_rect_rel(g.NavWindow->InnerRect.Min - g.NavWindow->Pos - ImVec2(1,1), g.NavWindow->InnerRect.Max - g.NavWindow->Pos + ImVec2(1,1));
 | 
					        ImRect window_rect_rel(g.NavWindow->InnerRect.Min - g.NavWindow->Pos - ImVec2(1,1), g.NavWindow->InnerRect.Max - g.NavWindow->Pos + ImVec2(1,1));
 | 
				
			||||||
        if (!window_rect_rel.Contains(g.NavRefRectRel))
 | 
					        if (!window_rect_rel.Contains(g.NavWindow->NavRefRectRel[g.NavLayer]))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            float pad = g.NavWindow->CalcFontSize() * 0.5f;
 | 
					            float pad = g.NavWindow->CalcFontSize() * 0.5f;
 | 
				
			||||||
            window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intend of starting navigation from first fully visible item
 | 
					            window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intend of starting navigation from first fully visible item
 | 
				
			||||||
            g.NavRefRectRel.ClipWith(window_rect_rel);
 | 
					            g.NavWindow->NavRefRectRel[g.NavLayer].ClipWith(window_rect_rel);
 | 
				
			||||||
            g.NavId = 0;
 | 
					            g.NavId = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        g.NavMoveFromClampedRefRect = false;
 | 
					        g.NavMoveFromClampedRefRect = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 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)
 | 
					    // 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.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + g.NavRefRectRel.Min, g.NavWindow->Pos + g.NavRefRectRel.Max) : ImRect();
 | 
					    g.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + g.NavWindow->NavRefRectRel[g.NavLayer].Min, g.NavWindow->Pos + g.NavWindow->NavRefRectRel[g.NavLayer].Max) : ImRect();
 | 
				
			||||||
    g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x);
 | 
					    g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x);
 | 
				
			||||||
    g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x;
 | 
					    g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x;
 | 
				
			||||||
    //g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG]
 | 
					    //g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG]
 | 
				
			||||||
 | 
					    //if (g.NavWindow) for (int layer = 0; layer < 2; layer++) g.OverlayDrawList.AddRect(g.NavWindow->Pos + g.NavWindow->NavRefRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRefRectRel[layer].Max, IM_COL32(255,200,0,255)); // [DEBUG]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ImGui::NewFrame()
 | 
					void ImGui::NewFrame()
 | 
				
			||||||
@@ -5509,7 +5514,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
 | 
				
			|||||||
        g.NavLayer = 0;
 | 
					        g.NavLayer = 0;
 | 
				
			||||||
        if (window && g.NavDisableMouseHover)
 | 
					        if (window && g.NavDisableMouseHover)
 | 
				
			||||||
            g.NavMousePosDirty = true;
 | 
					            g.NavMousePosDirty = true;
 | 
				
			||||||
        g.NavRefRectRel.Min = g.NavRefRectRel.Max = window ? (window->DC.CursorStartPos - window->Pos) : ImVec2(0,0);
 | 
					        window->NavRefRectRel[0].Min = window->NavRefRectRel[1].Max = window ? (window->DC.CursorStartPos - window->Pos) : ImVec2(0,0);
 | 
				
			||||||
        g.NavWindow = window;
 | 
					        g.NavWindow = window;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11622,6 +11627,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
 | 
				
			|||||||
                ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y);
 | 
					                ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y);
 | 
				
			||||||
                ImGui::BulletText("Active: %d, Accessed: %d", window->Active, window->Accessed);
 | 
					                ImGui::BulletText("Active: %d, Accessed: %d", window->Active, window->Accessed);
 | 
				
			||||||
                ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
 | 
					                ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
 | 
				
			||||||
 | 
					                ImGui::BulletText("NavRefRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRefRectRel[0].Min.x, window->NavRefRectRel[0].Min.y, window->NavRefRectRel[0].Max.x, window->NavRefRectRel[0].Max.y);
 | 
				
			||||||
                if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow");
 | 
					                if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow");
 | 
				
			||||||
                if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows");
 | 
					                if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows");
 | 
				
			||||||
                ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair));
 | 
					                ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair));
 | 
				
			||||||
@@ -11655,7 +11661,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
 | 
				
			|||||||
            ImGui::Text("ActiveId: 0x%08X/0x%08X, ActiveIdSource: %s", g.ActiveId, g.ActiveIdPreviousFrame, input_source_names[g.ActiveIdSource]);
 | 
					            ImGui::Text("ActiveId: 0x%08X/0x%08X, ActiveIdSource: %s", g.ActiveId, g.ActiveIdPreviousFrame, input_source_names[g.ActiveIdSource]);
 | 
				
			||||||
            ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
 | 
					            ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
 | 
				
			||||||
            ImGui::Text("NavWindow: '%s', NavId: 0x%08X, NavLayer: %d", g.NavWindow ? g.NavWindow->Name : "NULL", g.NavId, g.NavLayer);
 | 
					            ImGui::Text("NavWindow: '%s', NavId: 0x%08X, NavLayer: %d", g.NavWindow ? g.NavWindow->Name : "NULL", g.NavId, g.NavLayer);
 | 
				
			||||||
            ImGui::Text("NavRefRectRel: (%.1f,%.1f)(%.1f,%.1f)", g.NavRefRectRel.Min.x, g.NavRefRectRel.Min.y, g.NavRefRectRel.Max.x, g.NavRefRectRel.Max.y);
 | 
					 | 
				
			||||||
            ImGui::Text("NavUsable: %d, NavActive: %d", g.IO.NavUsable, g.IO.NavActive);
 | 
					            ImGui::Text("NavUsable: %d, NavActive: %d", g.IO.NavUsable, g.IO.NavActive);
 | 
				
			||||||
            ImGui::Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId);
 | 
					            ImGui::Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId);
 | 
				
			||||||
            ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover);
 | 
					            ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -459,7 +459,7 @@ struct ImGuiContext
 | 
				
			|||||||
    ImGuiID                 NavId;                              // Nav/focused item for navigation
 | 
					    ImGuiID                 NavId;                              // Nav/focused item for navigation
 | 
				
			||||||
    ImGuiID                 NavActivateId, NavInputId;          // ~~ IsKeyPressedMap(ImGuiKey_NavActive) ? NavId : 0, etc. (to make widget code terser)
 | 
					    ImGuiID                 NavActivateId, NavInputId;          // ~~ IsKeyPressedMap(ImGuiKey_NavActive) ? NavId : 0, etc. (to make widget code terser)
 | 
				
			||||||
    ImGuiID                 NavTabbedId;                        // 
 | 
					    ImGuiID                 NavTabbedId;                        // 
 | 
				
			||||||
    ImRect                  NavRefRectRel, NavScoringRectScreen;// Reference rectangle, in window space. Modified rectangle for directional navigation scoring, in screen space.
 | 
					    ImRect                  NavScoringRectScreen;               // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring.
 | 
				
			||||||
    ImGuiWindow*            NavWindowingTarget;
 | 
					    ImGuiWindow*            NavWindowingTarget;
 | 
				
			||||||
    float                   NavWindowingDisplayAlpha;
 | 
					    float                   NavWindowingDisplayAlpha;
 | 
				
			||||||
    bool                    NavWindowingToggleLayer;
 | 
					    bool                    NavWindowingToggleLayer;
 | 
				
			||||||
@@ -571,7 +571,7 @@ struct ImGuiContext
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        NavWindow = NULL;
 | 
					        NavWindow = NULL;
 | 
				
			||||||
        NavId = NavActivateId = NavInputId = NavTabbedId = 0;
 | 
					        NavId = NavActivateId = NavInputId = NavTabbedId = 0;
 | 
				
			||||||
        NavRefRectRel = NavScoringRectScreen = ImRect();
 | 
					        NavScoringRectScreen = ImRect();
 | 
				
			||||||
        NavWindowingTarget = NULL;
 | 
					        NavWindowingTarget = NULL;
 | 
				
			||||||
        NavWindowingDisplayAlpha = 0.0f;
 | 
					        NavWindowingDisplayAlpha = 0.0f;
 | 
				
			||||||
        NavWindowingToggleLayer = false;
 | 
					        NavWindowingToggleLayer = false;
 | 
				
			||||||
@@ -775,7 +775,8 @@ struct IMGUI_API ImGuiWindow
 | 
				
			|||||||
    ImVec2                  SetWindowPosVal;                    // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
 | 
					    ImVec2                  SetWindowPosVal;                    // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
 | 
				
			||||||
    ImVec2                  SetWindowPosPivot;                  // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right.
 | 
					    ImVec2                  SetWindowPosPivot;                  // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ImGuiID                 NavLastIds[2];                       // Last known NavId for this window, per layer (0/1)
 | 
					    ImGuiID                 NavLastIds[2];                      // Last known NavId for this window, per layer (0/1)
 | 
				
			||||||
 | 
					    ImRect                  NavRefRectRel[2];                   // Reference rectangle, in window space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ImGuiDrawContext        DC;                                 // Temporary per-window data, reset at the beginning of the frame
 | 
					    ImGuiDrawContext        DC;                                 // Temporary per-window data, reset at the beginning of the frame
 | 
				
			||||||
    ImVector<ImGuiID>       IDStack;                            // ID stack. ID are hashes seeded with the value at the top of the stack
 | 
					    ImVector<ImGuiID>       IDStack;                            // ID stack. ID are hashes seeded with the value at the top of the stack
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user