Nav: Rectangle rectangle stored per window and per layer as well. Makes things simpler, allows enable us to visualize more data.

This commit is contained in:
omar 2017-09-29 19:26:03 +02:00
parent 54eb4c485e
commit 9712a81f85
2 changed files with 22 additions and 16 deletions

View File

@ -1839,7 +1839,6 @@ ImGuiWindow::ImGuiWindow(const char* name)
Appearing = false; Appearing = false;
BeginCount = 0; BeginCount = 0;
PopupId = 0; PopupId = 0;
NavLastIds[0] = NavLastIds[1] = 0;
AutoFitFramesX = AutoFitFramesY = -1; AutoFitFramesX = AutoFitFramesY = -1;
AutoFitOnlyGrows = false; AutoFitOnlyGrows = false;
AutoFitChildAxises = 0x00; AutoFitChildAxises = 0x00;
@ -1848,6 +1847,9 @@ ImGuiWindow::ImGuiWindow(const char* name)
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
NavLastIds[0] = NavLastIds[1] = 0;
NavRefRectRel[0] = NavRefRectRel[1] = ImRect();
LastFrameActive = -1; LastFrameActive = -1;
ItemWidthDefault = 0.0f; ItemWidthDefault = 0.0f;
FontWindowScale = 1.0f; FontWindowScale = 1.0f;
@ -2223,7 +2225,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id, const ImRect* nav_bb_ar
// Update window-relative bounding box of navigated item // Update window-relative bounding box of navigated item
if (g.NavId == *id) if (g.NavId == *id)
{ {
g.NavRefRectRel = nav_bb_rel; window->NavRefRectRel[window->DC.NavLayerCurrent] = nav_bb_rel;
g.NavIdIsAlive = true; g.NavIdIsAlive = true;
g.NavIdTabCounter = window->FocusIdxTabCounter; g.NavIdTabCounter = window->FocusIdxTabCounter;
} }
@ -2459,7 +2461,7 @@ static void SetNavIdAndMoveMouse(ImGuiID id, int nav_layer, const ImRect& rect_r
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
SetNavId(id, nav_layer); SetNavId(id, nav_layer);
g.NavRefRectRel = rect_rel; g.NavWindow->NavRefRectRel[nav_layer] = rect_rel;
g.NavMousePosDirty = true; g.NavMousePosDirty = true;
g.NavDisableHighlight = false; g.NavDisableHighlight = false;
g.NavDisableMouseHover = true; g.NavDisableMouseHover = true;
@ -2487,11 +2489,13 @@ static void NavInitWindow(ImGuiWindow* window, bool force_reinit)
static ImVec2 NavCalcPreferredMousePos() static ImVec2 NavCalcPreferredMousePos()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (!g.NavWindow) ImGuiWindow* window = g.NavWindow;
if (!window)
return g.IO.MousePos; return g.IO.MousePos;
ImVec2 p = g.NavWindow->Pos + ImVec2(g.NavRefRectRel.Min.x + ImMin(g.Style.FramePadding.x*4, g.NavRefRectRel.GetWidth()), g.NavRefRectRel.Max.y - ImMin(g.Style.FramePadding.y, g.NavRefRectRel.GetHeight())); const ImRect& ref_rect_rel = window->NavRefRectRel[g.NavLayer];
ImRect r = GetVisibleRect(); ImVec2 pos = g.NavWindow->Pos + ImVec2(ref_rect_rel.Min.x + ImMin(g.Style.FramePadding.x*4, ref_rect_rel.GetWidth()), ref_rect_rel.Max.y - ImMin(g.Style.FramePadding.y, ref_rect_rel.GetHeight()));
return ImFloor(ImClamp(p, r.Min, r.Max)); // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta. ImRect visible_rect = GetVisibleRect();
return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max)); // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta.
} }
static int FindWindowIndex(ImGuiWindow* window) // FIXME-OPT O(N) static int FindWindowIndex(ImGuiWindow* window) // FIXME-OPT O(N)
@ -2580,7 +2584,7 @@ static void NavUpdate()
// Apply result from previous navigation init request (typically select the first item, unless SetItemDefaultFocus() has been called) // Apply result from previous navigation init request (typically select the first item, unless SetItemDefaultFocus() has been called)
IM_ASSERT(g.NavWindow); IM_ASSERT(g.NavWindow);
SetNavId(g.NavInitDefaultResultId, g.NavLayer); SetNavId(g.NavInitDefaultResultId, g.NavLayer);
g.NavRefRectRel = g.NavInitDefaultResultRectRel; g.NavWindow->NavRefRectRel[g.NavLayer] = g.NavInitDefaultResultRectRel;
if (g.NavDisableMouseHover) if (g.NavDisableMouseHover)
g.NavMousePosDirty = true; g.NavMousePosDirty = true;
} }
@ -2834,21 +2838,22 @@ static void NavUpdate()
{ {
// When we have manually scrolled and NavId is out of bounds, we clamp its bounding box (used for search) to the visible area to restart navigation within visible items // When we have manually scrolled and NavId is out of bounds, we clamp its bounding box (used for search) to the visible area to restart navigation within visible items
ImRect window_rect_rel(g.NavWindow->InnerRect.Min - g.NavWindow->Pos - ImVec2(1,1), g.NavWindow->InnerRect.Max - g.NavWindow->Pos + ImVec2(1,1)); ImRect window_rect_rel(g.NavWindow->InnerRect.Min - g.NavWindow->Pos - ImVec2(1,1), g.NavWindow->InnerRect.Max - g.NavWindow->Pos + ImVec2(1,1));
if (!window_rect_rel.Contains(g.NavRefRectRel)) if (!window_rect_rel.Contains(g.NavWindow->NavRefRectRel[g.NavLayer]))
{ {
float pad = g.NavWindow->CalcFontSize() * 0.5f; float pad = g.NavWindow->CalcFontSize() * 0.5f;
window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intend of starting navigation from first fully visible item window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intend of starting navigation from first fully visible item
g.NavRefRectRel.ClipWith(window_rect_rel); g.NavWindow->NavRefRectRel[g.NavLayer].ClipWith(window_rect_rel);
g.NavId = 0; g.NavId = 0;
} }
g.NavMoveFromClampedRefRect = false; g.NavMoveFromClampedRefRect = false;
} }
// For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items) // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items)
g.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + g.NavRefRectRel.Min, g.NavWindow->Pos + g.NavRefRectRel.Max) : ImRect(); g.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + g.NavWindow->NavRefRectRel[g.NavLayer].Min, g.NavWindow->Pos + g.NavWindow->NavRefRectRel[g.NavLayer].Max) : ImRect();
g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x); g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x);
g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x; g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x;
//g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG] //g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG]
//if (g.NavWindow) for (int layer = 0; layer < 2; layer++) g.OverlayDrawList.AddRect(g.NavWindow->Pos + g.NavWindow->NavRefRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRefRectRel[layer].Max, IM_COL32(255,200,0,255)); // [DEBUG]
} }
void ImGui::NewFrame() void ImGui::NewFrame()
@ -5509,7 +5514,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
g.NavLayer = 0; g.NavLayer = 0;
if (window && g.NavDisableMouseHover) if (window && g.NavDisableMouseHover)
g.NavMousePosDirty = true; g.NavMousePosDirty = true;
g.NavRefRectRel.Min = g.NavRefRectRel.Max = window ? (window->DC.CursorStartPos - window->Pos) : ImVec2(0,0); window->NavRefRectRel[0].Min = window->NavRefRectRel[1].Max = window ? (window->DC.CursorStartPos - window->Pos) : ImVec2(0,0);
g.NavWindow = window; g.NavWindow = window;
} }
@ -11622,6 +11627,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y); ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y);
ImGui::BulletText("Active: %d, Accessed: %d", window->Active, window->Accessed); ImGui::BulletText("Active: %d, Accessed: %d", window->Active, window->Accessed);
ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask); ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
ImGui::BulletText("NavRefRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRefRectRel[0].Min.x, window->NavRefRectRel[0].Min.y, window->NavRefRectRel[0].Max.x, window->NavRefRectRel[0].Max.y);
if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow");
if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows");
ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair));
@ -11655,7 +11661,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui::Text("ActiveId: 0x%08X/0x%08X, ActiveIdSource: %s", g.ActiveId, g.ActiveIdPreviousFrame, input_source_names[g.ActiveIdSource]); ImGui::Text("ActiveId: 0x%08X/0x%08X, ActiveIdSource: %s", g.ActiveId, g.ActiveIdPreviousFrame, input_source_names[g.ActiveIdSource]);
ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
ImGui::Text("NavWindow: '%s', NavId: 0x%08X, NavLayer: %d", g.NavWindow ? g.NavWindow->Name : "NULL", g.NavId, g.NavLayer); ImGui::Text("NavWindow: '%s', NavId: 0x%08X, NavLayer: %d", g.NavWindow ? g.NavWindow->Name : "NULL", g.NavId, g.NavLayer);
ImGui::Text("NavRefRectRel: (%.1f,%.1f)(%.1f,%.1f)", g.NavRefRectRel.Min.x, g.NavRefRectRel.Min.y, g.NavRefRectRel.Max.x, g.NavRefRectRel.Max.y);
ImGui::Text("NavUsable: %d, NavActive: %d", g.IO.NavUsable, g.IO.NavActive); ImGui::Text("NavUsable: %d, NavActive: %d", g.IO.NavUsable, g.IO.NavActive);
ImGui::Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId); ImGui::Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId);
ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover);

View File

@ -459,7 +459,7 @@ struct ImGuiContext
ImGuiID NavId; // Nav/focused item for navigation ImGuiID NavId; // Nav/focused item for navigation
ImGuiID NavActivateId, NavInputId; // ~~ IsKeyPressedMap(ImGuiKey_NavActive) ? NavId : 0, etc. (to make widget code terser) ImGuiID NavActivateId, NavInputId; // ~~ IsKeyPressedMap(ImGuiKey_NavActive) ? NavId : 0, etc. (to make widget code terser)
ImGuiID NavTabbedId; // ImGuiID NavTabbedId; //
ImRect NavRefRectRel, NavScoringRectScreen;// Reference rectangle, in window space. Modified rectangle for directional navigation scoring, in screen space. ImRect NavScoringRectScreen; // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring.
ImGuiWindow* NavWindowingTarget; ImGuiWindow* NavWindowingTarget;
float NavWindowingDisplayAlpha; float NavWindowingDisplayAlpha;
bool NavWindowingToggleLayer; bool NavWindowingToggleLayer;
@ -571,7 +571,7 @@ struct ImGuiContext
NavWindow = NULL; NavWindow = NULL;
NavId = NavActivateId = NavInputId = NavTabbedId = 0; NavId = NavActivateId = NavInputId = NavTabbedId = 0;
NavRefRectRel = NavScoringRectScreen = ImRect(); NavScoringRectScreen = ImRect();
NavWindowingTarget = NULL; NavWindowingTarget = NULL;
NavWindowingDisplayAlpha = 0.0f; NavWindowingDisplayAlpha = 0.0f;
NavWindowingToggleLayer = false; NavWindowingToggleLayer = false;
@ -776,6 +776,7 @@ struct IMGUI_API ImGuiWindow
ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right. ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right.
ImGuiID NavLastIds[2]; // Last known NavId for this window, per layer (0/1) ImGuiID NavLastIds[2]; // Last known NavId for this window, per layer (0/1)
ImRect NavRefRectRel[2]; // Reference rectangle, in window space
ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame
ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack