141 lines
4.6 KiB
Python
141 lines
4.6 KiB
Python
import time
|
|
import threading
|
|
|
|
|
|
class WhisplayInterface:
|
|
def __init__(self, board=None, long_press_threshold=0.5, double_press_threshold=0.3):
|
|
self._board = board
|
|
self._long_press_threshold = long_press_threshold
|
|
self._double_press_threshold = double_press_threshold
|
|
self._button_is_double_pressed_set = False
|
|
|
|
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_is_double_pressed = False
|
|
self._button_was_double_pressed = False
|
|
|
|
self._press_callbacks = []
|
|
self._release_callbacks = []
|
|
self._running = False
|
|
self._gesture_thread = None
|
|
|
|
if board is not None:
|
|
self.attach(board)
|
|
|
|
@property
|
|
def long_press_threshold(self):
|
|
return self._long_press_threshold
|
|
|
|
@property
|
|
def double_press_threshold(self):
|
|
return self._double_press_threshold
|
|
|
|
@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 is_double_pressed(self):
|
|
return self._button_is_double_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
|
|
|
|
def attach(self, board):
|
|
self._board = board
|
|
self._board.on_button_press(self._on_button_press)
|
|
self._board.on_button_release(self._on_button_release)
|
|
self.start()
|
|
|
|
def start(self):
|
|
if self._gesture_thread is not None:
|
|
return
|
|
self._running = True
|
|
self._gesture_thread = threading.Thread(daemon=True, target=self._gesture_loop)
|
|
self._gesture_thread.start()
|
|
|
|
def stop(self):
|
|
self._running = False
|
|
|
|
def on_press(self, callback):
|
|
self._press_callbacks.append(callback)
|
|
|
|
def on_release(self, callback):
|
|
self._release_callbacks.append(callback)
|
|
|
|
def acknowledge_press(self):
|
|
self._button_was_pressed = False
|
|
|
|
def acknowledge_long_press(self):
|
|
self._button_was_long_pressed = False
|
|
|
|
def acknowledge_double_press(self):
|
|
self._button_was_double_pressed = False
|
|
|
|
def _on_button_press(self):
|
|
self._button_is_pressed = True
|
|
self._button_press_start = time.time()
|
|
if self._button_press_end is not None:
|
|
gap = self._button_press_start - self._button_press_end
|
|
if gap < self._double_press_threshold:
|
|
self._button_is_double_pressed = True
|
|
self._button_is_double_pressed_set = True
|
|
for cb in self._press_callbacks:
|
|
cb()
|
|
|
|
def _on_button_release(self):
|
|
self._button_was_pressed = self._button_is_pressed
|
|
self._button_press_end = time.time()
|
|
self._button_was_long_pressed = self._button_is_long_pressed
|
|
self._button_was_double_pressed = self._button_is_double_pressed
|
|
self._button_is_pressed = False
|
|
self._button_is_double_pressed = False
|
|
self._button_is_long_pressed = False
|
|
self._button_is_double_pressed_set = False
|
|
for cb in self._release_callbacks:
|
|
cb()
|
|
|
|
def _gesture_loop(self):
|
|
while self._running:
|
|
try:
|
|
current_time = time.time()
|
|
if self._button_is_pressed:
|
|
if not self._button_is_double_pressed_set:
|
|
self._button_is_double_pressed = (
|
|
self._button_was_pressed
|
|
and self._button_press_end is not None
|
|
and current_time - self._button_press_end < self._double_press_threshold
|
|
)
|
|
if self._button_is_double_pressed:
|
|
self._button_is_double_pressed_set = True
|
|
self._button_is_long_pressed = (
|
|
current_time - self._button_press_start > self._long_press_threshold
|
|
)
|
|
except Exception:
|
|
pass
|
|
time.sleep(0.05)
|