Пример #1
0
    def __init__(self,
                 text: str,
                 handler: Optional[Callable[[], None]] = None,
                 width: int = 12) -> None:

        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() -> 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=width,
                             style=get_style,
                             dont_extend_width=True,
                             dont_extend_height=True)
Пример #2
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))
Пример #3
0
    def __init__(self,
                 text: AnyFormattedText,
                 style: str = '',
                 width: AnyDimension = None,
                 dont_extend_height: bool = True,
                 dont_extend_width: bool = False) -> None:

        self.text = text

        def get_width() -> AnyDimension:
            if width is None:
                text_fragments = to_formatted_text(self.text)
                text = fragment_list_to_text(text_fragments)
                if text:
                    longest_line = max(
                        get_cwidth(line) for line in text.splitlines())
                else:
                    return D(preferred=0)
                return D(preferred=longest_line)
            else:
                return width

        self.formatted_text_control = FormattedTextControl(
            text=lambda: self.text)

        self.window = Window(content=self.formatted_text_control,
                             width=get_width,
                             style='class:label ' + style,
                             dont_extend_height=dont_extend_height,
                             dont_extend_width=dont_extend_width)
Пример #4
0
    def __init__(self, values: Sequence[Tuple[_T, AnyFormattedText]]) -> None:
        assert len(values) > 0

        self.values = values
        # current_values will be used in multiple_selection,
        # current_value will be used otherwise.
        self.current_values: List[_T] = []
        self.current_value: _T = values[0][0]
        self._selected_index = 0

        # Key bindings.
        kb = KeyBindings()

        @kb.add('up')
        def _(event: E) -> None:
            self._selected_index = max(0, self._selected_index - 1)

        @kb.add('down')
        def _(event: E) -> None:
            self._selected_index = min(
                len(self.values) - 1, self._selected_index + 1)

        @kb.add('pageup')
        def _(event: E) -> None:
            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: E) -> None:
            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: E) -> None:
            self._handle_enter()

        @kb.add(Keys.Any)
        def _(event: E) -> None:
            # We first check values after the selected value, then all values.
            for value in self.values[self._selected_index + 1:] + self.values:
                if value[1].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=self.container_style,
                             right_margins=[
                                 ScrollbarMargin(display_arrows=True),
                             ],
                             dont_extend_height=True)
Пример #5
0
    def __init__(self) -> None:
        def get_formatted_text() -> StyleAndTextTuples:
            arg = get_app().key_processor.arg or ''
            if arg == '-':
                arg = '-1'

            return [
                ('class:arg-toolbar', 'Repeat: '),
                ('class:arg-toolbar.text', arg),
            ]

        self.window = Window(FormattedTextControl(get_formatted_text),
                             height=1)

        self.container = ConditionalContainer(content=self.window,
                                              filter=has_arg)
Пример #6
0
    def __init__(self, show_position: bool = False) -> None:
        def get_formatted_text() -> StyleAndTextTuples:
            buff = get_app().current_buffer

            if buff.validation_error:
                row, column = buff.document.translate_index_to_position(
                    buff.validation_error.cursor_position)

                if show_position:
                    text = '%s (line=%s column=%s)' % (
                        buff.validation_error.message, row + 1, column + 1)
                else:
                    text = buff.validation_error.message

                return [('class:validation-toolbar', text)]
            else:
                return []

        self.control = FormattedTextControl(get_formatted_text)

        self.container = ConditionalContainer(content=Window(self.control,
                                                             height=1),
                                              filter=has_validation_error)
Пример #7
0
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus
consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo
sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed
convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex
quis sodales maximus. """ * 100).split())

# 1. The layout
left_text = "Floating\nleft"
right_text = "Floating\nright"
top_text = "Floating\ntop"
bottom_text = "Floating\nbottom"
center_text = "Floating\ncenter"
quit_text = "Press 'q' to quit."

body = FloatContainer(
    content=Window(FormattedTextControl(LIPSUM), wrap_lines=True),
    floats=[

        # Important note: Wrapping the floating objects in a 'Frame' is
        #                 only required for drawing the border around the
        #                 floating text. We do it here to make the layout more
        #                 obvious.

        # Left float.
        Float(Frame(Window(FormattedTextControl(left_text), width=10,
                           height=2),
                    style='bg:#44ffff #ffffff'),
              left=0),

        # Right float.
        Float(Frame(Window(FormattedTextControl(right_text),
Пример #8
0

search_field = SearchToolbar(
    text_if_not_searching=[('class:not-searching',
                            "Press '/' to start searching.")])

text_area = TextArea(text=text,
                     read_only=True,
                     scrollbar=True,
                     line_numbers=True,
                     search_field=search_field,
                     lexer=PygmentsLexer(PythonLexer))

root_container = HSplit([
    # The top toolbar.
    Window(content=FormattedTextControl(get_statusbar_text),
           height=D.exact(1),
           style='class:status'),

    # The main content.
    text_area,
    search_field,
])

# Key bindings.
bindings = KeyBindings()


@bindings.add('c-c')
@bindings.add('q')
def _(event):
Пример #9
0
placerat massa tempor elementum. Sed tristique mauris ac suscipit euismod. Ut
tempus vehicula augue non venenatis. Mauris aliquam velit turpis, nec congue
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus
consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo
sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed
convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex
quis sodales maximus."""

# 1. The layout

left_text = '\nLeft aligned text. - (Press "q" to quit)\n\n' + LIPSUM
center_text = 'Centered text.\n\n' + LIPSUM
right_text = 'Right aligned text.\n\n' + LIPSUM

body = HSplit([
    Window(FormattedTextControl(left_text), align=WindowAlign.LEFT),
    Window(height=1, char='-'),
    Window(FormattedTextControl(center_text), align=WindowAlign.CENTER),
    Window(height=1, char='-'),
    Window(FormattedTextControl(right_text), align=WindowAlign.RIGHT),
])

# 2. Key bindings
kb = KeyBindings()


@kb.add('q')
def _(event):
    " Quit application. "
    event.app.exit()
Пример #10
0
dignissim placerat. In vel dictum ex, vulputate accumsan mi. Donec ut quam
placerat massa tempor elementum. Sed tristique mauris ac suscipit euismod. Ut
tempus vehicula augue non venenatis. Mauris aliquam velit turpis, nec congue
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus
consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo
sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed
convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex
quis sodales maximus. """

left_top = Window(BufferControl(Buffer(document=Document(LIPSUM))))
left_bottom = Window(BufferControl(Buffer(document=Document(LIPSUM))))
right_top = Window(BufferControl(Buffer(document=Document(LIPSUM))))
right_bottom = Window(BufferControl(Buffer(document=Document(LIPSUM))))

body = HSplit([
    Window(FormattedTextControl(top_text), height=2, style='reverse'),
    Window(height=1, char='-'),  # Horizontal line in the middle.
    VSplit([left_top, Window(width=1, char='|'), right_top]),
    Window(height=1, char='-'),  # Horizontal line in the middle.
    VSplit([left_bottom, Window(width=1, char='|'), right_bottom]),
])

# 2. Key bindings
kb = KeyBindings()


@kb.add('q')
def _(event):
    " Quit application. "
    event.app.exit()
Пример #11
0
# Ctrl-R.) It would be really annoying if the search key bindings are handled,
# but the user doesn't see any feedback. We will add the search toolbar to the
# bottom by using an HSplit.


def get_titlebar_text():
    return [
        ('class:title', ' Hello world '),
        ('class:title', ' (Press [Ctrl-Q] to quit.)'),
    ]


root_container = HSplit([
    # The titlebar.
    Window(height=1,
           content=FormattedTextControl(get_titlebar_text),
           align=WindowAlign.CENTER),

    # Horizontal separator.
    Window(height=1, char='-', style='class:line'),

    # The 'body', like defined above.
    body,
])


# 2. Adding key bindings
#   --------------------

# As a demonstration, we will add just a ControlQ key binding to exit the
# application.  Key bindings are registered in a
#!/usr/bin/env python
"""
Vertical split example.
"""
from prompt_toolkit_dev.application import Application
from prompt_toolkit_dev.key_binding import KeyBindings
from prompt_toolkit_dev.layout.containers import VSplit, Window
from prompt_toolkit_dev.layout.controls import FormattedTextControl
from prompt_toolkit_dev.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.
    Window(FormattedTextControl(right_text)),
])

# 2. Key bindings
kb = KeyBindings()


@kb.add('q')
def _(event):
    " Quit application. "
    event.app.exit()


# 3. The `Application`
Пример #13
0
from prompt_toolkit_dev.layout.dimension import D
from prompt_toolkit_dev.layout.layout import Layout
from prompt_toolkit_dev.widgets import Frame

TITLE = HTML(""" <u>VSplit VerticalAlign</u> example.
 Press <b>'q'</b> to quit.""")

LIPSUM = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Maecenas
quis interdum enim. Nam viverra, mauris et blandit malesuada, ante est bibendum
mauris, ac dignissim dui tellus quis ligula. Aenean condimentum leo at
dignissim placerat."""

# 1. The layout
body = HSplit([
    Frame(Window(FormattedTextControl(TITLE), height=2),
          style='bg:#88ff88 #000000'),
    VSplit([
        Window(FormattedTextControl(HTML('  <u>VerticalAlign.TOP</u>')),
               height=4,
               ignore_content_width=True,
               style='bg:#ff3333 #000000 bold',
               align=WindowAlign.CENTER),
        Window(FormattedTextControl(HTML('  <u>VerticalAlign.CENTER</u>')),
               height=4,
               ignore_content_width=True,
               style='bg:#ff3333 #000000 bold',
               align=WindowAlign.CENTER),
        Window(FormattedTextControl(HTML('  <u>VerticalAlign.BOTTOM</u>')),
               height=4,
               ignore_content_width=True,
Пример #14
0
            '[%s] <style bg="orange" fg="black">--&gt;</style> ') % lineno

    text = str(lineno) + '-' + '*' * (lineno // 2) + ': '
    return HTML('[%s.%s] <style bg="ansigreen" fg="ansiblack">%s</style>') % (
        lineno, wrap_count, text)


# Global wrap lines flag.
wrap_lines = True

# The layout
buff = Buffer(complete_while_typing=True)
buff.text = LIPSUM

body = FloatContainer(content=HSplit([
    Window(FormattedTextControl(
        'Press "q" to quit. Press "w" to enable/disable wrapping.'),
           height=1,
           style='reverse'),
    Window(BufferControl(buffer=buff),
           get_line_prefix=get_line_prefix,
           wrap_lines=Condition(lambda: wrap_lines)),
]),
                      floats=[
                          Float(xcursor=True,
                                ycursor=True,
                                content=CompletionsMenu(max_height=16,
                                                        scroll_offset=1))
                      ])

# Key bindings
kb = KeyBindings()
Пример #15
0
    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 _(event: E) -> None:
            self.selected_menu[0] = max(0, self.selected_menu[0] - 1)

        @kb.add('right', filter=in_main_menu)
        def _(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 _(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 _(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 _(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 _(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 _(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 _(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 _(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,
        )
Пример #16
0
    def _submenu(self, level: int = 0) -> Window:
        def get_text_fragments() -> StyleAndTextTuples:
            result: StyleAndTextTuples = []
            if level < len(self.selected_menu):
                menu = self._get_menu(level)
                if menu.children:
                    result.append(('class:menu', Border.TOP_LEFT))
                    result.append(('class:menu', Border.HORIZONTAL * (menu.width + 4)))
                    result.append(('class:menu', Border.TOP_RIGHT))
                    result.append(('', '\n'))
                    try:
                        selected_item = self.selected_menu[level + 1]
                    except IndexError:
                        selected_item = -1

                    def one_item(i: int, item: MenuItem) -> Iterable[OneStyleAndTextTuple]:
                        def mouse_handler(mouse_event: MouseEvent) -> None:
                            if mouse_event.event_type == MouseEventType.MOUSE_UP:
                                app = get_app()
                                if item.handler:
                                    app.layout.focus_last()
                                    item.handler()
                                else:
                                    self.selected_menu = self.selected_menu[:level + 1] + [i]

                        if i == selected_item:
                            yield ('[SetCursorPosition]', '')
                            style = 'class:menu-bar.selected-item'
                        else:
                            style = ''

                        yield ('class:menu', Border.VERTICAL)
                        if item.text == '-':
                            yield (style + 'class:menu-border',
                                   '{}'.format(Border.HORIZONTAL * (menu.width + 3)),
                                   mouse_handler)
                        else:
                            yield (style, ' {}'.format(item.text).ljust(menu.width + 3),
                                   mouse_handler)

                        if item.children:
                            yield (style, '>', mouse_handler)
                        else:
                            yield (style, ' ', mouse_handler)

                        if i == selected_item:
                            yield ('[SetMenuPosition]', '')
                        yield ('class:menu', Border.VERTICAL)

                        yield ('', '\n')

                    for i, item in enumerate(menu.children):
                        result.extend(one_item(i, item))

                    result.append(('class:menu', Border.BOTTOM_LEFT))
                    result.append(('class:menu', Border.HORIZONTAL * (menu.width + 4)))
                    result.append(('class:menu', Border.BOTTOM_RIGHT))
            return result

        return Window(
            FormattedTextControl(get_text_fragments),
            style='class:menu')
Пример #17
0
dignissim placerat. In vel dictum ex, vulputate accumsan mi. Donec ut quam
placerat massa tempor elementum. Sed tristique mauris ac suscipit euismod. Ut
tempus vehicula augue non venenatis. Mauris aliquam velit turpis, nec congue
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus
consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo
sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed
convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex
quis sodales maximus. """ * 100).split())

# 1. The layout
left_text = HTML("<reverse>transparent=False</reverse>\n")
right_text = HTML("<reverse>transparent=True</reverse>")
quit_text = "Press 'q' to quit."

body = FloatContainer(
    content=Window(FormattedTextControl(LIPSUM), wrap_lines=True),
    floats=[

        # Important note: Wrapping the floating objects in a 'Frame' is
        #                 only required for drawing the border around the
        #                 floating text. We do it here to make the layout more
        #                 obvious.

        # Left float.
        Float(Frame(Window(FormattedTextControl(left_text), width=20,
                           height=4)),
              transparent=False,
              left=0),

        # Right float.
        Float(Frame(
Пример #18
0
TITLE = HTML(""" <u>HSplit HorizontalAlign</u> example.
 Press <b>'q'</b> to quit.""")

LIPSUM = """\
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit.
Maecenas quis
interdum enim."""


# 1. The layout
body = HSplit([
    Frame(
        Window(FormattedTextControl(TITLE), height=2), style='bg:#88ff88 #000000'),
    HSplit([
        # Left alignment.
        VSplit([
            Window(FormattedTextControl(HTML('<u>LEFT</u>')), width=10,
                   ignore_content_width=True, style='bg:#ff3333 ansiblack', align=WindowAlign.CENTER),
            VSplit([
                Window(FormattedTextControl(LIPSUM), height=4, style='bg:#444488'),
                Window(FormattedTextControl(LIPSUM), height=4, style='bg:#444488'),
                Window(FormattedTextControl(LIPSUM), height=4, style='bg:#444488'),
            ], padding=1, padding_style='bg:#888888', align=HorizontalAlign.LEFT, height=5, padding_char='|'),
        ]),
        # Center alignment.
        VSplit([
            Window(FormattedTextControl(HTML('<u>CENTER</u>')), width=10,
                   ignore_content_width=True, style='bg:#ff3333 ansiblack', align=WindowAlign.CENTER),
Пример #19
0
placerat massa tempor elementum. Sed tristique mauris ac suscipit euismod. Ut
tempus vehicula augue non venenatis. Mauris aliquam velit turpis, nec congue
risus aliquam sit amet. Pellentesque blandit scelerisque felis, faucibus
consequat ante. Curabitur tempor tortor a imperdiet tincidunt. Nam sed justo
sit amet odio bibendum congue. Quisque varius ligula nec ligula gravida, sed
convallis augue faucibus. Nunc ornare pharetra bibendum. Praesent blandit ex
quis sodales maximus.""" * 40

# Create text buffers. The margins will update if you scroll up or down.

buff = Buffer()
buff.text = LIPSUM

# 1. The layout
body = HSplit([
    Window(FormattedTextControl('Press "q" to quit.'),
           height=1,
           style='reverse'),
    Window(
        BufferControl(buffer=buff),

        # Add margins.
        left_margins=[NumberedMargin(), ScrollbarMargin()],
        right_margins=[ScrollbarMargin(), ScrollbarMargin()],
    ),
])

# 2. Key bindings
kb = KeyBindings()

Пример #20
0
                                 Label(text=text),
                             ]),
                             buttons=[ok_button],
                             width=D(preferred=80),
                             modal=True)

    def __pt_container__(self):
        return self.dialog


body = HSplit([
    text_field,
    search_toolbar,
    ConditionalContainer(
        content=VSplit([
            Window(FormattedTextControl(get_statusbar_text),
                   style='class:status'),
            Window(FormattedTextControl(get_statusbar_right_text),
                   style='class:status.right',
                   width=9,
                   align=WindowAlign.RIGHT),
        ],
                       height=1),
        filter=Condition(lambda: ApplicationState.show_status_bar)),
])

# Global key bindings.
bindings = KeyBindings()


@bindings.add('c-c')