Skip to content

Commit

Permalink
Nav: keyboard/gamepad activation feedback properly timed instead of f…
Browse files Browse the repository at this point in the history
…rame buffer. (#456)

Amend d10641b
  • Loading branch information
ocornut committed Jan 22, 2024
1 parent 5b5e9bd commit 4c2c094
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
18 changes: 18 additions & 0 deletions imgui.cpp
Expand Up @@ -1047,6 +1047,8 @@ CODE
static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in
static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time before the window list starts to appear

static const float NAV_ACTIVATE_HIGHLIGHT_TIMER = 0.10f; // Time to highlight an item activated by a shortcut.

// Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by backend)
static const float WINDOWS_HOVER_PADDING = 4.0f; // Extend outside window for hovering/resizing (maxxed with TouchPadding) and inside windows for borders. Affect FindHoveredWindow().
static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time.
Expand Down Expand Up @@ -11169,6 +11171,13 @@ void ImGui::SetNavWindow(ImGuiWindow* window)
NavUpdateAnyRequestFlag();
}

void ImGui::NavHighlightActivated(ImGuiID id)
{
ImGuiContext& g = *GImGui;
g.NavHighlightActivatedId = id;
g.NavHighlightActivatedTimer = NAV_ACTIVATE_HIGHLIGHT_TIMER;
}

void ImGui::NavClearPreferredPosForAxis(ImGuiAxis axis)
{
ImGuiContext& g = *GImGui;
Expand Down Expand Up @@ -11849,13 +11858,22 @@ static void ImGui::NavUpdate()
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && (activate_down || input_down))
g.NavActivateDownId = g.NavId;
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && (activate_pressed || input_pressed))
{
g.NavActivatePressedId = g.NavId;
NavHighlightActivated(g.NavId);
}
}
if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
g.NavDisableHighlight = true;
if (g.NavActivateId != 0)
IM_ASSERT(g.NavActivateDownId == g.NavActivateId);

// Highlight
if (g.NavHighlightActivatedTimer > 0.0f)
g.NavHighlightActivatedTimer = ImMax(0.0f, g.NavHighlightActivatedTimer - io.DeltaTime);
if (g.NavHighlightActivatedTimer == 0.0f)
g.NavHighlightActivatedId = 0;

// Process programmatic activation request
// FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others)
if (g.NavNextActivateId != 0)
Expand Down
5 changes: 5 additions & 0 deletions imgui_internal.h
Expand Up @@ -2026,6 +2026,8 @@ struct ImGuiContext
ImGuiID NavActivateDownId; // ~~ IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_NavGamepadActivate) ? NavId : 0
ImGuiID NavActivatePressedId; // ~~ IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat)
ImGuiActivateFlags NavActivateFlags;
ImGuiID NavHighlightActivatedId;
float NavHighlightActivatedTimer;
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
ImGuiKeyChord NavJustMovedToKeyMods;
Expand Down Expand Up @@ -2293,6 +2295,8 @@ struct ImGuiContext
NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0;
NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
NavHighlightActivatedId = 0;
NavHighlightActivatedTimer = 0.0f;
NavJustMovedToKeyMods = ImGuiMod_None;
NavInputSource = ImGuiInputSource_Keyboard;
NavLayer = ImGuiNavLayer_Main;
Expand Down Expand Up @@ -3127,6 +3131,7 @@ namespace ImGui
IMGUI_API void NavMoveRequestCancel();
IMGUI_API void NavMoveRequestApplyResult();
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
IMGUI_API void NavHighlightActivated(ImGuiID id);
IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis);
IMGUI_API void NavRestoreHighlightAfterMove();
IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX();
Expand Down
4 changes: 4 additions & 0 deletions imgui_widgets.cpp
Expand Up @@ -675,6 +675,10 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
g.ActiveIdHasBeenPressedBefore = true;
}

// Activation highlight
if (g.NavHighlightActivatedId == id)
hovered = true;

if (out_hovered) *out_hovered = hovered;
if (out_held) *out_held = held;

Expand Down

0 comments on commit 4c2c094

Please sign in to comment.