diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 5a8dbfbc..755bc2db 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,6 +49,8 @@ Other Changes: - 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) - 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.) 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 diff --git a/imgui.cpp b/imgui.cpp index 3080a279..2665e1bb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4828,6 +4828,8 @@ bool ImGui::IsItemFocused() 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) { 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; } - 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) if (first_begin_of_the_frame) 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) { ImGuiContext& g = *GImGui; - IM_ASSERT(g.NavWindow); - IM_ASSERT(nav_layer == 0 || nav_layer == 1); + IM_ASSERT(g.NavWindow != NULL); + IM_ASSERT(nav_layer == ImGuiNavLayer_Main || nav_layer == ImGuiNavLayer_Menu); g.NavId = id; + g.NavLayer = (ImGuiNavLayer)nav_layer; g.NavFocusScopeId = focus_scope_id; g.NavWindow->NavLastIds[nav_layer] = id; } @@ -8838,7 +8838,7 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit) IM_ASSERT(window == g.NavWindow); bool init_for_nav = false; 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; 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) @@ -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; // Process navigation init request (select first/default focus) - if (g.NavInitResultId != 0 && (!g.NavDisableHighlight || g.NavInitRequestFromMove)) + if (g.NavInitResultId != 0) NavUpdateInitResult(); g.NavInitRequest = false; g.NavInitRequestFromMove = false; @@ -9029,7 +9029,7 @@ static void ImGui::NavUpdate() ImGuiWindow* parent_window = g.NavWindow->ParentWindow; IM_ASSERT(child_window->ChildId != 0); 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. g.NavIdIsAlive = false; // -V1048 if (g.NavDisableMouseHover) diff --git a/imgui.h b/imgui.h index c47d47bb..900f7d9a 100644 --- a/imgui.h +++ b/imgui.h @@ -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. // 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. 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 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 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). diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 380bb2a4..9b718e2d 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6581,7 +6581,6 @@ void ImGui::EndMenuBar() IM_ASSERT(window->DC.NavLayerActiveMaskNext & (1 << layer)); // Sanity check FocusWindow(window); 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.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; NavMoveRequestCancel();