Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057
| 10377 | |
| 10378 | // Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057 |
| 10379 | static bool ImGui::NavScoreItem(ImGuiNavItemData* result) |
| 10380 | { |
| 10381 | ImGuiContext& g = *GImGui; |
| 10382 | ImGuiWindow* window = g.CurrentWindow; |
| 10383 | if (g.NavLayer != window->DC.NavLayerCurrent) |
| 10384 | return false; |
| 10385 | |
| 10386 | // FIXME: Those are not good variables names |
| 10387 | ImRect cand = g.LastItemData.NavRect; // Current item nav rectangle |
| 10388 | 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) |
| 10389 | g.NavScoringDebugCount++; |
| 10390 | |
| 10391 | // When entering through a NavFlattened border, we consider child window items as fully clipped for scoring |
| 10392 | if (window->ParentWindow == g.NavWindow) |
| 10393 | { |
| 10394 | IM_ASSERT((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened); |
| 10395 | if (!window->ClipRect.Overlaps(cand)) |
| 10396 | return false; |
| 10397 | cand.ClipWithFull(window->ClipRect); // This allows the scored item to not overlap other candidates in the parent window |
| 10398 | } |
| 10399 | |
| 10400 | // 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) |
| 10401 | // For example, this ensures that items in one column are not reached when moving vertically from items in another column. |
| 10402 | NavClampRectToVisibleAreaForMoveDir(g.NavMoveClipDir, cand, window->ClipRect); |
| 10403 | |
| 10404 | // Compute distance between boxes |
| 10405 | // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed. |
| 10406 | float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x); |
| 10407 | 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 |
| 10408 | if (dby != 0.0f && dbx != 0.0f) |
| 10409 | dbx = (dbx / 1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f); |
| 10410 | float dist_box = ImFabs(dbx) + ImFabs(dby); |
| 10411 | |
| 10412 | // 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) |
| 10413 | float dcx = (cand.Min.x + cand.Max.x) - (curr.Min.x + curr.Max.x); |
| 10414 | float dcy = (cand.Min.y + cand.Max.y) - (curr.Min.y + curr.Max.y); |
| 10415 | float dist_center = ImFabs(dcx) + ImFabs(dcy); // L1 metric (need this for our connectedness guarantee) |
| 10416 | |
| 10417 | // Determine which quadrant of 'curr' our candidate item 'cand' lies in based on distance |
| 10418 | ImGuiDir quadrant; |
| 10419 | float dax = 0.0f, day = 0.0f, dist_axial = 0.0f; |
| 10420 | if (dbx != 0.0f || dby != 0.0f) |
| 10421 | { |
| 10422 | // For non-overlapping boxes, use distance between boxes |
| 10423 | dax = dbx; |
| 10424 | day = dby; |
| 10425 | dist_axial = dist_box; |
| 10426 | quadrant = ImGetDirQuadrantFromDelta(dbx, dby); |
| 10427 | } |
| 10428 | else if (dcx != 0.0f || dcy != 0.0f) |
| 10429 | { |
| 10430 | // For overlapping boxes with different centers, use distance between centers |
| 10431 | dax = dcx; |
| 10432 | day = dcy; |
| 10433 | dist_axial = dist_center; |
| 10434 | quadrant = ImGetDirQuadrantFromDelta(dcx, dcy); |
| 10435 | } |
| 10436 | else |
nothing calls this directly
no test coverage detected