""" Gesture event types for touch input. This module defines touch gestures that can be received from a HAL (Hardware Abstraction Layer) or touch input system, and the response format for actions to be performed. """ from __future__ import annotations from enum import Enum from dataclasses import dataclass from typing import Optional, Dict, Any class GestureType(Enum): """Touch gesture types from HAL""" TAP = "tap" # Single finger tap LONG_PRESS = "long_press" # Hold for 500ms+ SWIPE_LEFT = "swipe_left" # Swipe left (page forward) SWIPE_RIGHT = "swipe_right" # Swipe right (page back) SWIPE_UP = "swipe_up" # Swipe up (scroll down) SWIPE_DOWN = "swipe_down" # Swipe down (scroll up) PINCH_IN = "pinch_in" # Pinch fingers together (zoom out) PINCH_OUT = "pinch_out" # Spread fingers apart (zoom in) DRAG_START = "drag_start" # Start dragging/selection DRAG_MOVE = "drag_move" # Continue dragging DRAG_END = "drag_end" # End dragging/selection @dataclass class TouchEvent: """ Touch event from HAL. Represents a single touch gesture with its coordinates and metadata. """ gesture: GestureType x: int # Primary touch point X coordinate y: int # Primary touch point Y coordinate x2: Optional[int] = None # Secondary point X (for pinch/drag) y2: Optional[int] = None # Secondary point Y (for pinch/drag) timestamp_ms: float = 0 # Timestamp in milliseconds @classmethod def from_hal(cls, hal_data: dict) -> 'TouchEvent': """ Parse a touch event from HAL format. Args: hal_data: Dictionary with gesture data from HAL Expected keys: 'gesture', 'x', 'y', optionally 'x2', 'y2', 'timestamp' Returns: TouchEvent instance Example: >>> event = TouchEvent.from_hal({ ... 'gesture': 'tap', ... 'x': 450, ... 'y': 320 ... }) """ return cls( gesture=GestureType(hal_data['gesture']), x=hal_data['x'], y=hal_data['y'], x2=hal_data.get('x2'), y2=hal_data.get('y2'), timestamp_ms=hal_data.get('timestamp', 0) ) def to_dict(self) -> dict: """Convert to dictionary for serialization""" return { 'gesture': self.gesture.value, 'x': self.x, 'y': self.y, 'x2': self.x2, 'y2': self.y2, 'timestamp_ms': self.timestamp_ms } @dataclass class GestureResponse: """ Response from handling a gesture. This encapsulates the action that should be performed by the UI in response to a gesture, keeping all business logic in the library. """ action: str # Action type: "navigate", "define", "select", "zoom", "page_turn", "none", etc. data: Dict[str, Any] # Action-specific data def to_dict(self) -> dict: """ Convert to dictionary for Flask JSON response. Returns: Dictionary with action and data """ return { 'action': self.action, 'data': self.data } # Action type constants for clarity class ActionType: """Constants for gesture response action types""" NONE = "none" PAGE_TURN = "page_turn" NAVIGATE = "navigate" DEFINE = "define" SELECT = "select" ZOOM = "zoom" BOOK_LOADED = "book_loaded" WORD_SELECTED = "word_selected" SHOW_MENU = "show_menu" SELECTION_START = "selection_start" SELECTION_UPDATE = "selection_update" SELECTION_COMPLETE = "selection_complete" AT_START = "at_start" AT_END = "at_end" ERROR = "error" OVERLAY_OPENED = "overlay_opened" OVERLAY_CLOSED = "overlay_closed" CHAPTER_SELECTED = "chapter_selected"