Coding style.

- Divide input onto on_keyboard_input and on_mouse_input methods.
- Also let on_mouse_input see the original term code in case
  terminal.decode_mouse_input() is not enough.
This commit is contained in:
Andrew Hamilton 2021-04-11 17:41:07 +10:00
parent 39bda8cafb
commit a50f66554a
3 changed files with 41 additions and 33 deletions

View file

@ -659,7 +659,8 @@ class Help:
def _exit_help(self): def _exit_help(self):
self.screen._is_help_visible = False self.screen._is_help_visible = False
def _on_mouse_event(self, event, appearance_changed_event): def on_mouse_input(self, term_code, appearance_changed_event):
event = terminal.decode_mouse_input(term_code)
if event[1] == 4: # Mouse wheel up if event[1] == 4: # Mouse wheel up
self.view.portal.scroll_up() self.view.portal.scroll_up()
appearance_changed_event.set() appearance_changed_event.set()
@ -667,12 +668,9 @@ class Help:
self.view.portal.scroll_down() self.view.portal.scroll_down()
appearance_changed_event.set() appearance_changed_event.set()
def on_input_event(self, event, appearance_changed_event): def on_keyboard_input(self, term_code, appearance_changed_event):
if type(event) == tuple:
self._on_mouse_event(event, appearance_changed_event)
return
try: try:
action = self.key_map[event.lower()] action = self.key_map[term_code.lower()]
except KeyError: except KeyError:
pass pass
else: else:
@ -944,7 +942,14 @@ class Screen:
self._is_summary_focused or y <= view_height and self._is_summary_focused or y <= view_height and
not self._is_summary_focused))) not self._is_summary_focused)))
def _on_mouse_event(self, event): def on_mouse_input(self, term_code):
if self._is_help_visible:
self._help_widget.on_mouse_input(
term_code, self._appearance_changed_event)
return
event = terminal.decode_mouse_input(term_code)
if event[0] not in ["mouse press", "mouse drag"]:
return
x, y = event[2:4] x, y = event[2:4]
if event[0] == "mouse drag": if event[0] == "mouse drag":
last_x, last_y = self._last_mouse_position last_x, last_y = self._last_mouse_position
@ -967,23 +972,18 @@ class Screen:
self._select_entry_at_position( self._select_entry_at_position(
x, y, view_width, view_height) x, y, view_width, view_height)
self._last_mouse_position = x, y self._last_mouse_position = x, y
self._appearance_changed_event.set()
def on_input_event(self, event): def on_keyboard_input(self, term_code):
if self._is_help_visible: if self._is_help_visible:
self._help_widget.on_input_event( self._help_widget.on_keyboard_input(
event, self._appearance_changed_event) term_code, self._appearance_changed_event)
return return
if type(event) == tuple: action = (self._key_map.get(term_code) or
if event[0] in ["mouse press", "mouse drag"]: self._key_map.get(term_code.lower()))
self._on_mouse_event(event) if action is not None:
self._appearance_changed_event.set() action(self)
return self._appearance_changed_event.set()
else:
action = (self._key_map.get(event) or
self._key_map.get(event.lower()))
if action is not None:
action(self)
self._appearance_changed_event.set()
def _fix_listing(self): def _fix_listing(self):
widget = self._summary.get_selection() widget = self._summary.get_selection()

View file

@ -471,12 +471,12 @@ async def update_screen(screen_widget, appearance_changed_event):
def on_terminal_input(screen_widget): def on_terminal_input(screen_widget):
code = sys.stdin.read() term_code = sys.stdin.read()
if code.startswith(terminal.ESC + "[M"): # mouse if term_code.startswith(terminal.MOUSE):
for part in code.split(terminal.ESC + "[M")[1:]: for part in term_code.split(terminal.MOUSE)[1:]:
screen_widget.on_input_event(terminal.decode_mouse(part)) screen_widget.on_mouse_input(part)
else: else:
return screen_widget.on_input_event(code) # keyboard return screen_widget.on_keyboard_input(term_code)
@contextlib.contextmanager @contextlib.contextmanager
@ -512,17 +512,23 @@ def context(loop, appearance_changed_event, screen_widget, exit_loop=None):
class _Screen: class _Screen:
def __init__(self, appearance_changed_event): def __init__(self, appearance_changed_event):
self.appearance_changed_event = appearance_changed_event self._appearance_changed_event = appearance_changed_event
self.content = Filler(Text("Hello World")) self.content = Filler(Text("Hello World"))
def appearance(self, dimensions): def appearance(self, dimensions):
return self.content.appearance(dimensions) return self.content.appearance(dimensions)
def on_input_event(self, event): def on_keyboard_input(self, term_code):
if event == "q": if term_code == "q":
asyncio.get_event_loop().stop() asyncio.get_event_loop().stop()
self.content = Filler(Text(repr(event))) else:
self.appearance_changed_event.set() self.content = Filler(Text(repr(term_code)))
self._appearance_changed_event.set()
def on_mouse_input(self, term_code):
mouse_code = terminal.decode_mouse_input(term_code)
self.content = Filler(Text(repr(term_code) + " " + repr(mouse_code)))
self._appearance_changed_event.set()
def _main(): def _main():

View file

@ -9,6 +9,8 @@ import termios
ESC = "\x1b" ESC = "\x1b"
MOUSE = ESC + "[M"
normal = "[m" normal = "[m"
bold = "[1m" bold = "[1m"
italic = "[3m" italic = "[3m"
@ -78,8 +80,8 @@ def interactive():
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_termios_settings) termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_termios_settings)
def decode_mouse(code): def decode_mouse_input(term_code):
keys = [ord(byte) for byte in code] keys = [ord(byte) for byte in term_code]
b = keys[0] - 32 b = keys[0] - 32
x, y = (keys[1] - 33) % 256, (keys[2] - 33) % 256 x, y = (keys[1] - 33) % 256, (keys[2] - 33) % 256
button = ((b & 64) / 64 * 3) + (b & 3) + 1 button = ((b & 64) / 64 * 3) + (b & 3) + 1