Nav: do not clear per-window NavId when window reappears. Process NavInit regardless of current highllight state. Consistently set g.NavLayer in SetNavID(). (#787)

This commit is contained in:
ocornut 2021-03-08 17:14:05 +01:00
parent 954b06afe2
commit 4bb5a36f90
4 changed files with 12 additions and 11 deletions

View File

@ -49,6 +49,8 @@ Other Changes:
- Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible - Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible
area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825) area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825)
- Window, Nav: Fixed crash when calling SetWindowFocus(NULL) as the time a new window appears. (#3865) [@nem0] - Window, Nav: Fixed crash when calling SetWindowFocus(NULL) as the time a new window appears. (#3865) [@nem0]
- Nav: Various fixes for losing gamepad/keyboard navigation reference point when a window reappears or
when it appears while gamepad/keyboard are not being used. (#787)
- Drags: Fixed crash when using DragScalar() directly (not via common wrapper like DragFloat() etc.) - Drags: Fixed crash when using DragScalar() directly (not via common wrapper like DragFloat() etc.)
with ImGuiSliderFlags_AlwaysClamp + only one of either p_min or p_max set. (#3824) [@harry75369] with ImGuiSliderFlags_AlwaysClamp + only one of either p_min or p_max set. (#3824) [@harry75369]
- Drags, Sliders: Fixed a bug where editing value would use wrong number if there were digits right after - Drags, Sliders: Fixed a bug where editing value would use wrong number if there were digits right after

View File

@ -4828,6 +4828,8 @@ bool ImGui::IsItemFocused()
return true; return true;
} }
// Important: this can be useful but it is NOT equivalent to the behavior of e.g.Button()!
// Most widgets have specific reactions based on mouse-up/down state, mouse position etc.
bool ImGui::IsItemClicked(ImGuiMouseButton mouse_button) bool ImGui::IsItemClicked(ImGuiMouseButton mouse_button)
{ {
return IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_None); return IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_None);
@ -5724,9 +5726,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->PopupId = popup_ref.PopupId; window->PopupId = popup_ref.PopupId;
} }
if (window_just_appearing_after_hidden_for_resize && !(flags & ImGuiWindowFlags_ChildWindow))
window->NavLastIds[0] = 0;
// Update ->RootWindow and others pointers (before any possible call to FocusWindow) // Update ->RootWindow and others pointers (before any possible call to FocusWindow)
if (first_begin_of_the_frame) if (first_begin_of_the_frame)
UpdateWindowParentAndRootLinks(window, flags, parent_window); UpdateWindowParentAndRootLinks(window, flags, parent_window);
@ -8482,9 +8481,10 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id) void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(g.NavWindow); IM_ASSERT(g.NavWindow != NULL);
IM_ASSERT(nav_layer == 0 || nav_layer == 1); IM_ASSERT(nav_layer == ImGuiNavLayer_Main || nav_layer == ImGuiNavLayer_Menu);
g.NavId = id; g.NavId = id;
g.NavLayer = (ImGuiNavLayer)nav_layer;
g.NavFocusScopeId = focus_scope_id; g.NavFocusScopeId = focus_scope_id;
g.NavWindow->NavLastIds[nav_layer] = id; g.NavWindow->NavLastIds[nav_layer] = id;
} }
@ -8838,7 +8838,7 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
IM_ASSERT(window == g.NavWindow); IM_ASSERT(window == g.NavWindow);
bool init_for_nav = false; bool init_for_nav = false;
if (!(window->Flags & ImGuiWindowFlags_NoNavInputs)) if (!(window->Flags & ImGuiWindowFlags_NoNavInputs))
if (!(window->Flags & ImGuiWindowFlags_ChildWindow) || (window->Flags & ImGuiWindowFlags_Popup) || (window->NavLastIds[0] == 0) || force_reinit) if (window == window->RootWindow || (window->Flags & ImGuiWindowFlags_Popup) || (window->NavLastIds[0] == 0) || force_reinit)
init_for_nav = true; init_for_nav = true;
IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from NavInitWindow(), init_for_nav=%d, window=\"%s\", layer=%d\n", init_for_nav, window->Name, g.NavLayer); IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from NavInitWindow(), init_for_nav=%d, window=\"%s\", layer=%d\n", init_for_nav, window->Name, g.NavLayer);
if (init_for_nav) if (init_for_nav)
@ -8962,7 +8962,7 @@ static void ImGui::NavUpdate()
io.NavInputsDownDuration[i] = (io.NavInputs[i] > 0.0f) ? (io.NavInputsDownDuration[i] < 0.0f ? 0.0f : io.NavInputsDownDuration[i] + io.DeltaTime) : -1.0f; io.NavInputsDownDuration[i] = (io.NavInputs[i] > 0.0f) ? (io.NavInputsDownDuration[i] < 0.0f ? 0.0f : io.NavInputsDownDuration[i] + io.DeltaTime) : -1.0f;
// Process navigation init request (select first/default focus) // Process navigation init request (select first/default focus)
if (g.NavInitResultId != 0 && (!g.NavDisableHighlight || g.NavInitRequestFromMove)) if (g.NavInitResultId != 0)
NavUpdateInitResult(); NavUpdateInitResult();
g.NavInitRequest = false; g.NavInitRequest = false;
g.NavInitRequestFromMove = false; g.NavInitRequestFromMove = false;
@ -9029,7 +9029,7 @@ static void ImGui::NavUpdate()
ImGuiWindow* parent_window = g.NavWindow->ParentWindow; ImGuiWindow* parent_window = g.NavWindow->ParentWindow;
IM_ASSERT(child_window->ChildId != 0); IM_ASSERT(child_window->ChildId != 0);
FocusWindow(parent_window); FocusWindow(parent_window);
SetNavID(child_window->ChildId, 0, 0); SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0);
// Reassigning with same value, we're being explicit here. // Reassigning with same value, we're being explicit here.
g.NavIdIsAlive = false; // -V1048 g.NavIdIsAlive = false; // -V1048
if (g.NavDisableMouseHover) if (g.NavDisableMouseHover)

View File

@ -778,12 +778,12 @@ namespace ImGui
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.
// Item/Widgets Utilities // Item/Widgets Utilities
// - Most of the functions are referring to the last/previous item we submitted. // - Most of the functions are referring to the previous Item that has been submitted.
// - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions. // - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions.
IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options. IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options.
IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited. This will continuously return true while holding mouse button on an item. Items that don't interact will always return false) IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited. This will continuously return true while holding mouse button on an item. Items that don't interact will always return false)
IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation? IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation?
IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) == IsMouseClicked(mouse_button) && IsItemHovered() IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button = 0); // is the last item hovered and mouse clicked on? (**) == IsMouseClicked(mouse_button) && IsItemHovered()Important. (**) this it NOT equivalent to the behavior of e.g. Button(). Read comments in function definition.
IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling) IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling)
IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the "bool" return value of many widgets. IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the "bool" return value of many widgets.
IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive). IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive).

View File

@ -6581,7 +6581,6 @@ void ImGui::EndMenuBar()
IM_ASSERT(window->DC.NavLayerActiveMaskNext & (1 << layer)); // Sanity check IM_ASSERT(window->DC.NavLayerActiveMaskNext & (1 << layer)); // Sanity check
FocusWindow(window); FocusWindow(window);
SetNavIDWithRectRel(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]); SetNavIDWithRectRel(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
g.NavLayer = layer;
g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection.
g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
NavMoveRequestCancel(); NavMoveRequestCancel();