def create_layout(self, exam_lex, toolbar_lex): """ creates the layout """ lexer, exam_lex, toolbar_lex = get_lexers(self.shell_ctx.lexer, exam_lex, toolbar_lex) if not any(isinstance(processor, DefaultPrompt) for processor in self.input_processors): self.input_processors.append(DefaultPrompt(self.get_prompt_tokens)) layout_lower = ConditionalContainer( HSplit([ get_anyhline(self.shell_ctx.config), get_descriptions(self.shell_ctx.config, exam_lex, lexer), get_examplehline(self.shell_ctx.config), get_example(self.shell_ctx.config, exam_lex), ConditionalContainer( get_hline(), filter=self.show_default | self.show_symbol ), ConditionalContainer( Window( content=BufferControl( buffer_name='default_values', lexer=lexer ) ), filter=self.show_default ), ConditionalContainer( get_hline(), filter=self.show_default & self.show_symbol ), ConditionalContainer( Window( content=BufferControl( buffer_name='symbols', lexer=exam_lex ) ), filter=self.show_symbol ), ConditionalContainer( Window( content=BufferControl( buffer_name='progress', lexer=lexer ) ), filter=self.show_progress ), Window( content=BufferControl( buffer_name='bottom_toolbar', lexer=toolbar_lex ), ), ]), filter=~IsDone() & RendererHeightIsKnown() ) layout_full = HSplit([ FloatContainer( Window( BufferControl( input_processors=self.input_processors, lexer=lexer, preview_search=Always()), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=MAX_COMPLETION, scroll_offset=1, extra_filter=(HasFocus(DEFAULT_BUFFER))))]), layout_lower ]) return layout_full
], ignore_case=True) root_container = HSplit([ VSplit([ Frame(body=Label(text='Left frame\ncontent')), Dialog(title='The custom window', body=Label('hello\ntest')), textfield, ], height=D()), VSplit([ Frame(body=ProgressBar(), title='Progress bar'), Frame(title='Checkbox list', body=HSplit([ checkbox1, checkbox2, ])), Frame(title='Radio list', body=radios), ], padding=1), Box( body=VSplit([ yes_button, no_button, ], align='CENTER', padding=3), style='class:button-bar', height=3, ), ]) root_container = MenuContainer( body=root_container,
def __init__( self, python_input: "PythonInput", lexer=PythonLexer, extra_body=None, extra_toolbars=None, extra_buffer_processors=None, input_buffer_height: Optional[AnyDimension] = None, ) -> None: D = Dimension extra_body = [extra_body] if extra_body else [] extra_toolbars = extra_toolbars or [] extra_buffer_processors = extra_buffer_processors or [] input_buffer_height = input_buffer_height or D(min=6) search_toolbar = SearchToolbar(python_input.search_buffer) def create_python_input_window(): def menu_position(): """ When there is no autocompletion menu to be shown, and we have a signature, set the pop-up position at `bracket_start`. """ b = python_input.default_buffer if b.complete_state is None and python_input.signatures: row, col = python_input.signatures[0].bracket_start index = b.document.translate_row_col_to_index(row - 1, col) return index return Window( BufferControl( buffer=python_input.default_buffer, search_buffer_control=search_toolbar.control, lexer=lexer, include_default_input_processors=False, input_processors=[ ConditionalProcessor( processor=HighlightIncrementalSearchProcessor(), filter=has_focus(SEARCH_BUFFER) | has_focus(search_toolbar.control), ), HighlightSelectionProcessor(), DisplayMultipleCursors(), # Show matching parentheses, but only while editing. ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars="[](){}"), filter=has_focus(DEFAULT_BUFFER) & ~is_done & Condition(lambda: python_input. highlight_matching_parenthesis), ), ConditionalProcessor(processor=AppendAutoSuggestion(), filter=~is_done), ] + extra_buffer_processors, menu_position=menu_position, # Make sure that we always see the result of an reverse-i-search: preview_search=True, ), left_margins=[PythonPromptMargin(python_input)], # Scroll offsets. The 1 at the bottom is important to make sure # the cursor is never below the "Press [Meta+Enter]" message # which is a float. scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4), # As long as we're editing, prefer a minimal height of 6. height=(lambda: (None if get_app().is_done or python_input. show_exit_confirmation else input_buffer_height)), wrap_lines=Condition(lambda: python_input.wrap_lines), ) sidebar = python_sidebar(python_input) root_container = HSplit([ VSplit([ HSplit([ FloatContainer( content=HSplit([create_python_input_window()] + extra_body), floats=[ Float( xcursor=True, ycursor=True, content=ConditionalContainer( content=CompletionsMenu( scroll_offset=( lambda: python_input. completion_menu_scroll_offset), max_height=12, ), filter=show_completions_menu(python_input), ), ), Float( xcursor=True, ycursor=True, content=ConditionalContainer( content=MultiColumnCompletionsMenu(), filter=show_multi_column_completions_menu( python_input), ), ), Float( xcursor=True, ycursor=True, content=signature_toolbar(python_input), ), Float( left=2, bottom=1, content=exit_confirmation(python_input), ), Float( bottom=0, right=0, height=1, content=meta_enter_message(python_input), hide_when_covering_content=True, ), Float( bottom=1, left=1, right=0, content=python_sidebar_help(python_input), ), ], ), ArgToolbar(), search_toolbar, SystemToolbar(), ValidationToolbar(), ConditionalContainer( content=CompletionsToolbar(), filter=show_completions_toolbar(python_input) & ~is_done, ), # Docstring region. ConditionalContainer( content=Window( height=D.exact(1), char="\u2500", style="class:separator", ), filter=HasSignature(python_input) & ShowDocstring(python_input) & ~is_done, ), ConditionalContainer( content=Window( BufferControl( buffer=python_input.docstring_buffer, lexer=SimpleLexer(style="class:docstring"), # lexer=PythonLexer, ), height=D(max=12), ), filter=HasSignature(python_input) & ShowDocstring(python_input) & ~is_done, ), ]), ConditionalContainer( content=HSplit([ sidebar, Window(style="class:sidebar,separator", height=1), python_sidebar_navigation(python_input), ]), filter=ShowSidebar(python_input) & ~is_done, ), ]) ] + extra_toolbars + [ VSplit([ status_bar(python_input), show_sidebar_button_info(python_input) ]) ]) self.layout = Layout(root_container) self.sidebar = sidebar
# Output Field # ------------ output_field = TextArea(text=init_text(), lexer=PygmentsLexer(JsonLexer)) # Input Field # ----------- def accept_handler(buf): """Callback method invoked when <ENTER> is pressed.""" command_processor.accept_handler(buf, input_field, output_field) command_completer = WordCompleter([command.value for command in Command], ignore_case=True) input_field = TextArea(height=1, prompt=u'>>> ', lexer=PygmentsLexer(JsonLexer), completer=command_completer, style='class:input-field', multiline=False, wrap_lines=False, accept_handler=accept_handler) # Container # --------- container = HSplit([ output_field, Window(height=1, char=u'-', style=u'class:line'), input_field ])
def question(message, **kwargs): # TODO disabled, dict choices if not 'choices' in kwargs: raise PromptParameterException('choices') choices = kwargs.pop('choices', None) default = kwargs.pop('default', 0) # TODO page_size = kwargs.pop('page_size', 0) qmark = kwargs.pop('qmark', '?') # TODO style defaults on detail level style = kwargs.pop('style', default_style) ic = InquirerControl(choices, page_size) def get_prompt_tokens(cli): tokens = [] tokens.append((Token.QuestionMark, qmark)) tokens.append((Token.Question, ' %s ' % message)) if ic.answered: tokens.append((Token.Answer, ' ' + ic.get_selection()[0])) else: tokens.append((Token.Instruction, ' (Use arrow keys)')) return tokens # assemble layout layout = HSplit([ Window(height=D.exact(1), content=TokenListControl(get_prompt_tokens)), ConditionalContainer(Window(ic), filter=~IsDone()) ]) # key bindings manager = KeyBindingManager.for_prompt() @manager.registry.add_binding(Keys.ControlQ, eager=True) @manager.registry.add_binding(Keys.ControlC, eager=True) def _(event): raise KeyboardInterrupt() # event.cli.set_return_value(None) @manager.registry.add_binding(Keys.Down, eager=True) def move_cursor_down(event): ic.increment_selected_index() @manager.registry.add_binding(Keys.Up, eager=True) def move_cursor_up(event): ic.decrement_selected_index() @manager.registry.add_binding(Keys.Left, eager=True) def move_page_left(event): ic.decrement_page() @manager.registry.add_binding(Keys.Right, eager=True) def move_page_right(event): ic.increment_page() @manager.registry.add_binding(Keys.Enter, eager=True) def set_answer(event): ic.answered = True event.cli.set_return_value(ic.get_selection()[1]) return Application(layout=layout, key_bindings_registry=manager.registry, mouse_support=True, style=style)
Label(text=', '.join( [f'{k}:{v}' for k, v in c.__dict__.items() if k != 'tag'])) for c in jvm.class_files[class_name].const_pool ], ] frames = [list(f) for f in zip(*frames)] CONST_POOL_PAGES = [] for i in range(0, len(frames), 14): frames_chunk = frames[i:i + 14] page = Layout( HSplit([ VSplit([HSplit([Frame(VSplit(frame)) for frame in frames_chunk])]), Window(), Label('LEFT/RIGHT: change page. v: toggle view. q: quit.') ])) CONST_POOL_PAGES += [page] # start the JVM and record the Layout at each step log.info(f'Recording the execution of {method}...') ERROR = False try: stdout = jvm.call_function(method, arguments) except Exception as e: log.exception('Something went wrong during the execution') ERROR = True if not LAYOUT_STACK:
def __init__(self): available_archs = [ "arm", "x86_64", "riscv", "avr", "or1k", "xtensa", "microblaze", "msp430", ] # State variables: self.arch = available_archs[-1] self.stage = "asm" self.show_log = False self.optimize = False self.archs = cycle(available_archs) self.stages = cycle(["ir", "ast", "asm"]) # Some key bindings: kb = KeyBindings() @kb.add(Keys.F10, eager=True) def quit_(event): with open(self.cache_filename, "w") as f: f.write(self.source_buffer.text) event.app.exit() kb.add(Keys.F6, eager=True)(self.cycle_stage) kb.add(Keys.F7, eager=True)(self.next_architecture) kb.add(Keys.F8, eager=True)(self.toggle_optimize) kb.add(Keys.F9, eager=True)(self.toggle_log) kb.add("tab")(focus_next) kb.add("s-tab")(focus_previous) log_buffer = Buffer(multiline=True) show_log = Condition(lambda: self.show_log) self.errors_processor = DisplayErrorsProcessor() # Source: self.source_buffer = Buffer(multiline=True) src_lexer = PygmentsLexer(CLexer) code_edit = Window( content=BufferControl( buffer=self.source_buffer, lexer=src_lexer, input_processors=[self.errors_processor], ), left_margins=[NumberedMargin()], right_margins=[ScrollbarMargin(display_arrows=True)], ) # Output: self.output_buffer = Buffer(multiline=True) result_window = Window( content=BufferControl(self.output_buffer), right_margins=[ScrollbarMargin(display_arrows=True)], ) layout = Layout( HSplit([ Window( FormattedTextControl(self.get_title_bar_tokens), height=1, ), VSplit([ Frame(body=code_edit, title="source code"), Frame(body=result_window, title="assembly output"), ConditionalContainer( Window(content=BufferControl(log_buffer)), filter=show_log, ), ]), Window( FormattedTextControl(text="F9=toggle log F10=exit"), height=1, style="class:status", ), ])) style = style_from_pygments_cls(get_style_by_name("vim")) log_handler = MyHandler(log_buffer) fmt = logging.Formatter(fmt=logformat) log_handler.setFormatter(fmt) log_handler.setLevel(logging.DEBUG) logging.getLogger().setLevel(logging.INFO) logging.getLogger().addHandler(log_handler) self.source_buffer.on_text_changed += self.on_change self.application = Application(layout=layout, key_bindings=kb, style=style, full_screen=True) if os.path.exists(self.cache_filename): with open(self.cache_filename, "r") as f: src = f.read() else: src = DEMO_SOURCE self.source_buffer.text = src
def __init__(self, debugger): self._filename = None self.sources = {} self.debugger = debugger self.debugger.events.on_stop += self.on_stop self.current_address_margin = CurrentAddressMargin() kb = KeyBindings() self.locals_processor = DisplayVariablesProcessor() self.source_buffer = Buffer(multiline=True) self.bar_buffer = Buffer(multiline=True) self.register_buffer = Buffer(multiline=True) self.logs_buffer = Buffer(multiline=True) @kb.add(Keys.F10, eager=True) def quit_(event): event.app.exit() @kb.add(Keys.F8) def clear_breakpoint_(event): if self.has_source(): filename, row = self.get_current_location() self.debugger.clear_breakpoint(filename, row) @kb.add(Keys.F7) def set_breakpoint_(event): if self.has_source(): filename, row = self.get_current_location() self.debugger.set_breakpoint(filename, row) @kb.add(Keys.F6) def step_(event): self.debugger.step() @kb.add(Keys.F5) def run_(event): self.debugger.run() @kb.add(Keys.F4) def stop_(event): self.debugger.stop() @kb.add(Keys.PageUp) def scroll_up_(event): self.source_buffer.cursor_up(count=15) @kb.add(Keys.PageDown) def scroll_down_(event): self.source_buffer.cursor_down(count=15) src_lexer = PygmentsLexer(CLexer) source_code_window = Window( content=BufferControl( buffer=self.source_buffer, lexer=src_lexer, input_processors=[self.locals_processor], ), left_margins=[self.current_address_margin, NumberredMargin()], right_margins=[ScrollbarMargin(display_arrows=True)], cursorline=True, ) register_window = Window( content=BufferControl(buffer=self.register_buffer), width=20) title_text = "Welcome to the ppci debugger version {}".format( ppci_version) help_text = ("F4=stop F5=run F6=step F7=set breakpoint" + " F8=clear breakpoint F10=exit") # Application layout: layout = HSplit([ Window(content=FormattedTextControl(text=title_text), height=1), VSplit([ HSplit([ Frame(body=source_code_window), Window( content=BufferControl(buffer=self.logs_buffer), height=2, ), ]), Frame(body=register_window, title="registers"), ]), Window( content=FormattedTextControl(self.get_status_tokens), height=1, ), Window(content=FormattedTextControl(help_text), height=1), ]) style = style_from_pygments(get_style_by_name("vim")) log_handler = MyHandler(self.logs_buffer) fmt = logging.Formatter(fmt=logformat) log_handler.setFormatter(fmt) log_handler.setLevel(logging.DEBUG) logging.getLogger().setLevel(logging.DEBUG) logging.getLogger().addHandler(log_handler) self.application = Application(layout=layout, style=style, key_bindings=kb, full_screen=True)
def get_root_container(self) -> FloatContainer: buttons = [ Button("Play", width=MENU_BUTTON_WIDTH, handler=self._return_session), Button( "Difficulty", width=MENU_BUTTON_WIDTH, handler=lambda: self.multi_screen.add_floating_screen( self._difficulty_select_screen), ), Button("High Scores", width=MENU_BUTTON_WIDTH, handler=lambda: self.multi_screen.set_screen( self._high_score_screen)), HorizontalLine(), Button( "Back", width=MENU_BUTTON_WIDTH, handler=self.multi_screen.set_previous, ), ] menu_keybindings = _create_menu_keybindings(buttons) options_buttons_container = Frame( HSplit( buttons, width=Dimension(min=MENU_BUTTON_WIDTH, max=40), height=Dimension(), ), title="Options", key_bindings=menu_keybindings, ) difficulty_label_container = Box( Label( text=lambda: "Difficulty: {0}".format(self._selected_difficulty ), width=Dimension(min=40), ), padding=0, padding_left=1, ) game_description_container = Box( TextArea( text=self._selected_game.description, dont_extend_height=False, width=Dimension(min=40), read_only=True, scrollbar=True, wrap_lines=False, ), padding=0, padding_left=1, ) return FloatContainer(VSplit([ options_buttons_container, Frame( HSplit([ difficulty_label_container, HorizontalLine(), game_description_container, ]), title=self._selected_game.game_name, ), ]), floats=[])
def __init__(self, my_app: "sqlApp") -> None: self.my_app = my_app self.search_field = SearchToolbar() history_file = config_location() + 'history' ensure_dir_exists(history_file) hist = ThreadedHistory(FileHistory(expanduser(history_file))) self.input_buffer = Buffer( name="defaultbuffer", tempfile_suffix=".py", multiline=MultilineFilter(self.my_app), history=hist, completer=DynamicCompleter( lambda: ThreadedCompleter(self.my_app.completer)), # lambda: self.my_app.completer), auto_suggest=ThreadedAutoSuggest(AutoSuggestFromHistory()), complete_while_typing=Condition( lambda: self.my_app.active_conn is not None)) main_win_control = BufferControl( buffer=self.input_buffer, lexer=PygmentsLexer(SqlLexer), search_buffer_control=self.search_field.control, include_default_input_processors=False, input_processors=[AppendAutoSuggestion()], preview_search=True) self.main_win = Window( main_win_control, height=( lambda: (None if get_app().is_done else (Dimension(min=self.my_app.min_num_menu_lines) if not self.my_app.show_preview else Dimension( min=self.my_app.min_num_menu_lines, preferred=180)))), get_line_prefix=partial(sql_line_prefix, my_app=self.my_app), scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4)) self.lprompt = login_prompt(self.my_app) self.preview = preview_element(self.my_app) self.disconnect_dialog = disconnect_dialog(self.my_app) container = HSplit([ VSplit([ FloatContainer( content=HSplit([ self.main_win, self.search_field, ]), floats=[ Float( bottom=1, left=1, right=0, content=sql_sidebar_help(self.my_app), ), Float(content=self.lprompt), Float(content=self.preview, ), Float(content=self.disconnect_dialog, ), Float(left=2, bottom=1, content=exit_confirmation(self.my_app)), Float(xcursor=True, ycursor=True, transparent=True, content=CompletionsMenu(scroll_offset=1, max_height=16, extra_filter=has_focus( self.input_buffer))) ]), ConditionalContainer( content=sql_sidebar(self.my_app), filter=ShowSidebar(self.my_app) & ~is_done, ) ]), VSplit([ status_bar(self.my_app), show_sidebar_button_info(self.my_app) ]) ]) def accept(buff): app = get_app() app.exit(result=["non-preview", buff.text]) app.pre_run_callables.append(buff.reset) return True self.input_buffer.accept_handler = accept self.layout = Layout(container, focused_element=self.main_win)
systemOutput, ]), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1)) ] ) root_container = HSplit([ # The titlebar. Window(content=FormattedTextControl( get_statusbar_text), height=D.exact(1), style='class:status'), # Horizontal separator. Window(height=1, char='-', style='class:line'), # The 'body', like defined above. body, ]) kb = KeyBindings() @kb.add('c-c', eager=True) @kb.add('c-q', eager=True) def _(event): event.app.set_result(None) @kb.add('c-s', eager=True)
def __init__(self, engine, on_output, on_exit): self.engine = engine self.on_exit = on_exit self.on_output = on_output self.outcome = "" self.strokes_info = "" self.translation_info = "" # we start in the strokes field add_filter(engine) self.dicts = [] for path in self.engine.dictionaries: d = self.engine.dictionaries[path] if not d.readonly: self.dicts.append(d) self.dict_index = 0 picker_kb = KeyBindings() # FormattedTextControl can't have accept_handler bound @picker_kb.add("enter") def _(event): self.accept(None) @picker_kb.add("left") def _(event): target = self.dict_index - 1 if target < 0: target = len(self.dicts) - 1 self.dict_index = target @picker_kb.add("right") def _(event): target = self.dict_index + 1 if target > len(self.dicts) - 1: target = 0 self.dict_index = target self.dictionary_picker = Window(FormattedTextControl( focusable=True, text=lambda: f"{self.dicts[self.dict_index].path}", style="class:normal", key_bindings=picker_kb), height=1) self.strokes_field = TextArea( prompt="Strokes: ", height=1, multiline=False, wrap_lines=False, accept_handler=self.accept, style="class:normal", ) self.strokes_field.buffer.on_text_changed += self.strokes_changed self.translation_field = TextArea( prompt="Output: ", height=1, multiline=False, wrap_lines=False, accept_handler=self.accept, style="class:normal", ) self.translation_field.buffer.on_text_changed += self.translation_changed last_translations = engine.translator_state.translations retro_formatter = RetroFormatter(last_translations) last_words = retro_formatter.last_words(1) if last_words: self.translation_field.text = last_words[0].replace("\n", "").rstrip() kb = KeyBindings() @kb.add("escape", eager=True) def _(event): layout = get_app().layout remove_filter(self.engine) self.outcome = "Add translation abandoned" self.update_output() on_exit() def focus(direction): layout = get_app().layout if direction == 'next': layout.focus_next() if direction == 'previous': layout.focus_previous() if layout.has_focus(self.strokes_field): add_filter(self.engine) else: remove_filter(self.engine) self.update_output() @kb.add("tab") def _(event): focus('next') @kb.add("s-tab") def _(event): focus('previous') self.container = HSplit( [ self.dictionary_picker, self.strokes_field, self.translation_field ], key_bindings=kb, )
def question(message, **kwargs): # TODO need ENTER confirmation default = kwargs.pop('default', True) # TODO style defaults on detail level style = kwargs.pop('style', style_from_dict({ Token.QuestionMark: '#5F819D', #Token.Selected: '#FF9D00', # AWS orange Token.Instruction: '', # default Token.Answer: '#FF9D00 bold', # AWS orange Token.Question: 'bold', })) status = {'answer': None} def get_prompt_tokens(cli): tokens = [] tokens.append((Token.QuestionMark, '?')) tokens.append((Token.Question, ' %s ' % message)) if isinstance(status['answer'], bool): tokens.append((Token.Answer, ' Yes' if status['answer'] else ' No')) else: if default: instruction = ' (Y/n)' else: instruction = ' (y/N)' tokens.append((Token.Instruction, instruction)) return tokens # assemble layout # TODO this does not work without the HSplit?? layout = HSplit([ Window( height=D.exact(1), content=TokenListControl(get_prompt_tokens, align_center=False), ) ]) # key bindings manager = KeyBindingManager.for_prompt() @manager.registry.add_binding(Keys.ControlQ, eager=True) @manager.registry.add_binding(Keys.ControlC, eager=True) def _(event): raise KeyboardInterrupt() @manager.registry.add_binding('n') @manager.registry.add_binding('N') def key_n(event): status['answer'] = False event.cli.set_return_value(False) @manager.registry.add_binding('y') @manager.registry.add_binding('Y') def key_y(event): status['answer'] = True event.cli.set_return_value(True) @manager.registry.add_binding(Keys.Enter, eager=True) def set_answer(event): status['answer'] = default event.cli.set_return_value(default) return Application( layout=layout, key_bindings_registry=manager.registry, mouse_support=False, style=style, erase_when_done=False, )
def __init__(self, body, menu_items=None, floats=None, key_bindings=None): assert isinstance(menu_items, list) and \ all(isinstance(i, MenuItem) for i in menu_items) assert floats is None or all(isinstance(f, Float) for f in floats) self.body = body self.menu_items = menu_items self.selected_menu = [0] # Key bindings. kb = KeyBindings() @Condition def in_main_menu(): return len(self.selected_menu) == 1 @Condition def in_sub_menu(): return len(self.selected_menu) > 1 # Navigation through the main menu. @kb.add('left', filter=in_main_menu) def _(event): self.selected_menu[0] = max(0, self.selected_menu[0] - 1) @kb.add('right', filter=in_main_menu) def _(event): self.selected_menu[0] = min( len(self.menu_items) - 1, self.selected_menu[0] + 1) @kb.add('down', filter=in_main_menu) def _(event): self.selected_menu.append(0) @kb.add('c-c', filter=in_main_menu) @kb.add('c-g', filter=in_main_menu) def _(event): " Leave menu. " layout = event.app.layout layout.focus_previous() # Sub menu navigation. @kb.add('left', filter=in_sub_menu) @kb.add('c-g', filter=in_sub_menu) @kb.add('c-c', filter=in_sub_menu) def _(event): " Go back to parent menu. " if len(self.selected_menu) > 1: self.selected_menu.pop() @kb.add('right', filter=in_sub_menu) def _(event): " go into sub menu. " if self._get_menu(len(self.selected_menu) - 1).children: self.selected_menu.append(0) # If This item does not have a sub menu. Go up in the parent menu. elif len(self.selected_menu) == 2 and self.selected_menu[0] < len(self.menu_items) - 1: self.selected_menu = [min( len(self.menu_items) - 1, self.selected_menu[0] + 1)] if self.menu_items[self.selected_menu[0]].children: self.selected_menu.append(0) @kb.add('up', filter=in_sub_menu) def _(event): " Select previous (enabled) menu item or return to main menu. " # Look for previous enabled items in this sub menu. menu = self._get_menu(len(self.selected_menu) - 2) index = self.selected_menu[-1] previous_indexes = [i for i, item in enumerate(menu.children) if i < index and not item.disabled] if previous_indexes: self.selected_menu[-1] = previous_indexes[-1] elif len(self.selected_menu) == 2: # Return to main menu. self.selected_menu.pop() @kb.add('down', filter=in_sub_menu) def _(event): " Select next (enabled) menu item. " menu = self._get_menu(len(self.selected_menu) - 2) index = self.selected_menu[-1] next_indexes = [i for i, item in enumerate(menu.children) if i > index and not item.disabled] if next_indexes: self.selected_menu[-1] = next_indexes[0] @kb.add('enter') def _(event): " Click the selected menu item. " item = self._get_menu(len(self.selected_menu) - 1) if item.handler: event.app.layout.focus_previous() item.handler() # Controls. self.control = FormattedTextControl( self._get_menu_fragments, key_bindings=kb, focussable=True, show_cursor=False) self.window = Window( height=1, content=self.control, style='class:menu-bar') submenu = self._submenu(0) submenu2 = self._submenu(1) submenu3 = self._submenu(2) @Condition def has_focus(): return get_app().layout.current_window == self.window self.container = FloatContainer( content=HSplit([ # The titlebar. self.window, # The 'body', like defined above. body, ]), floats=[ Float(xcursor=self.window, ycursor=self.window, content=ConditionalContainer( content=Shadow(body=submenu), filter=has_focus)), Float(attach_to_window=submenu, xcursor=True, ycursor=True, allow_cover_cursor=True, content=ConditionalContainer( content=Shadow(body=submenu2), filter=has_focus & Condition(lambda: len(self.selected_menu) >= 1))), Float(attach_to_window=submenu2, xcursor=True, ycursor=True, allow_cover_cursor=True, content=ConditionalContainer( content=Shadow(body=submenu3), filter=has_focus & Condition(lambda: len(self.selected_menu) >= 2))), # -- ] + (floats or []), key_bindings=key_bindings, )
def __init__(self, context, back_app=None, data=None, errors=None, active_input=None): self.context = context self.back_app = back_app self.data = data or {} self.errors = errors or {} if self.method == StepsMethod.CONFIG: self.schema = context.methods[f"{self.service}.update"]["accepts"][ 0]["properties"] if not self.data: with self.context.get_client() as c: self.data = c.call(f"{self.service}.config") else: self.schema = context.methods[f"{self.service}.create"]["accepts"][ 0]["properties"] widgets, self.focus, complete = self._draw(active_input) inputs = list(filter(lambda w: not isinstance(w, Label), widgets)) buttons = [] if complete: buttons.append(Button(text="Save", handler=self._save, width=6)) buttons.append(Button(text="Back", handler=self._back, width=6)) inputs_kb = KeyBindings() first_input_selected = has_focus(inputs[0]) last_input_selected = has_focus(inputs[-1]) inputs_kb.add("up", filter=first_input_selected)( lambda event: event.app.layout.focus(buttons[-1])) inputs_kb.add("up", filter=~first_input_selected)(focus_previous) inputs_kb.add("down", filter=last_input_selected)( lambda event: event.app.layout.focus(buttons[0])) inputs_kb.add("down", filter=~last_input_selected)(focus_next) buttons_kb = KeyBindings() first_button_selected = has_focus(buttons[0]) last_button_selected = has_focus(buttons[-1]) buttons_kb.add("up", filter=first_button_selected)( lambda event: event.app.layout.focus(inputs[-1])) buttons_kb.add("up", filter=~first_button_selected)(focus_previous) buttons_kb.add("down", filter=last_button_selected)( lambda event: event.app.layout.focus(inputs[0])) buttons_kb.add("down", filter=~last_button_selected)(focus_next) buttons_kb.add("left", filter=first_button_selected)( lambda event: event.app.layout.focus(buttons[-1])) buttons_kb.add("left", filter=~first_button_selected)(focus_previous) buttons_kb.add("right", filter=last_button_selected)( lambda event: event.app.layout.focus(buttons[0])) buttons_kb.add("right", filter=~last_button_selected)(focus_next) frame_body = HSplit([ Box(body=HSplit(widgets, padding=0, key_bindings=inputs_kb), ), Box( body=VSplit(buttons, padding=1, key_bindings=buttons_kb), height=D(min=1, max=3, preferred=3), ), ]) frame = Shadow(body=Frame( title=lambda: self.title, body=frame_body, style="class:dialog.body", width=None, modal=True, )) self.container = Box(body=frame, style="class:dialog", width=None) self.app = None
def get_root_container(self) -> FloatContainer: score_store = Scores() with score_store: high_scores = score_store.get_scores(self._selected_game, self._selected_difficulty) score_table = format_scores(high_scores, sort_method=self._selected_sort, header_style=None) buttons = [ Button( "Sort By", width=MENU_BUTTON_WIDTH, handler=lambda: self.multi_screen.add_floating_screen( self._sort_select_screen), ), HorizontalLine(), Button("Back", width=MENU_BUTTON_WIDTH, handler=self.multi_screen.set_previous), ] menu_keybindings = _create_menu_keybindings(buttons) buttons_container = Frame( HSplit( buttons, width=Dimension(min=MENU_BUTTON_WIDTH, max=40), height=Dimension(), ), title="High Scores", key_bindings=menu_keybindings, ) difficulty_label_container = Box( Label( text=lambda: "Difficulty: {0}".format(self._selected_difficulty ), width=Dimension(min=40), ), padding=0, padding_left=1, ) high_scores_text_area = TextArea( text=score_table, read_only=True, scrollbar=True, wrap_lines=False, ) high_scores_text_area.window.cursorline = to_filter(True) high_scores_container = Box( high_scores_text_area, padding=0, padding_left=1, ) return FloatContainer( VSplit([ buttons_container, Frame( HSplit([ difficulty_label_container, HorizontalLine(), high_scores_container, ]), title=self._selected_game.game_name, ), ]), floats=[], )
def test_create_invalid_layout(): with pytest.raises(InvalidLayoutError): Layout(HSplit([]))
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.riitag_info = user.RiitagInfo() # placeholder self.menu_settings_button = Button( 'Settings', handler=lambda: self._set_state('Settings')) self.menu_view_button = Button('View Tag', handler=self.view_riitag) self.menu_exit_button = Button('Exit', handler=self.quit_app) self.menu_logout_button = Button('Logout', handler=self._logout) self.settings_back_button = Button( 'Back...', width=12, handler=lambda: self._set_state('Menu')) self.settings_reset_button = Button('Reset...', width=12, handler=self._reset_preferences) self.settings_pres_timeout_button = PreferenceButton( value=self.app.preferences.presence_timeout, increments=10, limits=(10, 120)) self.settings_check_interval_button = PreferenceButton( value=self.app.preferences.check_interval, increments=10, limits=(30, 60)) self.right_panel_state = 'Menu' self.menu_layout = Frame(Box(HSplit([ self.menu_settings_button, Label(''), self.menu_view_button, self.menu_exit_button, self.menu_logout_button, ]), padding_left=3, padding_top=2), title='Menu') self.settings_layout = Frame(Box(HSplit([ Window(FormattedTextControl( HTML( 'This is where you can modify settings\nregarding the underlying presence\nwatcher.' )), wrap_lines=True, width=25), Label(''), VSplit([ Label('Presence Timeout (min.):'), self.settings_pres_timeout_button ], width=15), VSplit([ Label('Refresh Interval (sec.):'), self.settings_check_interval_button ], padding=3), Label(''), VSplit([self.settings_back_button, self.settings_reset_button], align=WindowAlign.CENTER) ]), padding_left=3, padding_top=2), title='Settings')
#pods window podListArea = TextArea(text="", multiline=True, wrap_lines=False, scrollbar=enableScrollbar, lexer=lexer.PodStatusLexer(), read_only=True ) #add listener to cursor position changed podListArea.buffer.on_cursor_position_changed=Event(podListArea.buffer,podListCursorChanged) podListArea.window.cursorline = to_filter(True) podListAreaFrame = Frame(podListArea,title="Pods",width=80) left_container = HSplit([upper_left_container, #HorizontalLine(), #Window(height=1, char='-'), podListAreaFrame]) #print(namespaceWindow.current_value) #output area to output debug etc stuff outputArea = TextArea(text="", multiline=True, wrap_lines=False, lexer=lexer.OutputAreaLexer(), scrollbar=enableScrollbar, read_only=True) outputAreaFrame= Frame(outputArea,title="Output") content_container = VSplit([ # One window that holds the BufferControl with the default buffer on # the left.
def create_layout(python_input, lexer=PythonLexer, extra_body=None, extra_toolbars=None, extra_buffer_processors=None, input_buffer_height=None): D = LayoutDimension extra_body = [extra_body] if extra_body else [] extra_toolbars = extra_toolbars or [] extra_buffer_processors = extra_buffer_processors or [] input_buffer_height = input_buffer_height or D(min=6) def create_python_input_window(): def menu_position(cli): """ When there is no autocompletion menu to be shown, and we have a signature, set the pop-up position at `bracket_start`. """ b = cli.buffers[DEFAULT_BUFFER] if b.complete_state is None and python_input.signatures: row, col = python_input.signatures[0].bracket_start index = b.document.translate_row_col_to_index(row - 1, col) return index return Window( BufferControl( buffer_name=DEFAULT_BUFFER, lexer=lexer, input_processors=[ ConditionalProcessor( processor=HighlightSearchProcessor( preview_search=True), filter=HasFocus(SEARCH_BUFFER), ), HighlightSelectionProcessor(), DisplayMultipleCursors(DEFAULT_BUFFER), # Show matching parentheses, but only while editing. ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() & Condition(lambda cli: python_input. highlight_matching_parenthesis)), ConditionalProcessor(processor=AppendAutoSuggestion(), filter=~IsDone()) ] + extra_buffer_processors, menu_position=menu_position, # Make sure that we always see the result of an reverse-i-search: preview_search=True, ), left_margins=[PythonPromptMargin(python_input)], # Scroll offsets. The 1 at the bottom is important to make sure the # cursor is never below the "Press [Meta+Enter]" message which is a float. scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4), # As long as we're editing, prefer a minimal height of 6. get_height=(lambda cli: (None if cli.is_done or python_input. show_exit_confirmation else input_buffer_height)), wrap_lines=Condition(lambda cli: python_input.wrap_lines), ) return HSplit([ VSplit([ HSplit([ FloatContainer( content=HSplit([create_python_input_window()] + extra_body), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu( scroll_offset=Integer.from_callable( lambda: python_input. completion_menu_scroll_offset), max_height=12, extra_filter=show_completions_menu( python_input))), Float( xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=show_multi_column_completions_menu( python_input))), Float(xcursor=True, ycursor=True, content=signature_toolbar(python_input)), Float(left=2, bottom=1, content=exit_confirmation(python_input)), Float(bottom=0, right=0, height=1, content=meta_enter_message(python_input), hide_when_covering_content=True), Float(bottom=1, left=1, right=0, content=python_sidebar_help(python_input)), ]), ArgToolbar(), SearchToolbar(), SystemToolbar(), ValidationToolbar(), CompletionsToolbar( extra_filter=show_completions_toolbar(python_input)), # Docstring region. ConditionalContainer(content=Window( height=D.exact(1), content=FillControl('\u2500', token=Token.Separator)), filter=HasSignature(python_input) & ShowDocstring(python_input) & ~IsDone()), ConditionalContainer( content=Window( BufferControl( buffer_name='docstring', lexer=SimpleLexer(default_token=Token.Docstring), #lexer=PythonLexer, ), height=D(max=12)), filter=HasSignature(python_input) & ShowDocstring(python_input) & ~IsDone(), ), ]), HSplit([ python_sidebar(python_input), python_sidebar_navigation(python_input), ]) ]), ] + extra_toolbars + [ VSplit([ status_bar(python_input), show_sidebar_button_info(python_input), ]) ])
def __init__(self, pager: "Pager") -> None: self.pager = pager self.dynamic_body = _DynamicBody(pager) # Build an interface. has_colon = HasColon(pager) self.examine_control: BufferControl = BufferControl( buffer=pager.examine_buffer, lexer=SimpleLexer(style="class:examine,examine-text"), input_processors=[ BeforeInput(lambda: [("class:examine", " Examine: ")]) ], ) self.search_toolbar = SearchToolbar(vi_mode=True, search_buffer=pager.search_buffer) self.container = FloatContainer( content=HSplit([ ConditionalContainer( content=Titlebar(pager), filter=Condition(lambda: pager.display_titlebar), ), self.dynamic_body, self.search_toolbar, SystemToolbar(), ConditionalContainer( content=VSplit([ Window( height=1, content=FormattedTextControl( self._get_statusbar_left_tokens), style="class:statusbar", ), Window( height=1, content=FormattedTextControl( self._get_statusbar_right_tokens), style="class:statusbar.cursorposition", align=WindowAlign.RIGHT, ), ]), filter=~HasSearch() & ~has_focus(SYSTEM_BUFFER) & ~has_colon & ~has_focus("EXAMINE"), ), ConditionalContainer( content=Window(FormattedTextControl(" :"), height=1, style="class:examine"), filter=has_colon, ), ConditionalContainer( content=Window(self.examine_control, height=1, style="class:examine"), filter=has_focus(pager.examine_buffer), ), ]), floats=[ Float(right=0, height=1, bottom=1, content=_Arg()), Float( bottom=1, left=0, right=0, height=1, content=ConditionalContainer( content=MessageToolbarBar(pager), filter=Condition(lambda: bool(pager.message)), ), ), Float( right=0, height=1, bottom=1, content=ConditionalContainer( content=FormattedTextToolbar( lambda: [("class:loading", " Loading... ")], ), filter=Condition(lambda: pager.current_source_info. waiting_for_input_stream), ), ), Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu()), ], )
def __init__(self, body, title='', style='', width=None, height=None, key_bindings=None, modal=False): assert is_container(body) assert is_formatted_text(title) assert isinstance(style, six.text_type) assert is_dimension(width) assert is_dimension(height) assert key_bindings is None or isinstance(key_bindings, KeyBindings) assert isinstance(modal, bool) self.title = title self.body = body fill = partial(Window, style='class:frame.border') style = 'class:frame ' + style top_row_with_title = VSplit( [ fill(width=1, height=1, char=Border.TOP_LEFT), fill(char=Border.HORIZONTAL), fill(width=1, height=1, char='|'), # Notice: we use `Template` here, because `self.title` can be an # `HTML` object for instance. Label(lambda: Template(' {} ').format(self.title), style='class:frame.label', dont_extend_width=True), fill(width=1, height=1, char='|'), fill(char=Border.HORIZONTAL), fill(width=1, height=1, char=Border.TOP_RIGHT), ], height=1) top_row_without_title = VSplit([ fill(width=1, height=1, char=Border.TOP_LEFT), fill(char=Border.HORIZONTAL), fill(width=1, height=1, char=Border.TOP_RIGHT), ], height=1) @Condition def has_title(): return bool(self.title) self.container = HSplit( [ ConditionalContainer(content=top_row_with_title, filter=has_title), ConditionalContainer(content=top_row_without_title, filter=~has_title), VSplit( [ fill(width=1, char=Border.VERTICAL), DynamicContainer(lambda: self.body), fill(width=1, char=Border.VERTICAL), # Padding is required to make sure that if the content is # too small, that the right frame border is still aligned. ], padding=0), VSplit([ fill(width=1, height=1, char=Border.BOTTOM_LEFT), fill(char=Border.HORIZONTAL), fill(width=1, height=1, char=Border.BOTTOM_RIGHT), ]), ], width=width, height=height, style=style, key_bindings=key_bindings, modal=modal)
from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.layout.containers import HSplit from prompt_toolkit.layout.containers import VSplit, Window from prompt_toolkit.layout.controls import BufferControl from prompt_toolkit.layout.controls import FormattedTextControl from prompt_toolkit.layout.layout import Layout # 1. The layout left_text = "\nVertical-split example. Press 'q' to quit.\n\n(left pane.)" right_text = "\n(right pane.)" body = VSplit([ Window(FormattedTextControl(left_text)), Window(width=1, char='|'), # Vertical line in the middle. HSplit([ Window(FormattedTextControl(right_text), height=1), Window(FormattedTextControl(right_text), height=1), ]) ]) # 2. Key bindings kb = KeyBindings() @kb.add('q') def _(event): " Quit application. " event.app.exit() # 3. The `Application` application = Application(layout=Layout(body),
def make_app(fs): global append_to_log class PTK_STDOUT(): # our stdout def __init__(self, out): self.out = out def write(self, s): append(s, self.out) return len(s) def flush(self): pass class PTK_LOGGER(logging.StreamHandler): def __init__(self, level=logging.NOTSET, out=None): super().__init__(level) self.out = out def handle(self, record): append(record.getMessage(), self.out) def get_screen_size(): import fcntl import termios # Buffer for the C call buf = array.array(u'h', [0, 0, 0, 0]) fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, buf) return (buf[0], buf[1]) def my_on_resize(old_rs_handler, fs): fill_top(fs) return old_rs_handler() # ---------------------------------------------------------------------- # prepare the layout rows, _ = get_screen_size() top = Label('', style='reverse') log = TextArea(height=int((rows - 4) / 2), scrollbar=True) out = TextArea(text='\n^c: clear input, ^l: redraw, ^q: quit\n', scrollbar=True) msg = Label('cwd is /', style='reverse') cli_args = [] # for cli_accept(), filled later def append(s, c=out): if not c: c.text += '\n---\n' if c == log: s = s.split('\n')[0][:get_screen_size()[1] - 2] + '\n' t = c.text + s c.buffer.document = Document(text=t, cursor_position=len(t) - 1) def cli_accept(buf): app, cli, fs = cli_args append('\n---\n> ' + cli.text + '\n') app.cmd.onecmd(cli.text) msg.text = 'cwd is ' + fs.getcwd() cli.buffer.history.append_string(cli.text) cli.text = '' def fill_top(fs): s1 = ' SSB Drive' # (v20180831)' s2 = '[uuid ' + fs.uuid() + '] ' w = get_screen_size()[1] top.text = s1 + ' ' * (w - len(s1) - len(s2)) + s2 cli = TextArea(multiline=False, accept_handler=cli_accept) bot = VSplit([Label('> ', dont_extend_width=True), cli]) top_container = HSplit([top, log, HorizontalLine(), out, msg, bot]) app = Application(Layout(top_container), key_bindings=kb, full_screen=True) cli_args += [app, cli, fs] # for cli_accept() app.cli = cli # for retrieving it in the keyboard handler app.layout.focus(cli) fill_top(fs) old_rs_resize = app._on_resize app._on_resize = lambda: my_on_resize(old_rs_resize, fs) app.stdout = PTK_STDOUT(out) # used for cmd logging.getLogger('packet_stream').addHandler(PTK_LOGGER(out=log)) return app
def question(message, **kwargs): # TODO add bottom-bar (Move up and down to reveal more choices) # TODO extract common parts for list, checkbox, rawlist, expand # TODO validate if not 'choices' in kwargs: raise PromptParameterException('choices') # this does not implement default, use checked... if 'default' in kwargs: raise ValueError('Checkbox does not implement \'default\' ' 'use \'checked\':True\' in choice!') choices = kwargs.pop('choices', None) validator = setup_simple_validator(kwargs) # TODO style defaults on detail level style = kwargs.pop('style', default_style) pointer_index = kwargs.pop('pointer_index', 0) additional_parameters = dict() additional_parameters.update( {"pointer_sign": kwargs.pop('pointer_sign', '\u276f')}) additional_parameters.update( {"selected_sign": kwargs.pop('selected_sign', '\u25cf')}) additional_parameters.update( {"unselected_sign": kwargs.pop('unselected_sign', '\u25cb')}) ic = InquirerControl(choices, pointer_index, **additional_parameters) qmark = kwargs.pop('qmark', '?') def get_prompt_tokens(cli): tokens = [] tokens.append((Token.QuestionMark, qmark)) tokens.append((Token.Question, ' %s ' % message)) if ic.answered: nbr_selected = len(ic.selected_options) if nbr_selected == 0: tokens.append((Token.Answer, ' done')) elif nbr_selected == 1: tokens.append((Token.Answer, ' [%s]' % ic.selected_options[0])) else: tokens.append( (Token.Answer, ' done (%d selections)' % nbr_selected)) else: tokens.append((Token.Instruction, ' (<up>, <down> to move, <space> to select, <a> ' 'to toggle, <i> to invert)')) return tokens # assemble layout layout = HSplit([ Window(height=D.exact(1), content=TokenListControl(get_prompt_tokens, align_center=False)), ConditionalContainer(Window(ic, width=D.exact(43), height=D(min=3), scroll_offsets=ScrollOffsets(top=1, bottom=1)), filter=~IsDone()) ]) # key bindings manager = KeyBindingManager.for_prompt() @manager.registry.add_binding(Keys.ControlQ, eager=True) @manager.registry.add_binding(Keys.ControlC, eager=True) def _(event): raise KeyboardInterrupt() # event.cli.set_return_value(None) @manager.registry.add_binding(' ', eager=True) def toggle(event): pointed_choice = ic.choices[ic.pointer_index][1] # value if pointed_choice in ic.selected_options: ic.selected_options.remove(pointed_choice) else: ic.selected_options.append(pointed_choice) @manager.registry.add_binding('i', eager=True) def invert(event): inverted_selection = [ c[1] for c in ic.choices if not isinstance(c, Separator) and c[1] not in ic.selected_options and not c[2] ] ic.selected_options = inverted_selection @manager.registry.add_binding('a', eager=True) def all(event): all_selected = True # all choices have been selected for c in ic.choices: if not isinstance(c, Separator) and c[ 1] not in ic.selected_options and not c[2]: # add missing ones ic.selected_options.append(c[1]) all_selected = False if all_selected: ic.selected_options = [] @manager.registry.add_binding(Keys.Down, eager=True) def move_cursor_down(event): def _next(): ic.pointer_index = ((ic.pointer_index + 1) % ic.line_count) _next() while isinstance(ic.choices[ic.pointer_index], Separator) or \ ic.choices[ic.pointer_index][2]: _next() @manager.registry.add_binding(Keys.Up, eager=True) def move_cursor_up(event): def _prev(): ic.pointer_index = ((ic.pointer_index - 1) % ic.line_count) _prev() while isinstance(ic.choices[ic.pointer_index], Separator) or \ ic.choices[ic.pointer_index][2]: _prev() @manager.registry.add_binding(Keys.Enter, eager=True) def set_answer(event): ic.answered = True # TODO use validator event.cli.set_return_value(ic.get_selected_values()) return Application(layout=layout, key_bindings_registry=manager.registry, mouse_support=True, style=style)
def log_dialog(max_count=10): branch = repo.head.reference.name commits = [ c for c in repo.iter_commits(branch, skip=0, max_count=max_count) ] help = Label( HTML( f'(Press {ansired("n][Down")} or {ansired("b][Up")} to turn pages. {ansired("Ctrl+C][Esc")} to quit)' )) header = VSplit([ Label(HTML('Num'), width=5), Window(width=1, char="|"), Label(HTML('Commit'), width=9), Window(width=1, char="|"), Label(HTML('Author'), width=20), Window(width=1, char="|"), Label('Date', width=21), Window(width=1, char="|"), Label('Stats', width=10), Window(width=1, char="|"), Label('Description') ]) body = HSplit(rows(commits)) root_container = HSplit([ help, Window(height=1, char="-"), header, Window(height=1, char="-"), body ]) kb = KeyBindings() @kb.add("c-c", eager=True) @kb.add("escape") def _(event): event.app.exit() @kb.add('n') @kb.add('down') def _(event): global page page += max_count commits = [ c for c in repo.iter_commits(branch, skip=page, max_count=max_count) ] if not commits: event.app.exit() body.children = rows(commits) event.app.layout.reset() @kb.add('b') @kb.add('up') def _(event): global page page = max(page - max_count, 0) commits = [ c for c in repo.iter_commits(branch, skip=page, max_count=max_count) ] body.children = rows(commits) event.app.layout.reset() application = Application( layout=Layout(root_container), key_bindings=kb, # Let's add mouse support! mouse_support=False, # It switches the terminal to an alternate screen. full_screen=False) return application.run()
def __init__( self, body: AnyContainer, title: AnyFormattedText = "", style: str = "", width: AnyDimension = None, height: AnyDimension = None, key_bindings: Optional[KeyBindings] = None, modal: bool = False, ) -> None: self.title = title self.body = body fill = partial(Window, style="class:frame.border") style = "class:frame " + style top_row_with_title = VSplit( [ fill(width=1, height=1, char=Border.TOP_LEFT), fill(char=Border.HORIZONTAL), fill(width=1, height=1, char="|"), # Notice: we use `Template` here, because `self.title` can be an # `HTML` object for instance. Label( lambda: Template(" {} ").format(self.title), style="class:frame.label", dont_extend_width=True, ), fill(width=1, height=1, char="|"), fill(char=Border.HORIZONTAL), fill(width=1, height=1, char=Border.TOP_RIGHT), ], height=1, ) top_row_without_title = VSplit( [ fill(width=1, height=1, char=Border.TOP_LEFT), fill(char=Border.HORIZONTAL), fill(width=1, height=1, char=Border.TOP_RIGHT), ], height=1, ) @Condition def has_title() -> bool: return bool(self.title) self.container = HSplit( [ ConditionalContainer(content=top_row_with_title, filter=has_title), ConditionalContainer(content=top_row_without_title, filter=~has_title), VSplit( [ fill(width=1, char=Border.VERTICAL), DynamicContainer(lambda: self.body), fill(width=1, char=Border.VERTICAL), # Padding is required to make sure that if the content is # too small, the right frame border is still aligned. ], padding=0, ), VSplit([ fill(width=1, height=1, char=Border.BOTTOM_LEFT), fill(char=Border.HORIZONTAL), fill(width=1, height=1, char=Border.BOTTOM_RIGHT), ]), ], width=width, height=height, style=style, key_bindings=key_bindings, modal=modal, )
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, Window(FormattedTextControl('Press "q" to quit.'), height=1, style='reverse'), ]) # 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 # `load_default_key_bindings` utility function to create a registry that
def __init__( self, body: AnyContainer, menu_items: List["MenuItem"], floats: Optional[List[Float]] = None, key_bindings: Optional[KeyBindingsBase] = None, ) -> None: self.body = body self.menu_items = menu_items self.selected_menu = [0] # Key bindings. kb = KeyBindings() @Condition def in_main_menu() -> bool: return len(self.selected_menu) == 1 @Condition def in_sub_menu() -> bool: return len(self.selected_menu) > 1 # Navigation through the main menu. @kb.add("left", filter=in_main_menu) def _left(event: E) -> None: self.selected_menu[0] = max(0, self.selected_menu[0] - 1) @kb.add("right", filter=in_main_menu) def _right(event: E) -> None: self.selected_menu[0] = min( len(self.menu_items) - 1, self.selected_menu[0] + 1) @kb.add("down", filter=in_main_menu) def _down(event: E) -> None: self.selected_menu.append(0) @kb.add("c-c", filter=in_main_menu) @kb.add("c-g", filter=in_main_menu) def _cancel(event: E) -> None: "Leave menu." event.app.layout.focus_last() # Sub menu navigation. @kb.add("left", filter=in_sub_menu) @kb.add("c-g", filter=in_sub_menu) @kb.add("c-c", filter=in_sub_menu) def _back(event: E) -> None: "Go back to parent menu." if len(self.selected_menu) > 1: self.selected_menu.pop() @kb.add("right", filter=in_sub_menu) def _submenu(event: E) -> None: "go into sub menu." if self._get_menu(len(self.selected_menu) - 1).children: self.selected_menu.append(0) # If This item does not have a sub menu. Go up in the parent menu. elif (len(self.selected_menu) == 2 and self.selected_menu[0] < len(self.menu_items) - 1): self.selected_menu = [ min(len(self.menu_items) - 1, self.selected_menu[0] + 1) ] if self.menu_items[self.selected_menu[0]].children: self.selected_menu.append(0) @kb.add("up", filter=in_sub_menu) def _up_in_submenu(event: E) -> None: "Select previous (enabled) menu item or return to main menu." # Look for previous enabled items in this sub menu. menu = self._get_menu(len(self.selected_menu) - 2) index = self.selected_menu[-1] previous_indexes = [ i for i, item in enumerate(menu.children) if i < index and not item.disabled ] if previous_indexes: self.selected_menu[-1] = previous_indexes[-1] elif len(self.selected_menu) == 2: # Return to main menu. self.selected_menu.pop() @kb.add("down", filter=in_sub_menu) def _down_in_submenu(event: E) -> None: "Select next (enabled) menu item." menu = self._get_menu(len(self.selected_menu) - 2) index = self.selected_menu[-1] next_indexes = [ i for i, item in enumerate(menu.children) if i > index and not item.disabled ] if next_indexes: self.selected_menu[-1] = next_indexes[0] @kb.add("enter") def _click(event: E) -> None: "Click the selected menu item." item = self._get_menu(len(self.selected_menu) - 1) if item.handler: event.app.layout.focus_last() item.handler() # Controls. self.control = FormattedTextControl(self._get_menu_fragments, key_bindings=kb, focusable=True, show_cursor=False) self.window = Window(height=1, content=self.control, style="class:menu-bar") submenu = self._submenu(0) submenu2 = self._submenu(1) submenu3 = self._submenu(2) @Condition def has_focus() -> bool: return get_app().layout.current_window == self.window self.container = FloatContainer( content=HSplit([ # The titlebar. self.window, # The 'body', like defined above. body, ]), floats=[ Float( xcursor=True, ycursor=True, content=ConditionalContainer(content=Shadow(body=submenu), filter=has_focus), ), Float( attach_to_window=submenu, xcursor=True, ycursor=True, allow_cover_cursor=True, content=ConditionalContainer( content=Shadow(body=submenu2), filter=has_focus & Condition(lambda: len(self.selected_menu) >= 1), ), ), Float( attach_to_window=submenu2, xcursor=True, ycursor=True, allow_cover_cursor=True, content=ConditionalContainer( content=Shadow(body=submenu3), filter=has_focus & Condition(lambda: len(self.selected_menu) >= 2), ), ), # -- ] + (floats or []), key_bindings=key_bindings, )
def main(): click.secho(" ______ __ __ ______ __ __ ", fg="red") click.secho("/\ ___\ /\ \_\ \ /\ ___\ /\ \ /\ \ ", fg="yellow") click.secho("\ \ \____ \ \____ \ \ \ \____ \ \ \____ \ \ \ ", fg="green") click.secho(" \ \_____\ \/\_____\ \ \_____\ \ \_____\ \ \_\ ", fg="blue") click.secho(" \/_____/ \/_____/ \/_____/ \/_____/ \/_/ ", fg="magenta") main_prompt = prompt('graphistry>> ', enable_system_prompt=True) # The layout. output_field = TextArea(style='class:output-field', text=help_text) input_field = TextArea(height=2, prompt='graphistry>> ', style='class:input-field') bottom_field = TextArea(height=1, style='class:bottom-toolbar', text=revisionist_commit_history()) main_output = VSplit([ output_field, Window(char='~'), Window(width=20, style='class:line'), ]) container = HSplit([ main_output, Window(height=1, char='~', style='class:line'), input_field, bottom_field ]) # The key bindings. kb = KeyBindings() @kb.add('c-c') @kb.add('c-q') def _(event): " Pressing Ctrl-Q or Ctrl-C will exit the user interface. " event.app.exit() @kb.add('enter', filter=has_focus(input_field)) def _(event): try: output = '\n\nIn: {}\nOut: {}'.format( input_field.text, eval(input_field.text)) # Don't do 'eval' in real code! except BaseException as e: output = '\n\n{}'.format(e) new_text = output_field.text + output output_field.buffer.document = Document(text=new_text, cursor_position=len(new_text)) input_field.text = '' # Style. style = Style([ ('output-field', 'bg:#000044 #ffffff'), ('input-field', 'bg:#000000 #ffffff'), ('line', '#004400'), ('bottom-toolbar', '#000000 #ffffff'), ('bottom-toolbar.text', '#ffffff'), ]) # Run application. application = Application( layout=Layout(container, focused_element=input_field), key_bindings=kb, style=style, mouse_support=True, full_screen=True, ) application.run()