129 lines
3.9 KiB
Python
129 lines
3.9 KiB
Python
"""
|
|
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"
|
|
SETTING_CHANGED = "setting_changed"
|