Created
October 9, 2018 15:18
-
-
Save gsw945/3f41738e9641a330c64bf2f5a9a97fdf to your computer and use it in GitHub Desktop.
python-prompt-toolkit selection list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from prompt_toolkit.layout.margins import ScrollbarMargin | |
from prompt_toolkit.formatted_text import to_formatted_text | |
from prompt_toolkit.layout.controls import FormattedTextControl | |
from prompt_toolkit.layout.containers import Window | |
from prompt_toolkit.keys import Keys | |
from prompt_toolkit.key_binding.key_bindings import KeyBindings | |
from prompt_toolkit.formatted_text import HTML | |
class NewRadioList(object): | |
""" | |
List of radio buttons. Only one can be checked at the same time. | |
:param values: List of (value, label) tuples. | |
modified from: https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/prompt_toolkit/widgets/base.py | |
""" | |
def __init__(self, values): | |
assert isinstance(values, list) | |
assert len(values) > 0 | |
assert all(isinstance(i, tuple) and len(i) == 2 | |
for i in values) | |
self.values = values | |
self.current_value = values[0][0] | |
self._selected_index = 0 | |
# Key bindings. | |
kb = KeyBindings() | |
@kb.add('up') | |
def _(event): | |
self._selected_index = max(0, self._selected_index - 1) | |
self.current_value = self.values[self._selected_index][0] | |
@kb.add('down') | |
def _(event): | |
self._selected_index = min( | |
len(self.values) - 1, | |
self._selected_index + 1 | |
) | |
self.current_value = self.values[self._selected_index][0] | |
@kb.add(Keys.Any) | |
def _(event): | |
# We first check values after the selected value, then all values. | |
for value in self.values[self._selected_index + 1:] + self.values: | |
if value[0].startswith(event.data): | |
self._selected_index = self.values.index(value) | |
return | |
# Control and window. | |
self.control = FormattedTextControl( | |
self._get_text_fragments, | |
key_bindings=kb, | |
focusable=True) | |
self.window = Window( | |
content=self.control, | |
style='class:radio-list', | |
right_margins=[ | |
ScrollbarMargin(display_arrows=True), | |
], | |
dont_extend_height=True) | |
def _get_text_fragments(self): | |
result = [] | |
for i, value in enumerate(self.values): | |
checked = (value[0] == self.current_value) | |
selected = (i == self._selected_index) | |
style = '' | |
if checked: | |
style += ' class:radio-checked' | |
if selected: | |
style += ' class:radio-selected' | |
result.append((style, '')) | |
if selected: | |
result.append(('[SetCursorPosition]', '')) | |
display = value[1] | |
if checked: | |
result.append((style, '->')) | |
display = HTML('<style bg="#999" fg="red">{0}</style>'.format(display)) | |
else: | |
result.append((style, ' ')) | |
result.append((style, '')) | |
result.append(('class:radio', ' ')) | |
result.extend(to_formatted_text(display, style='class:radio')) | |
result.append(('', '\n')) | |
result.pop() # Remove last newline. | |
return result | |
def __pt_container__(self): | |
return self.window |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from prompt_toolkit.application import Application | |
from prompt_toolkit.layout import Layout | |
from prompt_toolkit.key_binding.defaults import load_key_bindings | |
from prompt_toolkit.key_binding.key_bindings import KeyBindings, merge_key_bindings | |
from prompt_toolkit.formatted_text import ANSI | |
from prompt_toolkit import print_formatted_text | |
from new_radio_list import NewRadioList | |
print('-' * 70) | |
print('press [up] or [down] to switch selection') | |
print('press [enter] to choose') | |
print('-' * 70) | |
values = [ | |
('python', 'Python'), | |
('php', 'PHP'), | |
('csharp', 'C#'), | |
('java', 'Java'), | |
] | |
rdo = NewRadioList(values) | |
def do_exit(event): | |
# get_app().exit() | |
event.app.exit(result=rdo.current_value) | |
def do_up_down(event): | |
print(event) | |
pass | |
bindings = KeyBindings() | |
bindings.add('enter')(do_exit) | |
app_bindings = merge_key_bindings([ | |
load_key_bindings(), | |
bindings | |
]) | |
selected = Application(layout=Layout(rdo), key_bindings=app_bindings).run() | |
print('your choice is:', end=' ') | |
# refer: https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/examples/print-text/ansi.py | |
print_formatted_text(ANSI('\x1b[91m{0}'.format(selected))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment