from tkinter import Frame, ttk from PIL import ImageDraw from .base import View from .draw_utils import draw_clock, draw_long_press class ButtonsManager(View): # left, left long, right, right long, both long config = { 'default': { 'left_button_press': 'start_timer_command', 'left_button_long_press': 'reset_timer_command', 'right_button_press': 'tare_command', 'right_button_long_press': 'select_recipe_command', 'both_buttons_long_press': 'open_settings_command', }, 'select_recipe': {}, 'settings': {}, } def __init__(self, parent, im_size, center, **actions): self.current_config = self.config['default'] self.long_press_threshold = 1000 # milliseconds self.left_press_start = None self.right_press_start = None self.both_press_start = None self.left_press_job = None self.right_press_job = None self.both_press_job = None for key, action in actions.items(): setattr(self, key, action) super().__init__(parent, im_size, center) def init_ui(self, parent): self.ui = Frame(parent) self.left_button = ttk.Button(self.ui, text="Left") # Bind mouse events for press detection self.left_button.bind("", self._left_button_press_start) self.left_button.bind("", self._left_button_press_end) self.left_button.pack(side="left") self.right_button = ttk.Button(self.ui, text="Right") # Bind mouse events for press detection self.right_button.bind("", self._right_button_press_start) self.right_button.bind("", self._right_button_press_end) self.right_button.pack(side="right") self.both_buttons = ttk.Button(self.ui, text="Both") # Bind mouse events for press detection self.both_buttons.bind("", self._both_buttons_press_start) self.both_buttons.bind("", self._both_buttons_press_end) self.both_buttons.pack() self.ui.pack() def update_weight(self, weight: float) -> None: im = self.bkg_im.copy() draw = ImageDraw.Draw(im) # Draw left button if self.current_config.get('left_button_press', None): draw.circle((10, 10), 2, fill='black') if self.current_config['left_button_press'] == 'start_timer_command': draw_clock(draw, (20, 10), radius=3) if self.current_config.get('left_button_long_press', None): y = self.size[1] - 10 draw_long_press(draw, (10, y)) if self.current_config['left_button_long_press'] == 'reset_timer_command': draw_clock(draw, (24, y), radius=3) draw.text((30, y - 5), "R", fill='black') # Draw right button if self.current_config.get('right_button_press', None): draw.circle((self.size[0] - 10, 10), 2, fill='black') if self.current_config['right_button_press'] == 'tare_command': draw.text((self.size[0] - 20, 4), "T", fill='black') if self.current_config.get('right_button_long_press', None): y = self.size[1] - 10 draw_long_press(draw, (self.size[0] - 10, y)) if self.current_config['right_button_long_press'] == 'select_recipe_command': draw.text((self.size[0] - 22, y - 5), "R", fill='black') return im ############ BUTTON ACTIONS ########### def left_button_press(self): action = self.current_config.get('left_button_press', None) if action: self.__getattribute__(action)() def left_button_long_press(self): action = self.current_config.get('left_button_long_press', None) if action: self.__getattribute__(action)() def right_button_press(self): action = self.current_config.get('right_button_press', None) if action: self.__getattribute__(action)() def right_button_long_press(self): action = self.current_config.get('right_button_long_press', None) if action: self.__getattribute__(action)() def both_buttons_long_press(self): action = self.current_config.get('both_buttons_long_press', None) if action: self.__getattribute__(action)() ############ BUTTON PRESS HANDLERS ########### def _left_button_press_start(self, event): """Handle left button press start""" self.left_press_start = self.ui.after_idle(lambda: None) # Get current time reference # Schedule long press detection self.left_press_job = self.ui.after(self.long_press_threshold, self._left_long_press_detected) def _left_button_press_end(self, event): """Handle left button press end""" if self.left_press_job: self.ui.after_cancel(self.left_press_job) self.left_press_job = None # If we get here, it was a short press self.left_button_press() self.left_press_start = None def _left_long_press_detected(self): """Called when long press threshold is reached for left button""" self.left_press_job = None self.left_button_long_press() def _right_button_press_start(self, event): """Handle right button press start""" self.right_press_start = self.ui.after_idle(lambda: None) # Get current time reference # Schedule long press detection self.right_press_job = self.ui.after(self.long_press_threshold, self._right_long_press_detected) def _right_button_press_end(self, event): """Handle right button press end""" if self.right_press_job: self.ui.after_cancel(self.right_press_job) self.right_press_job = None # If we get here, it was a short press self.right_button_press() self.right_press_start = None def _right_long_press_detected(self): """Called when long press threshold is reached for right button""" self.right_press_job = None self.right_button_long_press() def _both_buttons_press_start(self, event): """Handle both buttons press start""" self.both_press_start = self.ui.after_idle(lambda: None) # Get current time reference # Schedule long press detection self.both_press_job = self.ui.after(self.long_press_threshold, self._both_long_press_detected) def _both_buttons_press_end(self, event): """Handle both buttons press end""" if self.both_press_job: self.ui.after_cancel(self.both_press_job) self.both_press_job = None # If we get here, it was a short press (no action defined) self.both_press_start = None def _both_buttons_long_press_detected(self): """Called when long press threshold is reached for both buttons""" self.both_press_job = None self.both_buttons_long_press()