Nav: move code into NavMoveRequestSubmit(). NavApplyItemToResult() takes absolute rect., comments
This commit is contained in:
parent
7b913db1ce
commit
ee351d3548
@ -334,9 +334,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch)
|
||||
- nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name)
|
||||
- nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem
|
||||
- nav: NavFlattened: init requests don't work properly on flattened siblings.
|
||||
- nav: NavFlattened: pageup/pagedown/home/end don't work properly on flattened siblings.
|
||||
- nav: NavFlattened: ESC on a flattened child should select something.
|
||||
- nav: NavFlattened: broken: in typical usage scenario, the items of a fully clipped child are currently not considered to enter into a NavFlattened child.
|
||||
- nav: NavFlattened: init request doesn't select items that are part of a NavFlattened child
|
||||
- nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..).
|
||||
- nav: simulate right-click or context activation? (SHIFT+F10)
|
||||
- nav/tabbing: refactor old tabbing system and turn into navigation, should pass through all widgets (in submission order?).
|
||||
|
58
imgui.cpp
58
imgui.cpp
@ -917,8 +917,8 @@ static float NavUpdatePageUpPageDown();
|
||||
static inline void NavUpdateAnyRequestFlag();
|
||||
static void NavEndFrame();
|
||||
static bool NavScoreItem(ImGuiNavItemData* result, ImRect cand);
|
||||
static void NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel);
|
||||
static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id);
|
||||
static void NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb);
|
||||
static void NavProcessItem(ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb);
|
||||
static ImVec2 NavCalcPreferredRefPos();
|
||||
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
|
||||
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
|
||||
@ -7495,6 +7495,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
// Set item data
|
||||
// (DisplayRect is left untouched, made valid when ImGuiItemStatusFlags_HasDisplayRect is set)
|
||||
g.LastItemData.ID = id;
|
||||
g.LastItemData.Rect = bb;
|
||||
g.LastItemData.InFlags = g.CurrentItemFlags;
|
||||
@ -7516,7 +7517,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
if (g.NavId == id || g.NavAnyRequest)
|
||||
if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
|
||||
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
|
||||
NavProcessItem(window, nav_bb_arg ? *nav_bb_arg : bb, id);
|
||||
NavProcessItem(window, id, nav_bb_arg ? *nav_bb_arg : bb);
|
||||
|
||||
// [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd()
|
||||
#ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
@ -8879,20 +8880,22 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
|
||||
return new_best;
|
||||
}
|
||||
|
||||
static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel)
|
||||
static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.LastItemData.ID == id); // Otherwise pulling from window->DC wouldn't be right
|
||||
result->Window = window;
|
||||
result->ID = id;
|
||||
result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||
result->RectRel = nav_bb_rel;
|
||||
result->RectRel = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos);
|
||||
}
|
||||
|
||||
// We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above)
|
||||
static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id)
|
||||
// This is called after LastItemData is set.
|
||||
static void ImGui::NavProcessItem(ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiItemFlags item_flags = g.LastItemData.InFlags;
|
||||
const ImRect nav_bb_rel(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos);
|
||||
|
||||
// Process Init Request
|
||||
if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent)
|
||||
@ -8902,7 +8905,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
|
||||
if (candidate_for_nav_default_focus || g.NavInitResultId == 0)
|
||||
{
|
||||
g.NavInitResultId = id;
|
||||
g.NavInitResultRectRel = nav_bb_rel;
|
||||
g.NavInitResultRectRel = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos);
|
||||
}
|
||||
if (candidate_for_nav_default_focus)
|
||||
{
|
||||
@ -8926,14 +8929,14 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
|
||||
new_best = false;
|
||||
#endif
|
||||
if (new_best)
|
||||
NavApplyItemToResult(result, window, id, nav_bb_rel);
|
||||
NavApplyItemToResult(result, window, id, nav_bb);
|
||||
|
||||
// Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
|
||||
const float VISIBLE_RATIO = 0.70f;
|
||||
if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
|
||||
if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
|
||||
if (NavScoreItem(&g.NavMoveResultLocalVisible, nav_bb))
|
||||
NavApplyItemToResult(&g.NavMoveResultLocalVisible, window, id, nav_bb_rel);
|
||||
NavApplyItemToResult(&g.NavMoveResultLocalVisible, window, id, nav_bb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8944,7 +8947,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
|
||||
g.NavLayer = window->DC.NavLayerCurrent;
|
||||
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||
g.NavIdIsAlive = true;
|
||||
window->NavRectRel[window->DC.NavLayerCurrent] = nav_bb_rel; // Store item bounding box (relative to window position)
|
||||
window->NavRectRel[window->DC.NavLayerCurrent] = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); // Store item bounding box (relative to window position)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8954,6 +8957,21 @@ bool ImGui::NavMoveRequestButNoResultYet()
|
||||
return g.NavMoveScoringItems && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0;
|
||||
}
|
||||
|
||||
void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.NavWindow != NULL);
|
||||
g.NavMoveSubmitted = g.NavMoveScoringItems = true;
|
||||
g.NavMoveDir = move_dir;
|
||||
g.NavMoveClipDir = clip_dir;
|
||||
g.NavMoveFlags = move_flags;
|
||||
g.NavMoveForwardToNextFrame = false;
|
||||
g.NavMoveKeyMods = g.IO.KeyMods;
|
||||
g.NavMoveResultLocal.Clear();
|
||||
g.NavMoveResultLocalVisible.Clear();
|
||||
g.NavMoveResultOther.Clear();
|
||||
}
|
||||
|
||||
void ImGui::NavMoveRequestCancel()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -9304,7 +9322,6 @@ void ImGui::NavUpdateCreateMoveRequest()
|
||||
IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
|
||||
IM_ASSERT(g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded);
|
||||
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
|
||||
g.NavMoveForwardToNextFrame = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -9340,20 +9357,12 @@ void ImGui::NavUpdateCreateMoveRequest()
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we initiate a movement request and have no current NavId, we initiate a InitDefaultRequest that will be used as a fallback if the direction fails to find a match
|
||||
// FIXME: Would be nice to call a single function to initiate a new request
|
||||
// Submit
|
||||
g.NavMoveForwardToNextFrame = false;
|
||||
if (g.NavMoveDir != ImGuiDir_None)
|
||||
{
|
||||
IM_ASSERT(window != NULL);
|
||||
g.NavMoveSubmitted = g.NavMoveScoringItems = true;
|
||||
g.NavMoveKeyMods = io.KeyMods;
|
||||
g.NavMoveDirForDebug = g.NavMoveDir;
|
||||
g.NavMoveResultLocal.Clear();
|
||||
g.NavMoveResultLocalVisible.Clear();
|
||||
g.NavMoveResultOther.Clear();
|
||||
}
|
||||
NavMoveRequestSubmit(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags);
|
||||
|
||||
// Moving with no reference triggers a init request
|
||||
// Moving with no reference triggers a init request (will be used as a fallback if the direction fails to find a match)
|
||||
if (g.NavMoveSubmitted && g.NavId == 0)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer);
|
||||
@ -9507,6 +9516,7 @@ static void ImGui::NavUpdateCancelRequest()
|
||||
|
||||
// Handle PageUp/PageDown/Home/End keys
|
||||
// Called from NavUpdateCreateMoveRequest() which will use our output to create a move request
|
||||
// FIXME-NAV: This doesn't work properly with NavFlattened siblings as we use NavWindow rectangle for reference
|
||||
// FIXME-NAV: how to get Home/End to aim at the beginning/end of a 2D grid?
|
||||
static float ImGui::NavUpdatePageUpPageDown()
|
||||
{
|
||||
|
@ -758,7 +758,7 @@ enum ImGuiItemStatusFlags_
|
||||
{
|
||||
ImGuiItemStatusFlags_None = 0,
|
||||
ImGuiItemStatusFlags_HoveredRect = 1 << 0, // Mouse position is within item rectangle (does NOT mean that the window is in correct z-order and can be hovered!, this is only one part of the most-common IsItemHovered test)
|
||||
ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // window->DC.LastItemDisplayRect is valid
|
||||
ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // g.LastItemData.DisplayRect is valid
|
||||
ImGuiItemStatusFlags_Edited = 1 << 2, // Value exposed by item was edited in the current frame (should match the bool return value of most widgets)
|
||||
ImGuiItemStatusFlags_ToggledSelection = 1 << 3, // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected", only state changes, in order to easily handle clipping with less issues.
|
||||
ImGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state.
|
||||
@ -1123,8 +1123,8 @@ struct ImGuiLastItemData
|
||||
ImGuiID ID;
|
||||
ImGuiItemFlags InFlags; // See ImGuiItemFlags_
|
||||
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
||||
ImRect Rect;
|
||||
ImRect DisplayRect;
|
||||
ImRect Rect; // Full rectangle
|
||||
ImRect DisplayRect; // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set)
|
||||
|
||||
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
@ -2458,6 +2458,7 @@ namespace ImGui
|
||||
// Gamepad/Keyboard Navigation
|
||||
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
|
||||
IMGUI_API bool NavMoveRequestButNoResultYet();
|
||||
IMGUI_API void NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags);
|
||||
IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags);
|
||||
IMGUI_API void NavMoveRequestCancel();
|
||||
IMGUI_API void NavMoveRequestApplyResult();
|
||||
|
Loading…
Reference in New Issue
Block a user