Source code for simvx.core.input.drag

"""The drag threshold: how far a pointer travels from its press before the motion is a drag.

A setting on the tree, which every node inherits, and on any node, which its
subtree inherits, per pointer type: a finger lands a good deal further from
where it meant to than a mouse does, and a pen sits between them. The router
reads it once per press, from the node that took the press, and every event of
that press carries the answer as ``PointerEvent.dragging``.
"""

from __future__ import annotations

from collections.abc import Mapping

from .enums import PointerType

__all__ = ["DEFAULT_DRAG_THRESHOLD", "drag_threshold_map"]

#: What a tree starts with, in logical pixels, by pointer type.
DEFAULT_DRAG_THRESHOLD: Mapping[PointerType, float] = {
    PointerType.MOUSE: 4.0,
    PointerType.PEN: 6.0,
    PointerType.TOUCH: 12.0,
}


[docs] def drag_threshold_map(value: Mapping[PointerType | str, float] | None) -> dict[PointerType, float] | None: """Coerce a ``drag_threshold`` assignment: ``None``, or a map from pointer type to distance. Keys take the member or its plain string (``{"touch": 16}``), and a type the map leaves out is inherited. A negative distance or an unknown type raises naming what is allowed. """ if value is None: return None if not isinstance(value, Mapping): raise TypeError( f"drag_threshold takes a mapping from pointer type to distance, or None to inherit; got {value!r}" ) out: dict[PointerType, float] = {} for key, distance in value.items(): try: kind = PointerType(key) except ValueError: allowed = ", ".join(repr(t.value) for t in PointerType) raise ValueError(f"drag_threshold has no pointer type {key!r}; expected one of {allowed}") from None distance = float(distance) if distance < 0: raise ValueError(f"drag_threshold for {kind.value} must not be negative, got {distance}") out[kind] = distance return out