MCPcopy Create free account
hub / github.com/VictorGordan/opengl-tutorials / NavScoreItem

Method NavScoreItem

ImGUI GLFW Tutorial/imgui/imgui.cpp:8650–8779  ·  view source on GitHub ↗

Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057

Source from the content-addressed store, hash-verified

8648
8649// Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057
8650static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
8651{
8652 ImGuiContext& g = *GImGui;
8653 ImGuiWindow* window = g.CurrentWindow;
8654 if (g.NavLayer != window->DC.NavLayerCurrent)
8655 return false;
8656
8657 const ImRect& curr = g.NavScoringRect; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width)
8658 g.NavScoringCount++;
8659
8660 // When entering through a NavFlattened border, we consider child window items as fully clipped for scoring
8661 if (window->ParentWindow == g.NavWindow)
8662 {
8663 IM_ASSERT((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened);
8664 if (!window->ClipRect.Overlaps(cand))
8665 return false;
8666 cand.ClipWithFull(window->ClipRect); // This allows the scored item to not overlap other candidates in the parent window
8667 }
8668
8669 // We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items)
8670 // For example, this ensure that items in one column are not reached when moving vertically from items in another column.
8671 NavClampRectToVisibleAreaForMoveDir(g.NavMoveClipDir, cand, window->ClipRect);
8672
8673 // Compute distance between boxes
8674 // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed.
8675 float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x);
8676 float dby = NavScoreItemDistInterval(ImLerp(cand.Min.y, cand.Max.y, 0.2f), ImLerp(cand.Min.y, cand.Max.y, 0.8f), ImLerp(curr.Min.y, curr.Max.y, 0.2f), ImLerp(curr.Min.y, curr.Max.y, 0.8f)); // Scale down on Y to keep using box-distance for vertically touching items
8677 if (dby != 0.0f && dbx != 0.0f)
8678 dbx = (dbx / 1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f);
8679 float dist_box = ImFabs(dbx) + ImFabs(dby);
8680
8681 // Compute distance between centers (this is off by a factor of 2, but we only compare center distances with each other so it doesn't matter)
8682 float dcx = (cand.Min.x + cand.Max.x) - (curr.Min.x + curr.Max.x);
8683 float dcy = (cand.Min.y + cand.Max.y) - (curr.Min.y + curr.Max.y);
8684 float dist_center = ImFabs(dcx) + ImFabs(dcy); // L1 metric (need this for our connectedness guarantee)
8685
8686 // Determine which quadrant of 'curr' our candidate item 'cand' lies in based on distance
8687 ImGuiDir quadrant;
8688 float dax = 0.0f, day = 0.0f, dist_axial = 0.0f;
8689 if (dbx != 0.0f || dby != 0.0f)
8690 {
8691 // For non-overlapping boxes, use distance between boxes
8692 dax = dbx;
8693 day = dby;
8694 dist_axial = dist_box;
8695 quadrant = ImGetDirQuadrantFromDelta(dbx, dby);
8696 }
8697 else if (dcx != 0.0f || dcy != 0.0f)
8698 {
8699 // For overlapping boxes with different centers, use distance between centers
8700 dax = dcx;
8701 day = dcy;
8702 dist_axial = dist_center;
8703 quadrant = ImGetDirQuadrantFromDelta(dcx, dcy);
8704 }
8705 else
8706 {
8707 // Degenerate case: two overlapping buttons with same center, break ties arbitrarily (note that LastItemId here is really the _previous_ item order, but it doesn't matter)

Callers

nothing calls this directly

Calls 11

NavScoreItemDistIntervalFunction · 0.70
ImLerpFunction · 0.70
ImFormatStringFunction · 0.70
GetForegroundDrawListFunction · 0.70
ImVec2Function · 0.70
IsKeyPressedMapFunction · 0.70
AddRectMethod · 0.45
AddRectFilledMethod · 0.45
AddTextMethod · 0.45

Tested by

no test coverage detected