Nav: added SetNavCursorVisible(). (#1074, #2048, #7237, #8059)

+ Further internal renaming for consistency.
This commit is contained in:
ocornut 2024-10-18 17:06:30 +02:00
parent 0bae2db77f
commit 634a7ed988
5 changed files with 39 additions and 28 deletions

View File

@ -67,6 +67,8 @@ Other changes:
state to draw callbacks. (#6969, #5834, #7468, #3590) state to draw callbacks. (#6969, #5834, #7468, #3590)
- IO: WantCaptureKeyboard is never set when ImGuiConfigFlags_NoKeyboard is enabled. (#4921) - IO: WantCaptureKeyboard is never set when ImGuiConfigFlags_NoKeyboard is enabled. (#4921)
- Error Handling: turned a few more functions into recoverable errors. (#1651) - Error Handling: turned a few more functions into recoverable errors. (#1651)
- Nav: added NavSetCursorVisible(bool visible) to manipulate visibility of keyboard/gamepad
navigation cursor. (#1074, #2048, #7237, #8059)
- Nav: added io.ConfigNavEscapeClearFocusItem and io.ConfigNavEscapeClearFocusWindow to change - Nav: added io.ConfigNavEscapeClearFocusItem and io.ConfigNavEscapeClearFocusWindow to change
how pressing Escape affects navigation. (#8059, #2048, #1074, #3200) how pressing Escape affects navigation. (#8059, #2048, #1074, #3200)
- Set io.ConfigNavEscapeClearFocusItem = true (default) to clear focused item and highlight. - Set io.ConfigNavEscapeClearFocusItem = true (default) to clear focused item and highlight.

View File

@ -8558,7 +8558,7 @@ void ImGui::FocusItem()
return; return;
} }
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSetNavHighlight | ImGuiNavMoveFlags_NoSelect; ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSetNavCursorVisible | ImGuiNavMoveFlags_NoSelect;
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
SetNavWindow(window); SetNavWindow(window);
NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_Up, move_flags, scroll_flags); NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_Up, move_flags, scroll_flags);
@ -8593,7 +8593,7 @@ void ImGui::SetKeyboardFocusHere(int offset)
SetNavWindow(window); SetNavWindow(window);
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSetNavHighlight; ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSetNavCursorVisible;
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
if (offset == -1) if (offset == -1)
@ -12209,6 +12209,20 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
// In our terminology those should be interchangeable, yet right now this is super confusing. // In our terminology those should be interchangeable, yet right now this is super confusing.
// Those two functions are merely a legacy artifact, so at minimum naming should be clarified. // Those two functions are merely a legacy artifact, so at minimum naming should be clarified.
void ImGui::SetNavCursorVisible(bool visible)
{
ImGuiContext& g = *GImGui;
g.NavCursorVisible = visible;
}
// (was called NavRestoreHighlightAfterMove() before 1.91.4)
void ImGui::SetNavCursorVisibleAfterMove()
{
ImGuiContext& g = *GImGui;
g.NavCursorVisible = true;
g.NavHighlightItemUnderNav = g.NavMousePosDirty = true;
}
void ImGui::SetNavWindow(ImGuiWindow* window) void ImGui::SetNavWindow(ImGuiWindow* window)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -12735,13 +12749,6 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
} }
} }
void ImGui::NavRestoreHighlightAfterMove()
{
ImGuiContext& g = *GImGui;
g.NavCursorVisible = true;
g.NavHighlightItemUnderNav = g.NavMousePosDirty = true;
}
static inline void ImGui::NavUpdateAnyRequestFlag() static inline void ImGui::NavUpdateAnyRequestFlag()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -13050,7 +13057,7 @@ void ImGui::NavInitRequestApplyResult()
if (result->SelectionUserData != ImGuiSelectionUserData_Invalid) if (result->SelectionUserData != ImGuiSelectionUserData_Invalid)
g.NavLastValidSelectionUserData = result->SelectionUserData; g.NavLastValidSelectionUserData = result->SelectionUserData;
if (g.NavInitRequestFromMove) if (g.NavInitRequestFromMove)
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
} }
// Bias scoring rect ahead of scoring + update preferred pos (if missing) using source position // Bias scoring rect ahead of scoring + update preferred pos (if missing) using source position
@ -13243,9 +13250,9 @@ void ImGui::NavMoveRequestApplyResult()
if (result == NULL) if (result == NULL)
{ {
if (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) if (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing)
g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavHighlight; g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavCursorVisible;
if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0) if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavCursorVisible) == 0)
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
NavClearPreferredPosForAxis(axis); // On a failed move, clear preferred pos for this axis. NavClearPreferredPosForAxis(axis); // On a failed move, clear preferred pos for this axis.
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveSubmitted but not led to a result!\n"); IMGUI_DEBUG_LOG_NAV("[nav] NavMoveSubmitted but not led to a result!\n");
return; return;
@ -13330,9 +13337,9 @@ void ImGui::NavMoveRequestApplyResult()
g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState | ImGuiActivateFlags_FromTabbing; g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState | ImGuiActivateFlags_FromTabbing;
} }
// Enable nav highlight // Make nav cursor visible
if ((g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0) if ((g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavCursorVisible) == 0)
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
} }
// Process Escape/NavCancel input (to close a popup, get back to parent, clear focus) // Process Escape/NavCancel input (to close a popup, get back to parent, clear focus)
@ -13356,7 +13363,7 @@ static void ImGui::NavUpdateCancelRequest()
{ {
// Leave the "menu" layer // Leave the "menu" layer
NavRestoreLayer(ImGuiNavLayer_Main); NavRestoreLayer(ImGuiNavLayer_Main);
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
} }
else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow) else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow)
{ {
@ -13366,7 +13373,7 @@ static void ImGui::NavUpdateCancelRequest()
IM_ASSERT(child_window->ChildId != 0); IM_ASSERT(child_window->ChildId != 0);
FocusWindow(parent_window); FocusWindow(parent_window);
SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, WindowRectAbsToRel(parent_window, child_window->Rect())); SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, WindowRectAbsToRel(parent_window, child_window->Rect()));
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
} }
else if (g.OpenPopupStack.Size > 0 && g.OpenPopupStack.back().Window != NULL && !(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal)) else if (g.OpenPopupStack.Size > 0 && g.OpenPopupStack.back().Window != NULL && !(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
{ {
@ -13732,7 +13739,7 @@ static void ImGui::NavUpdateWindowing()
if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow)) if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow))
{ {
ClearActiveID(); ClearActiveID();
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
ClosePopupsOverWindow(apply_focus_window, false); ClosePopupsOverWindow(apply_focus_window, false);
FocusWindow(apply_focus_window, ImGuiFocusRequestFlags_RestoreFocusedChild); FocusWindow(apply_focus_window, ImGuiFocusRequestFlags_RestoreFocusedChild);
apply_focus_window = g.NavWindow; apply_focus_window = g.NavWindow;
@ -13779,7 +13786,7 @@ static void ImGui::NavUpdateWindowing()
if (new_nav_layer == ImGuiNavLayer_Menu) if (new_nav_layer == ImGuiNavLayer_Menu)
g.NavWindow->NavLastIds[new_nav_layer] = 0; g.NavWindow->NavLastIds[new_nav_layer] = 0;
NavRestoreLayer(new_nav_layer); NavRestoreLayer(new_nav_layer);
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
} }
} }
} }

10
imgui.h
View File

@ -900,10 +900,12 @@ namespace ImGui
IMGUI_API void PopClipRect(); IMGUI_API void PopClipRect();
// Focus, Activation // Focus, Activation
// - Prefer using "SetItemDefaultFocus()" over "if (IsWindowAppearing()) SetScrollHereY()" when applicable to signify "this is the default item" IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of of a newly appearing window.
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget.
// Keyboard/Gamepad Navigation
IMGUI_API void SetNavCursorVisible(bool visible); // alter visibility of keyboard/gamepad cursor. by default: show when using an arrow key, hide when clicking with mouse.
// Overlapping mode // Overlapping mode
IMGUI_API void SetNextItemAllowOverlap(); // allow next item to be overlapped by a subsequent item. Useful with invisible buttons, selectable, treenode covering an area where subsequent items may need to be added. Note that both Selectable() and TreeNode() have dedicated flags doing this. IMGUI_API void SetNextItemAllowOverlap(); // allow next item to be overlapped by a subsequent item. Useful with invisible buttons, selectable, treenode covering an area where subsequent items may need to be added. Note that both Selectable() and TreeNode() have dedicated flags doing this.
@ -996,7 +998,7 @@ namespace ImGui
// - Many related features are still in imgui_internal.h. For instance, most IsKeyXXX()/IsMouseXXX() functions have an owner-id-aware version. // - Many related features are still in imgui_internal.h. For instance, most IsKeyXXX()/IsMouseXXX() functions have an owner-id-aware version.
IMGUI_API void SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'. IMGUI_API void SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'.
// Inputs Utilities: Mouse specific // Inputs Utilities: Mouse
// - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right.
// - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle. // - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle.
// - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold') // - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold')
@ -1676,7 +1678,7 @@ enum ImGuiCol_
ImGuiCol_TextLink, // Hyperlink color ImGuiCol_TextLink, // Hyperlink color
ImGuiCol_TextSelectedBg, ImGuiCol_TextSelectedBg,
ImGuiCol_DragDropTarget, // Rectangle highlighting a drop target ImGuiCol_DragDropTarget, // Rectangle highlighting a drop target
ImGuiCol_NavHighlight, // Gamepad/keyboard: current highlighted item ImGuiCol_NavHighlight, // Color of gamepad/keyboard navigation cursor/rectangle, when visible
ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active
ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active

View File

@ -1578,7 +1578,7 @@ enum ImGuiNavMoveFlags_
ImGuiNavMoveFlags_IsPageMove = 1 << 11, // Identify a PageDown/PageUp request. ImGuiNavMoveFlags_IsPageMove = 1 << 11, // Identify a PageDown/PageUp request.
ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item. ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item.
ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo
ImGuiNavMoveFlags_NoSetNavHighlight = 1 << 14, // Do not alter the visible state of keyboard vs mouse nav highlight ImGuiNavMoveFlags_NoSetNavCursorVisible = 1 << 14, // Do not alter the nav cursor visible state
ImGuiNavMoveFlags_NoClearActiveId = 1 << 15, // (Experimental) Do not clear active id when applying move result ImGuiNavMoveFlags_NoClearActiveId = 1 << 15, // (Experimental) Do not clear active id when applying move result
}; };
@ -3114,7 +3114,7 @@ namespace ImGui
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
IMGUI_API void NavHighlightActivated(ImGuiID id); IMGUI_API void NavHighlightActivated(ImGuiID id);
IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis); IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis);
IMGUI_API void NavRestoreHighlightAfterMove(); IMGUI_API void SetNavCursorVisibleAfterMove();
IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX(); IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX();
IMGUI_API void SetNavWindow(ImGuiWindow* window); IMGUI_API void SetNavWindow(ImGuiWindow* window);
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel); IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);

View File

@ -7200,7 +7200,7 @@ int ImGui::TypingSelectFindMatch(ImGuiTypingSelectRequest* req, int items_count,
else else
idx = TypingSelectFindBestLeadingMatch(req, items_count, get_item_name_func, user_data); idx = TypingSelectFindBestLeadingMatch(req, items_count, get_item_name_func, user_data);
if (idx != -1) if (idx != -1)
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
return idx; return idx;
} }
@ -8883,7 +8883,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
{ {
want_open = want_open_nav_init = true; want_open = want_open_nav_init = true;
NavMoveRequestCancel(); NavMoveRequestCancel();
NavRestoreHighlightAfterMove(); SetNavCursorVisibleAfterMove();
} }
} }
else else