mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-28 09:30:56 +01:00
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: 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: 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: 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: 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: 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: 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: 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?).
|
- 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 inline void NavUpdateAnyRequestFlag();
|
||||||
static void NavEndFrame();
|
static void NavEndFrame();
|
||||||
static bool NavScoreItem(ImGuiNavItemData* result, ImRect cand);
|
static bool NavScoreItem(ImGuiNavItemData* result, ImRect cand);
|
||||||
static void NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel);
|
static void NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb);
|
||||||
static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id);
|
static void NavProcessItem(ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb);
|
||||||
static ImVec2 NavCalcPreferredRefPos();
|
static ImVec2 NavCalcPreferredRefPos();
|
||||||
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
|
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
|
||||||
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* 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;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
// Set item data
|
// Set item data
|
||||||
|
// (DisplayRect is left untouched, made valid when ImGuiItemStatusFlags_HasDisplayRect is set)
|
||||||
g.LastItemData.ID = id;
|
g.LastItemData.ID = id;
|
||||||
g.LastItemData.Rect = bb;
|
g.LastItemData.Rect = bb;
|
||||||
g.LastItemData.InFlags = g.CurrentItemFlags;
|
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.NavId == id || g.NavAnyRequest)
|
||||||
if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
|
if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
|
||||||
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
|
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()
|
// [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd()
|
||||||
#ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
#ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||||
@ -8879,20 +8880,22 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
|
|||||||
return new_best;
|
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->Window = window;
|
||||||
result->ID = id;
|
result->ID = id;
|
||||||
result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
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)
|
// 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;
|
ImGuiContext& g = *GImGui;
|
||||||
const ImGuiItemFlags item_flags = g.LastItemData.InFlags;
|
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
|
// Process Init Request
|
||||||
if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent)
|
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)
|
if (candidate_for_nav_default_focus || g.NavInitResultId == 0)
|
||||||
{
|
{
|
||||||
g.NavInitResultId = id;
|
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)
|
if (candidate_for_nav_default_focus)
|
||||||
{
|
{
|
||||||
@ -8926,14 +8929,14 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
|
|||||||
new_best = false;
|
new_best = false;
|
||||||
#endif
|
#endif
|
||||||
if (new_best)
|
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.
|
// Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
|
||||||
const float VISIBLE_RATIO = 0.70f;
|
const float VISIBLE_RATIO = 0.70f;
|
||||||
if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
|
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 (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))
|
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.NavLayer = window->DC.NavLayerCurrent;
|
||||||
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
|
||||||
g.NavIdIsAlive = true;
|
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;
|
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()
|
void ImGui::NavMoveRequestCancel()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@ -9304,7 +9322,6 @@ void ImGui::NavUpdateCreateMoveRequest()
|
|||||||
IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
|
IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
|
||||||
IM_ASSERT(g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded);
|
IM_ASSERT(g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded);
|
||||||
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
|
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
|
||||||
g.NavMoveForwardToNextFrame = false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -9340,20 +9357,12 @@ void ImGui::NavUpdateCreateMoveRequest()
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
// Submit
|
||||||
// FIXME: Would be nice to call a single function to initiate a new request
|
g.NavMoveForwardToNextFrame = false;
|
||||||
if (g.NavMoveDir != ImGuiDir_None)
|
if (g.NavMoveDir != ImGuiDir_None)
|
||||||
{
|
NavMoveRequestSubmit(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
if (g.NavMoveSubmitted && g.NavId == 0)
|
||||||
{
|
{
|
||||||
IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer);
|
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
|
// Handle PageUp/PageDown/Home/End keys
|
||||||
// Called from NavUpdateCreateMoveRequest() which will use our output to create a move request
|
// 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?
|
// FIXME-NAV: how to get Home/End to aim at the beginning/end of a 2D grid?
|
||||||
static float ImGui::NavUpdatePageUpPageDown()
|
static float ImGui::NavUpdatePageUpPageDown()
|
||||||
{
|
{
|
||||||
|
@ -758,7 +758,7 @@ enum ImGuiItemStatusFlags_
|
|||||||
{
|
{
|
||||||
ImGuiItemStatusFlags_None = 0,
|
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_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_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_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.
|
ImGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state.
|
||||||
@ -1123,8 +1123,8 @@ struct ImGuiLastItemData
|
|||||||
ImGuiID ID;
|
ImGuiID ID;
|
||||||
ImGuiItemFlags InFlags; // See ImGuiItemFlags_
|
ImGuiItemFlags InFlags; // See ImGuiItemFlags_
|
||||||
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
||||||
ImRect Rect;
|
ImRect Rect; // Full rectangle
|
||||||
ImRect DisplayRect;
|
ImRect DisplayRect; // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set)
|
||||||
|
|
||||||
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
@ -2458,6 +2458,7 @@ namespace ImGui
|
|||||||
// Gamepad/Keyboard Navigation
|
// Gamepad/Keyboard Navigation
|
||||||
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
|
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
|
||||||
IMGUI_API bool NavMoveRequestButNoResultYet();
|
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 NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags);
|
||||||
IMGUI_API void NavMoveRequestCancel();
|
IMGUI_API void NavMoveRequestCancel();
|
||||||
IMGUI_API void NavMoveRequestApplyResult();
|
IMGUI_API void NavMoveRequestApplyResult();
|
||||||
|
Loading…
Reference in New Issue
Block a user