28 lines
1.1 KiB
Python
28 lines
1.1 KiB
Python
"""Strict, shared geometry for device actions; planning never dispatches input."""
|
|
|
|
from typing import Annotated, Literal
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, StrictInt
|
|
|
|
|
|
class GestureModel(BaseModel):
|
|
model_config = ConfigDict(
|
|
extra="forbid", strict=True, allow_inf_nan=False, str_strip_whitespace=True
|
|
)
|
|
|
|
|
|
Point = Annotated[list[StrictInt], Field(min_length=2, max_length=2)]
|
|
Duration = Annotated[int, Field(strict=True, ge=1, le=10000)]
|
|
CoordinateSpace = Literal["normalized", "pixel"]
|
|
|
|
|
|
def pixel_point(point: list[int], space: CoordinateSpace, width: int, height: int) -> list[int]:
|
|
if width <= 0 or height <= 0:
|
|
raise ValueError("Screen dimensions must be positive.")
|
|
limits = [1001, 1001] if space == "normalized" else [width, height]
|
|
if any(p < 0 or p >= limit for p, limit in zip(point, limits, strict=True)):
|
|
raise ValueError(f"Point {point} is outside the {space} screen bounds.")
|
|
if space == "pixel":
|
|
return list(point)
|
|
return [min(size - 1, p * size // 1000) for p, size in zip(point, [width, height], strict=True)]
|