| 12779 | } |
| 12780 | |
| 12781 | ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window) |
| 12782 | { |
| 12783 | ImGuiContext& g = *GImGui; |
| 12784 | |
| 12785 | ImRect r_outer = GetPopupAllowedExtentRect(window); |
| 12786 | if (window->Flags & ImGuiWindowFlags_ChildMenu) |
| 12787 | { |
| 12788 | // Child menus typically request _any_ position within the parent menu item, and then we move the new menu outside the parent bounds. |
| 12789 | // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. |
| 12790 | IM_ASSERT(g.CurrentWindow == window); |
| 12791 | ImGuiWindow* parent_window = g.CurrentWindowStack[g.CurrentWindowStack.Size - 2].Window; |
| 12792 | float horizontal_overlap = g.Style.ItemInnerSpacing.x; // We want some overlap to convey the relative depth of each menu (currently the amount of overlap is hard-coded to style.ItemSpacing.x). |
| 12793 | ImRect r_avoid; |
| 12794 | if (parent_window->DC.MenuBarAppending) |
| 12795 | r_avoid = ImRect(-FLT_MAX, parent_window->ClipRect.Min.y, FLT_MAX, parent_window->ClipRect.Max.y); // Avoid parent menu-bar. If we wanted multi-line menu-bar, we may instead want to have the calling window setup e.g. a NextWindowData.PosConstraintAvoidRect field |
| 12796 | else |
| 12797 | r_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); |
| 12798 | return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Default); |
| 12799 | } |
| 12800 | if (window->Flags & ImGuiWindowFlags_Popup) |
| 12801 | { |
| 12802 | return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, ImRect(window->Pos, window->Pos), ImGuiPopupPositionPolicy_Default); // Ideally we'd disable r_avoid here |
| 12803 | } |
| 12804 | if (window->Flags & ImGuiWindowFlags_Tooltip) |
| 12805 | { |
| 12806 | // Position tooltip (always follows mouse + clamp within outer boundaries) |
| 12807 | // FIXME: |
| 12808 | // - Too many paths. One problem is that FindBestWindowPosForPopupEx() doesn't allow passing a suggested position (so touch screen path doesn't use it by default). |
| 12809 | // - Drag and drop tooltips are not using this path either: BeginTooltipEx() manually sets their position. |
| 12810 | // - Require some tidying up. In theory we could handle both cases in same location, but requires a bit of shuffling |
| 12811 | // as drag and drop tooltips are calling SetNextWindowPos() leading to 'window_pos_set_by_api' being set in Begin(). |
| 12812 | IM_ASSERT(g.CurrentWindow == window); |
| 12813 | const float scale = g.Style.MouseCursorScale; |
| 12814 | const ImVec2 ref_pos = NavCalcPreferredRefPos(ImGuiWindowFlags_Tooltip); |
| 12815 | |
| 12816 | if (g.IO.MouseSource == ImGuiMouseSource_TouchScreen && NavCalcPreferredRefPosSource(ImGuiWindowFlags_Tooltip) == ImGuiInputSource_Mouse) |
| 12817 | { |
| 12818 | ImVec2 tooltip_pos = ref_pos + TOOLTIP_DEFAULT_OFFSET_TOUCH * scale - (TOOLTIP_DEFAULT_PIVOT_TOUCH * window->Size); |
| 12819 | if (r_outer.Contains(ImRect(tooltip_pos, tooltip_pos + window->Size))) |
| 12820 | return tooltip_pos; |
| 12821 | } |
| 12822 | |
| 12823 | ImVec2 tooltip_pos = ref_pos + TOOLTIP_DEFAULT_OFFSET_MOUSE * scale; |
| 12824 | ImRect r_avoid; |
| 12825 | if (g.NavCursorVisible && g.NavHighlightItemUnderNav && !g.IO.ConfigNavMoveSetMousePos) |
| 12826 | r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); |
| 12827 | else |
| 12828 | r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * scale, ref_pos.y + 24 * scale); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. |
| 12829 | //GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255, 0, 255, 255)); |
| 12830 | |
| 12831 | return FindBestWindowPosForPopupEx(tooltip_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip); |
| 12832 | } |
| 12833 | IM_ASSERT(0); |
| 12834 | return window->Pos; |
| 12835 | } |
| 12836 | |
| 12837 | //----------------------------------------------------------------------------- |
| 12838 | // [SECTION] WINDOW FOCUS |