示例#1
0
    def __init__(self, inpipe):
        self.inpipe = inpipe
        self.tempfile = tempfile.NamedTemporaryFile(mode="w", delete=True)
        self.initialize_nodes()

        root = VSplit(
            [
                # Input buffer and status line
                HSplit(
                    [
                        self.first_line,
                        Window(
                            content=BufferControl(
                                buffer=self.input_buffer,
                                # This lexer is disabled for now because
                                # I don't want to mess with colourschemes
                                # lexer=PygmentsLexer(PythonLexer),
                            )
                        ),
                        self.error_output,
                    ],
                    width=Dimension(),
                ),
                Window(width=1, char="|"),
                # Output display area
                Window(ignore_content_width=True, content=self.output, wrap_lines=True),
            ],
            width=Dimension(),
        )

        layout = Layout(root)

        self.app = Application(layout=layout, key_bindings=kb, full_screen=True)
示例#2
0
def setup_logging_containers(repl):
    j = KosmosShellConfig.j

    panel_line_count = j.core.myenv.config.get("LOGGER_PANEL_NRLINES", 12)
    parent_container = get_ptpython_parent_container(repl)
    parent_container.children.extend(
        [
            ConditionalContainer(
                content=Window(height=Dimension.exact(1), char="\u2500", style="class:separator"),
                filter=HasLogs(repl) & ~is_done,
            ),
            ConditionalContainer(
                content=Window(
                    BufferControl(
                        buffer=LogPane.Buffer,
                        input_processors=[FormatANSIText(), HighlightIncrementalSearchProcessor()],
                        focusable=False,
                        preview_search=True,
                    ),
                    wrap_lines=True,
                    height=Dimension.exact(panel_line_count),
                ),
                filter=HasLogs(repl) & ~is_done,
            ),
        ]
    )
示例#3
0
def show_sidebar_button_info(python_input):
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """
    @if_mousedown
    def toggle_sidebar(mouse_event):
        " Click handler for the menu. "
        python_input.show_sidebar = not python_input.show_sidebar

    version = sys.version_info
    tokens = [
        ('class:status-toolbar.key', '[F2]', toggle_sidebar),
        ('class:status-toolbar', ' Menu', toggle_sidebar),
        ('class:status-toolbar', ' - '),
        ('class:status-toolbar.python-version', '%s %i.%i.%i' % (platform.python_implementation(),
                                               version[0], version[1], version[2])),
        ('class:status-toolbar', ' '),
    ]
    width = fragment_list_width(tokens)

    def get_text_fragments():
        # Python version
        return tokens

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            style='class:status-toolbar',
            height=Dimension.exact(1),
            width=Dimension.exact(width)),
        filter=~is_done & renderer_height_is_known &
            Condition(lambda: python_input.show_status_bar and
                                  not python_input.show_exit_confirmation))
示例#4
0
def python_sidebar_navigation(python_input):
    """
    Create the `Layout` showing the navigation information for the sidebar.
    """
    def get_text_fragments():
        tokens = []

        # Show navigation info.
        tokens.extend([
            ('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 tokens

    return Window(
        FormattedTextControl(get_text_fragments),
        style='class:sidebar',
        width=Dimension.exact(43),
        height=Dimension.exact(1))
    def preferred_dimensions(self, width):
        dimensions = [[]] * self.columns
        for row in self.children:
            assert isinstance(row, _Row)
            j = 0
            for cell in row.children:
                assert isinstance(cell, _Cell)

                if cell.merge != 1:
                    dimensions[j].append(cell.preferred_width(width))

                j += cell.merge

        for i, c in enumerate(dimensions):
            yield D.exact(1)

            try:
                w = self.column_widths[i]
            except IndexError:
                w = self.column_width
            if w is None:  # fitted
                yield max_layout_dimensions(c)
            else:  # fixed or weighted
                yield to_dimension(w)
        yield D.exact(1)
示例#6
0
def show_sidebar_button_info(python_input):
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """
    @if_mousedown
    def toggle_sidebar(mouse_event):
        " Click handler for the menu. "
        python_input.show_sidebar = not python_input.show_sidebar

    version = sys.version_info
    tokens = [
        ('class:status-toolbar.key', '[F2]', toggle_sidebar),
        ('class:status-toolbar', ' Menu', toggle_sidebar),
        ('class:status-toolbar', ' - '),
        ('class:status-toolbar.python-version',
         '%s %i.%i.%i' % (platform.python_implementation(), version[0],
                          version[1], version[2])),
        ('class:status-toolbar', ' '),
    ]
    width = fragment_list_width(tokens)

    def get_text_fragments():
        # Python version
        return tokens

    return ConditionalContainer(
        content=Window(FormattedTextControl(get_text_fragments),
                       style='class:status-toolbar',
                       height=Dimension.exact(1),
                       width=Dimension.exact(width)),
        filter=~is_done & renderer_height_is_known
        & Condition(lambda: python_input.show_status_bar and not python_input.
                    show_exit_confirmation))
示例#7
0
def sql_sidebar_navigation():
    """
    Create the `Layout` showing the navigation information for the sidebar.
    """

    def get_text_fragments():
        # Show navigation info.
        return [
            ("class:sidebar.navigation", "   "),
            ("class:sidebar.navigation.key", "[Up/Dn]"),
            ("class:sidebar.navigation", " "),
            ("class:sidebar.navigation.description", "Navigate"),
            ("class:sidebar.navigation", " "),
            ("class:sidebar.navigation.key", "[L/R]"),
            ("class:sidebar.navigation", " "),
            ("class:sidebar.navigation.description", "Expand/Collapse"),
            ("class:sidebar.navigation", "\n   "),
            ("class:sidebar.navigation.key", "[Enter]"),
            ("class:sidebar.navigation", " "),
            ("class:sidebar.navigation.description", "Connect/Preview"),
        ]

    return Window(
        FormattedTextControl(get_text_fragments),
        style = "class:sidebar.navigation",
        width=Dimension.exact( 45 ),
        height=Dimension(max = 2),
    )
示例#8
0
def python_sidebar_navigation(python_input):
    """
    Create the `Layout` showing the navigation information for the sidebar.
    """
    def get_text_fragments():
        tokens = []

        # Show navigation info.
        tokens.extend([
            ('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 tokens

    return Window(FormattedTextControl(get_text_fragments),
                  style='class:sidebar',
                  width=Dimension.exact(43),
                  height=Dimension.exact(1))
示例#9
0
    def get_root_container(self) -> FloatContainer:
        buttons = [
            *self._game_buttons.keys(),
            HorizontalLine(),
            Button("Quit", width=MENU_BUTTON_WIDTH, handler=self._exit),
        ]

        menu_keybindings = _create_menu_keybindings(buttons)

        game_buttons_container = Frame(
            HSplit(
                buttons,
                width=Dimension(min=MENU_BUTTON_WIDTH, max=40),
                height=Dimension(),
            ),
            title="Games",
            key_bindings=menu_keybindings,
        )

        game_description_container = Frame(
            Box(
                Label(
                    text=self._get_game_description,
                    dont_extend_height=False,
                    width=Dimension(min=40),
                ),
                padding=0,
                padding_left=1,
            ), )

        return FloatContainer(VSplit([
            game_buttons_container,
            game_description_container,
        ]),
                              floats=[])
示例#10
0
    def __init__(self, title="", label_text="", completer=None):
        self.future = Future()

        def accept_text(buf):
            app.layout.focus(ok_button)
            buf.complete_state = None
            return True

        def accept():
            self.future.set_result(self.text_area.text)

        def cancel():
            self.future.set_result(None)

        self.text_area = TextArea(
            completer=completer,
            multiline=False,
            width=Dimension(preferred=40),
            accept_handler=accept_text,
        )

        ok_button = Button(text="OK", handler=accept)
        cancel_button = Button(text="Cancel", handler=cancel)

        self.dialog = Dialog(
            title=title,
            body=HSplit([Label(text=label_text), self.text_area]),
            buttons=[ok_button, cancel_button],
            width=Dimension(preferred=80),
            modal=True,
        )
示例#11
0
def show_sidebar_button_info(my_app: "sqlApp") -> Container:
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """
    @if_mousedown
    def toggle_sidebar(mouse_event: MouseEvent) -> None:
        " Click handler for the menu. "
        my_app.show_sidebar = not my_app.show_sidebar

    # TO DO: app version rather than python
    version = sys.version_info
    tokens: StyleAndTextTuples = [
        ("class:status-toolbar.key", "[C-t]", toggle_sidebar),
        ("class:status-toolbar", " Object Browser", toggle_sidebar),
        ("class:status-toolbar", " - "),
        ("class:status-toolbar.cli-version", "odbcli %s" % __version__),
        ("class:status-toolbar", " "),
    ]
    width = fragment_list_width(tokens)

    def get_text_fragments() -> StyleAndTextTuples:
        # Python version
        return tokens

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            style="class:status-toolbar",
            height=Dimension.exact(1),
            width=Dimension.exact(width),
        ),
        filter=~is_done
        & Condition(lambda: not my_app.show_exit_confirmation)
        & renderer_height_is_known)
示例#12
0
        def get_default_buffer_control_height():
            # If there is an autocompletion menu to be shown, make sure that our
            # layout has at least a minimal height in order to display it.
            space = self.reserve_space_for_menu

            if space and not get_app().is_done:
                buff = default_buffer
                if buff.complete_while_typing() or buff.complete_state is not None:
                    return Dimension(min=space)
            return Dimension()
示例#13
0
    def _get_buffer_control_height(buf):
        # If there is an autocompletion menu to be shown, make sure that our
        # layout has at least a minimal height in order to display it.
        if reserve_space_for_menu and not get_app().is_done:
            buff = buffer
            # Reserve the space, either when there are completions, or when
            # `complete_while_typing` is true and we expect completions very
            # soon.
            if buff.complete_while_typing() or buff.complete_state is not None:
                return Dimension(min=reserve_space_for_menu)

        return Dimension()
示例#14
0
    def _create_layout(self):
        has_before_fragments, get_prompt_text_1, get_prompt_text_2 = \
            _split_multiline_prompt(self._get_prompt)

        default_buffer = self.default_buffer

        default_buffer_control = BufferControl(
            buffer=default_buffer,
            search_buffer_control=None,
            input_processors=[],
            include_default_input_processors=False)

        prompt_window = Window(FormattedTextControl(get_prompt_text_1),
                               dont_extend_height=True)
        default_buffer_window = Window(
            default_buffer_control,
            dont_extend_height=True,
            get_line_prefix=partial(self._get_line_prefix,
                                    get_prompt_text_2=get_prompt_text_2))
        divider = Window(char='_', height=1, style='fg:gray bg:black')
        search_window = Window(content=SearchControl(), style='')
        bottom_toolbar = ConditionalContainer(
            Window(FormattedTextControl(lambda: self.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))

        layout = HSplit([
            prompt_window, default_buffer_window, divider, search_window,
            bottom_toolbar
        ])

        return Layout(layout, default_buffer_window)
    def __init__(self,
                 text: str,
                 handler: Optional[Callable[[], None]] = None,
                 width: int = None) -> None:
        self.text = text
        self.handler = handler
        self.width = width

        if width is None:
            self.width = max(12, len(text) + 2)

        self.control = FormattedTextControl(
            self._get_text_fragments,
            key_bindings=self._get_key_bindings(),
            focusable=True,
        )

        def get_style() -> str:
            if get_app().layout.has_focus(self):
                return "class:button.focused"
            else:
                return "class:button"

        self.window = Window(
            self.control,
            align=WindowAlign.CENTER,
            height=1,
            width=Dimension(preferred=self.width, max=self.width),
            style=get_style,
            dont_extend_width=True,
            dont_extend_height=True,
            always_hide_cursor=True  # Stops curser from showing when selected
        )
示例#16
0
def InputDialog(on_ok,
                on_cancel,
                title="",
                prompt="",
                ok_text="OK",
                cancel_text="Cancel",
                is_text_valid=lambda text: True) -> Dialog:
    """Returns a Dialogue component displaying a text input box"""
    def on_accept(buf):
        if is_text_valid(textfield.text):
            get_app().layout.focus(ok_button)
        return True  # Keep text.

    def on_ok_clicked():
        if is_text_valid(textfield.text):
            on_ok(textfield.text)

    ok_button = Button(text=ok_text, handler=on_ok_clicked)
    exit_button = Button(text=cancel_text, handler=on_cancel)

    textfield = TextArea(multiline=False, accept_handler=on_accept)

    dialog = Dialog(
        title=title,
        body=HSplit(
            [Label(text=prompt, dont_extend_height=True), textfield],
            padding=Dimension(preferred=1, max=1),
        ),
        buttons=[ok_button, exit_button],
        with_background=True)

    return dialog
示例#17
0
def MenuScreen(controller):
    def on_start_click():
        new_state = PlayingScreenState(username=controller.state.username,
                                       choice_history=[root_branch],
                                       choice_index=0,
                                       start_time=time())
        controller.set_state(new_state)

    def on_help_click():
        new_state = HelpScreenState(username=controller.state.username,
                                    previous_state=controller.state)
        controller.set_state(new_state)

    buttons = [
        Button('start', handler=on_start_click),
        Button('help', handler=on_help_click),
        Button('quit', handler=exit_current_app)
    ]

    kb = create_vertical_button_list_kbs(buttons)

    body = Box(
        VSplit([
            HSplit(children=buttons,
                   padding=Dimension(preferred=1, max=1),
                   key_bindings=kb)
        ]))

    toolbar_content = Window(content=FormattedTextControl(
        'Hello %s. I wish you the best of luck...' %
        controller.state.username),
                             align=WindowAlign.CENTER,
                             height=1)

    return ToolbarFrame(body, toolbar_content)
示例#18
0
 def __init__(self, text: AnyFormattedText, style: str = '', **kw) -> None:
     # Note: The style needs to be applied to the toolbar as a whole, not
     #       just the `FormattedTextControl`.
     super().__init__(FormattedTextControl(text, **kw),
                      style=style,
                      dont_extend_height=True,
                      height=Dimension(min=1))
示例#19
0
def python_sidebar_help(python_input):
    """
    Create the `Layout` for the help text for the current item in the sidebar.
    """
    token = 'class:sidebar.helptext'

    def get_current_description():
        """
        Return the description of the selected option.
        """
        i = 0
        for category in python_input.options:
            for option in category.options:
                if i == python_input.selected_option_index:
                    return option.description
                i += 1
        return ''

    def get_help_text():
        return [(token, get_current_description())]

    return ConditionalContainer(
        content=Window(FormattedTextControl(get_help_text),
                       style=token,
                       height=Dimension(min=3)),
        filter=ShowSidebar(python_input)
        & Condition(lambda: python_input.show_sidebar_help) & ~is_done)
示例#20
0
def sql_sidebar_help(my_app: "sqlApp"):
    """
    Create the `Layout` for the help text for the current item in the sidebar.
    """
    token = "class:sidebar.helptext"

    def get_current_description():
        """
        Return the description of the selected option.
        """
        obj = my_app.selected_object
        if obj is not None:
            return obj.name
        return ""

    def get_help_text():
        return [(token, get_current_description())]

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_help_text), style=token, height=Dimension(min=3)
            ),
        filter = ~is_done
        & ShowSidebar(my_app)
        & Condition(
            lambda: not my_app.show_exit_confirmation
        ))
    def __init__(self, row, table, borders,
                 window_too_small=None, align=HorizontalAlign.JUSTIFY,
                 padding=D.exact(0), padding_char=None, padding_style='',
                 width=None, height=None, z_index=None,
                 modal=False, key_bindings=None, style=''):
        self.table = table
        self.borders = borders

        # ensure the row is iterable (has cells)
        if not isinstance(row, list):
            row = [row]
        children = []
        for c in row:
            m = 1
            if isinstance(c, Merge):
                c, m = c
            elif isinstance(c, dict):
                c, m = Merge(**c)
            children.append(_Cell(cell=c, table=table, row=self, merge=m))

        super().__init__(
            children=children,
            window_too_small=window_too_small,
            align=align,
            padding=padding,
            padding_char=padding_char,
            padding_style=padding_style,
            width=width,
            height=height,
            z_index=z_index,
            modal=modal,
            key_bindings=key_bindings,
            style=style)
    def __init__(self, prev, next, table, borders,
                 window_too_small=None, align=HorizontalAlign.JUSTIFY,
                 padding=D.exact(0), padding_char=None, padding_style='',
                 width=None, height=None, z_index=None,
                 modal=False, key_bindings=None, style=''):
        assert prev or next
        self.prev = prev
        self.next = next
        self.table = table
        self.borders = borders

        children = [_HorizontalBorder(borders=borders)] * self.columns

        super().__init__(
            children=children,
            window_too_small=window_too_small,
            align=align,
            padding=padding,
            padding_char=padding_char,
            padding_style=padding_style,
            width=width,
            height=height or 1,
            z_index=z_index,
            modal=modal,
            key_bindings=key_bindings,
            style=style)
示例#23
0
 def get_width(self, progress_bar: "ProgressBar") -> AnyDimension:
     width = 5
     for counter in progress_bar.counters:
         if counter.items_completed >= 1000:
             width = 6
             break
     return Dimension.exact(width)
示例#24
0
def select_menu(items, display_format=None, max_height=10):
    """ Presents a list of options and allows the user to select one.

    This presents a static list of options and prompts the user to select one.
    This is similar to a completion menu but is different in that it does not
    allow a user to type and the returned value is always a member of the list.

    :type items: list
    :param list: The list of items to be selected from. If this list contains
    elements that are not strings the display_format option must be specified.

    :type display_format: Callable[[Any], str]
    :param display_format: A callable that takes a single element from the
    items list as input and returns a string used to represent the item in the
    menu.

    :type max_height: int
    :param max_height: The max number of items to show in the list at a time.

    :returns: The selected element from the items list.
    """
    app_bindings = KeyBindings()

    @app_bindings.add('c-c')
    def exit_app(event):
        event.app.exit(exception=KeyboardInterrupt, style='class:aborting')

    min_height = min(max_height, len(items))
    menu_window = Window(
        SelectionMenuControl(items, display_format=display_format),
        always_hide_cursor=False,
        height=Dimension(min=min_height, max=min_height),
        scroll_offsets=ScrollOffsets(),
        right_margins=[ScrollbarMargin()],
    )

    # Using a FloatContainer was the only way I was able to succesfully
    # limit the height and width of the window.
    content = FloatContainer(
        Window(height=Dimension(min=min_height, max=min_height)),
        [Float(menu_window, top=0, left=0)])
    app = Application(
        layout=Layout(content),
        key_bindings=app_bindings,
        erase_when_done=True,
    )
    return app.run()
示例#25
0
文件: widgets.py 项目: plotski/upsies
 def __init__(self, text='', style=''):
     self.percent = 0
     self.container = VSplit(
         children=[
             Window(
                 style='class:info.progressbar.progress',
                 width=lambda: Dimension(weight=int(self.percent)),
                 height=1,
             ),
             Window(
                 style='class:info.progressbar',
                 width=lambda: Dimension(weight=int(100 - self.percent)),
                 height=1,
             ),
         ],
         style=style,
     )
示例#26
0
def expanding_object_notification(my_app: "sqlApp"):
    """
    Create the `Layout` for the 'Expanding object' notification.
    """
    def get_text_fragments():
        # Show navigation info.
        return [("fg:red", "Expanding object ...")]

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            style="class:sidebar",
            width=Dimension.exact(45),
            height=Dimension(max=1),
        ),
        filter=~is_done
        & ShowSidebar(my_app)
        & Condition(lambda: my_app.show_expanding_object))
示例#27
0
def setup_docstring_containers(repl):
    parent_container = get_ptpython_parent_container(repl)
    # the same as ptpython containers, but without signature checking
    parent_container.children.extend(
        [
            ConditionalContainer(
                content=Window(height=Dimension.exact(1), char="\u2500", style="class:separator"),
                filter=HasDocString(repl) & ShowDocstring(repl) & ~is_done,
            ),
            ConditionalContainer(
                content=Window(
                    BufferControl(buffer=repl.docstring_buffer, lexer=PygmentsLexer(PythonLexer)),
                    height=Dimension(max=12),
                ),
                filter=HasDocString(repl) & ShowDocstring(repl) & ~is_done,
            ),
        ]
    )
示例#28
0
    def render(self):
        choices_len = len(self._choices)

        buttons = [
            Button('[%s] %s' % (i, label) if choices_len > 1 else label,
                   handler=self._create_handler(sub_component))
            for ((label, sub_component),
                 i) in zip(self._choices, range(
                     1, choices_len +
                     1))  # this is still a loop even if it is inline..
        ]

        self._first_button = buttons[0]

        global global__default_target_focus
        global__default_target_focus = self._first_button

        kb = create_vertical_button_list_kbs(buttons)

        is_first_selected = has_focus(buttons[0])
        kb.add('up', filter=is_first_selected)(lambda e: focus_first_element())

        return Box(
            HSplit(
                [
                    TextArea(
                        text=self._label.format(
                            name=self._controller.state.username) + '\n',
                        read_only=True,
                        focusable=False,
                        scrollbar=True,
                        # push buttons to bottom of screen
                        height=Dimension(preferred=100000, max=100000)),
                    HSplit([
                        VSplit(children=[button], align=HorizontalAlign.CENTER)
                        for button in buttons
                    ],
                           padding=1,
                           key_bindings=kb)
                ],
                padding=Dimension(preferred=2, max=2),
                width=Dimension(),
                align=VerticalAlign.TOP),
            padding=1)
示例#29
0
def progress_dialog(
    title: AnyFormattedText = "",
    text: AnyFormattedText = "",
    run_callback: Callable[[Callable[[int], None], Callable[[str], None]], None] = (
        lambda *a: None
    ),
    style: Optional[BaseStyle] = None,
) -> Application[None]:
    """
    :param run_callback: A function that receives as input a `set_percentage`
        function and it does the work.
    """
    loop = get_event_loop()
    progressbar = ProgressBar()
    text_area = TextArea(
        focusable=False,
        # Prefer this text area as big as possible, to avoid having a window
        # that keeps resizing when we add text to it.
        height=D(preferred=10 ** 10),
    )

    dialog = Dialog(
        body=HSplit(
            [
                Box(Label(text=text)),
                Box(text_area, padding=D.exact(1)),
                progressbar,
            ]
        ),
        title=title,
        with_background=True,
    )
    app = _create_app(dialog, style)

    def set_percentage(value: int) -> None:
        progressbar.percentage = int(value)
        app.invalidate()

    def log_text(text: str) -> None:
        loop.call_soon_threadsafe(text_area.buffer.insert_text, text)
        app.invalidate()

    # Run the callback in the executor. When done, set a return value for the
    # UI, so that it quits.
    def start() -> None:
        try:
            run_callback(set_percentage, log_text)
        finally:
            app.exit()

    def pre_run() -> None:
        run_in_executor_with_context(start)

    app.pre_run_callables.append(pre_run)

    return app
示例#30
0
文件: layout.py 项目: mskar/ptpython
def show_sidebar_button_info(python_input: "PythonInput") -> Container:
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """

    @if_mousedown
    def toggle_sidebar(mouse_event: MouseEvent) -> None:
        " Click handler for the menu. "
        python_input.show_sidebar = not python_input.show_sidebar

    version = sys.version_info
    tokens: StyleAndTextTuples = [
        ("class:status-toolbar.key", "[F2]", toggle_sidebar),
        ("class:status-toolbar", " Menu", toggle_sidebar),
        ("class:status-toolbar", " - "),
        (
            "class:status-toolbar.python-version",
            "%s %i.%i.%i"
            % (platform.python_implementation(), version[0], version[1], version[2]),
        ),
        ("class:status-toolbar", " "),
    ]
    width = fragment_list_width(tokens)

    def get_text_fragments() -> StyleAndTextTuples:
        # Python version
        return tokens

    return ConditionalContainer(
        content=Window(
            FormattedTextControl(get_text_fragments),
            style="class:status-toolbar",
            height=Dimension.exact(1),
            width=Dimension.exact(width),
        ),
        filter=~is_done
        & renderer_height_is_known
        & Condition(
            lambda: python_input.show_status_bar
            and not python_input.show_exit_confirmation
        ),
    )
示例#31
0
    def _get_default_buffer_control_height(self):
        # If there is an autocompletion menu to be shown, make sure that our
        # layout has at least a minimal height in order to display it.
        if (self.completer is not None
                and self.complete_style != CompleteStyle.READLINE_LIKE):
            space = self.reserve_space_for_menu
        else:
            space = 0

        if space and not get_app().is_done:
            buff = self.default_buffer

            # Reserve the space, either when there are completions, or when
            # `complete_while_typing` is true and we expect completions very
            # soon.
            if buff.complete_while_typing() or buff.complete_state is not None:
                return Dimension(min=space)

        return Dimension()
    def __init__(self, text, **kw):
        # The style needs to be applied to the toolbar as a whole, not just the
        # `FormattedTextControl`.
        style = kw.pop('style', '')

        super(FormattedTextToolbar,
              self).__init__(FormattedTextControl(text, **kw),
                             style=style,
                             dont_extend_height=True,
                             height=Dimension(min=1))
def progress_dialog(
        title: AnyFormattedText = '',
        text: AnyFormattedText = '',
        run_callback: Callable[[Callable[[int], None], Callable[[str], None]], None] = (lambda *a: None),
        style: Optional[BaseStyle] = None) -> Application[None]:
    """
    :param run_callback: A function that receives as input a `set_percentage`
        function and it does the work.
    """
    loop = get_event_loop()
    progressbar = ProgressBar()
    text_area = TextArea(
        focusable=False,

        # Prefer this text area as big as possible, to avoid having a window
        # that keeps resizing when we add text to it.
        height=D(preferred=10**10))

    dialog = Dialog(
        body=HSplit([
            Box(Label(text=text)),
            Box(text_area, padding=D.exact(1)),
            progressbar,
        ]),
        title=title,
        with_background=True)
    app = _create_app(dialog, style)

    def set_percentage(value: int) -> None:
        progressbar.percentage = int(value)
        app.invalidate()

    def log_text(text: str) -> None:
        loop.call_soon_threadsafe(text_area.buffer.insert_text, text)
        app.invalidate()

    # Run the callback in the executor. When done, set a return value for the
    # UI, so that it quits.
    def start() -> None:
        try:
            run_callback(set_percentage, log_text)
        finally:
            app.exit()

    def pre_run() -> None:
        run_in_executor_with_context(start)
    app.pre_run_callables.append(pre_run)

    return app
def progress_dialog(title='', text='', run_callback=None, style=None, async_=False):
    """
    :param run_callback: A function that receives as input a `set_percentage`
        function and it does the work.
    """
    assert callable(run_callback)

    progressbar = ProgressBar()
    text_area = TextArea(
        focusable=False,

        # Prefer this text area as big as possible, to avoid having a window
        # that keeps resizing when we add text to it.
        height=D(preferred=10**10))

    dialog = Dialog(
        body=HSplit([
            Box(Label(text=text)),
            Box(text_area, padding=D.exact(1)),
            progressbar,
        ]),
        title=title,
        with_background=True)
    app = _create_app(dialog, style)

    def set_percentage(value):
        progressbar.percentage = int(value)
        app.invalidate()

    def log_text(text):
        text_area.buffer.insert_text(text)
        app.invalidate()

    # Run the callback in the executor. When done, set a return value for the
    # UI, so that it quits.
    def start():
        try:
            run_callback(set_percentage, log_text)
        finally:
            app.exit()

    run_in_executor(start)

    if async_:
        return app.run_async()
    else:
        return app.run()
示例#35
0
 def preferred_width(self, max_available_width):
     return D.exact(BigClock.WIDTH)
示例#36
0
 def preferred_width(self, max_available_width):
     # Enough to display all the digits.
     return Dimension.exact(6 * len('%s' % self._get_index()) - 1)
示例#37
0
 def preferred_height(self, width, max_available_height):
     return Dimension.exact(self.HEIGHT)
    def __init__(self, history):
        search_toolbar = SearchToolbar()

        self.help_buffer_control = BufferControl(
            buffer=history.help_buffer,
            lexer=PygmentsLexer(RstLexer))

        help_window = _create_popup_window(
            title='History Help',
            body=Window(
                content=self.help_buffer_control,
                right_margins=[ScrollbarMargin(display_arrows=True)],
                scroll_offsets=ScrollOffsets(top=2, bottom=2)))

        self.default_buffer_control = BufferControl(
            buffer=history.default_buffer,
            input_processors=[GrayExistingText(history.history_mapping)],
            lexer=PygmentsLexer(PythonLexer))

        self.history_buffer_control = BufferControl(
            buffer=history.history_buffer,
            lexer=PygmentsLexer(PythonLexer),
            search_buffer_control=search_toolbar.control,
            preview_search=True)

        history_window = Window(
            content=self.history_buffer_control,
            wrap_lines=False,
            left_margins=[HistoryMargin(history)],
            scroll_offsets=ScrollOffsets(top=2, bottom=2))

        self.root_container = HSplit([
            #  Top title bar.
            Window(
                content=FormattedTextControl(_get_top_toolbar_fragments),
                align=WindowAlign.CENTER,
                style='class:status-toolbar'),
            FloatContainer(
                content=VSplit([
                    # Left side: history.
                    history_window,
                    # Separator.
                    Window(width=D.exact(1),
                           char=BORDER.LIGHT_VERTICAL,
                           style='class:separator'),
                    # Right side: result.
                    Window(
                        content=self.default_buffer_control,
                        wrap_lines=False,
                        left_margins=[ResultMargin(history)],
                        scroll_offsets=ScrollOffsets(top=2, bottom=2)),
                ]),
                floats=[
                    # Help text as a float.
                    Float(width=60, top=3, bottom=2,
                          content=ConditionalContainer(
                              content=help_window, filter=has_focus(history.help_buffer))),
                ]
            ),
            # Bottom toolbars.
            ArgToolbar(),
            search_toolbar,
            Window(
                content=FormattedTextControl(
                    partial(_get_bottom_toolbar_fragments, history=history)),
                style='class:status-toolbar'),
        ])

        self.layout = Layout(self.root_container, history_window)
    def __init__(self,
                 text: str = '',
                 multiline: FilterOrBool = True,
                 password: FilterOrBool = False,
                 lexer: Optional[Lexer] = None,
                 auto_suggest: Optional[AutoSuggest] = None,
                 completer: Optional[Completer] = None,
                 complete_while_typing: FilterOrBool = True,
                 accept_handler: Optional[BufferAcceptHandler] = None,
                 history: Optional[History] = None,
                 focusable: FilterOrBool = True,
                 focus_on_click: FilterOrBool = False,
                 wrap_lines: FilterOrBool = True,
                 read_only: FilterOrBool = False,
                 width: AnyDimension = None,
                 height: AnyDimension = None,
                 dont_extend_height: FilterOrBool = False,
                 dont_extend_width: FilterOrBool = False,
                 line_numbers: bool = False,
                 get_line_prefix: Optional[GetLinePrefixCallable] = None,
                 scrollbar: bool = False,
                 style: str = '',
                 search_field: Optional[SearchToolbar] = None,
                 preview_search: FilterOrBool = True,
                 prompt: AnyFormattedText = '',
                 input_processors: Optional[List[Processor]] = None) -> None:

        if search_field is None:
            search_control = None
        elif isinstance(search_field, SearchToolbar):
            search_control = search_field.control

        if input_processors is None:
            input_processors = []

        # Writeable attributes.
        self.completer = completer
        self.complete_while_typing = complete_while_typing
        self.lexer = lexer
        self.auto_suggest = auto_suggest
        self.read_only = read_only
        self.wrap_lines = wrap_lines

        self.buffer = Buffer(
            document=Document(text, 0),
            multiline=multiline,
            read_only=Condition(lambda: is_true(self.read_only)),
            completer=DynamicCompleter(lambda: self.completer),
            complete_while_typing=Condition(
                lambda: is_true(self.complete_while_typing)),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept_handler,
            history=history)

        self.control = BufferControl(
            buffer=self.buffer,
            lexer=DynamicLexer(lambda: self.lexer),
            input_processors=[
                ConditionalProcessor(
                    AppendAutoSuggestion(),
                    has_focus(self.buffer) & ~is_done),
                ConditionalProcessor(
                    processor=PasswordProcessor(),
                    filter=to_filter(password)
                ),
                BeforeInput(prompt, style='class:text-area.prompt'),
            ] + input_processors,
            search_buffer_control=search_control,
            preview_search=preview_search,
            focusable=focusable,
            focus_on_click=focus_on_click)

        if multiline:
            if scrollbar:
                right_margins = [ScrollbarMargin(display_arrows=True)]
            else:
                right_margins = []
            if line_numbers:
                left_margins = [NumberedMargin()]
            else:
                left_margins = []
        else:
            height = D.exact(1)
            left_margins = []
            right_margins = []

        style = 'class:text-area ' + style

        self.window = Window(
            height=height,
            width=width,
            dont_extend_height=dont_extend_height,
            dont_extend_width=dont_extend_width,
            content=self.control,
            style=style,
            wrap_lines=Condition(lambda: is_true(self.wrap_lines)),
            left_margins=left_margins,
            right_margins=right_margins,
            get_line_prefix=get_line_prefix)
示例#40
0
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)
示例#41
0
def python_sidebar(python_input):
    """
    Create the `Layout` for the sidebar with the configurable options.
    """
    def get_text_fragments():
        tokens = []

        def append_category(category):
            tokens.extend([
                ('class:sidebar', '  '),
                ('class:sidebar.title', '   %-36s' % category.title),
                ('class:sidebar', '\n'),
            ])

        def append(index, label, status):
            selected = index == python_input.selected_option_index

            @if_mousedown
            def select_item(mouse_event):
                python_input.selected_option_index = index

            @if_mousedown
            def goto_next(mouse_event):
                " Select item and go to next value. "
                python_input.selected_option_index = index
                option = python_input.selected_option
                option.activate_next()

            sel = ',selected' if selected else ''

            tokens.append(('class:sidebar' + sel, ' >' if selected else '  '))
            tokens.append(('class:sidebar.label' + sel, '%-24s' % label, select_item))
            tokens.append(('class:sidebar.status' + sel, ' ', select_item))
            tokens.append(('class:sidebar.status' + sel, '%s' % status, goto_next))

            if selected:
                tokens.append(('[SetCursorPosition]', ''))

            tokens.append(('class:sidebar.status' + sel, ' ' * (13 - len(status)), goto_next))
            tokens.append(('class:sidebar', '<' if selected else ''))
            tokens.append(('class:sidebar', '\n'))

        i = 0
        for category in python_input.options:
            append_category(category)

            for option in category.options:
                append(i, option.title, '%s' % option.get_current_value())
                i += 1

        tokens.pop()  # Remove last newline.

        return tokens

    class Control(FormattedTextControl):
        def move_cursor_down(self):
            python_input.selected_option_index += 1

        def move_cursor_up(self):
            python_input.selected_option_index -= 1

    return Window(
        Control(get_text_fragments),
        style='class:sidebar',
        width=Dimension.exact(43),
        height=Dimension(min=3),
        scroll_offsets=ScrollOffsets(top=1, bottom=1))
示例#42
0
 def preferred_height(self, width, max_available_height):
     return D.exact(BigClock.HEIGHT)
示例#43
0
    def __init__(self, text='', multiline=True, password=False,
                 lexer=None, auto_suggest=None, completer=None,
                 complete_while_typing=True, accept_handler=None, history=None,
                 focusable=True, focus_on_click=False, wrap_lines=True,
                 read_only=False, width=None, height=None,
                 dont_extend_height=False, dont_extend_width=False,
                 line_numbers=False, get_line_prefix=None, scrollbar=False,
                 style='', search_field=None, preview_search=True, prompt='',
                 input_processors=None):
       # assert isinstance(text, six.text_type)

        if search_field is None:
            search_control = None

        if input_processors is None:
            input_processors = []

        # Writeable attributes.
        self.completer = completer
        self.complete_while_typing = complete_while_typing
        self.lexer = lexer
        self.auto_suggest = auto_suggest
        self.read_only = read_only
        self.wrap_lines = wrap_lines

        self.buffer = Buffer(
            document=Document(text, 0),
            multiline=multiline,
            read_only=Condition(lambda: is_true(self.read_only)),
            completer=DynamicCompleter(lambda: self.completer),
            complete_while_typing=Condition(
                lambda: is_true(self.complete_while_typing)),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept_handler,
            history=history)

        self.control = BufferControl(
            buffer=self.buffer,
            lexer=DynamicLexer(lambda: self.lexer),
            input_processors=[
                ConditionalProcessor(
                    AppendAutoSuggestion(),
                    has_focus(self.buffer) & is_done), #
                ConditionalProcessor(
                    processor=PasswordProcessor(),
                    filter=to_filter(password)
                ),
                BeforeInput(prompt, style='class:text-area.prompt'),
            ] + input_processors,
            search_buffer_control=search_control,
            preview_search=preview_search,
            focusable=focusable,
            focus_on_click=focus_on_click)

        if multiline:
            if scrollbar:
                right_margins = [ScrollbarMargin(display_arrows=True)]
            else:
                right_margins = []
            if line_numbers:
                left_margins = [NumberedMargin()]
            else:
                left_margins = []
        else:
            height = D.exact(1)
            left_margins = []
            right_margins = []

        style = 'class:text-area ' + style

        self.window = Window(
            height=height,
            width=width,
            dont_extend_height=dont_extend_height,
            dont_extend_width=dont_extend_width,
            content=self.control,
            style=style,
            wrap_lines=Condition(lambda: is_true(self.wrap_lines)),
            left_margins=left_margins,
            right_margins=right_margins,
            get_line_prefix=get_line_prefix)