commit a147f342171e70c3b756ad38cb9145ff7e67c2ac Author: Damian Johnson atagar@torproject.org Date: Tue Mar 15 10:08:25 2016 -0700
Move key_input() to nyx.curses
This has always belonged as a function. This allows us to drop direct curses usage from the controller - only spots left are a couple addch() calls in the panels! --- nyx/controller.py | 22 ++--------------- nyx/curses.py | 69 ++++++++++++++++++++++++++++++++++------------------- nyx/menu/menu.py | 2 +- nyx/panel/config.py | 2 +- nyx/panel/graph.py | 2 +- nyx/popups.py | 16 ++++++------- 6 files changed, 57 insertions(+), 56 deletions(-)
diff --git a/nyx/controller.py b/nyx/controller.py index 7b96134..602c85e 100644 --- a/nyx/controller.py +++ b/nyx/controller.py @@ -3,10 +3,7 @@ Main interface loop for nyx, periodically redrawing the screen and issuing user input to the proper panels. """
-from __future__ import absolute_import - import time -import curses import threading
import nyx.curses @@ -34,8 +31,7 @@ NYX_CONTROLLER = None
def conf_handler(key, value): if key == 'features.redrawRate': - # https://docs.python.org/2/library/curses.html?#curses.halfdelay - return min(max(1, value), 25.5) + return max(1, value) elif key == 'features.refreshRate': return max(0, value)
@@ -146,20 +142,6 @@ class Controller:
return self._screen
- def key_input(self, input_timeout = None): - """ - Gets keystroke from the user. - - :param int input_timeout: duration in seconds to wait for user input - """ - - if input_timeout: - curses.halfdelay(input_timeout * 10) - else: - curses.cbreak() # wait indefinitely for key presses (no timeout) - - return nyx.curses.KeyInput(self.get_screen().getch()) - def get_page_count(self): """ Provides the number of pages the interface has. This may be zero if all @@ -436,7 +418,7 @@ def start_nyx(stdscr): if override_key: key, override_key = override_key, None else: - key = control.key_input(CONFIG['features.redrawRate']) + key = nyx.curses.key_input(CONFIG['features.redrawRate'])
if key.match('right'): control.next_page() diff --git a/nyx/curses.py b/nyx/curses.py index a2d0dfa..0b6e24a 100644 --- a/nyx/curses.py +++ b/nyx/curses.py @@ -8,8 +8,9 @@ if we want Windows support in the future too.
::
- curses_attr - curses encoded text attribute start - initializes curses with the given function + key_input - get keypress by user + curses_attr - curses encoded text attribute
is_color_supported - checks if terminal supports color output get_color_override - provides color we override requests with @@ -131,29 +132,6 @@ CONFIG = stem.util.conf.config_dict('nyx', { }, conf_handler)
-def curses_attr(*attributes): - """ - Provides encoding for the given curses text attributes. - - :param list attributes: curses text attributes and colors - - :returns: **int** that can be used with curses - """ - - encoded = curses.A_NORMAL - - for attr in attributes: - if attr in Color: - override = get_color_override() - encoded |= _color_attr()[override if override else attr] - elif attr in Attr: - encoded |= CURSES_ATTRIBUTES[attr] - else: - raise ValueError("'%s' isn't a valid curses text attribute" % attr) - - return encoded - - def start(function, transparent_background = False, cursor = True): """ Starts a curses interface, delegating to the given function. The function @@ -186,6 +164,49 @@ def start(function, transparent_background = False, cursor = True): curses.wrapper(_wrapper)
+def key_input(input_timeout = None): + """ + Gets a key press from the user. + + :param int input_timeout: duration in seconds to wait for user input + + :returns: :class:`~nyx.curses.KeyInput` that was pressed + """ + + if input_timeout: + # Timeout can't be longer than 25.5 seconds... + # https://docs.python.org/2/library/curses.html?#curses.halfdelay + + curses.halfdelay(min(input_timeout, 25.5) * 10) + else: + curses.cbreak() # wait indefinitely for key presses (no timeout) + + return KeyInput(CURSES_SCREEN.getch()) + + +def curses_attr(*attributes): + """ + Provides encoding for the given curses text attributes. + + :param list attributes: curses text attributes and colors + + :returns: **int** that can be used with curses + """ + + encoded = curses.A_NORMAL + + for attr in attributes: + if attr in Color: + override = get_color_override() + encoded |= _color_attr()[override if override else attr] + elif attr in Attr: + encoded |= CURSES_ATTRIBUTES[attr] + else: + raise ValueError("'%s' isn't a valid curses text attribute" % attr) + + return encoded + + def is_color_supported(): """ Checks if curses currently supports rendering colors. diff --git a/nyx/menu/menu.py b/nyx/menu/menu.py index 7d49b3e..da22362 100644 --- a/nyx/menu/menu.py +++ b/nyx/menu/menu.py @@ -119,7 +119,7 @@ def show_menu():
popup.win.refresh()
- cursor.handle_key(control.key_input()) + cursor.handle_key(nyx.curses.key_input())
# redraws the rest of the interface if we're rendering on it again
diff --git a/nyx/panel/config.py b/nyx/panel/config.py index 45f82a8..5b8a636 100644 --- a/nyx/panel/config.py +++ b/nyx/panel/config.py @@ -213,7 +213,7 @@ class ConfigPanel(nyx.panel.Panel): popup.addstr(0, 0, 'Torrc to save:', HIGHLIGHT) popup.win.refresh()
- key = nyx.controller.get_controller().key_input() + key = nyx.curses.key_input()
if key.match('left'): selection = max(0, selection - 1) diff --git a/nyx/panel/graph.py b/nyx/panel/graph.py index 2b3714e..257716e 100644 --- a/nyx/panel/graph.py +++ b/nyx/panel/graph.py @@ -480,7 +480,7 @@ class GraphPanel(nyx.panel.Panel): while True: msg = 'press the down/up to resize the graph, and enter when done' control.set_msg(msg, BOLD, True) - key = control.key_input() + key = nyx.curses.key_input()
if key.match('down'): # don't grow the graph if it's already consuming the whole display diff --git a/nyx/popups.py b/nyx/popups.py index e6df000..61273f3 100644 --- a/nyx/popups.py +++ b/nyx/popups.py @@ -111,7 +111,7 @@ def show_msg(msg, max_wait = None, attr = HIGHLIGHT): control = nyx.controller.get_controller() control.set_msg(msg, attr, True)
- key_press = control.key_input(max_wait) + key_press = nyx.curses.key_input(max_wait) control.set_msg() return key_press
@@ -176,7 +176,7 @@ def show_help_popup(): popup.addstr(7, 2, 'Press any key...')
popup.win.refresh() - exit_key = control.key_input() + exit_key = nyx.curses.key_input()
if not exit_key.is_selection() and not exit_key.is_scroll() and \ not exit_key.match('left', 'right'): @@ -192,8 +192,6 @@ def show_about_popup():
with popup_window(9, 80) as (popup, _, height): if popup: - control = nyx.controller.get_controller() - popup.win.box() popup.addstr(0, 0, 'About:', HIGHLIGHT) popup.addstr(1, 2, 'nyx, version %s (released %s)' % (__version__, __release_date__), BOLD) @@ -203,7 +201,7 @@ def show_about_popup(): popup.addstr(7, 2, 'Press any key...') popup.win.refresh()
- control.key_input() + nyx.curses.key_input()
def show_count_dialog(title, counts): @@ -250,7 +248,7 @@ def show_count_dialog(title, counts): popup.addstr(0, 0, title, HIGHLIGHT) popup.win.refresh()
- nyx.controller.get_controller().key_input() + nyx.curses.key_input()
def show_sort_dialog(title, options, old_selection, option_colors): @@ -304,7 +302,7 @@ def show_sort_dialog(title, options, old_selection, option_colors):
popup.win.refresh()
- key = nyx.controller.get_controller().key_input() + key = nyx.curses.key_input()
if key.match('left'): cursor_location = max(0, cursor_location - 1) @@ -405,7 +403,7 @@ def show_menu(title, options, old_selection):
popup.win.refresh()
- key = control.key_input() + key = nyx.curses.key_input()
if key.match('up'): selection = max(0, selection - 1) @@ -457,7 +455,7 @@ def show_descriptor_popup(fingerprint, color, max_width, is_close_key): _draw(popup, title, lines, color, scroller.location(), show_line_numbers) redraw = False
- key = nyx.controller.get_controller().key_input() + key = nyx.curses.key_input()
if key.is_scroll(): redraw = scroller.handle_key(key, len(lines), height - 2)
tor-commits@lists.torproject.org