mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-03 22:51:06 +01:00 
			
		
		
		
	Refactor: Internals: Moved Navigation functions in imgui.cpp in their own section. (part 7) (#2036, #787)
This commit is contained in:
		
							
								
								
									
										221
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										221
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -2761,44 +2761,6 @@ static ImGuiWindow* FindWindowNavFocusable(int i_start, int i_stop, int dir) //
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    if (mode == ImGuiInputReadMode_Down)
 | 
			
		||||
        return g.IO.NavInputs[n];                         // Instant, read analog input (0.0f..1.0f, as provided by user)
 | 
			
		||||
 | 
			
		||||
    const float t = g.IO.NavInputsDownDuration[n];
 | 
			
		||||
    if (t < 0.0f && mode == ImGuiInputReadMode_Released)  // Return 1.0f when just released, no repeat, ignore analog input.
 | 
			
		||||
        return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f);
 | 
			
		||||
    if (t < 0.0f)
 | 
			
		||||
        return 0.0f;
 | 
			
		||||
    if (mode == ImGuiInputReadMode_Pressed)               // Return 1.0f when just pressed, no repeat, ignore analog input.
 | 
			
		||||
        return (t == 0.0f) ? 1.0f : 0.0f;
 | 
			
		||||
    if (mode == ImGuiInputReadMode_Repeat)
 | 
			
		||||
        return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.80f);
 | 
			
		||||
    if (mode == ImGuiInputReadMode_RepeatSlow)
 | 
			
		||||
        return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 1.00f, g.IO.KeyRepeatRate * 2.00f);
 | 
			
		||||
    if (mode == ImGuiInputReadMode_RepeatFast)
 | 
			
		||||
        return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.30f);
 | 
			
		||||
    return 0.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor, float fast_factor)
 | 
			
		||||
{
 | 
			
		||||
    ImVec2 delta(0.0f, 0.0f);
 | 
			
		||||
    if (dir_sources & ImGuiNavDirSourceFlags_Keyboard)
 | 
			
		||||
        delta += ImVec2(GetNavInputAmount(ImGuiNavInput_KeyRight_, mode)   - GetNavInputAmount(ImGuiNavInput_KeyLeft_,   mode), GetNavInputAmount(ImGuiNavInput_KeyDown_,   mode) - GetNavInputAmount(ImGuiNavInput_KeyUp_,   mode));
 | 
			
		||||
    if (dir_sources & ImGuiNavDirSourceFlags_PadDPad)
 | 
			
		||||
        delta += ImVec2(GetNavInputAmount(ImGuiNavInput_DpadRight, mode)   - GetNavInputAmount(ImGuiNavInput_DpadLeft,   mode), GetNavInputAmount(ImGuiNavInput_DpadDown,   mode) - GetNavInputAmount(ImGuiNavInput_DpadUp,   mode));
 | 
			
		||||
    if (dir_sources & ImGuiNavDirSourceFlags_PadLStick)
 | 
			
		||||
        delta += ImVec2(GetNavInputAmount(ImGuiNavInput_LStickRight, mode) - GetNavInputAmount(ImGuiNavInput_LStickLeft, mode), GetNavInputAmount(ImGuiNavInput_LStickDown, mode) - GetNavInputAmount(ImGuiNavInput_LStickUp, mode));
 | 
			
		||||
    if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakSlow))
 | 
			
		||||
        delta *= slow_factor;
 | 
			
		||||
    if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakFast))
 | 
			
		||||
        delta *= fast_factor;
 | 
			
		||||
    return delta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
@@ -2936,7 +2898,6 @@ static void ImGui::NavUpdateWindowing()
 | 
			
		||||
        ImGuiWindow* new_nav_window = g.NavWindow;
 | 
			
		||||
        while ((new_nav_window->DC.NavLayerActiveMask & (1 << 1)) == 0 && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
 | 
			
		||||
            new_nav_window = new_nav_window->ParentWindow;
 | 
			
		||||
 | 
			
		||||
        if (new_nav_window != g.NavWindow)
 | 
			
		||||
        {
 | 
			
		||||
            ImGuiWindow* old_nav_window = g.NavWindow;
 | 
			
		||||
@@ -2949,78 +2910,6 @@ static void ImGui::NavUpdateWindowing()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Window has already passed the IsWindowNavFocusable()
 | 
			
		||||
static const char* GetFallbackWindowNameForWindowingList(ImGuiWindow* window)
 | 
			
		||||
{
 | 
			
		||||
    if (window->Flags & ImGuiWindowFlags_Popup)
 | 
			
		||||
        return "(Popup)";
 | 
			
		||||
    if ((window->Flags & ImGuiWindowFlags_MenuBar) && strcmp(window->Name, "##MainMenuBar") == 0)
 | 
			
		||||
        return "(Main menu bar)";
 | 
			
		||||
    return "(Untitled)";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Overlay displayed when using CTRL+TAB. Called by EndFrame().
 | 
			
		||||
void ImGui::NavUpdateWindowingList()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    IM_ASSERT(g.NavWindowingTarget != NULL);
 | 
			
		||||
 | 
			
		||||
    if (g.NavWindowingTimer < NAV_WINDOWING_LIST_APPEAR_DELAY)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (g.NavWindowingList == NULL)
 | 
			
		||||
        g.NavWindowingList = FindWindowByName("###NavWindowingList");
 | 
			
		||||
    ImGuiViewportP* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ (ImGuiViewportP*)GetMainViewport();
 | 
			
		||||
    SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX));
 | 
			
		||||
    SetNextWindowPos(viewport->Pos + viewport->Size * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
 | 
			
		||||
    PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f);
 | 
			
		||||
    Begin("###NavWindowingList", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings);
 | 
			
		||||
    for (int n = g.Windows.Size - 1; n >= 0; n--)
 | 
			
		||||
    {
 | 
			
		||||
        ImGuiWindow* window = g.Windows[n];
 | 
			
		||||
        if (!IsWindowNavFocusable(window))
 | 
			
		||||
            continue;
 | 
			
		||||
        const char* label = window->Name;
 | 
			
		||||
        if (label == FindRenderedTextEnd(label))
 | 
			
		||||
            label = GetFallbackWindowNameForWindowingList(window);
 | 
			
		||||
        Selectable(label, g.NavWindowingTarget == window);
 | 
			
		||||
    }
 | 
			
		||||
    End();
 | 
			
		||||
    PopStyleVar();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Scroll to keep newly navigated item fully into view
 | 
			
		||||
// NB: We modify rect_rel by the amount we scrolled for, so it is immediately updated.
 | 
			
		||||
static void NavScrollToBringItemIntoView(ImGuiWindow* window, const ImRect& item_rect)
 | 
			
		||||
{
 | 
			
		||||
    ImRect window_rect(window->InnerMainRect.Min - ImVec2(1, 1), window->InnerMainRect.Max + ImVec2(1, 1));
 | 
			
		||||
    //GetOverlayDrawList(window)->AddRect(window_rect_rel.Min, window_rect_rel.Max, IM_COL32_WHITE); // [DEBUG]
 | 
			
		||||
    if (window_rect.Contains(item_rect))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    if (window->ScrollbarX && item_rect.Min.x < window_rect.Min.x)
 | 
			
		||||
    {
 | 
			
		||||
        window->ScrollTarget.x = item_rect.Min.x - window->Pos.x + window->Scroll.x - g.Style.ItemSpacing.x;
 | 
			
		||||
        window->ScrollTargetCenterRatio.x = 0.0f;
 | 
			
		||||
    }
 | 
			
		||||
    else if (window->ScrollbarX && item_rect.Max.x >= window_rect.Max.x)
 | 
			
		||||
    {
 | 
			
		||||
        window->ScrollTarget.x = item_rect.Max.x - window->Pos.x + window->Scroll.x + g.Style.ItemSpacing.x;
 | 
			
		||||
        window->ScrollTargetCenterRatio.x = 1.0f;
 | 
			
		||||
    }
 | 
			
		||||
    if (item_rect.Min.y < window_rect.Min.y)
 | 
			
		||||
    {
 | 
			
		||||
        window->ScrollTarget.y = item_rect.Min.y - window->Pos.y + window->Scroll.y - g.Style.ItemSpacing.y;
 | 
			
		||||
        window->ScrollTargetCenterRatio.y = 0.0f;
 | 
			
		||||
    }
 | 
			
		||||
    else if (item_rect.Max.y >= window_rect.Max.y)
 | 
			
		||||
    {
 | 
			
		||||
        window->ScrollTarget.y = item_rect.Max.y - window->Pos.y + window->Scroll.y + g.Style.ItemSpacing.y;
 | 
			
		||||
        window->ScrollTargetCenterRatio.y = 1.0f;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport)
 | 
			
		||||
{
 | 
			
		||||
    window->Viewport = viewport;
 | 
			
		||||
@@ -8517,6 +8406,76 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags mov
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    if (mode == ImGuiInputReadMode_Down)
 | 
			
		||||
        return g.IO.NavInputs[n];                         // Instant, read analog input (0.0f..1.0f, as provided by user)
 | 
			
		||||
 | 
			
		||||
    const float t = g.IO.NavInputsDownDuration[n];
 | 
			
		||||
    if (t < 0.0f && mode == ImGuiInputReadMode_Released)  // Return 1.0f when just released, no repeat, ignore analog input.
 | 
			
		||||
        return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f);
 | 
			
		||||
    if (t < 0.0f)
 | 
			
		||||
        return 0.0f;
 | 
			
		||||
    if (mode == ImGuiInputReadMode_Pressed)               // Return 1.0f when just pressed, no repeat, ignore analog input.
 | 
			
		||||
        return (t == 0.0f) ? 1.0f : 0.0f;
 | 
			
		||||
    if (mode == ImGuiInputReadMode_Repeat)
 | 
			
		||||
        return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.80f);
 | 
			
		||||
    if (mode == ImGuiInputReadMode_RepeatSlow)
 | 
			
		||||
        return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 1.00f, g.IO.KeyRepeatRate * 2.00f);
 | 
			
		||||
    if (mode == ImGuiInputReadMode_RepeatFast)
 | 
			
		||||
        return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.30f);
 | 
			
		||||
    return 0.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor, float fast_factor)
 | 
			
		||||
{
 | 
			
		||||
    ImVec2 delta(0.0f, 0.0f);
 | 
			
		||||
    if (dir_sources & ImGuiNavDirSourceFlags_Keyboard)
 | 
			
		||||
        delta += ImVec2(GetNavInputAmount(ImGuiNavInput_KeyRight_, mode)   - GetNavInputAmount(ImGuiNavInput_KeyLeft_,   mode), GetNavInputAmount(ImGuiNavInput_KeyDown_,   mode) - GetNavInputAmount(ImGuiNavInput_KeyUp_,   mode));
 | 
			
		||||
    if (dir_sources & ImGuiNavDirSourceFlags_PadDPad)
 | 
			
		||||
        delta += ImVec2(GetNavInputAmount(ImGuiNavInput_DpadRight, mode)   - GetNavInputAmount(ImGuiNavInput_DpadLeft,   mode), GetNavInputAmount(ImGuiNavInput_DpadDown,   mode) - GetNavInputAmount(ImGuiNavInput_DpadUp,   mode));
 | 
			
		||||
    if (dir_sources & ImGuiNavDirSourceFlags_PadLStick)
 | 
			
		||||
        delta += ImVec2(GetNavInputAmount(ImGuiNavInput_LStickRight, mode) - GetNavInputAmount(ImGuiNavInput_LStickLeft, mode), GetNavInputAmount(ImGuiNavInput_LStickDown, mode) - GetNavInputAmount(ImGuiNavInput_LStickUp, mode));
 | 
			
		||||
    if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakSlow))
 | 
			
		||||
        delta *= slow_factor;
 | 
			
		||||
    if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakFast))
 | 
			
		||||
        delta *= fast_factor;
 | 
			
		||||
    return delta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Scroll to keep newly navigated item fully into view
 | 
			
		||||
// NB: We modify rect_rel by the amount we scrolled for, so it is immediately updated.
 | 
			
		||||
static void NavScrollToBringItemIntoView(ImGuiWindow* window, const ImRect& item_rect)
 | 
			
		||||
{
 | 
			
		||||
    ImRect window_rect(window->InnerMainRect.Min - ImVec2(1, 1), window->InnerMainRect.Max + ImVec2(1, 1));
 | 
			
		||||
    //GetOverlayDrawList(window)->AddRect(window_rect_rel.Min, window_rect_rel.Max, IM_COL32_WHITE); // [DEBUG]
 | 
			
		||||
    if (window_rect.Contains(item_rect))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    if (window->ScrollbarX && item_rect.Min.x < window_rect.Min.x)
 | 
			
		||||
    {
 | 
			
		||||
        window->ScrollTarget.x = item_rect.Min.x - window->Pos.x + window->Scroll.x - g.Style.ItemSpacing.x;
 | 
			
		||||
        window->ScrollTargetCenterRatio.x = 0.0f;
 | 
			
		||||
    }
 | 
			
		||||
    else if (window->ScrollbarX && item_rect.Max.x >= window_rect.Max.x)
 | 
			
		||||
    {
 | 
			
		||||
        window->ScrollTarget.x = item_rect.Max.x - window->Pos.x + window->Scroll.x + g.Style.ItemSpacing.x;
 | 
			
		||||
        window->ScrollTargetCenterRatio.x = 1.0f;
 | 
			
		||||
    }
 | 
			
		||||
    if (item_rect.Min.y < window_rect.Min.y)
 | 
			
		||||
    {
 | 
			
		||||
        window->ScrollTarget.y = item_rect.Min.y - window->Pos.y + window->Scroll.y - g.Style.ItemSpacing.y;
 | 
			
		||||
        window->ScrollTargetCenterRatio.y = 0.0f;
 | 
			
		||||
    }
 | 
			
		||||
    else if (item_rect.Max.y >= window_rect.Max.y)
 | 
			
		||||
    {
 | 
			
		||||
        window->ScrollTarget.y = item_rect.Max.y - window->Pos.y + window->Scroll.y + g.Style.ItemSpacing.y;
 | 
			
		||||
        window->ScrollTargetCenterRatio.y = 1.0f;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ImGui::NavUpdate()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
@@ -8869,6 +8828,46 @@ static float ImGui::NavUpdatePageUpPageDown(int allowed_dir_flags)
 | 
			
		||||
    return 0.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Window has already passed the IsWindowNavFocusable()
 | 
			
		||||
static const char* GetFallbackWindowNameForWindowingList(ImGuiWindow* window)
 | 
			
		||||
{
 | 
			
		||||
    if (window->Flags & ImGuiWindowFlags_Popup)
 | 
			
		||||
        return "(Popup)";
 | 
			
		||||
    if ((window->Flags & ImGuiWindowFlags_MenuBar) && strcmp(window->Name, "##MainMenuBar") == 0)
 | 
			
		||||
        return "(Main menu bar)";
 | 
			
		||||
    return "(Untitled)";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Overlay displayed when using CTRL+TAB. Called by EndFrame().
 | 
			
		||||
void ImGui::NavUpdateWindowingList()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    IM_ASSERT(g.NavWindowingTarget != NULL);
 | 
			
		||||
 | 
			
		||||
    if (g.NavWindowingTimer < NAV_WINDOWING_LIST_APPEAR_DELAY)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (g.NavWindowingList == NULL)
 | 
			
		||||
        g.NavWindowingList = FindWindowByName("###NavWindowingList");
 | 
			
		||||
    ImGuiViewportP* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ (ImGuiViewportP*)GetMainViewport();
 | 
			
		||||
    SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX));
 | 
			
		||||
    SetNextWindowPos(viewport->Pos + viewport->Size * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
 | 
			
		||||
    PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f);
 | 
			
		||||
    Begin("###NavWindowingList", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings);
 | 
			
		||||
    for (int n = g.Windows.Size - 1; n >= 0; n--)
 | 
			
		||||
    {
 | 
			
		||||
        ImGuiWindow* window = g.Windows[n];
 | 
			
		||||
        if (!IsWindowNavFocusable(window))
 | 
			
		||||
            continue;
 | 
			
		||||
        const char* label = window->Name;
 | 
			
		||||
        if (label == FindRenderedTextEnd(label))
 | 
			
		||||
            label = GetFallbackWindowNameForWindowingList(window);
 | 
			
		||||
        Selectable(label, g.NavWindowingTarget == window);
 | 
			
		||||
    }
 | 
			
		||||
    End();
 | 
			
		||||
    PopStyleVar();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// COLUMNS
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user