Scroll to keep newly navigated item fully into view
| 10215 | |
| 10216 | // Scroll to keep newly navigated item fully into view |
| 10217 | ImVec2 ImGui::ScrollToRectEx(ImGuiWindow* window, const ImRect& item_rect, ImGuiScrollFlags flags) |
| 10218 | { |
| 10219 | ImGuiContext& g = *GImGui; |
| 10220 | ImRect window_rect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1)); |
| 10221 | //GetForegroundDrawList(window)->AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG] |
| 10222 | |
| 10223 | // Check that only one behavior is selected per axis |
| 10224 | IM_ASSERT((flags & ImGuiScrollFlags_MaskX_) == 0 || ImIsPowerOfTwo(flags & ImGuiScrollFlags_MaskX_)); |
| 10225 | IM_ASSERT((flags & ImGuiScrollFlags_MaskY_) == 0 || ImIsPowerOfTwo(flags & ImGuiScrollFlags_MaskY_)); |
| 10226 | |
| 10227 | // Defaults |
| 10228 | ImGuiScrollFlags in_flags = flags; |
| 10229 | if ((flags & ImGuiScrollFlags_MaskX_) == 0 && window->ScrollbarX) |
| 10230 | flags |= ImGuiScrollFlags_KeepVisibleEdgeX; |
| 10231 | if ((flags & ImGuiScrollFlags_MaskY_) == 0) |
| 10232 | flags |= window->Appearing ? ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeY; |
| 10233 | |
| 10234 | const bool fully_visible_x = item_rect.Min.x >= window_rect.Min.x && item_rect.Max.x <= window_rect.Max.x; |
| 10235 | const bool fully_visible_y = item_rect.Min.y >= window_rect.Min.y && item_rect.Max.y <= window_rect.Max.y; |
| 10236 | const bool can_be_fully_visible_x = (item_rect.GetWidth() + g.Style.ItemSpacing.x * 2.0f) <= window_rect.GetWidth() || (window->AutoFitFramesX > 0) || (window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0; |
| 10237 | const bool can_be_fully_visible_y = (item_rect.GetHeight() + g.Style.ItemSpacing.y * 2.0f) <= window_rect.GetHeight() || (window->AutoFitFramesY > 0) || (window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0; |
| 10238 | |
| 10239 | if ((flags & ImGuiScrollFlags_KeepVisibleEdgeX) && !fully_visible_x) |
| 10240 | { |
| 10241 | if (item_rect.Min.x < window_rect.Min.x || !can_be_fully_visible_x) |
| 10242 | SetScrollFromPosX(window, item_rect.Min.x - g.Style.ItemSpacing.x - window->Pos.x, 0.0f); |
| 10243 | else if (item_rect.Max.x >= window_rect.Max.x) |
| 10244 | SetScrollFromPosX(window, item_rect.Max.x + g.Style.ItemSpacing.x - window->Pos.x, 1.0f); |
| 10245 | } |
| 10246 | else if (((flags & ImGuiScrollFlags_KeepVisibleCenterX) && !fully_visible_x) || (flags & ImGuiScrollFlags_AlwaysCenterX)) |
| 10247 | { |
| 10248 | if (can_be_fully_visible_x) |
| 10249 | SetScrollFromPosX(window, ImFloor((item_rect.Min.x + item_rect.Max.y) * 0.5f) - window->Pos.x, 0.5f); |
| 10250 | else |
| 10251 | SetScrollFromPosX(window, item_rect.Min.x - window->Pos.x, 0.0f); |
| 10252 | } |
| 10253 | |
| 10254 | if ((flags & ImGuiScrollFlags_KeepVisibleEdgeY) && !fully_visible_y) |
| 10255 | { |
| 10256 | if (item_rect.Min.y < window_rect.Min.y || !can_be_fully_visible_y) |
| 10257 | SetScrollFromPosY(window, item_rect.Min.y - g.Style.ItemSpacing.y - window->Pos.y, 0.0f); |
| 10258 | else if (item_rect.Max.y >= window_rect.Max.y) |
| 10259 | SetScrollFromPosY(window, item_rect.Max.y + g.Style.ItemSpacing.y - window->Pos.y, 1.0f); |
| 10260 | } |
| 10261 | else if (((flags & ImGuiScrollFlags_KeepVisibleCenterY) && !fully_visible_y) || (flags & ImGuiScrollFlags_AlwaysCenterY)) |
| 10262 | { |
| 10263 | if (can_be_fully_visible_y) |
| 10264 | SetScrollFromPosY(window, ImFloor((item_rect.Min.y + item_rect.Max.y) * 0.5f) - window->Pos.y, 0.5f); |
| 10265 | else |
| 10266 | SetScrollFromPosY(window, item_rect.Min.y - window->Pos.y, 0.0f); |
| 10267 | } |
| 10268 | |
| 10269 | ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); |
| 10270 | ImVec2 delta_scroll = next_scroll - window->Scroll; |
| 10271 | |
| 10272 | // Also scroll parent window to keep us into view if necessary |
| 10273 | if (!(flags & ImGuiScrollFlags_NoScrollParent) && (window->Flags & ImGuiWindowFlags_ChildWindow)) |
| 10274 | { |
nothing calls this directly
no test coverage detected