def __init__(self, text=''): assert is_formatted_text(text) self.checked = True kb = KeyBindings() @kb.add(' ') @kb.add('enter') def _(event): self.checked = not self.checked self.control = FormattedTextControl(self._get_text_fragments, key_bindings=kb, focusable=True) self.window = Window(width=3, content=self.control, height=1) self.container = VSplit( [self.window, Label(text=Template(' {}').format(text))], style='class:checkbox')
def meta_enter_message(python_input: "PythonInput") -> Container: """ Create the `Layout` for the 'Meta+Enter` message. """ def get_text_fragments() -> StyleAndTextTuples: return [("class:accept-message", " [Meta+Enter] Execute ")] @Condition def extra_condition() -> bool: " Only show when... " b = python_input.default_buffer return (python_input.show_meta_enter_message and (not b.document.is_cursor_at_the_end or python_input.accept_input_on_enter is None) and "\n" in b.text) visible = ~is_done & has_focus(DEFAULT_BUFFER) & extra_condition return ConditionalContainer(content=Window( FormattedTextControl(get_text_fragments)), filter=visible)
def create_application_table(yarn_watcher): """Create table with the list of applications.""" def get_text(): result = [] result.append(('', Border.TOP_LEFT)) result.append(('', Border.HORIZONTAL * (DEFAULT_ROW_WIDTH - 2))) result.append(('', Border.TOP_RIGHT)) result.append(('', '\n')) for a in yarn_watcher.apps: result.append(('', Border.VERTICAL)) if a == yarn_watcher.current_application: result.append(('[SetCursorPosition]', '')) result.append(('class:table.current', a.as_text())) else: result.append(('', a.as_text())) result.append(('', Border.VERTICAL)) result.append(('', '\n')) result.append(('', Border.BOTTOM_LEFT)) result.append(('', Border.HORIZONTAL * (DEFAULT_ROW_WIDTH - 2))) result.append(('', Border.BOTTOM_RIGHT)) result.append(('', '\n')) return result kb = KeyBindings() @kb.add('up') def _(event): yarn_watcher.select_previous() @kb.add('down') def _(event): yarn_watcher.select_next() control = FormattedTextControl(get_text, focusable=True, key_bindings=kb) return Window(control, width=DEFAULT_ROW_WIDTH, always_hide_cursor=True, style='class:table')
def make_readout(self, label, attribute, align, width, label_side='left'): readout_widget = Window( getattr(self, attribute), dont_extend_width=True, dont_extend_height=True, style='class:info.readout', width=width, align=WindowAlign.RIGHT, ) label_widget = Window(FormattedTextControl(label), dont_extend_width=True) if label_side == 'left': children = [label_widget, readout_widget] elif label_side == 'right': children = [readout_widget, label_widget] return VSplit( children=children, padding=1, align=getattr(HorizontalAlign, align.upper()), )
def __init__( self, text: AnyFormattedText, style: str = "", width: AnyDimension = None, dont_extend_height: bool = True, dont_extend_width: bool = False, align: Union[WindowAlign, Callable[[], WindowAlign]] = WindowAlign.LEFT, ) -> None: self.text = text def get_width() -> AnyDimension: 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 self.formatted_text_control = FormattedTextControl( text=lambda: self.text) self.window = Window( content=self.formatted_text_control, width=get_width, height=D(min=1), style="class:label " + style, dont_extend_height=dont_extend_height, dont_extend_width=dont_extend_width, align=align, )
def __init__(self, editor, buffer_window, buffer): def get_scroll_text(): info = buffer_window.render_info if info: if info.full_height_visible: return 'All' elif info.top_visible: return 'Top' elif info.bottom_visible: return 'Bot' else: percentage = info.vertical_scroll_percentage return '%2i%%' % percentage return '' def get_tokens(): main_document = buffer.document return [ ('class:cursorposition', '(%i,%i)' % (main_document.cursor_position_row + 1, main_document.cursor_position_col + 1)), ('', ' - '), ('class:percentage', get_scroll_text()), ('', ' '), ] super(WindowStatusBarRuler, self).__init__(Window( FormattedTextControl(get_tokens), char=' ', align=WindowAlign.RIGHT, style='class:toolbar.status', height=1, ), filter=Condition(lambda: editor.show_ruler))
def create_exit_confirmation( python_input: "PythonInput", style="class:exit-confirmation" ) -> Container: """ Create `Layout` for the exit message. """ def get_text_fragments() -> StyleAndTextTuples: # Show "Do you really want to exit?" return [ (style, "\n %s ([y]/n) " % python_input.exit_message), ("[SetCursorPosition]", ""), (style, " \n"), ] visible = ~is_done & Condition(lambda: python_input.show_exit_confirmation) return ConditionalContainer( content=Window( FormattedTextControl(get_text_fragments, focusable=True), style=style ), filter=visible, )
def python_sidebar_navigation(python_input): """ Create the `Layout` showing the navigation information for the sidebar. """ def get_text_fragments(): # Show navigation info. return [ ("class:sidebar", " "), ("class:sidebar.key", "[Arrows]"), ("class:sidebar", " "), ("class:sidebar.description", "Navigate"), ("class:sidebar", " "), ("class:sidebar.key", "[Enter]"), ("class:sidebar", " "), ("class:sidebar.description", "Hide menu"), ] return Window( FormattedTextControl(get_text_fragments), style="class:sidebar", width=Dimension.exact(43), height=Dimension.exact(1), )
def __init__(self, show_position=False): def get_formatted_text(): buff = get_app().current_buffer if buff.validation_error: row, column = buff.document.translate_index_to_position( buff.validation_error.cursor_position) if show_position: text = '%s (line=%s column=%s)' % ( buff.validation_error.message, row + 1, column + 1) else: text = buff.validation_error.message return [('class:validation-toolbar', text)] else: return [] self.control = FormattedTextControl(get_formatted_text) self.container = ConditionalContainer(content=Window(self.control, height=1), filter=has_validation_error)
def get_layout(self): widget = self.get_widget() vsplit_components = [widget] if 'message' in self._question and self._question['message']: vsplit_components.insert( 0, Label( self._question['message'], dont_extend_width=True, dont_extend_height=False, style='class:selectone.question', ), ) btn_all = Button('All', widget.select_all) btn_none = Button('None', widget.select_none) buttons = Box( body=VSplit([btn_all, btn_none], padding=1), height=D(min=1, max=3, preferred=3), padding_left=0, ) hsplit_components = [buttons, VSplit(vsplit_components, padding=1)] if 'description' in self._question and self._question['description']: hsplit_components.insert( 0, Window( FormattedTextControl( FormattedText([( 'class:selectone.question', self._question['description'], )]), ), wrap_lines=True, height=D(min=1, max=5, preferred=3), ), ) return HSplit(hsplit_components, padding=1)
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) @kb.add('down') def _(event): self._selected_index = min( len(self.values) - 1, self._selected_index + 1) @kb.add('enter') @kb.add(' ') def _(event): self.current_value = self.values[self._selected_index][0] # 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 __init__(self): self._current_channel = None self._message_text_area = TextArea(read_only=True, focusable=False) self._message_input = TextArea(height=3, multiline=False) self._message_input.accept_handler = self._handle_message_entered self._root_container = HSplit([ Frame(Window(height=1, content=FormattedTextControl(lambda: [("class:title", self.get_title())]), align=WindowAlign.CENTER)), self._message_text_area, Frame(self._message_input) ]) self._keybindings = KeyBindings() @self._keybindings.add("c-c") def _(event): event.app.exit() self._app = Application(layout=Layout(self._root_container), full_screen=True, key_bindings=self._keybindings) self._app.run()
def __init__(self, block, focusable, on_text_changed): self.focusable = focusable self.block = block self.on_text_changed = on_text_changed self.buffer = Buffer(document=Document(self.block['attrs']['content'], 0), on_text_changed=self.on_text_changed) self.control = BufferControl(buffer=self.buffer, focusable=self.focusable) self.container = VSplit([ Window(FormattedTextControl(lambda: '[x]' if block['attrs']['done'] else '[ ]'), dont_extend_width=True, dont_extend_height=True), Window(content=self.control, dont_extend_width=True, dont_extend_height=True) ], padding=1, padding_char=' ', align=HorizontalAlign.LEFT)
def __init__(self, text, handler=None): assert isinstance(text, six.text_type) assert handler is None or callable(handler) self.text = text self.handler = handler self.control = FormattedTextControl( self._get_text_fragments, key_bindings=self._get_key_bindings(), show_cursor=False, focusable=True) def get_style(): if get_app().layout.has_focus(self): return 'class:button.focused' return 'class:button' self.window = Window( self.control, height=1, style=get_style, dont_extend_width=True, dont_extend_height=True)
def __init__(self, title: str = "DLNest Output", routineTask=None, analyzerRoutineTask=None, freq: int = 1, analyzerFreq: int = 5, style: str = "class:analyzer_output"): super(AnalyzerOutput, self).__init__(title, routineTask, freq, style) self.analyzerRoutineTask = analyzerRoutineTask if not self.analyzerRoutineTask is None: self.scheduler.add_job(self.analyzerRoutineTask, 'interval', seconds=analyzerFreq, args=[self]) self.infoText = FormattedTextControl( [("", " No analyze task is running ")], focusable=False, show_cursor=False) self.infoWindow = Window(content=self.infoText) self.infoLabel = Box( body=self.infoWindow, height=3, padding_top=1, padding_bottom=1, # padding_left=3, # padding_right=3, style="class:analyzer_info_label") self.window = Frame(HSplit([self.infoLabel, self.shower]), title=self.title, style=self.style, modal=True, key_bindings=self.kb)
def signature_toolbar(python_input): """ Return the `Layout` for the signature. """ def get_text_fragments(): result = [] append = result.append Signature = 'class:signature-toolbar' if python_input.signatures: sig = python_input.signatures[0] # Always take the first one. append((Signature, ' ')) try: append((Signature, sig.full_name)) except IndexError: # Workaround for #37: https://github.com/jonathanslenders/python-prompt-toolkit/issues/37 # See also: https://github.com/davidhalter/jedi/issues/490 return [] append((Signature + ',operator', '(')) try: enumerated_params = enumerate(sig.params) except AttributeError: # Workaround for #136: https://github.com/jonathanslenders/ptpython/issues/136 # AttributeError: 'Lambda' object has no attribute 'get_subscope_by_name' return [] for i, p in enumerated_params: # Workaround for #47: 'p' is None when we hit the '*' in the signature. # and sig has no 'index' attribute. # See: https://github.com/jonathanslenders/ptpython/issues/47 # https://github.com/davidhalter/jedi/issues/598 description = (p.description if p else '*') #or '*' sig_index = getattr(sig, 'index', 0) if i == sig_index: # Note: we use `_Param.description` instead of # `_Param.name`, that way we also get the '*' before args. append((Signature + ',current-name', str(description))) else: append((Signature, str(description))) append((Signature + ',operator', ', ')) if sig.params: # Pop last comma result.pop() append((Signature + ',operator', ')')) append((Signature, ' ')) return result return ConditionalContainer( content=Window(FormattedTextControl(get_text_fragments), height=Dimension.exact(1)), filter= # Show only when there is a signature HasSignature(python_input) & # And there are no completions to be shown. (would cover signature pop-up.) ~(has_completions & (show_completions_menu(python_input) | show_multi_column_completions_menu(python_input))) # Signature needs to be shown. & ShowSignature(python_input) & # Not done yet. ~is_done)
def __init__(self, options: Sequence[Option], default_index: int = 0, header_filter: Callable[[Option], str] = str, match_filter: Callable[[Option], str] = str, custom_filter: Optional[Callable[[str], bool]] = None, search_buffer: Buffer = Buffer(multiline=False), cpu_count: int = os.cpu_count()): self.search_buffer = search_buffer self.last_query_text = '' # type: str self.search_buffer.on_text_changed += self.update self.header_filter = header_filter self.match_filter = match_filter self.current_index = default_index # type: Optional[int] self.entries_left_offset = 0 self.cpu_count = cpu_count self.options_headers_linecount = [] # type: List[int] self._indices_to_lines = [] # type: List[int] self.options_headers = [] # type: FormattedText self.options_matchers = [] # type: List[str] self.indices = [] # type: List[int] self._options = [] # type: Sequence[Option] self.marks = [] # type: List[int] self.max_entry_height = 1 # type: int # options are processed here also through the setter # ################################################## self.set_options(options) self.cursor = Point(0, 0) # type: Point # ################################################## self.content = FormattedTextControl( text=self.get_tokens, focusable=False, key_bindings=None, get_cursor_position=lambda: self.cursor, ) self.content_window = Window( content=self.content, wrap_lines=False, allow_scroll_beyond_bottom=True, scroll_offsets=ScrollOffsets(bottom=self.max_entry_height), cursorline=False, cursorcolumn=False, # right_margins=[NumberedMargin()], # left_margins=[NumberedMargin()], align=WindowAlign.LEFT, height=None, get_line_prefix=self.get_line_prefix # get_line_prefix=lambda line, b: [('bg:red', ' ')] ) self.update() super(OptionsList, self).__init__(content=self.content_window, filter=(custom_filter if custom_filter is not None else has_focus(self.search_buffer)))
'lion', 'mouse', 'rabbit', 'rat', 'snake', 'spider', 'turkey', 'turtle', ], ignore_case=True) # The layout buff = Buffer(completer=animal_completer, complete_while_typing=True) body = FloatContainer(content=HSplit([ Window(FormattedTextControl('Press "q" to quit.'), height=1, style='reverse'), Window(BufferControl(buffer=buff)), ]), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1)) ]) # Key bindings kb = KeyBindings()
from prompt_toolkit import Application from prompt_toolkit.buffer import Buffer from prompt_toolkit.layout.containers import VSplit, Window from prompt_toolkit.layout.controls import BufferControl, FormattedTextControl from prompt_toolkit.layout.layout import Layout buffer1 = Buffer() # Editable buffer. root_container = VSplit([ # One window that holds the BufferControl with the default buffer on # the left. Window(content=BufferControl(buffer=buffer1)), # A vertical line in the middle. We explicitly specify the width, to # make sure that the layout engine will not try to divide the whole # width by three for all these windows. The window will simply fill its # content by repeating this character. Window(width=1, char='|'), # Display the text 'Hello world' on the right. Window(content=FormattedTextControl(text='Hello world')), ]) layout = Layout(root_container) app = Application(layout=layout, full_screen=True) app.run() # You won't be able to Exit this app
placerat massa tempor elementum. Sed tristique mauris ac suscipit euismod. Ut tempus vehicula augue non venenatis. Mauris aliquam velit turpis, nec congue risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex quis sodales maximus.""" # 1. The layout left_text = '\nLeft aligned text. - (Press "q" to quit)\n\n' + LIPSUM center_text = "Centered text.\n\n" + LIPSUM right_text = "Right aligned text.\n\n" + LIPSUM body = HSplit([ Window(FormattedTextControl(left_text), align=WindowAlign.LEFT), Window(height=1, char="-"), Window(FormattedTextControl(center_text), align=WindowAlign.CENTER), Window(height=1, char="-"), Window(FormattedTextControl(right_text), align=WindowAlign.RIGHT), ]) # 2. Key bindings kb = KeyBindings() @kb.add("q") def _(event): " Quit application. " event.app.exit()
# Ctrl-R.) It would be really annoying if the search key bindings are handled, # but the user doesn't see any feedback. We will add the search toolbar to the # bottom by using an HSplit. def get_titlebar_text(): return [ ('class:title', ' Hello world '), ('class:title', ' (Press [Ctrl-Q] to quit.)'), ] root_container = HSplit([ # The titlebar. Window(height=1, content=FormattedTextControl(get_titlebar_text), align=WindowAlign.CENTER), # Horizontal separator. Window(height=1, char='-', style='class:line'), # The 'body', like defined above. body, ]) # 2. Adding key bindings # -------------------- # As a demonstration, we will add just a ControlQ key binding to exit the # application. Key bindings are registered in a # `prompt_toolkit.key_bindings.registry.Registry` instance. We use the
def play(tracks: Iterable[Dict[str, str]]) -> None: if not tracks: logger.warning('Empty playlist') return try: if platform.system() == 'Windows': os.add_dll_directory( r'C:\Program Files\VideoLAN\VLC') # type: ignore import vlc # type: ignore instance = vlc.Instance("--vout=dummy") devices = instance.audio_output_enumerate_devices() if not devices: logger.error('no audio output') return if all([device['name'] != b'pulse' for device in devices]): logger.error('pulse audio is not available, available devices : ') for device in devices: logger.error(device['name']) return if not instance: logger.critical('Unable to start VLC instance') return player = instance.media_list_player_new() if not player: logger.critical('Unable to create VLC player') return tracks_path = [track['path'] for track in tracks] media_list = instance.media_list_new(tracks_path) if not media_list: logger.critical('Unable to create VLC media list') return player.set_media_list(media_list) bindings = KeyBindings() def print_help() -> None: print_formatted_text( HTML( '<violet>Bindings: q = quit | p = play | s = pause/continue | right = next song | left = previous song | l = playlist</violet>' )) @bindings.add('p') def _play_binding(event: Any) -> None: # pylint: disable=unused-argument def play() -> None: """Play song""" player.play() run_in_terminal(play) @bindings.add('q') def _quit_binding(event: Any) -> None: player.pause() event.app.exit() @bindings.add('s') def _pause_binding(event: Any) -> None: # pylint: disable=unused-argument player.pause() @bindings.add('l') def _playlist_binding(event: Any) -> None: # pylint: disable=unused-argument def playlist() -> None: """List songs""" media_player = player.get_media_player() media = media_player.get_media() media.parse() current_artist = media.get_meta(vlc.Meta.Artist) current_album = media.get_meta(vlc.Meta.Album) current_title = media.get_meta(vlc.Meta.Title) print_playlist(tracks, current_artist=current_artist, current_album=current_album, current_title=current_title) run_in_terminal(playlist) @bindings.add('right') def _next_binding(event: Any) -> None: # pylint: disable=unused-argument player.next() @bindings.add('left') def _previous_binding(event: Any) -> None: # pylint: disable=unused-argument player.previous() @bindings.add('h') def _help(event: Any) -> None: # pylint: disable=unused-argument def _print_help() -> None: print_help() run_in_terminal(_print_help) get_app().invalidate() def bottom_toolbar() -> Any: media_player = player.get_media_player() media = media_player.get_media() media.parse() media_time = seconds_to_human(round(media_player.get_time() / 1000)) media_length = seconds_to_human( round(media_player.get_length() / 1000)) artist = media.get_meta(vlc.Meta.Artist) album = media.get_meta(vlc.Meta.Album) title = media.get_meta(vlc.Meta.Title) current = f'({media_time} / {media_length}) {artist} - {album} - {title}' get_app().invalidate() return HTML(f'Current song: {current}') print_help() player.play() root_container = HSplit([ Window(FormattedTextControl(lambda: bottom_toolbar, style='class:bottom-toolbar.text'), style='class:bottom-toolbar') ]) layout = Layout(root_container) app: Any = Application(layout=layout, key_bindings=bindings) app.run() except Exception as e: # pylint:disable=broad-except logger.exception(e)
def _create_layout(self): """ Create `Layout` for this prompt. """ dyncond = self._dyncond # Create functions that will dynamically split the prompt. (If we have # a multiline prompt.) has_before_fragments, get_prompt_text_1, get_prompt_text_2 = \ _split_multiline_prompt(self._get_prompt) default_buffer = self.default_buffer search_buffer = self.search_buffer # Create processors list. all_input_processors = [ HighlightIncrementalSearchProcessor(), HighlightSelectionProcessor(), ConditionalProcessor(AppendAutoSuggestion(), has_focus(default_buffer) & ~is_done), ConditionalProcessor(PasswordProcessor(), dyncond('is_password')), DisplayMultipleCursors(), # Users can insert processors here. DynamicProcessor( lambda: merge_processors(self.input_processors or [])), # For single line mode, show the prompt before the input. ConditionalProcessor( merge_processors([ BeforeInput(get_prompt_text_2), ShowArg(), ]), ~dyncond('multiline')) ] # Create bottom toolbars. bottom_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.bottom_toolbar, style='class:bottom-toolbar.text'), style='class:bottom-toolbar', dont_extend_height=True, height=Dimension(min=1)), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None)) search_toolbar = SearchToolbar( search_buffer, ignore_case=dyncond('search_ignore_case')) search_buffer_control = SearchBufferControl( buffer=search_buffer, input_processors=[ ReverseSearchProcessor(), ShowArg(), ], ignore_case=dyncond('search_ignore_case')) system_toolbar = SystemToolbar( enable_global_bindings=dyncond('enable_system_prompt')) def get_search_buffer_control(): " Return the UIControl to be focused when searching start. " if _true(self.multiline): return search_toolbar.control else: return search_buffer_control default_buffer_control = BufferControl( buffer=default_buffer, search_buffer_control=get_search_buffer_control, input_processors=all_input_processors, include_default_input_processors=False, lexer=DynamicLexer(lambda: self.lexer), preview_search=True) default_buffer_window = Window( default_buffer_control, height=self._get_default_buffer_control_height, left_margins=[ # In multiline mode, use the window margin to display # the prompt and continuation fragments. ConditionalMargin( PromptMargin(get_prompt_text_2, self._get_continuation), filter=dyncond('multiline'), ) ], wrap_lines=dyncond('wrap_lines')) @Condition def multi_column_complete_style(): return self.complete_style == CompleteStyle.MULTI_COLUMN # Build the layout. layout = HSplit([ # The main input, with completion menus floating on top of it. FloatContainer( HSplit([ ConditionalContainer( Window(FormattedTextControl(get_prompt_text_1), dont_extend_height=True), Condition(has_before_fragments)), ConditionalContainer( default_buffer_window, Condition(lambda: get_app().layout.current_control != search_buffer_control), ), ConditionalContainer( Window(search_buffer_control), Condition(lambda: get_app().layout.current_control == search_buffer_control), ), ]), [ # Completion menus. Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=has_focus(default_buffer) & ~multi_column_complete_style)), Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( show_meta=True, extra_filter=has_focus(default_buffer) & multi_column_complete_style)), # The right prompt. Float(right=0, top=0, hide_when_covering_content=True, content=_RPrompt(lambda: self.rprompt)), ]), ConditionalContainer(ValidationToolbar(), filter=~is_done), ConditionalContainer(system_toolbar, dyncond('enable_system_prompt') & ~is_done), # In multiline mode, we use two toolbars for 'arg' and 'search'. ConditionalContainer( Window(FormattedTextControl(self._get_arg_text), height=1), dyncond('multiline') & has_arg), ConditionalContainer(search_toolbar, dyncond('multiline') & ~is_done), bottom_toolbar, ]) return Layout(layout, default_buffer_window)
def generate_layout(input_field: TextArea, output_field: TextArea, log_field: TextArea, right_pane_toggle: Button, log_field_button: Button, search_field: SearchToolbar, timer: TextArea, process_monitor: TextArea, trade_monitor: TextArea, command_tabs: Dict[str, CommandTab], ): components = {} components["item_top_version"] = Window(FormattedTextControl(get_version), style="class:header") components["item_top_active"] = Window(FormattedTextControl(get_active_strategy), style="class:header") components["item_top_file"] = Window(FormattedTextControl(get_strategy_file), style="class:header") components["item_top_gateway"] = Window(FormattedTextControl(get_gateway_status), style="class:header") components["item_top_toggle"] = right_pane_toggle components["pane_top"] = VSplit([components["item_top_version"], components["item_top_active"], components["item_top_file"], components["item_top_gateway"], components["item_top_toggle"]], height=1) components["pane_bottom"] = VSplit([trade_monitor, process_monitor, timer], height=1) output_pane = Box(body=output_field, padding=0, padding_left=2, style="class:output-field") input_pane = Box(body=input_field, padding=0, padding_left=2, padding_top=1, style="class:input-field") components["pane_left"] = HSplit([output_pane, input_pane], width=Dimension(weight=1)) if all(not t.is_selected for t in command_tabs.values()): log_field_button.window.style = "class:tab_button.focused" else: log_field_button.window.style = "class:tab_button" tab_buttons = [log_field_button] for tab in sorted(command_tabs.values(), key=lambda x: x.tab_index): if tab.button is not None: if tab.is_selected: tab.button.window.style = "class:tab_button.focused" else: tab.button.window.style = "class:tab_button" tab.close_button.window.style = tab.button.window.style tab_buttons.append(VSplit([tab.button, tab.close_button])) pane_right_field = log_field focused_right_field = [tab.output_field for tab in command_tabs.values() if tab.is_selected] if focused_right_field: pane_right_field = focused_right_field[0] components["pane_right_top"] = VSplit(tab_buttons, height=1, style="class:log-field", padding_char=" ", padding=2) components["pane_right"] = ConditionalContainer( Box(body=HSplit([components["pane_right_top"], pane_right_field, search_field], width=Dimension(weight=1)), padding=0, padding_left=2, style="class:log-field"), filter=True ) components["hint_menus"] = [Float(xcursor=True, ycursor=True, transparent=True, content=CompletionsMenu(max_height=16, scroll_offset=1))] root_container = HSplit([ components["pane_top"], VSplit( [FloatContainer(components["pane_left"], components["hint_menus"]), components["pane_right"]]), components["pane_bottom"], ]) return Layout(root_container, focused_element=input_field), components
def __init__(self, get_formatted_text): super(_RPrompt, self).__init__(FormattedTextControl(get_formatted_text), align=WindowAlign.RIGHT, style='class:rprompt')
"spider", "turkey", "turtle", ], ignore_case=True, ) # The layout buff = Buffer(completer=animal_completer, complete_while_typing=True) body = FloatContainer( content=HSplit( [ Window( FormattedTextControl('Press "q" to quit.'), height=1, style="reverse" ), Window(BufferControl(buffer=buff)), ] ), floats=[ Float( xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1), ) ], ) # Key bindings
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex quis sodales maximus. """ * 100).split()) # 1. The layout left_text = "Floating\nleft" right_text = "Floating\nright" top_text = "Floating\ntop" bottom_text = "Floating\nbottom" center_text = "Floating\ncenter" quit_text = "Press 'q' to quit." body = FloatContainer( content=Window(FormattedTextControl(LIPSUM), wrap_lines=True), floats=[ # Important note: Wrapping the floating objects in a 'Frame' is # only required for drawing the border around the # floating text. We do it here to make the layout more # obvious. # Left float. Float(Frame(Window(FormattedTextControl(left_text), width=10, height=2), style='bg:#44ffff #ffffff'), left=0), # Right float. Float(Frame(Window(FormattedTextControl(right_text),
def start_app(args): """Text-based GUI application""" cmd = Commands() completer = WordCompleter(cmd.commands(), meta_dict=cmd.meta_dict(), ignore_case=True) history = InMemoryHistory() # Individual windows input_field = TextArea(height=1, prompt='ctserial> ', style='class:input-field', completer=completer, history=history) output_field = TextArea(scrollbar=True, style='class:output-field', text='') statusbar = Window(content=FormattedTextControl(get_statusbar_text), height=1, style='class:statusbar') # Organization of windows body = FloatContainer(HSplit([ input_field, Window(height=1, char='-', style='class:line'), output_field, statusbar ]), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1)) ]) # Adding menus root_container = MenuContainer( body=body, menu_items=[], # menu_items=[ # MenuItem('Project ', children=[ # MenuItem('New'), # MenuItem('Open'), # MenuItem('Save'), # MenuItem('Save as...'), # MenuItem('-', disabled=True), # MenuItem('Exit'), ]), # MenuItem('View ', children=[ # MenuItem('Split'), ]), # MenuItem('Info ', children=[ # MenuItem('Help'), # MenuItem('About'), ]), ], floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1)), ]) # The key bindings. kb = KeyBindings() @kb.add('space') def _(event): input_text = input_field.text cursor = len(input_text) input_updated = input_text[:cursor] + ' ' + input_text[cursor + 1:] cursor += 1 input_field.buffer.document = Document(text=input_updated, cursor_position=cursor) input_field.buffer.completer = WordCompleter([], ignore_case=True) @kb.add('enter', filter=has_focus(input_field)) def _(event): # Process commands on prompt after hitting enter key # tx_bytes = parse_command(input_field.text, event=event) input_field.buffer.completer = WordCompleter(cmd.commands(), meta_dict=cmd.meta_dict(), ignore_case=True) if len(input_field.text) == 0: return output_text = cmd.execute(input_field.text, output_field.text, event) input_field.buffer.reset(append_to_history=True) # For commands that do not send data to serial device if output_text == None: input_field.text = '' return # For invalid commands forcing users to correct them elif output_text == False: return # For invalid commands forcing users to correct them else: output_field.buffer.document = Document( text=output_text, cursor_position=len(output_text)) input_field.text = '' @kb.add('c-c') def _(event): """Pressing Control-C will copy highlighted text to clipboard""" data = output_field.buffer.copy_selection() get_app().clipboard.set_data(data) @kb.add('c-p') def _(event): """Pressing Control-P will paste text from clipboard""" input_field.buffer.paste_clipboard_data(get_app().clipboard.get_data()) @kb.add('c-q') def _(event): " Pressing Ctrl-Q will exit the user interface. " cmd.do_exit(input_field.text, output_field.text, event) @kb.add('c-d') def _(event): """Press Ctrl-D to start the python debugger""" import pdb pdb.set_trace() style = Style([ # ('output-field', 'bg:#000000 #ffffff'), # ('input-field', 'bg:#000000 #ffffff'), ('line', '#004400'), ('statusbar', 'bg:#AAAAAA') ]) # Run application. application = MyApplication(layout=Layout(root_container, focused_element=input_field), key_bindings=kb, style=style, mouse_support=True, full_screen=True) application.run()
("class:title", " (Press [Ctrl-Q] to quit.)"), ] left_buffer = Buffer() right_buffer = Buffer() left_window = Window(BufferControl(buffer=left_buffer), height=2) right_window = Window(BufferControl(buffer=right_buffer)) body = VSplit([ HSplit([ left_window, Window( height=1, content=FormattedTextControl(lambda: [("class:title", "(o_0)")]), ), ]), Window(width=1, char="|", style="class:line"), right_window, ]) root_container = HSplit([ Window( height=1, content=FormattedTextControl(get_titlebar_text), align=WindowAlign.CENTER, ), Window(height=1, char="-", style="class:line"), body, ])
#!/usr/bin/env python # vim: set fileencoding=utf-8 from prompt_toolkit import Application, HTML from prompt_toolkit.layout.containers import Window from prompt_toolkit.layout.controls import FormattedTextControl from prompt_toolkit.layout.layout import Layout from prompt_toolkit.key_binding import KeyBindings # naformátovaná zpráva message = HTML("<ansired>Hello</ansired> <ansiblue>world!</ansiblue>") # ovládací prvek s naformátovaným textem text = FormattedTextControl(text=message) # okno obsahující jediný ovládací prvek window = Window(content=text) # správce rozvržení layout = Layout(window) # napojení na klávesové zkratky key_bindings = KeyBindings() @key_bindings.add('escape') def on_escape_press(event): """Callback funkce volaná při stisku klávesy Esc.""" print("\n\n[escape]\n\n") event.app.exit()