def __enter__(self): # Create UI Application. title_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.title), height=1, style='class:progressbar,title'), filter=Condition(lambda: self.title is not None)) bottom_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.bottom_toolbar, style='class:bottom-toolbar.text'), style='class:bottom-toolbar', height=1), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None)) def width_for_formatter(formatter): return formatter.get_width(progress_bar=self) progress_controls = [ Window(content=_ProgressControl(self, f), width=width_for_formatter(f)) for f in self.formatters ] self.app = Application( min_redraw_interval=.05, layout=Layout( HSplit([ title_toolbar, VSplit(progress_controls, height=lambda: D(preferred=len(self.counters), max=len(self.counters))), Window(), bottom_toolbar, ])), style=self.style, key_bindings=self.key_bindings, output=self.output, input=self.input) # Run application in different thread. def run(): with _auto_refresh_context(self.app, .3): try: self.app.run() except Exception as e: traceback.print_exc() print(e) self._thread = threading.Thread(target=run) self._thread.start() # Attach WINCH signal handler in main thread. # (Interrupt that we receive during resize events.) self._has_sigwinch = hasattr(signal, 'SIGWINCH') and in_main_thread() if self._has_sigwinch: self._previous_winch_handler = self._loop.add_signal_handler( signal.SIGWINCH, self.app.invalidate) return self
def get_positions_column_view(self) -> Window: return Window( content=FormattedTextControl(self.__watchlist_subtitle_view_text), ignore_content_width=True, style=PyTickerStyles.GREY_BACKGROUND_BLACK_TEXT, align=WindowAlign.LEFT, )
def update_layout(self): if self.overview: self.layout = Layout( HSplit([ self.header, VSplit([ HSplit(self.server_windows), HSplit([ self.overview, Window(FormattedTextControl( text="[Ins ][Home][PgUp]\n[Del ][End ][PgDn]"), style="class:overview", height=2, align=WindowAlign.CENTER, dont_extend_height=True), ]), ]), self.footer, ]), ) else: self.layout = Layout( HSplit([ self.header, VSplit([ HSplit(self.server_windows), ]), self.footer, ]), )
def __init__(self, text, handler=None, width=12, finished_callback=None): assert isinstance(width, int) self.loop = asyncio.get_event_loop() if handler: if not asyncio.iscoroutinefunction(handler): raise Exception("handler is not a coroutine function.") self._call_back = finished_callback self.text = text self.handler = handler self.width = width self.control = FormattedTextControl( self._get_text_fragments, key_bindings=self._get_key_bindings(), focusable=True, ) def get_style(): if get_app().layout.has_focus(self): return "class:button.focused" else: return "class:button" self.window = Window( self.control, align=WindowAlign.LEFT, height=1, width=width, style=get_style, dont_extend_width=True, dont_extend_height=True, )
def show_message(self, title, message, callback=None): cancel_button = Button('Cancel', handler=lambda: response_received(False)) ok_button = Button('OK', handler=lambda: response_received(True)) def response_received(is_ok): if callback: callback(is_ok) self._float_message_layout = None self.layout.focus_next() self.invalidate() message_frame = Frame( HSplit([ Window(FormattedTextControl(HTML(message + '\n\n')), align=WindowAlign.CENTER), VSplit([ cancel_button, ok_button ], padding=3, align=WindowAlign.CENTER) ], padding=1), title=title, ) self._float_message_layout = message_frame self.layout.focus(cancel_button) self.invalidate()
def __enter__(self): # Create UI Application. title_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.title), height=1), filter=Condition(lambda: self.title is not None)) bottom_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.bottom_toolbar, style='class:bottom-toolbar.text'), style='class:bottom-toolbar', height=1), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None)) self.app = Application(min_redraw_interval=.05, layout=Layout( HSplit([ title_toolbar, Window( content=_ProgressControl(self), height=lambda: len(self.counters)), Window(), bottom_toolbar, ])), style=self.style) # Run application in different thread. def run(): try: self.app.run() except Exception as e: import traceback traceback.print_exc() print(e) self._thread = threading.Thread(target=run) self._thread.start() # Attach WINCH signal handler in main thread. # (Interrupt that we receive during resize events.) self._has_sigwinch = hasattr(signal, 'SIGWINCH') and in_main_thread() if self._has_sigwinch: self._previous_winch_handler = self._loop.add_signal_handler( signal.SIGWINCH, self.app.invalidate) return self
def get_positions_title_view(self) -> Window: return Window( FormattedTextControl(HTML(self.__positions_title_view_text)), height=1, ignore_content_width=True, style=PyTickerStyles.GREY_BACKGROUND_BLACK_TEXT, align=WindowAlign.CENTER, )
def __init__(self, values): assert isinstance(values, list) assert len(values) > 0 assert all(isinstance(i, list) and len(i) == 2 for i in values) self.values = values 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('pageup') def _(event): w = event.app.layout.current_window self._selected_index = max( 0, self._selected_index - len(w.render_info.displayed_lines)) @kb.add('pagedown') def _(event): w = event.app.layout.current_window self._selected_index = min( len(self.values) - 1, self._selected_index + len(w.render_info.displayed_lines)) @kb.add('enter') @kb.add(' ') def _(event): self.values[self._selected_index][1] = not self.values[ self._selected_index][1] @kb.add(Keys.Any) def _(event): # We first check values after the selected value, then all values. for value in self.values[self._selected_index + 1:] + self.values: if value[0].startswith(event.data): self._selected_index = self.values.index(value) return # Control and window. self.control = FormattedTextControl(self._get_text_fragments, key_bindings=kb, focusable=True) self.window = Window(content=self.control, style='class:checkbox-list', right_margins=[ ScrollbarMargin(display_arrows=True), ], dont_extend_height=True)
def _header_windows(self, formatted_headers): if len(formatted_headers): header_control = FormattedTextControl( self._sep.join(formatted_headers) ) header_windows = [Window(header_control, height=1)] else: header_windows = [Window(height=1, width=0)] return header_windows
def _create_ui(self): btn_start = Button("Start", handler=self.tomato.start) btn_pause = Button("Pause", handler=self.tomato.pause) btn_reset = Button("Reset", handler=self.tomato.reset) btn_reset_all = Button("Reset All", handler=self.tomato.reset_all) btn_exit = Button("Exit", handler=self._exit_clicked) # All the widgets for the UI. self.text_area = FormattedTextControl(focusable=False, show_cursor=False) text_window = Window( content=self.text_area, dont_extend_height=True, height=11, style="bg:#ffffff #000000", ) root_container = Box( HSplit([ Label(text="Press `Tab` to move the focus."), HSplit([ VSplit( [ btn_start, btn_pause, btn_reset, btn_reset_all, btn_exit, ], padding=1, style="bg:#cccccc", ), text_window, ]), ])) layout = Layout(container=root_container, focused_element=btn_start) self._set_key_bindings() # Styling. style = Style([ ("left-pane", "bg:#888800 #000000"), ("right-pane", "bg:#00aa00 #000000"), ("button", "#000000"), ("button-arrow", "#000000"), ("button focused", "bg:#ff0000"), ("red", "#ff0000"), ("green", "#00ff00"), ]) self.application = Application(layout=layout, key_bindings=self.kb, style=style, full_screen=True)
def __init__(self, address=None, user=None, password=None): host, _, port = (address or "localhost:7687").partition(":") self.address = "%s:%s" % (host or "localhost", port or 7687) self.user = user or "neo4j" self.auth = (self.user, password or "") self.style_list = StyleList() self.style_list.assign_style(self.address) primary_server = ServerControl(self, self.address, self.auth) primary_server.attach() self.server_windows = [ Window(content=primary_server, style="class:server") ] self.header = Window(content=FormattedTextControl( text="AGENT SMITH v{}".format(__version__)), always_hide_cursor=True, height=1, dont_extend_height=True, style="class:page-header") self.footer = Window( content=FormattedTextControl(text="[Ctrl+O] Overview " "[PgUp]/[PgDn] Server " "[Up]/[Down] Transaction " "[Ctrl+K] Kill " "[Ctrl+C] Exit"), always_hide_cursor=True, height=1, dont_extend_height=True, style="class:page-footer") self.focus_index = 0 super(AgentSmith, self).__init__( key_bindings=self.bindings, style=self.style, # mouse_support=True, full_screen=True, ) self.update_layout()
def __init__(self): self.selected_line = 0 self.container = Window( content=FormattedTextControl( text=self._get_formatted_text, focusable=True, key_bindings=self._get_key_bindings(), ), style="class:select-box", cursorline=True, right_margins=[ ScrollbarMargin(display_arrows=True), ], width=20, always_hide_cursor=True, )
def __init__(self, address=None, user=None, password=None): host, _, port = (address or "localhost:7687").partition(":") self.address = "%s:%s" % (host or "localhost", port or 7687) self.user = user or "neo4j" self.auth = (self.user, password or "") self.overview = OverviewControl(self.address, self.auth) self.overview_visible = False self.overview_window = Window(content=self.overview, dont_extend_width=True, style="bg:#202020") self.server_windows = [Window(content=ServerControl(self.address, self.auth, self.overview.add_highlight()))] self.help_bar = Window(content=FormattedTextControl(text="[Ctrl+C] Exit [F12] Overview"), height=1, dont_extend_height=True, style="bg:ansibrightblack fg:ansiwhite") super(Neotop, self).__init__( key_bindings=self.bindings, style=self.style, # mouse_support=True, full_screen=True, ) self.update_layout() self.overview.start()
def update_layout(self): if self.overview_visible: self.layout = Layout( VSplit([ HSplit(self.server_windows + [self.help_bar]), HSplit([ self.overview_window, Window(FormattedTextControl(text="[Ins ][Home][PgUp]\n[Del ][End ][PgDn]"), style="bg:#202020 fg:ansigray", height=2, align=WindowAlign.CENTER, dont_extend_height=True), ]), ]), ) else: self.layout = Layout( VSplit([ HSplit(self.server_windows + [self.help_bar]), ]), )
def __init__(self, text: six.text_type, handler=None) -> None: self.text = text self.handler = handler self.control = FormattedTextControl( self.text, key_bindings=self._get_key_bindings(), focusable=True) def get_style(): if get_app().layout.has_focus(self): return 'class:selectable-label.focused' else: return 'class:selectable-label' self.window = Window( self.control, style=get_style, dont_extend_width=False, dont_extend_height=True, always_hide_cursor=True, )
def __enter__(self) -> 'ProgressBar': # Create UI Application. title_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.title), height=1, style='class:progressbar,title'), filter=Condition(lambda: self.title is not None)) bottom_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.bottom_toolbar, style='class:bottom-toolbar.text'), style='class:bottom-toolbar', height=1), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None)) def width_for_formatter(formatter: Formatter) -> AnyDimension: # Needs to be passed as callable (partial) to the 'width' # parameter, because we want to call it on every resize. return formatter.get_width(progress_bar=self) progress_controls = [ Window(content=_ProgressControl(self, f), width=functools.partial(width_for_formatter, f)) for f in self.formatters ] self.app: Application[None] = Application( min_redraw_interval=.05, layout=Layout( HSplit([ title_toolbar, VSplit(progress_controls, height=lambda: D(preferred=len(self.counters), max=len(self.counters))), Window(), bottom_toolbar, ])), style=self.style, key_bindings=self.key_bindings, color_depth=self.color_depth, output=self.output, input=self.input) # Run application in different thread. def run() -> None: set_event_loop(self._app_loop) with _auto_refresh_context(self.app, .3): try: self.app.run() except BaseException as e: traceback.print_exc() print(e) self._thread = threading.Thread(target=run) self._thread.start() # Attach WINCH signal handler in main thread. # (Interrupt that we receive during resize events.) self._has_sigwinch = hasattr(signal, 'SIGWINCH') and in_main_thread() if self._has_sigwinch: self._previous_winch_handler = signal.getsignal(signal.SIGWINCH) self._loop.add_signal_handler(signal.SIGWINCH, self.invalidate) return self
def built_in_functions(): docs = [ pydoc.render_doc(builtin, renderer=pydoc.plaintext).split("\n", 1)[1] for builtin_name, builtin in vars(builtins).items() if type(builtin) in (types.FunctionType, types.BuiltinFunctionType) and not builtin_name.startswith("_") ] new("\n".join(docs)) QLabel = partial(Label, dont_extend_width=True) SPACE = QLabel(" ") preview = FormattedTextControl() preview_frame = PreviewFrame( preview, title="Preview", style="fg:#AAAAAA bold", ) root_container = MenuContainer( body=HSplit([ VSplit([ HSplit([ open_file_frame, search_toolbar, ]), Window(preview), ], ), VSplit(
def __enter__(self) -> "ProgressBar": # Create UI Application. title_toolbar = ConditionalContainer( Window( FormattedTextControl(lambda: self.title), height=1, style="class:progressbar,title", ), filter=Condition(lambda: self.title is not None), ) bottom_toolbar = ConditionalContainer( Window( FormattedTextControl(lambda: self.bottom_toolbar, style="class:bottom-toolbar.text"), style="class:bottom-toolbar", height=1, ), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None), ) def width_for_formatter(formatter: Formatter) -> AnyDimension: # Needs to be passed as callable (partial) to the 'width' # parameter, because we want to call it on every resize. return formatter.get_width(progress_bar=self) progress_controls = [ Window( content=_ProgressControl(self, f), width=functools.partial(width_for_formatter, f), ) for f in self.formatters ] self.app: Application[None] = Application( min_redraw_interval=0.05, layout=Layout( HSplit([ title_toolbar, VSplit( progress_controls, height=lambda: D(preferred=len(self.counters), max=len(self.counters)), ), Window(), bottom_toolbar, ])), style=self.style, key_bindings=self.key_bindings, refresh_interval=0.3, color_depth=self.color_depth, output=self.output, input=self.input, ) # Run application in different thread. def run() -> None: set_event_loop(self._app_loop) try: self.app.run(pre_run=self._app_started.set) except BaseException as e: traceback.print_exc() print(e) ctx: contextvars.Context = contextvars.copy_context() self._thread = threading.Thread(target=ctx.run, args=(run, )) self._thread.start() return self
# buffer1 = Buffer() input_field = TextArea(height=1, prompt=f'> ', style='class:input-field', multiline=False, wrap_lines=False, accept_handler=accept) output_field = TextArea( style='class:output-field', dont_extend_height=True, ) toolbar = SystemToolbar() testx = FormattedTextControl('Press "q" to quit.') root_container = HSplit([ # 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( testx, allow_scroll_beyond_bottom=True, ), Window(height=1, char='-', style='class:line'), toolbar,
def __init__( self, title=None, elements=None, width=None, height=None, align=WindowAlign.LEFT, get_bullet=None, allow_select=True, scrollbar=True, ): self.index = 0 self.get_bullet = get_bullet self.selected = -1 self.elements = elements or [] self.title = title self.allow_select = allow_select self.cursor = Point(0, 0) self.scrollbar = scrollbar self.control = FormattedTextControl( text=self._get_text, focusable=True, get_cursor_position=lambda: self.cursor, key_bindings=self.get_key_bindings(), ) # TODO: figure out how to the make it look nicer right_margins = [ ConditionalMargin( ScrollbarMargin(display_arrows=True), filter=Condition(lambda: self.scrollbar), ), ] self.title_window = FormattedTextArea( text=self.title, height=Dimension(min=1), width=Dimension(min=1), ) self.list_window = Window( content=self.control, width=width, height=height, always_hide_cursor=False, style="class:list", wrap_lines=True, dont_extend_height=True, dont_extend_width=False, cursorline=False, right_margins=right_margins, allow_scroll_beyond_bottom=True, get_line_prefix=self._get_line_prefix, ) self.window = HSplit( children=[ Box( self.title_window, padding=Dimension.exact(1), ), Box( self.list_window, padding=Dimension.exact(1), padding_top=Dimension.exact(0), ), ], height=Dimension(min=1), width=Dimension(min=1), )
status = {"general": "Press CTRL-Q to quit"} def set_status(key, value): """Add a status to the status bar.""" status[key] = value status_bar.text = HTML(get_status()) def get_status(): return " | ".join((val for val in status.values())) status_bar = FormattedTextControl(HTML(get_status()), show_cursor=False, style="class:status") def get_layout(entry_point, top_menu_items): set_current_sidebar(entry_point) menu = DynamicContainer(get_current_sidebar) # windows that are focused by pressing tab keys. main_focus = [menu, _output_window] following = get_following(main_focus) def next_main_window(event): next_idx = following(1)
def __init__(self, username: str, password: str): super().__init__(username, password, handle_data=DataFormat.ANSI) self.commands = [] self.output_buffer = Buffer_() self.cursor_pos = 0 self.chat_buffer = Buffer_() self.output = BufferControl(self.output_buffer, input_processors=[FormatText()], include_default_input_processors=True) self.chat = BufferControl(self.chat_buffer, input_processors=[FormatText()], include_default_input_processors=True) self.hide_ip = "--hide-ip" in sys.argv self.suggest = AutoSuggestFromLogs([ CommandSuggest(), ]) self.input = TextArea(height=1, prompt=" >> ", multiline=False, wrap_lines=False, accept_handler=self.accept, auto_suggest=self.suggest, dont_extend_width=True) self.host_ip = FormattedTextControl(ANSI("")) self.chat_float = Float(Frame(Window(self.chat, wrap_lines=True)), right=1, top=0, width=40, height=12, hide_when_covering_content=True) self.text = "" self.chat_text = "" def set_frame_size(fn): def inner(*args): size = self.app.output.get_size() self.chat_float.width = size.columns // 3 self.chat_float.height = size.rows // 2 return fn(*args) return inner self.out_window = Window(self.output, wrap_lines=True) kb = KeyBindings() @kb.add('c-c') @kb.add('c-q') def _(_): self.app.exit() self._loop = False self.run_again = False @kb.add('c-i', filter=has_focus(self.input)) def __(_): fut = self.suggest.get_suggestion_future(self.input.buffer, self.input.document) text = self.input.text def set_input(fut_2): res = fut_2.result() if res is not None: self.input.text = text + res.text self.input.document = Document(self.input.text, cursor_position=len( self.input.text)) fut.add_done_callback(set_input) @kb.add(Keys.ScrollUp) def sup(_): self.output_buffer.cursor_up(1) self.out_window._scroll_up() # pylint: disable=protected-access @kb.add(Keys.ScrollDown) def sdown(_): self.output_buffer.cursor_down(1) self.out_window._scroll_down() # pylint: disable=protected-access self.app = Application( layout=Layout( container=HSplit([ Frame( FloatContainer(self.out_window, floats=[self.chat_float])), Frame( VSplit([ self.input, Window(self.host_ip, align=WindowAlign.RIGHT, dont_extend_width=True) ])) ]), focused_element=self.input, ), full_screen=True, mouse_support=True, enable_page_navigation_bindings=True, key_bindings=merge_key_bindings([kb]), paste_mode=True, ) self.app._on_resize = set_frame_size(self.app._on_resize) # pylint: disable=protected-access self.run_again = True self.loop = get_event_loop() self._loop = False self.own_pass = "" self.own_ip = "" self.current_ip = ""
def _get_main_title_layout(self): return Frame(Window(FormattedTextControl(HTML("<u>PyTicker</u>")), height=1, align=WindowAlign.CENTER), style=PyTickerStyles.DARK_GREY_BACKGROUND_BLACK_TEXT)
tomato = Tomato() def exit_clicked(_=None): get_app().exit() # All the widgets for the UI. btn_start = Button("Start", handler=tomato.start) btn_pause = Button("Pause", handler=tomato.pause) btn_reset = Button("Reset", handler=tomato.reset) btn_reset_all = Button("Reset All", handler=tomato.reset_all) btn_exit = Button("Exit", handler=exit_clicked) text_area = FormattedTextControl(focusable=False, show_cursor=False) text_window = Window( content=text_area, dont_extend_height=True, height=11, style="bg:#ffffff #000000" ) root_container = Box( HSplit( [ Label(text="Press `Tab` to move the focus."), HSplit( [ VSplit( [btn_start, btn_pause, btn_reset, btn_reset_all, btn_exit], padding=1, style="bg:#cccccc", ),
def __init__(self): # styling style = Style.from_dict({ 'completion-menu.completion': 'bg:#008888 #ffffff', 'completion-menu.completion.current': 'bg:#00aaaa #000000', 'scrollbar.background': 'bg:#88aaaa', 'scrollbar.button': 'bg:#222222', 'input-field': '#004400', 'buffer': '#ff0066', }) # create input fields self.source_field = make_text_area('[Source folder]: ') self.target_field = make_text_area('[Target folder]: ') self.dry_field = make_text_area('[{:13}]: '.format("Dry? (y/n)")) # get completers initialize_database() con = db_connect() self.source_field.completer = FuzzyCompleter( WordCompleter(get_source_paths(con), ignore_case=True)) self.target_field.completer = FuzzyCompleter( WordCompleter(get_target_paths(con), ignore_case=True)) self.dry_field.completer = WordCompleter( ['Yes', 'No', 'True', 'False', 'yes', 'no'], ignore_case=True) # bottom toolbar def bottom_toolbar_call(): s1 = '<b><style bg="ansired">C-H</style></b>: history mode.' s2 = '<b><style bg="ansired">C-C/C-Q</style></b>: exit app.' s3 = '<b><style bg="ansired">C-O</style></b>: ordered paths.' s4 = '<b><style bg="ansired">C-R</style></b>: reverse paths.' return HTML(" ".join([s1, s2, s3, s4])) self.bottom_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: bottom_toolbar_call, 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: bottom_toolbar_call is not None))) # create app body self.body = FloatContainer(content=HSplit(children=[ self.source_field, self.target_field, self.dry_field, self.bottom_toolbar ], height=8), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=12, scroll_offset=1)) ]) # define internal logic def execute_command(buff): """Send command to subprocess dealing with dry argument recursively""" dry = False if buff.text.lower() in ['n', 'no', 'false'] else True dry_flag = 'DRY' if dry else 'NOT DRY' dry_string = 'n' if dry else '' command = "rsync -avucP{} {} {}".format(dry_string, self.source_field.text, self.target_field.text) def run_script(): subprocess.call(command, shell=True) def print_info(): print_formatted_text( HTML('<ansired>{} </ansired>'.format(dry_flag))) print_formatted_text( HTML('<ansired>{} </ansired>'.format( 'You entered: {}'.format(command)))) print_formatted_text( HTML('<ansired>{} </ansired>'.format('Running...'))) run_in_terminal(print_info) if dry: run_in_terminal(run_script) return else: con = db_connect() create_rsync_record(con, self.source_field.text, self.target_field.text) run_in_terminal(run_script) app = get_app() app.exit() return self.dry_field.buffer.accept_handler = execute_command # Key bindings self.kb = KeyBindings() @self.kb.add('c-q') @self.kb.add('c-c') def _(event): " Quit application. " event.app.exit() #kb.add('enter')(focus_next) self.kb.add('tab')(focus_next) self.kb.add('s-tab')(focus_previous) # The `Application` self.app = Application( layout=Layout(self.body), #style=style, key_bindings=self.kb, full_screen=False, mouse_support=True)
def _create_app(self): # Create UI Application. title_toolbar = ConditionalContainer( Window( FormattedTextControl(lambda: self.title), height=1, style="class:progressbar,title", ), filter=Condition(lambda: self.title is not None), ) bottom_toolbar = ConditionalContainer( Window( FormattedTextControl( lambda: self.bottom_toolbar, style="class:bottom-toolbar.text" ), style="class:bottom-toolbar", height=1, ), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None), ) def width_for_formatter(formatter: Formatter) -> AnyDimension: # Needs to be passed as callable (partial) to the 'width' # parameter, because we want to call it on every resize. return formatter.get_width(progress_bar=self) progress_controls = [ Window( content=_ProgressControl(self, f), width=functools.partial(width_for_formatter, f), ) for f in self.formatters ] body = self.create_content(progress_controls) self.root = FloatContainer( content=HSplit( [ title_toolbar, body, bottom_toolbar, ] ), floats=[] ) if self.key_bindings is None: self.create_key_bindings() self.app: Application[None] = Application( min_redraw_interval=0.05, layout=Layout(self.root), style=self.style, key_bindings=self.key_bindings, refresh_interval=0.3, color_depth=self.color_depth, output=self.output, input=self.input, full_screen=True, ) return self.app
from prompt_toolkit import HTML from prompt_toolkit.layout import FormattedTextControl, Window, WindowAlign from pyticker.core.util import ProjectConstants from pyticker.view.pyticker_styles import PyTickerStyles WATCHLIST_STOCKS_TEXT = FormattedTextControl(style="bold") class WatchListView(object): def __init__(self): self.__width = ProjectConstants.WIDTH self.__watchlist_title_view_text = '<u>Watchlist</u>' self.__watchlist_subtitle_view_text = f'{"Symbol".ljust(self.__width)}{"Pr Close".ljust(self.__width)}{"Open".ljust(self.__width)}' \ f'{"D Low".ljust(self.__width)}{"D High".ljust(self.__width)}{"Mkt Price".ljust(self.__width)}' \ f'{"Change".ljust(self.__width)}' def get_watchlist_title_view(self) -> Window: return Window( FormattedTextControl(HTML(self.__watchlist_title_view_text)), height=1, ignore_content_width=True, style=PyTickerStyles.GREY_BACKGROUND_BLACK_TEXT, align=WindowAlign.CENTER, ) def get_watchlist_column_view(self) -> Window: return Window( content=FormattedTextControl(self.__watchlist_subtitle_view_text), ignore_content_width=True, style=PyTickerStyles.GREY_BACKGROUND_BLACK_TEXT,
async def _init(self, values: Sequence[Tuple[_T, AnyFormattedText]]) -> None: started_values = await aislice(values, PAGE_SIZE) # started_values = await aislice(values, PAGE_SIZE) if not started_values: raise IndexError('Values is empty.') self.values = started_values # current_values will be used in multiple_selection, # current_value will be used otherwise. self.current_values: List[_T] = [] self.current_value: _T = started_values[0][0] self._selected_index = 0 # Key bindings. kb = KeyBindings() @kb.add("up") def _up(event: E) -> None: self._selected_index = max(0, self._selected_index - 1) @kb.add("down") def _down(event: E) -> None: async def handler(event): if self._selected_index + 1 >= len(self.values): self.values.extend(await aislice(values, PAGE_SIZE)) self._selected_index = min( len(self.values) - 1, self._selected_index + 1) asyncio.get_event_loop().create_task(async_handler(handler, event)) @kb.add("pageup") def _pageup(event: E) -> None: w = event.app.layout.current_window if w.render_info: self._selected_index = max( 0, self._selected_index - len(w.render_info.displayed_lines)) @kb.add("pagedown") def _pagedown(event: E) -> None: async def handler(event): w = event.app.layout.current_window if self._selected_index + len( w.render_info.displayed_lines) >= len(self.values): self.values.extend(await aislice(values, PAGE_SIZE)) if w.render_info: self._selected_index = min( len(self.values) - 1, self._selected_index + len(w.render_info.displayed_lines), ) asyncio.get_event_loop().create_task(async_handler(handler, event)) @kb.add("enter") def _enter(event: E) -> None: if self.many: event.app.exit(result=self.current_values) else: event.app.exit(result=self.current_value) @kb.add(" ") def _enter(event: E) -> None: self._handle_enter() # Control and window. self.control = FormattedTextControl(self._get_text_fragments, key_bindings=kb, focusable=True) self.window = Window( content=self.control, style=self.container_style, right_margins=[ ConditionalMargin( margin=ScrollbarMargin(display_arrows=True), filter=Condition(lambda: self.show_scrollbar), ), ], dont_extend_height=True, )
from prompt_toolkit import HTML from prompt_toolkit.layout import Window, FormattedTextControl, WindowAlign from pyticker.core.util import ProjectConstants from pyticker.view.pyticker_styles import PyTickerStyles POSITION_STOCKS_TEXT = FormattedTextControl(style="bold") class PositionsView(object): def __init__(self): self.__width = ProjectConstants.WIDTH self.__positions_title_view_text = '<u>Positions</u>' self.__watchlist_subtitle_view_text = f'{"Symbol".ljust(self.__width)}{"Qty".ljust(6)}{"Inv Price".ljust(self.__width)}' \ f'{"Total Inv".ljust(self.__width)}{"Mkt Price".ljust(self.__width)}{"Curr Val".ljust(self.__width)}' \ f'{"Profit/Loss".ljust(self.__width)}' def get_positions_title_view(self) -> Window: return Window( FormattedTextControl(HTML(self.__positions_title_view_text)), height=1, ignore_content_width=True, style=PyTickerStyles.GREY_BACKGROUND_BLACK_TEXT, align=WindowAlign.CENTER, ) def get_positions_column_view(self) -> Window: return Window( content=FormattedTextControl(self.__watchlist_subtitle_view_text), ignore_content_width=True, style=PyTickerStyles.GREY_BACKGROUND_BLACK_TEXT,