mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-04 01:34:32 +00:00 
			
		
		
		
	Nav: Moving all nav inputs to io.NavInputs[] float array, new enum labelled for gamepad. (#323)
This commit is contained in:
		
							
								
								
									
										188
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										188
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -873,10 +873,9 @@ ImGuiIO::ImGuiIO()
 | 
			
		||||
    MousePos = ImVec2(-1,-1);
 | 
			
		||||
    MousePosPrev = ImVec2(-1,-1);
 | 
			
		||||
    MouseDragThreshold = 6.0f;
 | 
			
		||||
    for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++)
 | 
			
		||||
        MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
 | 
			
		||||
    for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++)
 | 
			
		||||
        KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f;
 | 
			
		||||
    for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
 | 
			
		||||
    for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) KeysDownDuration[i]  = KeysDownDurationPrev[i] = -1.0f;
 | 
			
		||||
    for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f;
 | 
			
		||||
 | 
			
		||||
    // Set OS X style defaults based on __APPLE__ compile time flag
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
@@ -2378,6 +2377,60 @@ static ImGuiWindow* FindWindowNavigable(int i_start, int i_stop, int dir) // FIX
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum ImGuiNavReadMode
 | 
			
		||||
{
 | 
			
		||||
    ImGuiNavReadMode_Down,
 | 
			
		||||
    ImGuiNavReadMode_Pressed,
 | 
			
		||||
    ImGuiNavReadMode_Repeat,
 | 
			
		||||
    ImGuiNavReadMode_RepeatSlow,
 | 
			
		||||
    ImGuiNavReadMode_RepeatFast
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// FIXME-NAVIGATION: Expose navigation repeat delay/rate
 | 
			
		||||
static float GetNavInputAmount(ImGuiNavInput n, ImGuiNavReadMode mode)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    if (mode == ImGuiNavReadMode_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];  // Duration pressed
 | 
			
		||||
    if (mode == ImGuiNavReadMode_Pressed)           // Return 1.0f when just pressed, no repeat, ignore analog input (we don't need it for Pressed logic)
 | 
			
		||||
        return (t == 0.0f) ? 1.0f : 0.0f;
 | 
			
		||||
    if (mode == ImGuiNavReadMode_Repeat)
 | 
			
		||||
        return (float)ImGui::CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.80f);
 | 
			
		||||
    if (mode == ImGuiNavReadMode_RepeatSlow)
 | 
			
		||||
        return (float)ImGui::CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 1.00f, g.IO.KeyRepeatRate * 2.00f);
 | 
			
		||||
    if (mode == ImGuiNavReadMode_RepeatFast)
 | 
			
		||||
        return (float)ImGui::CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.30f);
 | 
			
		||||
    return 0.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equivalent of IsKeyDown() for NavInputs[]
 | 
			
		||||
static bool IsNavInputDown(ImGuiNavInput n)
 | 
			
		||||
{
 | 
			
		||||
    return GImGui->IO.NavInputs[n] > 0.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equivalent of IsKeyPressed() for NavInputs[]
 | 
			
		||||
static bool IsNavInputPressed(ImGuiNavInput n, ImGuiNavReadMode mode)// = ImGuiNavReadMode_Re)
 | 
			
		||||
{
 | 
			
		||||
    return GetNavInputAmount(n, mode) > 0.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ImVec2 GetNavInputAmount2d(int stick_no, ImGuiNavReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f)
 | 
			
		||||
{
 | 
			
		||||
    IM_ASSERT(ImGuiNavInput_PadScrollUp == ImGuiNavInput_PadUp + 4);
 | 
			
		||||
    IM_ASSERT(stick_no >= 0 && stick_no < 2);
 | 
			
		||||
 | 
			
		||||
    ImVec2 delta;
 | 
			
		||||
    delta.x = GetNavInputAmount(ImGuiNavInput_PadRight + stick_no*4, mode) - GetNavInputAmount(ImGuiNavInput_PadLeft + stick_no*4, mode); 
 | 
			
		||||
    delta.y = GetNavInputAmount(ImGuiNavInput_PadDown  + stick_no*4, mode) - GetNavInputAmount(ImGuiNavInput_PadUp   + stick_no*4, mode); 
 | 
			
		||||
    if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_PadTweakSlow))
 | 
			
		||||
        delta *= slow_factor;
 | 
			
		||||
    if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_PadTweakFast))
 | 
			
		||||
        delta *= fast_factor;
 | 
			
		||||
    return delta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void NavUpdate()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
@@ -2452,7 +2505,7 @@ static void NavUpdate()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Navigation windowing mode (change focus, move/resize window)
 | 
			
		||||
    if (!g.NavWindowingTarget && IsKeyPressedMap(ImGuiKey_NavMenu, false))
 | 
			
		||||
    if (!g.NavWindowingTarget && IsNavInputPressed(ImGuiNavInput_PadMenu, ImGuiNavReadMode_Pressed))
 | 
			
		||||
    {
 | 
			
		||||
        ImGuiWindow* window = g.NavWindow;
 | 
			
		||||
        if (!window)
 | 
			
		||||
@@ -2467,13 +2520,13 @@ static void NavUpdate()
 | 
			
		||||
    if (g.NavWindowingTarget)
 | 
			
		||||
    {
 | 
			
		||||
        // Visuals only appears after a brief time holding the button, so that a fast tap (to toggle NavLayer) doesn't add visual noise
 | 
			
		||||
        const float pressed_duration = g.IO.KeysDownDuration[g.IO.KeyMap[ImGuiKey_NavMenu]];
 | 
			
		||||
        const float pressed_duration = g.IO.NavInputsDownDuration[ImGuiNavInput_PadMenu];
 | 
			
		||||
        g.NavWindowingDisplayAlpha = ImMax(g.NavWindowingDisplayAlpha, ImSaturate((pressed_duration - 0.20f) / 0.05f));
 | 
			
		||||
        g.NavWindowingToggleLayer &= (g.NavWindowingDisplayAlpha < 1.0f); // Once button is held long enough we don't consider it a tag-to-toggle-layer press anymore.
 | 
			
		||||
 | 
			
		||||
        // Select window to focus
 | 
			
		||||
        // FIXME-NAVIGATION: Need to clarify input semantic, naming is misleading/incorrect here.
 | 
			
		||||
        int focus_change_dir = IsKeyPressedMap(ImGuiKey_NavTweakFaster, true) ? -1 : IsKeyPressedMap(ImGuiKey_NavTweakSlower, true) ? +1 : 0;
 | 
			
		||||
        const int focus_change_dir = (int)IsNavInputPressed(ImGuiNavInput_PadFocusPrev, ImGuiNavReadMode_RepeatSlow) - (int)IsNavInputPressed(ImGuiNavInput_PadFocusNext, ImGuiNavReadMode_RepeatSlow);
 | 
			
		||||
        if (focus_change_dir != 0 && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal))
 | 
			
		||||
        {
 | 
			
		||||
            const int i_current = FindWindowIndex(g.NavWindowingTarget);
 | 
			
		||||
@@ -2488,7 +2541,7 @@ static void NavUpdate()
 | 
			
		||||
        // Move window
 | 
			
		||||
        if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
 | 
			
		||||
        {
 | 
			
		||||
            const ImVec2 move_delta = ImGui::NavGetMovingDir(1);
 | 
			
		||||
            const ImVec2 move_delta = GetNavInputAmount2d(1, ImGuiNavReadMode_Down);
 | 
			
		||||
            if (move_delta.x != 0.0f || move_delta.y != 0.0f)
 | 
			
		||||
            {
 | 
			
		||||
                const float move_speed = ImFloor(600 * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
 | 
			
		||||
@@ -2498,7 +2551,7 @@ static void NavUpdate()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!IsKeyDownMap(ImGuiKey_NavMenu))
 | 
			
		||||
        if (!IsNavInputDown(ImGuiNavInput_PadMenu))
 | 
			
		||||
        {
 | 
			
		||||
            // Apply actual focus only when releasing the NavMenu button (until then the window was merely rendered front-most)
 | 
			
		||||
            if (g.NavWindowingTarget && !g.NavWindowingToggleLayer && (!g.NavWindow || g.NavWindowingTarget != g.NavWindow->RootNonPopupWindow))
 | 
			
		||||
@@ -2532,7 +2585,7 @@ static void NavUpdate()
 | 
			
		||||
    g.IO.NavActive = (g.IO.NavUsable && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL) || g.NavInitDefaultRequest;
 | 
			
		||||
 | 
			
		||||
    // Process NavCancel input (to close a popup, get back to parent, clear focus)
 | 
			
		||||
    if (IsKeyPressedMap(ImGuiKey_NavCancel))
 | 
			
		||||
    if (IsNavInputPressed(ImGuiNavInput_PadCancel, ImGuiNavReadMode_Pressed))
 | 
			
		||||
    {
 | 
			
		||||
        if (g.ActiveId != 0)
 | 
			
		||||
        {
 | 
			
		||||
@@ -2577,8 +2630,8 @@ static void NavUpdate()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g.NavActivateId = (g.NavId && !g.NavDisableHighlight && !g.NavWindowingTarget && g.ActiveId == 0 && IsKeyPressedMap(ImGuiKey_NavActivate)) ? g.NavId : 0;
 | 
			
		||||
    g.NavInputId = (g.NavId && !g.NavDisableHighlight && !g.NavWindowingTarget && g.ActiveId == 0 && IsKeyPressedMap(ImGuiKey_NavInput)) ? g.NavId : 0;
 | 
			
		||||
    g.NavActivateId = (g.NavId && !g.NavDisableHighlight && !g.NavWindowingTarget && g.ActiveId == 0 && IsNavInputPressed(ImGuiNavInput_PadActivate, ImGuiNavReadMode_Repeat)) ? g.NavId : 0;
 | 
			
		||||
    g.NavInputId = (g.NavId && !g.NavDisableHighlight && !g.NavWindowingTarget && g.ActiveId == 0 && IsNavInputPressed(ImGuiNavInput_PadInput, ImGuiNavReadMode_Repeat)) ? g.NavId : 0;
 | 
			
		||||
    if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
 | 
			
		||||
    {
 | 
			
		||||
        g.NavActivateId = g.NavInputId = 0;
 | 
			
		||||
@@ -2591,10 +2644,10 @@ static void NavUpdate()
 | 
			
		||||
    g.NavMoveDir = ImGuiNavDir_None;
 | 
			
		||||
    if (g.NavWindow && !g.NavWindowingTarget && allowed_dir_flags && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
 | 
			
		||||
    {
 | 
			
		||||
        if ((allowed_dir_flags & (1<<ImGuiNavDir_Left))  && IsKeyPressedMap(ImGuiKey_NavLeft,  true)) g.NavMoveDir = ImGuiNavDir_Left;
 | 
			
		||||
        if ((allowed_dir_flags & (1<<ImGuiNavDir_Right)) && IsKeyPressedMap(ImGuiKey_NavRight, true)) g.NavMoveDir = ImGuiNavDir_Right;
 | 
			
		||||
        if ((allowed_dir_flags & (1<<ImGuiNavDir_Up))    && IsKeyPressedMap(ImGuiKey_NavUp,    true)) g.NavMoveDir = ImGuiNavDir_Up;
 | 
			
		||||
        if ((allowed_dir_flags & (1<<ImGuiNavDir_Down))  && IsKeyPressedMap(ImGuiKey_NavDown,  true)) g.NavMoveDir = ImGuiNavDir_Down;
 | 
			
		||||
        if ((allowed_dir_flags & (1<<ImGuiNavDir_Left))  && IsNavInputPressed(ImGuiNavInput_PadLeft,  ImGuiNavReadMode_Repeat)) g.NavMoveDir = ImGuiNavDir_Left;
 | 
			
		||||
        if ((allowed_dir_flags & (1<<ImGuiNavDir_Right)) && IsNavInputPressed(ImGuiNavInput_PadRight, ImGuiNavReadMode_Repeat)) g.NavMoveDir = ImGuiNavDir_Right;
 | 
			
		||||
        if ((allowed_dir_flags & (1<<ImGuiNavDir_Up))    && IsNavInputPressed(ImGuiNavInput_PadUp,    ImGuiNavReadMode_Repeat)) g.NavMoveDir = ImGuiNavDir_Up;
 | 
			
		||||
        if ((allowed_dir_flags & (1<<ImGuiNavDir_Down))  && IsNavInputPressed(ImGuiNavInput_PadDown,  ImGuiNavReadMode_Repeat)) g.NavMoveDir = ImGuiNavDir_Down;
 | 
			
		||||
    }
 | 
			
		||||
    if (g.NavMoveDir != ImGuiNavDir_None)
 | 
			
		||||
        g.NavMoveRequest = true;
 | 
			
		||||
@@ -2608,7 +2661,7 @@ static void NavUpdate()
 | 
			
		||||
            SetWindowScrollY(g.NavWindow, ImFloor(g.NavWindow->Scroll.y + ((g.NavMoveDir == ImGuiNavDir_Up) ? -1.0f : +1.0f) * scroll_speed));
 | 
			
		||||
 | 
			
		||||
        // Manual scroll with NavScrollXXX keys
 | 
			
		||||
        ImVec2 scroll_dir = ImGui::NavGetMovingDir(1, 1.0f/10.0f, 10.0f);
 | 
			
		||||
        ImVec2 scroll_dir = GetNavInputAmount2d(1, ImGuiNavReadMode_Down, 1.0f/10.0f, 10.0f);
 | 
			
		||||
        if (scroll_dir.x != 0.0f && g.NavWindow->ScrollbarX)
 | 
			
		||||
        {
 | 
			
		||||
            SetWindowScrollX(g.NavWindow, ImFloor(g.NavWindow->Scroll.x + scroll_dir.x * scroll_speed));
 | 
			
		||||
@@ -2695,6 +2748,9 @@ void ImGui::NewFrame()
 | 
			
		||||
    memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration));
 | 
			
		||||
    for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++)
 | 
			
		||||
        g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f;
 | 
			
		||||
    memcpy(g.IO.NavInputsPrev, g.IO.NavInputs, sizeof(g.IO.NavInputs));
 | 
			
		||||
    for (int i = 0; i < IM_ARRAYSIZE(g.IO.NavInputs); i++)
 | 
			
		||||
        g.IO.NavInputsDownDuration[i] = (g.IO.NavInputs[i] > 0.0f) ? (g.IO.NavInputsDownDuration[i] < 0.0f ? 0.0f : g.IO.NavInputsDownDuration[i] + g.IO.DeltaTime) : -1.0f;
 | 
			
		||||
 | 
			
		||||
    // Update directional navigation which may override MousePos if 'NavMovesMouse=true'
 | 
			
		||||
    NavUpdate();
 | 
			
		||||
@@ -3708,20 +3764,23 @@ bool ImGui::IsKeyDown(int key_index)
 | 
			
		||||
    return GImGui->IO.KeysDown[key_index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ImGui::CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate)
 | 
			
		||||
{
 | 
			
		||||
    if (t == 0.0f)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if (t <= repeat_delay || repeat_rate <= 0.0f)
 | 
			
		||||
        return 0;
 | 
			
		||||
    const int count = (int)((t - repeat_delay) / repeat_rate) - (int)((t_prev - repeat_delay) / repeat_rate);
 | 
			
		||||
    return (count > 0) ? count : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ImGui::GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    if (key_index < 0) return false;
 | 
			
		||||
    IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown));
 | 
			
		||||
    const float t = g.IO.KeysDownDuration[key_index];
 | 
			
		||||
    if (t == 0.0f)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if (t > repeat_delay && repeat_rate > 0.0f)
 | 
			
		||||
    {
 | 
			
		||||
        int count = (int)((t - repeat_delay) / repeat_rate) - (int)((t - repeat_delay - g.IO.DeltaTime) / repeat_rate);
 | 
			
		||||
        return (count > 0) ? count : 0;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
    return CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, repeat_delay, repeat_rate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ImGui::IsKeyPressed(int key_index, bool repeat)
 | 
			
		||||
@@ -4823,9 +4882,13 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
 | 
			
		||||
                ImVec2 nav_resize_delta(0.0f, 0.0f);
 | 
			
		||||
                if (g.NavWindowingTarget == window)
 | 
			
		||||
                {
 | 
			
		||||
                    const float resize_speed = ImFloor(600 * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
 | 
			
		||||
                    nav_resize_delta = NavGetMovingDir(0) * resize_speed;
 | 
			
		||||
                    held |= (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f); // For coloring
 | 
			
		||||
                    nav_resize_delta = GetNavInputAmount2d(0, ImGuiNavReadMode_Down);
 | 
			
		||||
                    if (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f)
 | 
			
		||||
                    {
 | 
			
		||||
                        nav_resize_delta *= ImFloor(600 * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
 | 
			
		||||
                        g.NavDisableMouseHover = true;
 | 
			
		||||
                        held = true; // For coloring
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ImVec2 size_target(FLT_MAX,FLT_MAX);
 | 
			
		||||
@@ -6267,13 +6330,13 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
 | 
			
		||||
    {
 | 
			
		||||
        // We report navigated item as hovered but we don't set g.HoveredId to not interfere with mouse
 | 
			
		||||
        hovered = true;
 | 
			
		||||
        if (!g.NavWindowingTarget && IsKeyDownMap(ImGuiKey_NavActivate))
 | 
			
		||||
        if (!g.NavWindowingTarget && IsNavInputDown(ImGuiNavInput_PadActivate))
 | 
			
		||||
        {
 | 
			
		||||
            // Set active id so it can be queried by user via IsItemActive(), etc. but don't react to it ourselves
 | 
			
		||||
            g.NavActivateId = g.NavId;
 | 
			
		||||
            SetActiveID(g.NavId, window);
 | 
			
		||||
            g.NavActivateId = id;
 | 
			
		||||
            SetActiveID(id, window);
 | 
			
		||||
            g.ActiveIdAllowNavDirFlags = (1 << ImGuiNavDir_Left) | (1 << ImGuiNavDir_Right) | (1 << ImGuiNavDir_Up) | (1 << ImGuiNavDir_Down);
 | 
			
		||||
            if (IsKeyPressedMap(ImGuiKey_NavActivate, (flags & ImGuiButtonFlags_Repeat) != 0))
 | 
			
		||||
            if (IsNavInputPressed(ImGuiNavInput_PadActivate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiNavReadMode_Repeat : ImGuiNavReadMode_Pressed))
 | 
			
		||||
                pressed = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -6296,7 +6359,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
 | 
			
		||||
            g.NavDisableHighlight = true;
 | 
			
		||||
    }
 | 
			
		||||
    if (g.ActiveId == id && g.ActiveIdSource == ImGuiInputSource_Nav)
 | 
			
		||||
        if (!IsKeyDownMap(ImGuiKey_NavActivate))
 | 
			
		||||
        if (!IsNavInputDown(ImGuiNavInput_PadActivate))
 | 
			
		||||
            SetActiveID(0);
 | 
			
		||||
 | 
			
		||||
    // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one.
 | 
			
		||||
@@ -7136,47 +7199,6 @@ int ImGui::ParseFormatPrecision(const char* fmt, int default_precision)
 | 
			
		||||
    return precision;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ImVec2 ImGui::NavGetMovingDir(int stick_no, float slow_factor, float fast_factor)
 | 
			
		||||
{
 | 
			
		||||
    IM_ASSERT(stick_no >= 0 && stick_no < 2);
 | 
			
		||||
    ImVec2 dir(0.0f, 0.0f);
 | 
			
		||||
    if (stick_no == 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (IsKeyDownMap(ImGuiKey_NavLeft))  dir.x -= 1.0f;
 | 
			
		||||
        if (IsKeyDownMap(ImGuiKey_NavRight)) dir.x += 1.0f;
 | 
			
		||||
        if (IsKeyDownMap(ImGuiKey_NavUp))    dir.y -= 1.0f;
 | 
			
		||||
        if (IsKeyDownMap(ImGuiKey_NavDown))  dir.y += 1.0f;
 | 
			
		||||
    }
 | 
			
		||||
    if (stick_no == 1)
 | 
			
		||||
    {
 | 
			
		||||
        if (IsKeyDownMap(ImGuiKey_NavScrollLeft))  dir.x -= 1.0f;
 | 
			
		||||
        if (IsKeyDownMap(ImGuiKey_NavScrollRight)) dir.x += 1.0f;
 | 
			
		||||
        if (IsKeyDownMap(ImGuiKey_NavScrollUp))    dir.y -= 1.0f;
 | 
			
		||||
        if (IsKeyDownMap(ImGuiKey_NavScrollDown))  dir.y += 1.0f;
 | 
			
		||||
    }
 | 
			
		||||
    if (slow_factor != 0.0f && IsKeyDownMap(ImGuiKey_NavTweakSlower))
 | 
			
		||||
        dir *= slow_factor;
 | 
			
		||||
    if (fast_factor != 0.0f && IsKeyDownMap(ImGuiKey_NavTweakFaster))
 | 
			
		||||
        dir *= fast_factor;
 | 
			
		||||
    return dir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Adjustment delta for slider/drag/etc. 
 | 
			
		||||
// FIXME-NAVIGATION: Accelerate over time? Expose more settings? Handle faster/slower modifiers here instead of widget level? 
 | 
			
		||||
ImVec2 ImGui::NavGetTweakDelta()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    float repeat_delay = g.IO.KeyRepeatDelay * 0.80f;
 | 
			
		||||
    float repeat_rate = g.IO.KeyRepeatRate * 0.30f;
 | 
			
		||||
 | 
			
		||||
    ImVec2 delta(0.0f, 0.0f);
 | 
			
		||||
    if (int count = GetKeyPressedAmount(g.IO.KeyMap[ImGuiKey_NavLeft],  repeat_delay, repeat_rate)) delta.x = (float)-count;
 | 
			
		||||
    if (int count = GetKeyPressedAmount(g.IO.KeyMap[ImGuiKey_NavRight], repeat_delay, repeat_rate)) delta.x = (float)+count;
 | 
			
		||||
    if (int count = GetKeyPressedAmount(g.IO.KeyMap[ImGuiKey_NavUp],    repeat_delay, repeat_rate)) delta.y = (float)-count;
 | 
			
		||||
    if (int count = GetKeyPressedAmount(g.IO.KeyMap[ImGuiKey_NavDown],  repeat_delay, repeat_rate)) delta.y = (float)+count;
 | 
			
		||||
    return delta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
 | 
			
		||||
{
 | 
			
		||||
    static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f };
 | 
			
		||||
@@ -7275,15 +7297,15 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
 | 
			
		||||
                normalized_pos = 1.0f - normalized_pos;
 | 
			
		||||
            set_new_value = true;
 | 
			
		||||
        }
 | 
			
		||||
        else if (g.ActiveIdSource == ImGuiInputSource_Nav && IsKeyDownMap(ImGuiKey_NavActivate))
 | 
			
		||||
        else if (g.ActiveIdSource == ImGuiInputSource_Nav && IsNavInputDown(ImGuiNavInput_PadActivate))
 | 
			
		||||
        {
 | 
			
		||||
            const ImVec2 delta2 = NavGetTweakDelta();
 | 
			
		||||
            const ImVec2 delta2 = GetNavInputAmount2d(0, ImGuiNavReadMode_RepeatFast, 0.0f, 0.0f);
 | 
			
		||||
            if (float delta = is_horizontal ? delta2.x : -delta2.y)
 | 
			
		||||
            {
 | 
			
		||||
                normalized_pos = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos);
 | 
			
		||||
                if (decimal_precision == 0 && !is_non_linear)
 | 
			
		||||
                {
 | 
			
		||||
                    if (fabsf(v_max - v_min) <= 100.0f || IsKeyDownMap(ImGuiKey_NavTweakSlower))
 | 
			
		||||
                    if (fabsf(v_max - v_min) <= 100.0f || IsNavInputDown(ImGuiNavInput_PadTweakSlow))
 | 
			
		||||
                        delta = ((delta < 0.0f) ? -1.0f : +1.0f) / (v_max - v_min); // Gamepad/keyboard tweak speeds in integer steps
 | 
			
		||||
                    else
 | 
			
		||||
                        delta /= 100.0f;
 | 
			
		||||
@@ -7291,10 +7313,10 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    delta /= 100.0f;    // Gamepad/keyboard tweak speeds in % of slider bounds
 | 
			
		||||
                    if (IsKeyDownMap(ImGuiKey_NavTweakSlower))
 | 
			
		||||
                    if (IsNavInputDown(ImGuiNavInput_PadTweakSlow))
 | 
			
		||||
                        delta /= 10.0f;
 | 
			
		||||
                }
 | 
			
		||||
                if (IsKeyDownMap(ImGuiKey_NavTweakFaster))
 | 
			
		||||
                if (IsNavInputDown(ImGuiNavInput_PadTweakFast))
 | 
			
		||||
                    delta *= 10.0f;
 | 
			
		||||
                normalized_pos = ImSaturate(normalized_pos + delta); // FIXME-NAVIGATION: todo: cancel adjustment if current value already past edge and we are moving in edge direction, to avoid clamping value to edge.
 | 
			
		||||
                set_new_value = true;
 | 
			
		||||
@@ -7602,7 +7624,7 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s
 | 
			
		||||
    // Process clicking on the drag
 | 
			
		||||
    if (g.ActiveId == id)
 | 
			
		||||
    {
 | 
			
		||||
        if (g.IO.MouseDown[0] || IsKeyDownMap(ImGuiKey_NavActivate))
 | 
			
		||||
        if (g.IO.MouseDown[0] || IsNavInputDown(ImGuiNavInput_PadActivate))
 | 
			
		||||
        {
 | 
			
		||||
            if (g.ActiveIdIsJustActivated)
 | 
			
		||||
            {
 | 
			
		||||
@@ -7627,11 +7649,7 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s
 | 
			
		||||
            }
 | 
			
		||||
            if (g.ActiveIdSource == ImGuiInputSource_Nav)
 | 
			
		||||
            {
 | 
			
		||||
                adjust_delta = NavGetTweakDelta().x;
 | 
			
		||||
                if (IsKeyDownMap(ImGuiKey_NavTweakFaster))
 | 
			
		||||
                    adjust_delta *= 10.0f;
 | 
			
		||||
                if (IsKeyDownMap(ImGuiKey_NavTweakSlower))
 | 
			
		||||
                    adjust_delta /= 10.0f;
 | 
			
		||||
                adjust_delta = GetNavInputAmount2d(0, ImGuiNavReadMode_RepeatFast, 1.0f/10.0f, 1.0f).x;
 | 
			
		||||
            }
 | 
			
		||||
            adjust_delta *= v_speed;
 | 
			
		||||
            g.DragLastMouseDelta.x = mouse_drag_delta.x;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								imgui.h
									
									
									
									
									
								
							@@ -70,6 +70,7 @@ typedef void* ImTextureID;          // user data to identify a texture (this is
 | 
			
		||||
typedef int ImGuiCol;               // a color identifier for styling       // enum ImGuiCol_
 | 
			
		||||
typedef int ImGuiStyleVar;          // a variable identifier for styling    // enum ImGuiStyleVar_
 | 
			
		||||
typedef int ImGuiKey;               // a key identifier (ImGui-side enum)   // enum ImGuiKey_
 | 
			
		||||
typedef int ImGuiNavInput;          // an input identifier for gamepad nav  // enum ImGuiNavInput_
 | 
			
		||||
typedef int ImGuiAlign;             // alignment                            // enum ImGuiAlign_
 | 
			
		||||
typedef int ImGuiColorEditMode;     // color edit mode for ColorEdit*()     // enum ImGuiColorEditMode_
 | 
			
		||||
typedef int ImGuiMouseCursor;       // a mouse cursor identifier            // enum ImGuiMouseCursor_
 | 
			
		||||
@@ -437,7 +438,7 @@ namespace ImGui
 | 
			
		||||
    IMGUI_API bool          IsKeyDown(int key_index);                                           // key_index into the keys_down[] array, imgui doesn't know the semantic of each entry, uses your own indices!
 | 
			
		||||
    IMGUI_API bool          IsKeyPressed(int key_index, bool repeat = true);                    // uses user's key indices as stored in the keys_down[] array. if repeat=true. uses io.KeyRepeatDelay / KeyRepeatRate
 | 
			
		||||
    IMGUI_API bool          IsKeyReleased(int key_index);                                       // "
 | 
			
		||||
    IMGUI_API int           GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, typically 0 or 1 but may be >1 if RepeatRate is small enough that DeltaTime > RepeatRate
 | 
			
		||||
    IMGUI_API int           GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate
 | 
			
		||||
    IMGUI_API bool          IsMouseDown(int button);                                            // is mouse button held
 | 
			
		||||
    IMGUI_API bool          IsMouseClicked(int button, bool repeat = false);                    // did mouse button clicked (went from !Down to Down)
 | 
			
		||||
    IMGUI_API bool          IsMouseDoubleClicked(int button);                                   // did mouse button double-clicked. a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime.
 | 
			
		||||
@@ -576,10 +577,10 @@ enum ImGuiSelectableFlags_
 | 
			
		||||
enum ImGuiKey_
 | 
			
		||||
{
 | 
			
		||||
    ImGuiKey_Tab,       // for tabbing through fields
 | 
			
		||||
    ImGuiKey_LeftArrow, // for text edit
 | 
			
		||||
    ImGuiKey_RightArrow,// for text edit
 | 
			
		||||
    ImGuiKey_UpArrow,   // for text edit
 | 
			
		||||
    ImGuiKey_DownArrow, // for text edit
 | 
			
		||||
    ImGuiKey_LeftArrow, // for text edit
 | 
			
		||||
    ImGuiKey_RightArrow,// for text edit
 | 
			
		||||
    ImGuiKey_PageUp,
 | 
			
		||||
    ImGuiKey_PageDown,
 | 
			
		||||
    ImGuiKey_Home,      // for text edit
 | 
			
		||||
@@ -594,27 +595,31 @@ enum ImGuiKey_
 | 
			
		||||
    ImGuiKey_X,         // for text edit CTRL+X: cut
 | 
			
		||||
    ImGuiKey_Y,         // for text edit CTRL+Y: redo
 | 
			
		||||
    ImGuiKey_Z,         // for text edit CTRL+Z: undo
 | 
			
		||||
 | 
			
		||||
    // Inputs for Gamepad/Keyboard navigation. Feed those buttons with the input of either or both peripherals involved.
 | 
			
		||||
    ImGuiKey_NavActivate,   // press button, tweak value        // e.g. Space key, Circle button
 | 
			
		||||
    ImGuiKey_NavCancel,     // close menu/popup/child, unselect // e.g. Escape key, Cross button
 | 
			
		||||
    ImGuiKey_NavInput,      // text input                       // e.g. Enter key, Triangle button
 | 
			
		||||
    ImGuiKey_NavMenu,       // access menu, focus, move, resize // e.g. Square button
 | 
			
		||||
    ImGuiKey_NavLeft,       // e.g. Left arrow, D-Pad left
 | 
			
		||||
    ImGuiKey_NavRight,      // e.g. Right arrow, D-Pad right
 | 
			
		||||
    ImGuiKey_NavUp,         // e.g. Up arrow, D-Pad up
 | 
			
		||||
    ImGuiKey_NavDown,       // e.g. Down arrow, D-Pad down
 | 
			
		||||
    ImGuiKey_NavScrollLeft, // e.g. Analog left
 | 
			
		||||
    ImGuiKey_NavScrollRight,// e.g. Analog right
 | 
			
		||||
    ImGuiKey_NavScrollUp,   // e.g. Analog up
 | 
			
		||||
    ImGuiKey_NavScrollDown, // e.g. Analog down
 | 
			
		||||
    ImGuiKey_NavTweakFaster,// e.g. Shift key, R-trigger
 | 
			
		||||
    ImGuiKey_NavTweakSlower,// e.g. Alt key, L-trigger
 | 
			
		||||
    ImGuiKey_NavLast_,
 | 
			
		||||
 | 
			
		||||
    ImGuiKey_COUNT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum ImGuiNavInput_
 | 
			
		||||
{
 | 
			
		||||
    ImGuiNavInput_PadActivate,      // press button, tweak value                    // e.g. Circle button
 | 
			
		||||
    ImGuiNavInput_PadCancel,        // close menu/popup/child, lose selection       // e.g. Cross button
 | 
			
		||||
    ImGuiNavInput_PadInput,         // text input                                   // e.g. Triangle button
 | 
			
		||||
    ImGuiNavInput_PadMenu,          // access menu, focus, move, resize             // e.g. Square button
 | 
			
		||||
    ImGuiNavInput_PadUp,            // move up, resize window (with PadMenu held)   // e.g. D-pad up/down/left/right
 | 
			
		||||
    ImGuiNavInput_PadDown,          // move down
 | 
			
		||||
    ImGuiNavInput_PadLeft,          // move left
 | 
			
		||||
    ImGuiNavInput_PadRight,         // move right
 | 
			
		||||
    ImGuiNavInput_PadScrollUp,      // scroll up, move window (with PadMenu held)   // e.g. right stick up/down/left/right
 | 
			
		||||
    ImGuiNavInput_PadScrollDown,    // "
 | 
			
		||||
    ImGuiNavInput_PadScrollLeft,    //
 | 
			
		||||
    ImGuiNavInput_PadScrollRight,   //
 | 
			
		||||
    ImGuiNavInput_PadFocusPrev,     // next window (with PadMenu held)              // e.g. L-trigger
 | 
			
		||||
    ImGuiNavInput_PadFocusNext,     // prev window (with PadMenu held)              // e.g. R-trigger
 | 
			
		||||
    ImGuiNavInput_PadTweakSlow,     // slower tweaks                                // e.g. L-trigger
 | 
			
		||||
    ImGuiNavInput_PadTweakFast,     // faster tweaks                                // e.g. R-trigger
 | 
			
		||||
 | 
			
		||||
    ImGuiNavInput_COUNT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Enumeration for PushStyleColor() / PopStyleColor()
 | 
			
		||||
enum ImGuiCol_
 | 
			
		||||
{
 | 
			
		||||
@@ -824,6 +829,7 @@ struct ImGuiIO
 | 
			
		||||
    bool        KeySuper;                   // Keyboard modifier pressed: Cmd/Super/Windows
 | 
			
		||||
    bool        KeysDown[512];              // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data)
 | 
			
		||||
    ImWchar     InputCharacters[16+1];      // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
 | 
			
		||||
    float       NavInputs[ImGuiNavInput_COUNT];
 | 
			
		||||
 | 
			
		||||
    // Functions
 | 
			
		||||
    IMGUI_API void AddInputCharacter(ImWchar c);                        // Helper to add a new character into InputCharacters[]
 | 
			
		||||
@@ -863,6 +869,8 @@ struct ImGuiIO
 | 
			
		||||
    float       MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the click point
 | 
			
		||||
    float       KeysDownDuration[512];      // Duration the keyboard key has been down (0.0f == just pressed)
 | 
			
		||||
    float       KeysDownDurationPrev[512];  // Previous duration the key has been down
 | 
			
		||||
    float       NavInputsDownDuration[ImGuiNavInput_COUNT];
 | 
			
		||||
    float       NavInputsPrev[ImGuiNavInput_COUNT];
 | 
			
		||||
 | 
			
		||||
    IMGUI_API   ImGuiIO();
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1528,6 +1528,9 @@ void ImGui::ShowTestWindow(bool* p_open)
 | 
			
		||||
            ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
 | 
			
		||||
 | 
			
		||||
            ImGui::Text("NavUsable: %d, NavActive: %d", io.NavUsable, io.NavActive);
 | 
			
		||||
            ImGui::Text("NavInputs down:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputs[i] > 0.0f)                    { ImGui::SameLine(); ImGui::Text("[%d] %.2f", i, io.NavInputs[i]); }
 | 
			
		||||
            ImGui::Text("NavInputs pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] == 0.0f)    { ImGui::SameLine(); ImGui::Text("[%d]", i); }
 | 
			
		||||
            ImGui::Text("NavInputs duration:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] >= 0.0f)   { ImGui::SameLine(); ImGui::Text("[%d] %.2f", i, io.NavInputsDownDuration[i]); }
 | 
			
		||||
 | 
			
		||||
            ImGui::Button("Hovering me sets the\nkeyboard capture flag");
 | 
			
		||||
            if (ImGui::IsItemHovered())
 | 
			
		||||
 
 | 
			
		||||
@@ -784,8 +784,7 @@ namespace ImGui
 | 
			
		||||
 | 
			
		||||
    IMGUI_API void          OpenPopupEx(const char* str_id, bool reopen_existing);
 | 
			
		||||
 | 
			
		||||
    IMGUI_API ImVec2        NavGetTweakDelta();
 | 
			
		||||
    IMGUI_API ImVec2        NavGetMovingDir(int stick_no, float slow_factor = 0.0f, float fast_factor = 0.0f);
 | 
			
		||||
    IMGUI_API int           CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate);
 | 
			
		||||
 | 
			
		||||
    inline IMGUI_API ImU32  GetColorU32(ImGuiCol idx, float alpha_mul)  { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * alpha_mul; return ImGui::ColorConvertFloat4ToU32(c); }
 | 
			
		||||
    inline IMGUI_API ImU32  GetColorU32(const ImVec4& col)              { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user