async def prompt_multiline_text_output(self, title, text=''): result = ImbTuiResult() input_done = asyncio.Event() def ok_handler() -> None: input_done.set() def back_handler() -> None: result.back_selected = True input_done.set() ok_button = Button(text='Ok', handler=ok_handler) back_button = Button(text='Back', handler=back_handler) dialog = Dialog( title=title, body=TextArea(text=text, wrap_lines=True, multiline=True, scrollbar=True, read_only=True), buttons=[ok_button, back_button], modal=False, ) dialog.container.container.content.style = "" self.app_frame.body = HSplit([ dialog, ]) self.app.invalidate() self.app.layout.focus(self.app_frame) await input_done.wait() return result
async def long_prompt_text_input(self, title, prompt: Union[str, Iterable[str]], initial_text='', allow_other=False): 'prompt for single text input with a multi-line prompt' result = ImbTuiResult() input_done = asyncio.Event() def accept(buf) -> bool: get_app().layout.focus(ok_button) return True # Keep text. dialog_body = [] if isinstance(prompt, str): dialog_body.append( Window(FormattedTextControl(prompt), height=1, align=WindowAlign.CENTER)) else: for line in prompt: dialog_body.append( Window(FormattedTextControl(line), height=1, align=WindowAlign.CENTER)) text_field = TextArea(text=initial_text, multiline=False, accept_handler=accept) dialog_body.append(text_field) def ok_handler(): result.value = text_field.text input_done.set() def back_handler(): result.back_selected = True input_done.set() ok_button = Button(text='Ok', handler=ok_handler) dialog = Dialog( title=title, body=HSplit(dialog_body), buttons=[ ok_button, Button(text="Back", handler=back_handler), ], modal=False, ) # disable a_reverse style applied to dialogs dialog.container.container.content.style = "" self.app_frame.body = HSplit([ Window(), dialog, Window(), ]) self.app.invalidate() self.app.layout.focus(self.app_frame) await input_done.wait() return result
def disconnect_dialog(my_app: "sqlApp"): def yes_handler() -> None: obj = my_app.selected_object obj.conn.close() if my_app.active_conn is obj.conn: my_app.active_conn = None my_app.show_disconnect_dialog = False my_app.show_sidebar = True my_app.application.layout.focus("sidebarbuffer") def no_handler() -> None: my_app.show_disconnect_dialog = False my_app.show_sidebar = True my_app.application.layout.focus("sidebarbuffer") dialog = Dialog( title=lambda: my_app.selected_object.name, body=Label(text="Are you sure you want to disconnect?", dont_extend_height=True), buttons=[ Button(text="OK", handler=yes_handler), Button(text="Cancel", handler=no_handler), ], with_background=False, ) return ConditionalContainer(content=dialog, filter=ShowDisconnectDialog(my_app) & ~is_done)
def __init__(self, event=None, title='', text=''): content = Window(height=3, align=WindowAlign.CENTER, content=FormattedTextControl(text=text, show_cursor=False, modal=True)) body = HSplit([ Window(height=1, char=' '), content, Window(height=1, char=' '), ], padding=1) dialog = Dialog(body, title=title, width=D(preferred=80), with_background=True) loading_float = Float(content=dialog) root_container.floats.append(loading_float) self.focus = event.app.layout.focus self.focus(content)
def __init__(self, event, auth): super().__init__() self.event = event self.authtype = 'digest' authuser = auth.get('user', '') authpass = auth.get('password', '') self.authuser.text = authuser self.authuser.buffer.document = Document(authuser, len(authuser)) self.authpass_one.text = authpass self.authpass_one.buffer.document = Document(authpass, len(authpass)) self.authpass_two.text = authpass self.authpass_two.buffer.document = Document(authpass, len(authpass)) self.dialog = Dialog( title='Digest Authentication', body=HSplit([ Label(text='Username:\n'), self.authuser, Window(height=1, char=' '), Label(text='Password'), self.authpass_one, Window(height=1, char=' '), Label(text='Retype password'), self.authpass_two ]), buttons=[self.ok_button, self.cancel_button, self.delete_button], width=D(preferred=80), with_background=True, modal=True) root_container.floats.append(Float(self.dialog)) event.app.layout.focus(self.dialog)
def add_to_list(self, _ev=None): if self.current_station: def select_list(st_list): stations = list( map(lambda st: st[0], MyStations.get_stations(st_list))) if self.current_station['name'] in stations: log.info('%s station already in %s\'s list', self.current_station['name'], st_list) else: log.info('save %s in %s\'s list', self.current_station['name'], st_list) MyStations.save_station(st_list, str(self.current_station['name']), str(self.current_station['url'])) self.close_dialog() def new_list(buffer): log.info('new list: %s', buffer.text) select_list(buffer.text) radio_list = RadioList(values=list( map(lambda i: (i, i), MyStations.get_lists())), handler=select_list) text_input = TextArea(multiline=False, accept_handler=new_list) dialog = Dialog(title="Add to list", body=HSplit([text_input, radio_list], padding=1), width=40, with_background=True) self.wm.show_dialog(dialog) self.app.layout = self.wm.layout self.keep_window()
def __init__(self, event): def ok_handler(): # if len(ButtonManager.buttons) > 0: delete_server(event, name) root_container.floats.pop() def cancel_handler(): root_container.floats.pop() event.app.layout.focus(ButtonManager.prev_button) # Get data about server currently editing name = ButtonManager.current_button # Dialog configuration ok_button = Button(text='OK', handler=ok_handler) cancel_button = Button(text='Cancel', handler=cancel_handler) self.dialog = Dialog( title='Delete confirmation', body=Label( text='Are you sure you want to delete {}?'.format(name)), buttons=[cancel_button, ok_button], width=D(preferred=80), with_background=True) root_container.floats.append(Float(self.dialog)) event.app.layout.focus(self.dialog)
def __init__(self, event, dialog): def ok_handler(): root_container.floats.pop() db.update_one(values={'name': name, 'auth': None}) event.app.layout.focus(ButtonManager.prev_button) select_item(event) def cancel_handler(): root_container.floats.pop() root_container.floats.append(self.auth_float) event.app.layout.focus(dialog) ok_button = Button(text='OK', handler=ok_handler) cancel_button = Button(text='Cancel', handler=cancel_handler) name = ButtonManager.current_button self.dialog = Dialog( title='Delete confirmation', body=Label( text='Are you sure you want to delete authentication for {}?'. format(name)), buttons=[cancel_button, ok_button], width=D(preferred=80), with_background=True) self.auth_float = root_container.floats.pop() root_container.floats.append(Float(self.dialog)) event.app.layout.focus(self.dialog)
def radiolist_dialog(title='', text='', ok_text='Ok', cancel_text='Cancel', values=None, style=None, async_=False): """ Display a simple message box and wait until the user presses enter. """ def ok_handler(): get_app().exit(result=radio_list.current_value) radio_list = RadioList(values) dialog = Dialog(title=title, body=HSplit([ Label(text=text, dont_extend_height=True), radio_list, ], padding=1), buttons=[ Button(text=ok_text, handler=ok_handler), Button(text=cancel_text, handler=_return_none), ], with_background=True) return _run_dialog(dialog, style, async_=async_)
def input_dialog(title='', text='', ok_text='OK', cancel_text='Cancel', completer=None, password=False, style=None, async_=False): """ Display a text input box. Return the given text, or None when cancelled. """ def accept(buf): get_app().layout.focus(ok_button) return True # Keep text. def ok_handler(): get_app().exit(result=textfield.text) ok_button = Button(text=ok_text, handler=ok_handler) cancel_button = Button(text=cancel_text, handler=_return_none) textfield = TextArea( multiline=False, password=password, completer=completer, accept_handler=accept) dialog = Dialog( title=title, body=HSplit([ Label(text=text, dont_extend_height=True), textfield, ], padding=D(preferred=1, max=1)), buttons=[ok_button, cancel_button], with_background=True) return _run_dialog(dialog, style, async_=async_)
def __init__(self, title='', label_text='', completer=None): self.future = Future() def accept_text(): get_app().layout.focus(ok_button) self.text_area.buffer.complete_state = None def accept(): self.future.set_result(self.text_area.text) def cancel(): self.future.set_result(None) self.text_area = TextArea( completer=completer, multiline=False, width=D(preferred=40), accept_handler=accept_text) ok_button = Button(text='OK', handler=accept) cancel_button = Button(text='Cancel', handler=cancel) self.dialog = Dialog( title=title, body=HSplit([ Label(text=label_text), self.text_area ]), buttons=[ok_button, cancel_button], width=D(preferred=80), modal=True)
def radiolist_dialog(title='', text='', ok_text='Ok', cancel_text='Cancel', values=None, style=None, async_=False): """ Display a simple list of element the user can choose amongst. Only one element can be selected at a time using Arrow keys and Enter. The focus can be moved between the list and the Ok/Cancel button with tab. """ def ok_handler(): get_app().exit(result=radio_list.current_value) radio_list = RadioList(values) dialog = Dialog( title=title, body=HSplit([ Label(text=text, dont_extend_height=True), radio_list, ], padding=1), buttons=[ Button(text=ok_text, handler=ok_handler), Button(text=cancel_text, handler=_return_none), ], with_background=True) return _run_dialog(dialog, style, async_=async_)
def yes_no_dialog( title: AnyFormattedText = "", text: AnyFormattedText = "", yes_text: str = "Yes", no_text: str = "No", style: Optional[BaseStyle] = None, ) -> Application[bool]: """ Display a Yes/No dialog. Return a boolean. """ def yes_handler() -> None: get_app().exit(result=True) def no_handler() -> None: get_app().exit(result=False) dialog = Dialog( title=title, body=Label(text=text, dont_extend_height=True), buttons=[ Button(text=yes_text, handler=yes_handler), Button(text=no_text, handler=no_handler), ], with_background=True, ) return _create_app(dialog, style)
def __init__(self, title="", label_text="", completer=None): self.future = Future() def accept_text(buf): app.layout.focus(ok_button) buf.complete_state = None return True def accept(): self.future.set_result(self.text_area.text) def cancel(): self.future.set_result(None) self.text_area = TextArea( completer=completer, multiline=False, width=Dimension(preferred=40), accept_handler=accept_text, ) ok_button = Button(text="OK", handler=accept) cancel_button = Button(text="Cancel", handler=cancel) self.dialog = Dialog( title=title, body=HSplit([Label(text=label_text), self.text_area]), buttons=[ok_button, cancel_button], width=Dimension(preferred=80), modal=True, )
def button_dialog( title: AnyFormattedText = "", text: AnyFormattedText = "", buttons: List[Tuple[str, _T]] = [], style: Optional[BaseStyle] = None, ) -> Application[_T]: """ Display a dialog with button choices (given as a list of tuples). Return the value associated with button. """ def button_handler(v: _T) -> None: get_app().exit(result=v) dialog = Dialog( title=title, body=Label(text=text, dont_extend_height=True), buttons=[ Button(text=t, handler=functools.partial(button_handler, v)) for t, v in buttons ], with_background=True, ) return _create_app(dialog, style)
def __init__(self, title='', text='', ok_text='Ok', width=None, wrap_lines=True, scrollbar=False): self.future = Future() def accept_text(buf): get_app().layout.focus(ok_button) buf.complete_state = None return True def accept(): self.future.set_result(self.text_area.text) def cancel(): self.future.set_result(None) text_width = len(max(text.split('\n'), key=len)) + 2 self.text_area = TextArea(completer=completer, multiline=False, width=D(preferred=text_width), accept_handler=accept_text) ok_button = Button(text='OK', handler=accept) cancel_button = Button(text='Cancel', handler=cancel) self.dialog = Dialog(title=title, body=HSplit([Label(text=text), self.text_area]), buttons=[ok_button, cancel_button], width=width, modal=True)
def yes_no_dialog(title='', text='', yes_text='Yes', no_text='No', style=None, async_=False): """ Display a Yes/No dialog. Return a boolean. """ def yes_handler(): get_app().exit(result=True) def no_handler(): get_app().exit(result=False) dialog = Dialog(title=title, body=Label(text=text, dont_extend_height=True), buttons=[ Button(text=yes_text, handler=yes_handler), Button(text=no_text, handler=no_handler), ], with_background=True) return _run_dialog(dialog, style, async_=async_)
def __init__(self, title, text, yes_text, no_text, button=None): self.future = Future() def yes_handler(): self.future.set_result(True) def no_handler(): self.future.set_result(None) self.buttons = [ Button(text=yes_text, handler=yes_handler), Button(text=no_text, handler=no_handler), ] if button: self.buttons.insert( 1, Button(text=button[0], handler=lambda: button[1](self))) self.dialog = Dialog( title=title, body=HSplit([Label(text=text)]), buttons=self.buttons, width=D(preferred=50), modal=True, )
def radiolist_dialog(title: AnyFormattedText = '', text: AnyFormattedText = '', ok_text: str = 'Ok', cancel_text: str = 'Cancel', values: Optional[List[Tuple[_T, AnyFormattedText]]] = None, style: Optional[BaseStyle] = None) -> Application[_T]: """ Display a simple list of element the user can choose amongst. Only one element can be selected at a time using Arrow keys and Enter. The focus can be moved between the list and the Ok/Cancel button with tab. """ if values is None: values = [] def ok_handler() -> None: get_app().exit(result=radio_list.current_value) radio_list = RadioList(values) dialog = Dialog(title=title, body=HSplit([ Label(text=text, dont_extend_height=True), radio_list, ], padding=1), buttons=[ Button(text=ok_text, handler=ok_handler), Button(text=cancel_text, handler=_return_none), ], with_background=True) return _create_app(dialog, style)
def __init__(self, title, text, asking=False): self.future = Future() def set_done(): self.future.set_result(None) def accept(): self.future.set_result(True) def cancel(): self.future.set_result(False) if asking: buttons = [ Button(text="Yes", handler=accept), Button(text="No", handler=cancel), ] else: buttons = [Button(text="OK", handler=set_done)] text = "\n".join( [textwrap.fill(line, width=71) for line in text.splitlines()]) self.dialog = Dialog( title=title, body=HSplit([Label(text=text)]), buttons=buttons, width=D(preferred=75), modal=True, )
def InputDialog(on_ok, on_cancel, title="", prompt="", ok_text="OK", cancel_text="Cancel", is_text_valid=lambda text: True) -> Dialog: """Returns a Dialogue component displaying a text input box""" def on_accept(buf): if is_text_valid(textfield.text): get_app().layout.focus(ok_button) return True # Keep text. def on_ok_clicked(): if is_text_valid(textfield.text): on_ok(textfield.text) ok_button = Button(text=ok_text, handler=on_ok_clicked) exit_button = Button(text=cancel_text, handler=on_cancel) textfield = TextArea(multiline=False, accept_handler=on_accept) dialog = Dialog( title=title, body=HSplit( [Label(text=prompt, dont_extend_height=True), textfield], padding=Dimension(preferred=1, max=1), ), buttons=[ok_button, exit_button], with_background=True) return dialog
def get_root_container(self) -> Dialog: sort_radiolist = RadioList([(sort_method, sort_method.column_name) for sort_method in ScoreSort]) def ok_handler() -> None: self._selected_sort_setter(sort_radiolist.current_value) self.multi_screen.clear_floating() def cancel_handler() -> None: self.multi_screen.clear_floating() return Dialog( title="Sort By", body=HSplit( [ Label(text="Select the column to sort by", dont_extend_height=True), sort_radiolist, ], padding=1, ), buttons=[ Button(text="Okay", handler=ok_handler), Button(text="Cancel", handler=cancel_handler), ], with_background=True, )
def get_root_container(self) -> Dialog: difficulty_store = DifficultyPresets() with difficulty_store: difficulty_names = difficulty_store.get_difficulty_names( self._selected_game_getter().game_name) difficulty_radiolist = RadioList([(difficulty, difficulty) for difficulty in difficulty_names]) def ok_handler() -> None: self._selected_difficulty_setter( difficulty_radiolist.current_value) self.multi_screen.clear_floating() def cancel_handler() -> None: self.multi_screen.clear_floating() return Dialog( title="Difficulty", body=HSplit( [ Label(text="Select a difficulty", dont_extend_height=True), difficulty_radiolist, ], padding=1, ), buttons=[ Button(text="Okay", handler=ok_handler), Button(text="Cancel", handler=cancel_handler), ], with_background=True, )
def __init__(self, event, title='', text=''): def ok_handler(): root_container.floats.pop() # If there was an original dialog, insert it back into layout if self.orig_dialog: root_container.floats.append(self.orig_dialog) event.app.layout.focus(root_container.float_container) else: event.app.layout.focus(ButtonManager.prev_button) ok_button = Button(text='OK', handler=ok_handler) dialog = Dialog(Window(wrap_lines=True, content=FormattedTextControl(text=text), always_hide_cursor=True), title=title, width=D(preferred=80), buttons=[ok_button], with_background=True) try: # If a dialog was already up, save it self.orig_dialog = root_container.floats.pop() except IndexError: self.orig_dialog = None root_container.floats.append(Float(content=dialog)) event.app.layout.focus(ok_button)
def __init__(self, pymux, client_state): self.pymux = pymux self.client_state = client_state # Popup dialog for displaying keys, etc... search_textarea = SearchToolbar() self._popup_textarea = TextArea(scrollbar=True, read_only=True, search_field=search_textarea) self.popup_dialog = Dialog( title='Keys', body=HSplit([ Window(FormattedTextControl(text=''), height=1), # 1 line margin. self._popup_textarea, search_textarea, Window(FormattedTextControl(text=HTML( 'Press [<b>q</b>] to quit or [<b>/</b>] for searching.')), align=WindowAlign.CENTER, height=1) ])) self.layout = self._create_layout() # Keep track of render information. self.pane_write_positions = {}
def __init__(self, title='', text='', ok_text='Ok', lexer=None, width=None, wrap_lines=True, scrollbar=False): self.future = Future() self.text = text def set_done(): self.future.set_result(None) def get_text_width(): if width is None: text_fragments = to_formatted_text(self.text) text = fragment_list_to_text(text_fragments) if text: longest_line = max( get_cwidth(line) for line in text.splitlines()) else: return D(preferred=0) return D(preferred=longest_line) else: return width # text_width = len(max(self.text.split('\n'), key=len)) + 2 # text_height = len(text.split('\n')) # TODO: Add dynamic_h_scrollbar to TextArea and this Dialog # def dynamic_horizontal_scrollbar(): # max_text_width = get_app().renderer.output.get_size().columns - 2 def dynamic_virtical_scrollbar(): text_fragments = to_formatted_text(self.text) text = fragment_list_to_text(text_fragments) if text: text_height = len(self.text.splitlines()) max_text_height = get_app().renderer.output.get_size().rows - 6 if text_height > max_text_height: return True self.text_area = TextArea(text=text, lexer=lexer, read_only=True, focusable=False, width=get_text_width(), wrap_lines=wrap_lines, scrollbar=dynamic_virtical_scrollbar()) ok_button = Button(text='OK', handler=(lambda: set_done())) self.dialog = Dialog(title=title, body=self.text_area, buttons=[ok_button], width=width, modal=True)
def progress_dialog( title: AnyFormattedText = "", text: AnyFormattedText = "", run_callback: Callable[[Callable[[int], None], Callable[[str], None]], None] = ( lambda *a: None ), style: Optional[BaseStyle] = None, ) -> Application[None]: """ :param run_callback: A function that receives as input a `set_percentage` function and it does the work. """ loop = get_event_loop() progressbar = ProgressBar() text_area = TextArea( focusable=False, # Prefer this text area as big as possible, to avoid having a window # that keeps resizing when we add text to it. height=D(preferred=10 ** 10), ) dialog = Dialog( body=HSplit( [ Box(Label(text=text)), Box(text_area, padding=D.exact(1)), progressbar, ] ), title=title, with_background=True, ) app = _create_app(dialog, style) def set_percentage(value: int) -> None: progressbar.percentage = int(value) app.invalidate() def log_text(text: str) -> None: loop.call_soon_threadsafe(text_area.buffer.insert_text, text) app.invalidate() # Run the callback in the executor. When done, set a return value for the # UI, so that it quits. def start() -> None: try: run_callback(set_percentage, log_text) finally: app.exit() def pre_run() -> None: run_in_executor_with_context(start) app.pre_run_callables.append(pre_run) return app
async def prompt_yn(self, title, prompt, disable_back=False, allow_other=False, other_button_text="Other"): result = ImbTuiResult() input_done = asyncio.Event() def yes_handler(): result.value = True input_done.set() def no_handler(): result.value = False input_done.set() def back_handler(): result.back_selected = True input_done.set() def other_handler(): result.other_selected = True input_done.set() buttons = [ Button(text="Yes", handler=yes_handler), Button(text="No", handler=no_handler) ] if not disable_back: buttons.append(Button(text="Back", handler=back_handler)) if allow_other: buttons.append( Button(text=other_button_text, handler=other_handler)) yn_dialog = Dialog( title=title, body=Window(FormattedTextControl(prompt), height=1, align=WindowAlign.CENTER), buttons=buttons, modal=False, ) # disable a_reverse style applied to dialogs yn_dialog.container.container.content.style = "" self.app_frame.body = HSplit([ Window(), yn_dialog, Window(), ]) self.app.invalidate() self.app.layout.focus(self.app_frame) await input_done.wait() return result
def __init__(self, ok_btn_cb: Callable[[], None] = None): if ok_btn_cb is None: ok_btn_cb = self.hide self.dialog = Dialog(body=Label("Task has no action associated"), title="🙄", buttons=[Button("Ok", handler=ok_btn_cb)], modal=True) self.visible = False super().__init__(self.dialog, filter=Condition(lambda: self.visible))
def message_dialog(title='', text='', ok_text='Ok', style=None, async_=False): """ Display a simple message box and wait until the user presses enter. """ dialog = Dialog(title=title, body=Label(text=text, dont_extend_height=True), buttons=[ Button(text=ok_text, handler=_return_none), ], with_background=True) return _run_dialog(dialog, style, async_=async_)