mirror of
https://github.com/ocornut/imgui.git
synced 2025-02-22 05:09:56 +01:00
Nav: Refactor NavMoveResult** flags into ImGuiNavMoveResult structure as we are going to want two instances of it. (#787) (+1 squashed commits)
+ store window inside result.
This commit is contained in:
parent
1cf38d0334
commit
72485a5d04
58
imgui.cpp
58
imgui.cpp
@ -2132,7 +2132,7 @@ static float NavScoreItemDistInterval(float a0, float a1, float b0, float b1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Scoring function for directional navigation. Based on https://gist.github.com/rygorous/6981057
|
// Scoring function for directional navigation. Based on https://gist.github.com/rygorous/6981057
|
||||||
static bool NavScoreItem(ImRect cand)
|
static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.NavWindow;
|
ImGuiWindow* window = g.NavWindow;
|
||||||
@ -2207,21 +2207,21 @@ static bool NavScoreItem(ImRect cand)
|
|||||||
if (quadrant == g.NavMoveDir)
|
if (quadrant == g.NavMoveDir)
|
||||||
{
|
{
|
||||||
// Does it beat the current best candidate?
|
// Does it beat the current best candidate?
|
||||||
if (dist_box < g.NavMoveResultDistBox)
|
if (dist_box < result->DistBox)
|
||||||
{
|
{
|
||||||
g.NavMoveResultDistBox = dist_box;
|
result->DistBox = dist_box;
|
||||||
g.NavMoveResultDistCenter = dist_center;
|
result->DistCenter = dist_center;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (dist_box == g.NavMoveResultDistBox)
|
if (dist_box == result->DistBox)
|
||||||
{
|
{
|
||||||
// Try using distance between center points to break ties
|
// Try using distance between center points to break ties
|
||||||
if (dist_center < g.NavMoveResultDistCenter)
|
if (dist_center < result->DistCenter)
|
||||||
{
|
{
|
||||||
g.NavMoveResultDistCenter = dist_center;
|
result->DistCenter = dist_center;
|
||||||
new_best = true;
|
new_best = true;
|
||||||
}
|
}
|
||||||
else if (dist_center == g.NavMoveResultDistCenter)
|
else if (dist_center == result->DistCenter)
|
||||||
{
|
{
|
||||||
// Still tied! we need to be extra-careful to make sure everything gets linked properly. We consistently break ties by symbolically moving "later" items
|
// Still tied! we need to be extra-careful to make sure everything gets linked properly. We consistently break ties by symbolically moving "later" items
|
||||||
// (with higher index) to the right/downwards by an infinitesimal amount since we the current "best" button already (so it must have a lower index),
|
// (with higher index) to the right/downwards by an infinitesimal amount since we the current "best" button already (so it must have a lower index),
|
||||||
@ -2237,11 +2237,11 @@ static bool NavScoreItem(ImRect cand)
|
|||||||
// This is just to avoid buttons having no links in a particular direction when there's a suitable neighbor. you get good graphs without this too.
|
// This is just to avoid buttons having no links in a particular direction when there's a suitable neighbor. you get good graphs without this too.
|
||||||
// 2017/09/29: FIXME: This now currently only enabled inside menubars, ideally we'd disable it everywhere. Menus in particular need to catch failure. For general navigation it feels awkward.
|
// 2017/09/29: FIXME: This now currently only enabled inside menubars, ideally we'd disable it everywhere. Menus in particular need to catch failure. For general navigation it feels awkward.
|
||||||
// Disabling it may however lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option?
|
// Disabling it may however lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option?
|
||||||
if (g.NavMoveResultDistBox == FLT_MAX && dist_axial < g.NavMoveResultDistAxial) // Check axial match
|
if (result->DistBox == FLT_MAX && dist_axial < result->DistAxial) // Check axial match
|
||||||
if (g.NavLayer == 1 && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
if (g.NavLayer == 1 && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
||||||
if ((g.NavMoveDir == ImGuiDir_Left && dax < 0.0f) || (g.NavMoveDir == ImGuiDir_Right && dax > 0.0f) || (g.NavMoveDir == ImGuiDir_Up && day < 0.0f) || (g.NavMoveDir == ImGuiDir_Down && day > 0.0f))
|
if ((g.NavMoveDir == ImGuiDir_Left && dax < 0.0f) || (g.NavMoveDir == ImGuiDir_Right && dax > 0.0f) || (g.NavMoveDir == ImGuiDir_Up && day < 0.0f) || (g.NavMoveDir == ImGuiDir_Down && day > 0.0f))
|
||||||
{
|
{
|
||||||
g.NavMoveResultDistAxial = dist_axial;
|
result->DistAxial = dist_axial;
|
||||||
new_best = true;
|
new_best = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2288,19 +2288,21 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
|
|||||||
// Scoring for navigation
|
// Scoring for navigation
|
||||||
if (g.NavId != id && !(item_flags & ImGuiItemFlags_NoNav))
|
if (g.NavId != id && !(item_flags & ImGuiItemFlags_NoNav))
|
||||||
{
|
{
|
||||||
|
ImGuiNavMoveResult* result = &g.NavMoveResult;
|
||||||
#if IMGUI_DEBUG_NAV_SCORING
|
#if IMGUI_DEBUG_NAV_SCORING
|
||||||
// [DEBUG] Score all items in NavWindow at all times
|
// [DEBUG] Score all items in NavWindow at all times
|
||||||
if (!g.NavMoveRequest)
|
if (!g.NavMoveRequest)
|
||||||
g.NavMoveDir = g.NavMoveDirLast;
|
g.NavMoveDir = g.NavMoveDirLast;
|
||||||
bool new_best = NavScoreItem(nav_bb) && g.NavMoveRequest;
|
bool new_best = NavScoreItem(result, nav_bb) && g.NavMoveRequest;
|
||||||
#else
|
#else
|
||||||
bool new_best = g.NavMoveRequest && NavScoreItem(nav_bb);
|
bool new_best = g.NavMoveRequest && NavScoreItem(result, nav_bb);
|
||||||
#endif
|
#endif
|
||||||
if (new_best)
|
if (new_best)
|
||||||
{
|
{
|
||||||
g.NavMoveResultId = id;
|
result->ID = id;
|
||||||
g.NavMoveResultParentId = window->IDStack.back();
|
result->ParentID = window->IDStack.back();
|
||||||
g.NavMoveResultRectRel = nav_bb_rel;
|
result->Window = window;
|
||||||
|
result->RectRel = nav_bb_rel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2881,17 +2883,18 @@ static void ImGui::NavUpdate()
|
|||||||
g.NavJustMovedToId = 0;
|
g.NavJustMovedToId = 0;
|
||||||
|
|
||||||
// Process navigation move request
|
// Process navigation move request
|
||||||
if (g.NavMoveRequest && g.NavMoveResultId != 0)
|
if (g.NavMoveRequest && g.NavMoveResult.ID != 0)
|
||||||
{
|
{
|
||||||
// Scroll to keep newly navigated item fully into view
|
// Scroll to keep newly navigated item fully into view
|
||||||
IM_ASSERT(g.NavWindow);
|
ImGuiNavMoveResult* result = &g.NavMoveResult;
|
||||||
|
IM_ASSERT(g.NavWindow && result->Window);
|
||||||
if (g.NavLayer == 0)
|
if (g.NavLayer == 0)
|
||||||
NavScrollToBringItemIntoView(g.NavWindow, g.NavMoveResultRectRel);
|
NavScrollToBringItemIntoView(result->Window, result->RectRel);
|
||||||
|
|
||||||
// Apply result from previous frame navigation directional move request
|
// Apply result from previous frame navigation directional move request
|
||||||
ClearActiveID();
|
ClearActiveID();
|
||||||
SetNavIDAndMoveMouse(g.NavMoveResultId, g.NavLayer, g.NavMoveResultRectRel);
|
SetNavIDAndMoveMouse(result->ID, g.NavLayer, result->RectRel);
|
||||||
g.NavJustMovedToId = g.NavMoveResultId;
|
g.NavJustMovedToId = result->ID;
|
||||||
g.NavMoveFromClampedRefRect = false;
|
g.NavMoveFromClampedRefRect = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2899,7 +2902,7 @@ static void ImGui::NavUpdate()
|
|||||||
if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive)
|
if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive)
|
||||||
{
|
{
|
||||||
IM_ASSERT(g.NavMoveRequest);
|
IM_ASSERT(g.NavMoveRequest);
|
||||||
if (g.NavMoveResultId == 0)
|
if (g.NavMoveResult.ID == 0)
|
||||||
g.NavDisableHighlight = false;
|
g.NavDisableHighlight = false;
|
||||||
g.NavMoveRequestForward = ImGuiNavForward_None;
|
g.NavMoveRequestForward = ImGuiNavForward_None;
|
||||||
}
|
}
|
||||||
@ -3058,9 +3061,10 @@ static void ImGui::NavUpdate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reset search
|
// Reset search
|
||||||
g.NavMoveResultId = 0;
|
ImGuiNavMoveResult* result = &g.NavMoveResult;
|
||||||
g.NavMoveResultParentId = 0;
|
result->ID = result->ParentID = 0;
|
||||||
g.NavMoveResultDistAxial = g.NavMoveResultDistBox = g.NavMoveResultDistCenter = FLT_MAX;
|
result->Window = NULL;
|
||||||
|
result->DistAxial = result->DistBox = result->DistCenter = FLT_MAX;
|
||||||
|
|
||||||
// When we have manually scrolled (without using navigation) and NavId becomes out of bounds, we project its bounding box to the visible area to restart navigation within visible items
|
// When we have manually scrolled (without using navigation) and NavId becomes out of bounds, we project its bounding box to the visible area to restart navigation within visible items
|
||||||
if (g.NavMoveRequest && g.NavMoveFromClampedRefRect && g.NavLayer == 0)
|
if (g.NavMoveRequest && g.NavMoveFromClampedRefRect && g.NavLayer == 0)
|
||||||
@ -4821,7 +4825,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla
|
|||||||
static void NavProcessMoveRequestWrapAround(ImGuiWindow* window)
|
static void NavProcessMoveRequestWrapAround(ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.NavMoveRequest && g.NavWindow == window && g.NavMoveResultId == 0)
|
if (g.NavMoveRequest && g.NavWindow == window && g.NavMoveResult.ID == 0)
|
||||||
if ((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == 0)
|
if ((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == 0)
|
||||||
{
|
{
|
||||||
g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
|
g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
|
||||||
@ -10856,7 +10860,7 @@ void ImGui::EndMenuBar()
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
// Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings.
|
// Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings.
|
||||||
if (g.NavMoveRequest && g.NavMoveResultId == 0 && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
if (g.NavMoveRequest && g.NavMoveResult.ID == 0 && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
||||||
{
|
{
|
||||||
ImGuiWindow* nav_earliest_child = g.NavWindow;
|
ImGuiWindow* nav_earliest_child = g.NavWindow;
|
||||||
while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
||||||
@ -11024,7 +11028,7 @@ void ImGui::EndMenu()
|
|||||||
// Nav: When a left move request within our child menu failed, close the menu
|
// Nav: When a left move request within our child menu failed, close the menu
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveRequest && g.NavMoveResultId == 0 && g.NavMoveDir == ImGuiDir_Left && window->DC.LayoutType == ImGuiLayoutType_Vertical)
|
if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveRequest && g.NavMoveResult.ID == 0 && g.NavMoveDir == ImGuiDir_Left && window->DC.LayoutType == ImGuiLayoutType_Vertical)
|
||||||
{
|
{
|
||||||
ClosePopupToLevel(g.OpenPopupStack.Size - 1);
|
ClosePopupToLevel(g.OpenPopupStack.Size - 1);
|
||||||
g.NavMoveRequest = false;
|
g.NavMoveRequest = false;
|
||||||
|
@ -504,6 +504,19 @@ struct ImDrawDataBuilder
|
|||||||
IMGUI_API void FlattenIntoSingleLayer();
|
IMGUI_API void FlattenIntoSingleLayer();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ImGuiNavMoveResult
|
||||||
|
{
|
||||||
|
ImGuiID ID; // Best candidate
|
||||||
|
ImGuiID ParentID; // Best candidate window->IDStack.back() - to compare context
|
||||||
|
ImGuiWindow* Window; // Best candidate window
|
||||||
|
float DistBox; // Best candidate box distance to current NavId
|
||||||
|
float DistCenter; // Best candidate center distance to current NavId
|
||||||
|
float DistAxial; // Best candidate selected distance (box/center) to current NavId
|
||||||
|
ImRect RectRel; // Best candidate bounding box in window relative space
|
||||||
|
|
||||||
|
ImGuiNavMoveResult() { ID = ParentID = 0; Window = NULL; DistBox = DistCenter = DistAxial = 0.0f; }
|
||||||
|
};
|
||||||
|
|
||||||
// Storage for SetNexWindow** functions
|
// Storage for SetNexWindow** functions
|
||||||
struct ImGuiNextWindowData
|
struct ImGuiNextWindowData
|
||||||
{
|
{
|
||||||
@ -620,12 +633,7 @@ struct ImGuiContext
|
|||||||
ImGuiNavForward NavMoveRequestForward; // None / ForwardQueued / ForwardActive (this is used to navigate sibling parent menus from a child menu)
|
ImGuiNavForward NavMoveRequestForward; // None / ForwardQueued / ForwardActive (this is used to navigate sibling parent menus from a child menu)
|
||||||
ImGuiDir NavMoveDir; // Direction of the move request (left/right/up/down)
|
ImGuiDir NavMoveDir; // Direction of the move request (left/right/up/down)
|
||||||
ImGuiDir NavMoveDirLast; // Direction of the previous move request
|
ImGuiDir NavMoveDirLast; // Direction of the previous move request
|
||||||
ImGuiID NavMoveResultId; // Best move request candidate
|
ImGuiNavMoveResult NavMoveResult; // Best move request candidate
|
||||||
ImGuiID NavMoveResultParentId; // Best move request candidate window->IDStack.back() - to compare context
|
|
||||||
float NavMoveResultDistBox; // Best move request candidate box distance to current NavId
|
|
||||||
float NavMoveResultDistCenter; // Best move request candidate center distance to current NavId
|
|
||||||
float NavMoveResultDistAxial;
|
|
||||||
ImRect NavMoveResultRectRel; // Best move request candidate bounding box in window relative space
|
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user
|
ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user
|
||||||
@ -738,9 +746,6 @@ struct ImGuiContext
|
|||||||
NavMoveRequest = false;
|
NavMoveRequest = false;
|
||||||
NavMoveRequestForward = ImGuiNavForward_None;
|
NavMoveRequestForward = ImGuiNavForward_None;
|
||||||
NavMoveDir = NavMoveDirLast = ImGuiDir_None;
|
NavMoveDir = NavMoveDirLast = ImGuiDir_None;
|
||||||
NavMoveResultId = 0;
|
|
||||||
NavMoveResultParentId = 0;
|
|
||||||
NavMoveResultDistBox = NavMoveResultDistCenter = NavMoveResultDistAxial = 0.0f;
|
|
||||||
|
|
||||||
ModalWindowDarkeningRatio = 0.0f;
|
ModalWindowDarkeningRatio = 0.0f;
|
||||||
OverlayDrawList._Data = &DrawListSharedData;
|
OverlayDrawList._Data = &DrawListSharedData;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user