Add help modal window - toot - Unnamed repository; edit this file 'description'… | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit 760a80442cbaa76ed8061d264fb9167cd2bb525e | |
parent 2ecc6a28c6b1cd2efd4bd94d801954e87ab1b320 | |
Author: Ivan Habunek <[email protected]> | |
Date: Mon, 22 Jan 2018 10:07:18 +0100 | |
Add help modal window | |
Diffstat: | |
toot/ui/app.py | 99 +++++++++++++++++++++++++++---- | |
1 file changed, 88 insertions(+), 11 deletions(-) | |
--- | |
diff --git a/toot/ui/app.py b/toot/ui/app.py | |
@@ -2,6 +2,8 @@ | |
import webbrowser | |
+from toot import __version__ | |
+ | |
from toot.exceptions import ConsoleError | |
from toot.ui.utils import draw_horizontal_divider, draw_lines | |
from toot.utils import format_content, trunc | |
@@ -9,6 +11,7 @@ from toot.utils import format_content, trunc | |
# Attempt to load curses, which is not available on windows | |
try: | |
import curses | |
+ import curses.panel | |
except ImportError as e: | |
raise ConsoleError("Curses is not available on this platform") | |
@@ -40,8 +43,8 @@ class Color: | |
class HeaderWindow: | |
- def __init__(self, height, width, y, x): | |
- self.window = curses.newwin(height, width, y, x) | |
+ def __init__(self, stdscr, height, width, y, x): | |
+ self.window = stdscr.subwin(height, width, y, x) | |
self.height = height | |
self.width = width | |
@@ -53,8 +56,8 @@ class HeaderWindow: | |
class FooterWindow: | |
- def __init__(self, height, width, y, x): | |
- self.window = curses.newwin(height, width, y, x) | |
+ def __init__(self, stdscr, height, width, y, x): | |
+ self.window = stdscr.subwin(height, width, y, x) | |
self.height = height | |
self.width = width | |
@@ -76,7 +79,7 @@ class FooterWindow: | |
class StatusListWindow: | |
"""Window which shows the scrollable list of statuses (left side).""" | |
- def __init__(self, height, width, top, left): | |
+ def __init__(self, stdscr, height, width, top, left): | |
# Dimensions and position of region in stdscr which will contain the p… | |
self.region_height = height | |
self.region_width = width | |
@@ -167,8 +170,8 @@ class StatusListWindow: | |
class StatusDetailWindow: | |
"""Window which shows details of a status (right side)""" | |
- def __init__(self, height, width, y, x): | |
- self.window = curses.newwin(height, width, y, x) | |
+ def __init__(self, stdscr, height, width, y, x): | |
+ self.window = stdscr.subwin(height, width, y, x) | |
self.height = height | |
self.width = width | |
@@ -226,6 +229,74 @@ class StatusDetailWindow: | |
self.window.refresh() | |
+class Modal: | |
+ def __init__(self, stdscr): | |
+ height, width, y, x = self.get_size_pos(stdscr) | |
+ | |
+ self.window = curses.newwin(height, width, y, x) | |
+ self.draw() | |
+ self.panel = curses.panel.new_panel(self.window) | |
+ self.panel.hide() | |
+ | |
+ def get_content(self): | |
+ raise NotImplementedError() | |
+ | |
+ def get_size_pos(self, stdscr): | |
+ screen_height, screen_width = stdscr.getmaxyx() | |
+ | |
+ content = self.get_content() | |
+ height = len(content) + 2 | |
+ width = max(len(l) for l in content) + 4 | |
+ | |
+ y = (screen_height - height) // 2 | |
+ x = (screen_width - width) // 2 | |
+ | |
+ return height, width, y, x | |
+ | |
+ def draw(self): | |
+ self.window.erase() | |
+ self.window.box() | |
+ draw_lines(self.window, self.get_content(), 1, 2, Color.WHITE) | |
+ | |
+ def show(self): | |
+ self.panel.top() | |
+ self.panel.show() | |
+ self.window.refresh() | |
+ curses.panel.update_panels() | |
+ | |
+ def hide(self): | |
+ self.panel.hide() | |
+ curses.panel.update_panels() | |
+ | |
+ def loop(self): | |
+ self.show() | |
+ | |
+ key = None | |
+ while key != 'q': | |
+ key = self.window.getkey() | |
+ | |
+ self.hide() | |
+ | |
+ | |
+class HelpModal(Modal): | |
+ def get_content(self): | |
+ return [ | |
+ ("toot v{}".format(__version__), Color.GREEN | curses.A_BOLD), | |
+ "", | |
+ "Key bindings:", | |
+ "", | |
+ " h - show help", | |
+ " j or ↓ - move down", | |
+ " k or ↑ - move up", | |
+ " v - view current toot in browser", | |
+ " q - quit application", | |
+ "", | |
+ "Press q to exist help.", | |
+ "", | |
+ ("https://github.com/ihabunek/toot", Color.YELLOW), | |
+ ] | |
+ | |
+ | |
class TimelineApp: | |
def __init__(self, status_generator): | |
self.status_generator = status_generator | |
@@ -257,10 +328,12 @@ class TimelineApp: | |
left_width = max(min(screen_width // 3, 60), 30) | |
right_width = screen_width - left_width | |
- self.header = HeaderWindow(2, screen_width, 0, 0) | |
- self.footer = FooterWindow(2, screen_width, screen_height - 2, 0) | |
- self.left = StatusListWindow(screen_height - 4, left_width, 2, 0) | |
- self.right = StatusDetailWindow(screen_height - 4, right_width, 2, lef… | |
+ self.header = HeaderWindow(self.stdscr, 2, screen_width, 0, 0) | |
+ self.footer = FooterWindow(self.stdscr, 2, screen_width, screen_height… | |
+ self.left = StatusListWindow(self.stdscr, screen_height - 4, left_widt… | |
+ self.right = StatusDetailWindow(self.stdscr, screen_height - 4, right_… | |
+ | |
+ self.help_modal = HelpModal(self.stdscr) | |
def loop(self): | |
while True: | |
@@ -269,6 +342,10 @@ class TimelineApp: | |
if key.lower() == 'q': | |
return | |
+ elif key.lower() == 'h': | |
+ self.help_modal.loop() | |
+ self.full_redraw() | |
+ | |
elif key.lower() == 'v': | |
status = self.get_selected_status() | |
if status: |