Class UITKScreenSpace
Screen-to-panel conversion and edge clamping for the cursor-anchored widgets — the tooltip, the dropdown and the context menu.
public static class UITKScreenSpace
- Inheritance
-
UITKScreenSpace
- Inherited Members
Remarks
This exists because the same two mistakes were made independently in each of them.
The first is the Y axis. The Input System reports the pointer with Y measured from the
bottom of the screen; UI Toolkit lays out from the top. Handing a raw
Mouse.current.position to UnityEngine.UIElements.RuntimePanelUtils.ScreenToPanel(UnityEngine.UIElements.IPanel, UnityEngine.Vector2) therefore
mirrors the widget about the horizontal centre of the screen — hover something near the
top and the tooltip appears near the bottom.
The second is measurement. An element's resolvedStyle size is NaN until the layout
pass that follows the frame it was added or re-cloned in, so a clamp computed at the
moment of positioning has nothing to clamp against and silently does nothing. The clamp
here reports whether it could be applied, and the caller defers a single re-clamp to the
element's next UnityEngine.UIElements.GeometryChangedEvent when it could not.
Sizes are compared against the container's contentRect rather than
Screen.width/Screen.height: PanelSettings scales the panel against a
reference resolution, so at any other resolution the two spaces differ and a clamp in
pixels leaves the widget short of, or past, the edge it was meant to sit inside.
Methods
PlaceClamped(VisualElement, VisualElement, Vector2, bool)
Positions element at desired and keeps it inside
container, deferring the clamp when the element has not been laid
out yet.
public static void PlaceClamped(VisualElement container, VisualElement element, Vector2 desired, bool flip = false)
Parameters
containerVisualElementElement the position is measured against, normally the panel root.
elementVisualElementAbsolutely-positioned element to move.
desiredVector2Preferred top-left corner, in panel points.
flipboolWhen true, an element that would overhang an edge is placed on the other side of
desiredinstead of being slid back along it. That is what a menu or a tooltip opened near the bottom of the screen wants: sliding it up would put it under the cursor, which is the one place it must not be.
TryGetPointerPanelPosition(IPanel, out Vector2)
Reads the pointer position in panel coordinates.
public static bool TryGetPointerPanelPosition(IPanel panel, out Vector2 position)
Parameters
panelIPanelPanel to convert into.
positionVector2The pointer position in panel points.
Returns
- bool
True when a mouse exists and the position could be converted.