menu: support for click button long press

- long press with timer (button release is not needed anymore)
- initial support for edit mode long press gcode

Signed-off-by: Janar Sööt <janar.soot@gmail.com>
This commit is contained in:
Janar Sööt 2018-12-20 20:59:02 +02:00 committed by Kevin O'Connor
parent 265769787f
commit b9cccc5959
2 changed files with 55 additions and 30 deletions

View File

@ -93,7 +93,11 @@
#parameter: #parameter:
# Value from parameter (always index 0) is taken as input value when in edit mode. # Value from parameter (always index 0) is taken as input value when in edit mode.
#gcode: #gcode:
# This will be triggered in realtime or on exit from edit mode. # This will be triggered in realtime mode, on exit from edit mode
# or in edit mode this will be triggered after click button long press (>0.8sec).
#longpress_gcode:
# In edit mode this will be triggered after click button long press (>0.8sec).
# The default is empty. This parameter is optional.
#reverse: #reverse:
# This attribute accepts static boolean value. # This attribute accepts static boolean value.
# When enabled it will reverse increment and decrement directions for input. # When enabled it will reverse increment and decrement directions for input.
@ -162,7 +166,7 @@
#leave_gcode #leave_gcode
#longpress_menu: #longpress_menu:
# Entry point to menu container. When this attribute is set then # Entry point to menu container. When this attribute is set then
# long press > 1s will initiate this menu container if not in edit mode. # long press > 0.8s will initiate this menu container if not in edit mode.
# The default is disabled. This parameter is optional. # The default is disabled. This parameter is optional.
#items: #items:
# It accepts only 'card' elements. You are able to switch between different card screens # It accepts only 'card' elements. You are able to switch between different card screens

View File

@ -494,6 +494,7 @@ class MenuInput(MenuCommand):
self._input_max = config.getfloat('input_max', sys.float_info.max) self._input_max = config.getfloat('input_max', sys.float_info.max)
self._input_step = config.getfloat('input_step', above=0.) self._input_step = config.getfloat('input_step', above=0.)
self._input_step2 = config.getfloat('input_step2', 0, minval=0.) self._input_step2 = config.getfloat('input_step2', 0, minval=0.)
self._longpress_gcode = config.get('longpress_gcode', '')
def is_scrollable(self): def is_scrollable(self):
return False return False
@ -507,6 +508,9 @@ class MenuInput(MenuCommand):
def get_gcode(self): def get_gcode(self):
return self._get_formatted(self._gcode, self._input_value) return self._get_formatted(self._gcode, self._input_value)
def get_longpress_gcode(self):
return self._get_formatted(self._longpress_gcode, self._input_value)
def is_editing(self): def is_editing(self):
return self._input_value is not None return self._input_value is not None
@ -885,6 +889,7 @@ menu_items = {
MENU_UPDATE_DELAY = .100 MENU_UPDATE_DELAY = .100
TIMER_DELAY = .200 TIMER_DELAY = .200
LONG_PRESS_DURATION = 0.800
BLINK_FAST_SEQUENCE = (True, True, False, False) BLINK_FAST_SEQUENCE = (True, True, False, False)
BLINK_SLOW_SEQUENCE = (True, True, True, True, False, False, False) BLINK_SLOW_SEQUENCE = (True, True, True, True, False, False, False)
@ -920,7 +925,7 @@ class MenuManager:
self.up_pin = config.get('up_pin', None) self.up_pin = config.get('up_pin', None)
self.down_pin = config.get('down_pin', None) self.down_pin = config.get('down_pin', None)
self.kill_pin = config.get('kill_pin', None) self.kill_pin = config.get('kill_pin', None)
self._last_press = 0 self._last_click_press = 0
self._encoder_fast_rate = config.getfloat( self._encoder_fast_rate = config.getfloat(
'encoder_fast_rate', .03, above=0.) 'encoder_fast_rate', .03, above=0.)
self._last_encoder_cw_eventtime = 0 self._last_encoder_cw_eventtime = 0
@ -1006,7 +1011,12 @@ class MenuManager:
) )
if self.timeout_idx == 0: if self.timeout_idx == 0:
self.timeout_check(eventtime) self.timeout_check(eventtime)
# check long press
if (self._last_click_press > 0 and (
eventtime - self._last_click_press) >= LONG_PRESS_DURATION):
# long click
self._last_click_press = 0
self._long_click_callback(eventtime)
return eventtime + TIMER_DELAY return eventtime + TIMER_DELAY
def timeout_check(self, eventtime): def timeout_check(self, eventtime):
@ -1300,7 +1310,7 @@ class MenuManager:
self.stack_pop() self.stack_pop()
self.running = False self.running = False
def select(self): def select(self, long_press=False):
container = self.stack_peek() container = self.stack_peek()
if self.running and isinstance(container, MenuContainer): if self.running and isinstance(container, MenuContainer):
self.timer = 0 self.timer = 0
@ -1313,6 +1323,10 @@ class MenuManager:
self.selected = 0 self.selected = 0
elif isinstance(current, MenuInput): elif isinstance(current, MenuInput):
if current.is_editing(): if current.is_editing():
if long_press is True:
self.queue_gcode(current.get_gcode())
self.queue_gcode(current.get_longpress_gcode())
else:
self.queue_gcode(current.get_gcode()) self.queue_gcode(current.get_gcode())
current.reset_value() current.reset_value()
else: else:
@ -1416,10 +1430,21 @@ class MenuManager:
def click_callback(self, eventtime, state): def click_callback(self, eventtime, state):
if self.click_pin: if self.click_pin:
if state: if state:
self._last_press = eventtime self._last_click_press = eventtime
elif self._last_click_press > 0:
if (eventtime - self._last_click_press) < LONG_PRESS_DURATION:
# short click
self._last_click_press = 0
self._short_click_callback(eventtime)
def _short_click_callback(self, eventtime):
if self.is_running():
self.select()
else: else:
if eventtime - self._last_press > 1.0: # lets start and populate the menu items
# long click self.begin(eventtime)
def _long_click_callback(self, eventtime):
if not self.is_running(): if not self.is_running():
# lets start and populate the menu items # lets start and populate the menu items
self.begin(eventtime) self.begin(eventtime)
@ -1433,13 +1458,9 @@ class MenuManager:
self.stack_push(menu) self.stack_push(menu)
self.top_row = 0 self.top_row = 0
self.selected = 0 self.selected = 0
else: return
# short click if container.is_editing():
if self.is_running(): self.select(True)
self.select()
else:
# lets start and populate the menu items
self.begin(eventtime)
def back_callback(self, eventtime): def back_callback(self, eventtime):
if self.back_pin: if self.back_pin: