import time import threading import runtime.whisplay_client class WhisplayInterface: LONG_PRESS_THRESHOLD = 0.5 DOUBLE_PRESS_THRESHOLD = 0.3 def __init__(self): self.board = None self._lock = threading.Lock() self._button_press_start = None self._button_press_end = None self._button_is_pressed = False self._button_was_pressed = False self._button_is_long_pressed = False self._button_was_long_pressed = False self._button_was_double_pressed = False # Edge-detection state self._prev_is_pressed = False self._prev_press_end = None # -- Properties -- @property def is_pressed(self): return self._button_is_pressed @property def was_pressed(self): return self._button_was_pressed @property def is_long_pressed(self): return self._button_is_long_pressed @property def was_long_pressed(self): return self._button_was_long_pressed @property def was_double_pressed(self): return self._button_was_double_pressed @property def press_duration(self): if self._button_press_start is None: return 0.0 end = self._button_press_end if self._button_press_end is not None else time.time() return end - self._button_press_start # -- Attachment -- def create_board(self, app_id, display_name, icon, use_daemon_default_log=True): self.board = runtime.whisplay_client.create_whisplay_hardware(app_id=app_id, display_name=display_name, icon=icon, use_daemon_default_log=use_daemon_default_log) self.board.on_button_press(self._on_button_press) self.board.on_button_release(self._on_button_release) # -- Internal press/release (called from GPIO thread) -- def _on_button_press(self): with self._lock: self._button_is_pressed = True self._button_press_start = time.time() def _on_button_release(self): with self._lock: self._button_is_pressed = False self._button_press_end = time.time() # -- Polled update (called from gesture thread) -- def update_gestures(self): self._button_was_pressed = False self._button_was_long_pressed = False self._button_was_double_pressed = False with self._lock: is_pressed = self._button_is_pressed press_start = self._button_press_start press_end = self._button_press_end now = time.time() # Press edge: transitioned from not-pressed to pressed if not self._prev_is_pressed and is_pressed: if self._prev_press_end is not None and press_start is not None: gap = press_start - self._prev_press_end if gap < WhisplayInterface.DOUBLE_PRESS_THRESHOLD: self._button_was_double_pressed = True # Release edge: transitioned from pressed to not-pressed if self._prev_is_pressed and not is_pressed: self._button_was_pressed = True if press_start is not None and press_end is not None: duration = press_end - press_start if duration >= WhisplayInterface.LONG_PRESS_THRESHOLD: self._button_was_long_pressed = True self._prev_press_end = press_end # Level flag: currently held past threshold if is_pressed and press_start is not None: self._button_is_long_pressed = (now - press_start) >= WhisplayInterface.LONG_PRESS_THRESHOLD else: self._button_is_long_pressed = False self._prev_is_pressed = is_pressed