menu_keys: Move button handling from menu.py to new file menu_keys.py
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
a1fc1ac214
commit
7d8ade74e8
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
import os, logging, sys, ast, re, string
|
import os, logging, sys, ast, re, string
|
||||||
|
from . import menu_keys
|
||||||
|
|
||||||
class error(Exception):
|
class error(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -963,7 +963,6 @@ 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)
|
||||||
|
|
||||||
|
@ -993,118 +992,10 @@ class MenuManager:
|
||||||
self.cols, self.rows = lcd_chip.get_dimensions()
|
self.cols, self.rows = lcd_chip.get_dimensions()
|
||||||
self.timeout = config.getint('menu_timeout', 0)
|
self.timeout = config.getint('menu_timeout', 0)
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
# buttons
|
|
||||||
self.encoder_pins = config.get('encoder_pins', None)
|
|
||||||
self.click_pin = config.get('click_pin', None)
|
|
||||||
self.back_pin = config.get('back_pin', None)
|
|
||||||
self.up_pin = config.get('up_pin', None)
|
|
||||||
self.down_pin = config.get('down_pin', None)
|
|
||||||
self.kill_pin = config.get('kill_pin', None)
|
|
||||||
# analog button ranges
|
|
||||||
self.analog_range_click_pin = config.get(
|
|
||||||
'analog_range_click_pin', None)
|
|
||||||
self.analog_range_back_pin = config.get(
|
|
||||||
'analog_range_back_pin', None)
|
|
||||||
self.analog_range_up_pin = config.get(
|
|
||||||
'analog_range_up_pin', None)
|
|
||||||
self.analog_range_down_pin = config.get(
|
|
||||||
'analog_range_down_pin', None)
|
|
||||||
self.analog_range_kill_pin = config.get(
|
|
||||||
'analog_range_kill_pin', None)
|
|
||||||
self._last_click_press = 0
|
|
||||||
self.analog_pullup = config.getfloat(
|
|
||||||
'analog_pullup_resistor', 4700., above=0.)
|
|
||||||
self._encoder_fast_rate = config.getfloat(
|
|
||||||
'encoder_fast_rate', .03, above=0.)
|
|
||||||
self._last_encoder_cw_eventtime = 0
|
|
||||||
self._last_encoder_ccw_eventtime = 0
|
|
||||||
# printer objects
|
|
||||||
self.buttons = self.printer.load_object(config, "buttons")
|
|
||||||
# register itself for printer callbacks
|
# register itself for printer callbacks
|
||||||
self.printer.add_object('menu', self)
|
self.printer.add_object('menu', self)
|
||||||
self.printer.register_event_handler("klippy:ready", self.handle_ready)
|
self.printer.register_event_handler("klippy:ready", self.handle_ready)
|
||||||
# register buttons & encoder
|
menu_keys.MenuKeys(config, self.key_event)
|
||||||
if self.buttons:
|
|
||||||
# digital buttons
|
|
||||||
if self.encoder_pins:
|
|
||||||
try:
|
|
||||||
pin1, pin2 = self.encoder_pins.split(',')
|
|
||||||
except Exception:
|
|
||||||
raise config.error("Unable to parse encoder_pins")
|
|
||||||
self.buttons.register_rotary_encoder(
|
|
||||||
pin1.strip(), pin2.strip(),
|
|
||||||
self.encoder_cw_callback, self.encoder_ccw_callback)
|
|
||||||
if self.click_pin:
|
|
||||||
if self.analog_range_click_pin is not None:
|
|
||||||
try:
|
|
||||||
p_min, p_max = map(
|
|
||||||
float, self.analog_range_click_pin.split(','))
|
|
||||||
except Exception:
|
|
||||||
raise config.error(
|
|
||||||
"Unable to parse analog_range_click_pin")
|
|
||||||
self.buttons.register_adc_button(
|
|
||||||
self.click_pin, p_min, p_max, self.analog_pullup,
|
|
||||||
self.click_callback)
|
|
||||||
else:
|
|
||||||
self.buttons.register_buttons(
|
|
||||||
[self.click_pin], self.click_callback)
|
|
||||||
if self.back_pin:
|
|
||||||
if self.analog_range_back_pin is not None:
|
|
||||||
try:
|
|
||||||
p_min, p_max = map(
|
|
||||||
float, self.analog_range_back_pin.split(','))
|
|
||||||
except Exception:
|
|
||||||
raise config.error(
|
|
||||||
"Unable to parse analog_range_back_pin")
|
|
||||||
self.buttons.register_adc_button_push(
|
|
||||||
self.back_pin, p_min, p_max, self.analog_pullup,
|
|
||||||
self.back_callback)
|
|
||||||
else:
|
|
||||||
self.buttons.register_button_push(
|
|
||||||
self.back_pin, self.back_callback)
|
|
||||||
if self.up_pin:
|
|
||||||
if self.analog_range_up_pin is not None:
|
|
||||||
try:
|
|
||||||
p_min, p_max = map(
|
|
||||||
float, self.analog_range_up_pin.split(','))
|
|
||||||
except Exception:
|
|
||||||
raise config.error(
|
|
||||||
"Unable to parse analog_range_up_pin")
|
|
||||||
self.buttons.register_adc_button_push(
|
|
||||||
self.up_pin, p_min, p_max, self.analog_pullup,
|
|
||||||
self.up_callback)
|
|
||||||
else:
|
|
||||||
self.buttons.register_button_push(
|
|
||||||
self.up_pin, self.up_callback)
|
|
||||||
if self.down_pin:
|
|
||||||
if self.analog_range_down_pin is not None:
|
|
||||||
try:
|
|
||||||
p_min, p_max = map(
|
|
||||||
float, self.analog_range_down_pin.split(','))
|
|
||||||
except Exception:
|
|
||||||
raise config.error(
|
|
||||||
"Unable to parse analog_range_down_pin")
|
|
||||||
self.buttons.register_adc_button_push(
|
|
||||||
self.down_pin, p_min, p_max, self.analog_pullup,
|
|
||||||
self.down_callback)
|
|
||||||
else:
|
|
||||||
self.buttons.register_button_push(
|
|
||||||
self.down_pin, self.down_callback)
|
|
||||||
if self.kill_pin:
|
|
||||||
if self.analog_range_kill_pin is not None:
|
|
||||||
try:
|
|
||||||
p_min, p_max = map(
|
|
||||||
float, self.analog_range_kill_pin.split(','))
|
|
||||||
except Exception:
|
|
||||||
raise config.error(
|
|
||||||
"Unable to parse analog_range_kill_pin")
|
|
||||||
self.buttons.register_adc_button_push(
|
|
||||||
self.kill_pin, p_min, p_max, self.analog_pullup,
|
|
||||||
self.kill_callback)
|
|
||||||
else:
|
|
||||||
self.buttons.register_button_push(
|
|
||||||
self.kill_pin, self.kill_callback)
|
|
||||||
|
|
||||||
# Add MENU commands
|
# Add MENU commands
|
||||||
self.gcode.register_mux_command("MENU", "DO", 'dump', self.cmd_DO_DUMP,
|
self.gcode.register_mux_command("MENU", "DO", 'dump', self.cmd_DO_DUMP,
|
||||||
desc=self.cmd_DO_help)
|
desc=self.cmd_DO_help)
|
||||||
|
@ -1144,12 +1035,6 @@ 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):
|
||||||
|
@ -1588,29 +1473,6 @@ class MenuManager:
|
||||||
msg = "{0} = {1}".format(key1, self.parameters.get(key1))
|
msg = "{0} = {1}".format(key1, self.parameters.get(key1))
|
||||||
gcmd.respond_info(msg)
|
gcmd.respond_info(msg)
|
||||||
|
|
||||||
# buttons & encoder callbacks
|
|
||||||
def encoder_cw_callback(self, eventtime):
|
|
||||||
fast_rate = ((eventtime - self._last_encoder_cw_eventtime)
|
|
||||||
<= self._encoder_fast_rate)
|
|
||||||
self._last_encoder_cw_eventtime = eventtime
|
|
||||||
self.up(fast_rate)
|
|
||||||
|
|
||||||
def encoder_ccw_callback(self, eventtime):
|
|
||||||
fast_rate = ((eventtime - self._last_encoder_ccw_eventtime)
|
|
||||||
<= self._encoder_fast_rate)
|
|
||||||
self._last_encoder_ccw_eventtime = eventtime
|
|
||||||
self.down(fast_rate)
|
|
||||||
|
|
||||||
def click_callback(self, eventtime, state):
|
|
||||||
if self.click_pin:
|
|
||||||
if state:
|
|
||||||
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):
|
def _short_click_callback(self, eventtime):
|
||||||
if self.is_running():
|
if self.is_running():
|
||||||
self.select()
|
self.select()
|
||||||
|
@ -1636,19 +1498,18 @@ class MenuManager:
|
||||||
if container.is_editing():
|
if container.is_editing():
|
||||||
self.select(True)
|
self.select(True)
|
||||||
|
|
||||||
def back_callback(self, eventtime):
|
def key_event(self, key, eventtime):
|
||||||
if self.back_pin:
|
if key == 'click':
|
||||||
|
self._short_click_callback(eventtime)
|
||||||
|
elif key == 'long_click':
|
||||||
|
self._long_click_callback(eventtime)
|
||||||
|
elif key == 'up':
|
||||||
|
self.up(False)
|
||||||
|
elif key == 'fast_up':
|
||||||
|
self.up(True)
|
||||||
|
elif key == 'down':
|
||||||
|
self.down(False)
|
||||||
|
elif key == 'fast_down':
|
||||||
|
self.down(True)
|
||||||
|
elif key == 'back':
|
||||||
self.back()
|
self.back()
|
||||||
|
|
||||||
def up_callback(self, eventtime):
|
|
||||||
if self.up_pin:
|
|
||||||
self.up()
|
|
||||||
|
|
||||||
def down_callback(self, eventtime):
|
|
||||||
if self.down_pin:
|
|
||||||
self.down()
|
|
||||||
|
|
||||||
def kill_callback(self, eventtime):
|
|
||||||
if self.kill_pin:
|
|
||||||
# Emergency Stop
|
|
||||||
self.printer.invoke_shutdown("Shutdown due to kill button!")
|
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Support for menu button press tracking
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 Janar Sööt <janar.soot@gmail.com>
|
||||||
|
#
|
||||||
|
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
|
|
||||||
|
LONG_PRESS_DURATION = 0.800
|
||||||
|
TIMER_DELAY = .200
|
||||||
|
|
||||||
|
class MenuKeys:
|
||||||
|
def __init__(self, config, callback):
|
||||||
|
self.printer = config.get_printer()
|
||||||
|
self.callback = callback
|
||||||
|
# buttons
|
||||||
|
self.encoder_pins = config.get('encoder_pins', None)
|
||||||
|
self.click_pin = config.get('click_pin', None)
|
||||||
|
self.back_pin = config.get('back_pin', None)
|
||||||
|
self.up_pin = config.get('up_pin', None)
|
||||||
|
self.down_pin = config.get('down_pin', None)
|
||||||
|
self.kill_pin = config.get('kill_pin', None)
|
||||||
|
# analog button ranges
|
||||||
|
self.analog_range_click_pin = config.get(
|
||||||
|
'analog_range_click_pin', None)
|
||||||
|
self.analog_range_back_pin = config.get(
|
||||||
|
'analog_range_back_pin', None)
|
||||||
|
self.analog_range_up_pin = config.get(
|
||||||
|
'analog_range_up_pin', None)
|
||||||
|
self.analog_range_down_pin = config.get(
|
||||||
|
'analog_range_down_pin', None)
|
||||||
|
self.analog_range_kill_pin = config.get(
|
||||||
|
'analog_range_kill_pin', None)
|
||||||
|
self._last_click_press = 0
|
||||||
|
self.analog_pullup = config.getfloat(
|
||||||
|
'analog_pullup_resistor', 4700., above=0.)
|
||||||
|
self._encoder_fast_rate = config.getfloat(
|
||||||
|
'encoder_fast_rate', .03, above=0.)
|
||||||
|
self._last_encoder_cw_eventtime = 0
|
||||||
|
self._last_encoder_ccw_eventtime = 0
|
||||||
|
# printer objects
|
||||||
|
self.buttons = self.printer.load_object(config, "buttons")
|
||||||
|
# register buttons & encoder
|
||||||
|
if self.buttons:
|
||||||
|
# digital buttons
|
||||||
|
if self.encoder_pins:
|
||||||
|
try:
|
||||||
|
pin1, pin2 = self.encoder_pins.split(',')
|
||||||
|
except Exception:
|
||||||
|
raise config.error("Unable to parse encoder_pins")
|
||||||
|
self.buttons.register_rotary_encoder(
|
||||||
|
pin1.strip(), pin2.strip(),
|
||||||
|
self.encoder_cw_callback, self.encoder_ccw_callback)
|
||||||
|
if self.click_pin:
|
||||||
|
if self.analog_range_click_pin is not None:
|
||||||
|
try:
|
||||||
|
p_min, p_max = map(
|
||||||
|
float, self.analog_range_click_pin.split(','))
|
||||||
|
except Exception:
|
||||||
|
raise config.error(
|
||||||
|
"Unable to parse analog_range_click_pin")
|
||||||
|
self.buttons.register_adc_button(
|
||||||
|
self.click_pin, p_min, p_max, self.analog_pullup,
|
||||||
|
self.click_callback)
|
||||||
|
else:
|
||||||
|
self.buttons.register_buttons(
|
||||||
|
[self.click_pin], self.click_callback)
|
||||||
|
if self.back_pin:
|
||||||
|
if self.analog_range_back_pin is not None:
|
||||||
|
try:
|
||||||
|
p_min, p_max = map(
|
||||||
|
float, self.analog_range_back_pin.split(','))
|
||||||
|
except Exception:
|
||||||
|
raise config.error(
|
||||||
|
"Unable to parse analog_range_back_pin")
|
||||||
|
self.buttons.register_adc_button_push(
|
||||||
|
self.back_pin, p_min, p_max, self.analog_pullup,
|
||||||
|
self.back_callback)
|
||||||
|
else:
|
||||||
|
self.buttons.register_button_push(
|
||||||
|
self.back_pin, self.back_callback)
|
||||||
|
if self.up_pin:
|
||||||
|
if self.analog_range_up_pin is not None:
|
||||||
|
try:
|
||||||
|
p_min, p_max = map(
|
||||||
|
float, self.analog_range_up_pin.split(','))
|
||||||
|
except Exception:
|
||||||
|
raise config.error(
|
||||||
|
"Unable to parse analog_range_up_pin")
|
||||||
|
self.buttons.register_adc_button_push(
|
||||||
|
self.up_pin, p_min, p_max, self.analog_pullup,
|
||||||
|
self.up_callback)
|
||||||
|
else:
|
||||||
|
self.buttons.register_button_push(
|
||||||
|
self.up_pin, self.up_callback)
|
||||||
|
if self.down_pin:
|
||||||
|
if self.analog_range_down_pin is not None:
|
||||||
|
try:
|
||||||
|
p_min, p_max = map(
|
||||||
|
float, self.analog_range_down_pin.split(','))
|
||||||
|
except Exception:
|
||||||
|
raise config.error(
|
||||||
|
"Unable to parse analog_range_down_pin")
|
||||||
|
self.buttons.register_adc_button_push(
|
||||||
|
self.down_pin, p_min, p_max, self.analog_pullup,
|
||||||
|
self.down_callback)
|
||||||
|
else:
|
||||||
|
self.buttons.register_button_push(
|
||||||
|
self.down_pin, self.down_callback)
|
||||||
|
if self.kill_pin:
|
||||||
|
if self.analog_range_kill_pin is not None:
|
||||||
|
try:
|
||||||
|
p_min, p_max = map(
|
||||||
|
float, self.analog_range_kill_pin.split(','))
|
||||||
|
except Exception:
|
||||||
|
raise config.error(
|
||||||
|
"Unable to parse analog_range_kill_pin")
|
||||||
|
self.buttons.register_adc_button_push(
|
||||||
|
self.kill_pin, p_min, p_max, self.analog_pullup,
|
||||||
|
self.kill_callback)
|
||||||
|
else:
|
||||||
|
self.buttons.register_button_push(
|
||||||
|
self.kill_pin, self.kill_callback)
|
||||||
|
# start timer
|
||||||
|
reactor = self.printer.get_reactor()
|
||||||
|
reactor.register_timer(self.timer_event, reactor.NOW)
|
||||||
|
|
||||||
|
def timer_event(self, 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.callback('long_click', eventtime)
|
||||||
|
return eventtime + TIMER_DELAY
|
||||||
|
|
||||||
|
# buttons & encoder callbacks
|
||||||
|
def encoder_cw_callback(self, eventtime):
|
||||||
|
fast_rate = ((eventtime - self._last_encoder_cw_eventtime)
|
||||||
|
<= self._encoder_fast_rate)
|
||||||
|
self._last_encoder_cw_eventtime = eventtime
|
||||||
|
if fast_rate:
|
||||||
|
self.callback('fast_up', eventtime)
|
||||||
|
else:
|
||||||
|
self.callback('up', eventtime)
|
||||||
|
|
||||||
|
def encoder_ccw_callback(self, eventtime):
|
||||||
|
fast_rate = ((eventtime - self._last_encoder_ccw_eventtime)
|
||||||
|
<= self._encoder_fast_rate)
|
||||||
|
self._last_encoder_ccw_eventtime = eventtime
|
||||||
|
if fast_rate:
|
||||||
|
self.callback('fast_down', eventtime)
|
||||||
|
else:
|
||||||
|
self.callback('down', eventtime)
|
||||||
|
|
||||||
|
def click_callback(self, eventtime, state):
|
||||||
|
if self.click_pin:
|
||||||
|
if state:
|
||||||
|
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.callback('click', eventtime)
|
||||||
|
|
||||||
|
def back_callback(self, eventtime):
|
||||||
|
if self.back_pin:
|
||||||
|
self.callback('back', eventtime)
|
||||||
|
|
||||||
|
def up_callback(self, eventtime):
|
||||||
|
if self.up_pin:
|
||||||
|
self.callback('up', eventtime)
|
||||||
|
|
||||||
|
def down_callback(self, eventtime):
|
||||||
|
if self.down_pin:
|
||||||
|
self.callback('down', eventtime)
|
||||||
|
|
||||||
|
def kill_callback(self, eventtime):
|
||||||
|
if self.kill_pin:
|
||||||
|
# Emergency Stop
|
||||||
|
self.printer.invoke_shutdown("Shutdown due to kill button!")
|
Loading…
Reference in New Issue