Beispiel #1
0
    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
Beispiel #2
0
    def get_root_container(self) -> FloatContainer:
        validator = CoordinateValidator(self.maze_grid)

        maze_grid_container = Label(text=self.maze_grid.format_grid, )

        coordinates_input_container = Window(
            BufferControl(
                buffer=Buffer(
                    validator=validator,
                    validate_while_typing=False,
                    multiline=False,
                    accept_handler=self._accept_handler,
                ),
                input_processors=[
                    BeforeInput("Enter coordinates (x, y): "),
                ],
            ), )

        validation_toolbar = ConditionalContainer(
            ValidationToolbar(),
            filter=~is_done,
        )

        return FloatContainer(
            HSplit([
                maze_grid_container,
                HorizontalLine(),
                coordinates_input_container,
                validation_toolbar,
            ]),
            floats=[],
        )
Beispiel #3
0
    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
Beispiel #4
0
def create_inquirer_layout(
    ic: InquirerControl,
    get_prompt_tokens: Callable[[], List[Tuple[str, str]]],
    **kwargs: Any,
) -> Layout:
    """Create a layout combining question and inquirer selection."""

    ps = PromptSession(get_prompt_tokens, reserve_space_for_menu=0, **kwargs)
    _fix_unecessary_blank_lines(ps)

    validation_prompt = PromptSession(bottom_toolbar=lambda: ic.error_message,
                                      **kwargs)

    return Layout(
        HSplit([
            ps.layout.container,
            ConditionalContainer(Window(ic), filter=~IsDone()),
            ConditionalContainer(
                validation_prompt.layout.container,
                filter=Condition(lambda: ic.error_message is not None),
            ),
        ]))
Beispiel #5
0
    def __init__(self, question):
        self._answer_control = AnswerControl()

        @Condition
        def answered():
            return self.answer is not None

        self.answered = answered

        q = self.build_question()

        self._header_control = QuestionHeaderControl(question)
        widgets = [
            VSplit(
                [
                    Window(
                        self._header_control,
                        wrap_lines=True,
                        dont_extend_height=True,
                        dont_extend_width=True,
                    ),
                    ConditionalContainer(
                        Window(
                            self._answer_control,
                            wrap_lines=True,
                            dont_extend_height=True,
                        ),
                        self.answered,
                    ),
                ]
            )
        ]
        if q is not None:
            widgets.append(ConditionalContainer(q, ~self.answered))

        widgets.extend([ConditionalContainer(ValidationToolbar(), ~self.answered)])

        self._widget = HSplit(widgets, key_bindings=self.key_bindings())
Beispiel #6
0
def create_inquirer_layout(ic: InquirerControl,
                           get_prompt_tokens: Callable[[], List[Tuple[Text,
                                                                      Text]]],
                           **kwargs) -> Layout:
    """Create a layout combining question and inquirer selection."""

    ps = PromptSession(get_prompt_tokens, reserve_space_for_menu=0, **kwargs)

    _fix_unecessary_blank_lines(ps)

    return Layout(
        HSplit([
            ps.layout.container,
            ConditionalContainer(Window(ic), filter=~IsDone())
        ]))
Beispiel #7
0
 def __init__(self, tui):
     super().__init__(tui)
     self.list = DynamicContainer(self.get_container)
     self.back_button = ConditionalContainer(
         Button("Back", handler=self.pop),
         filter=Condition(lambda: len(self.pages) > 1),
     )
     self.exit_button = Button("Exit", handler=exit_app)
     self.container = HSplit(
         [
             self.list,
             self.back_button,
             self.exit_button,
         ],
         height=Dimension(min=1),
         width=Dimension(min=1),
         key_bindings=self.get_key_bindings(),
     )
Beispiel #8
0
 def create_help(self):
     ctx = self.ctx
     dialog = Dialog(
         Label(
             dedent(
                 """
                 Tab               Switch focus between INPUT/OUTPUT/COMMAND
                 Ctrl-P            Copy OUTPUT to clipboard
                 Ctrl-O            Exit and print OUTPUT to stdout
                 Ctrl-C            Exit
                 Ctrl-T            Toggle vertical/horizontal view
                 Ctrl-L            Toggle live/manual mode
                 Ctrl-R            Run processing (when in manual mode)
                 Enter/Ctrl-M      Run processing (when in manual mode, in COMMAND)
                 F1                Toggle help
             """
             ).strip(),
             dont_extend_width=False,
             dont_extend_height=False,
         ),
         title="Help",
     )
     return ConditionalContainer(dialog, Condition(lambda: ctx.display_help))
Beispiel #9
0
    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
Beispiel #10
0
    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
Beispiel #11
0
    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)
Beispiel #12
0
    wrap_lines=False,
    # completer=completion,
    complete_while_typing=True)

placeholder_text = ("Nothing here yet:\n"
                    " - Type \"help\" to see available commands.\n"
                    " - Press \"?\" for the list of keybindings.")
entry_placeholder = Label(
    FormattedText([("class:placeholder", placeholder_text)]))

task_list = HSplit([entry_placeholder])
agenda_pane = ScrollablePane(task_list)

show_kb_help = False
bindings_help = ConditionalContainer(Box(
    Shadow(Frame(Label(""), "Key bindings:"))),
                                     filter=Condition(lambda: show_kb_help))

root_container = FloatContainer(
    content=HSplit([agenda_pane,
                    HorizontalLine(), history_field, input_field]),
    floats=[
        Float(
            xcursor=True,
            ycursor=True,
            content=CompletionsMenu(max_height=16, scroll_offset=1),
        ),
        Float(bindings_help),
    ],
)
Beispiel #13
0
    def homeLayoutFactory(self):
        content = self.studio.content

        statusBar = Frame(
            Window(BufferControl(buffer=content.getBuffer("statusBar"),
                                 focusable=False),
                   height=D(min=1, max=1, preferred=1),
                   align=WindowAlign.CENTER))

        savedModelsBox = Box(HSplit([
            Label(text="Saved Models: ", style="class:blue class:underlined"),
            Window(
                BufferControl(buffer=content.getBuffer("savedModels"),
                              focusable=False))
        ]),
                             padding=0)

        modelDefinitionsBox = Box(HSplit([
            Label(text="Model Definitions: ",
                  style="class:blue class:underlined"),
            Window(
                BufferControl(buffer=content.getBuffer("modelDefinitions"),
                              focusable=False))
        ]),
                                  padding=0)

        rightSidebar = Frame(
            HSplit([savedModelsBox,
                    HorizontalLine(), modelDefinitionsBox]))

        createModelButton = Button("[C] Create Model                 ",
                                   handler=self.studio.layouts.swapper(
                                       Layouts.CREATE))
        loadModelButton = Button("[L] Load Saved Model             ",
                                 handler=self.studio.layouts.swapper(
                                     Layouts.LOAD))
        importModelButton = Button("[I] Import Model From Definition ",
                                   handler=self.studio.layouts.swapper(
                                       Layouts.IMPORT))
        editModelButton = Button("[E] Edit Model                   ",
                                 handler=self.studio.layouts.swapper(
                                     Layouts.EDIT))
        deleteModelButton = Button("[D] Delete Model                 ",
                                   handler=self.studio.layouts.swapper(
                                       Layouts.DELETE))
        quitButton = Button("[Q] Quit                         ",
                            handler=self.studio.exit)

        editModelButton = ConditionalContainer(
            editModelButton, filter=self.studio.controller.modelExistsFilter())

        leftSidebar = HSplit([
            createModelButton,
            loadModelButton,
            importModelButton,
            editModelButton,
            deleteModelButton,
            quitButton,
        ])

        creditBar = Label(
            text="Created by Samuel Ellertson - github.com/SamuelEllertson",
            style="class:blue")

        body = VSplit([Frame(Sizeable(leftSidebar)), Sizeable(rightSidebar)])

        root = HSplit([statusBar, body, creditBar])

        return Layout(container=root, focused_element=createModelButton)
Beispiel #14
0
    'history': True,
    'diff': False,
}


@Condition
def diff_visible() -> bool:
    global WINDOW_VISIBILITY
    return WINDOW_VISIBILITY['diff']


MARGINS = [
    ScrollbarMargin(display_arrows=True),
    ConditionalMargin(MyMargin(), filter=diff_visible)
]
DIFF_CONTAINER = ConditionalContainer(DiffView(key_bindings=KD),
                                      filter=diff_visible)

HISTORY_CONTAINER = HistoryContainer(KB, ARGUMENTS, right_margins=MARGINS)


def get_container():
    width = screen_width()
    if width >= 160:
        return VSplit([HISTORY_CONTAINER, DIFF_CONTAINER])
    return HSplit([HISTORY_CONTAINER, DIFF_CONTAINER])


DYNAMIC_CONTAINER = DynamicContainer(get_container)
LAYOUT = Layout(DYNAMIC_CONTAINER, focused_element=HISTORY_CONTAINER)

Beispiel #15
0
    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
Beispiel #16
0
    def set_status(self, text: str) -> None:
        ''' Set some text to show in the status bar '''
        self.content.text = text

    def clear(self) -> None:
        ''' Clear the content of the status bar '''
        self.content.text = ''

    def create_content(self,
                       width: int,
                       height: int,
                       preview_search: bool = False) -> UIContent:
        self.content.width = width
        return self.content


STATUS = StatusBar()


@Condition
def statis_is_visible() -> bool:
    ''' Return `True` if status line is visible '''
    return bool(STATUS.content.text)


STATUS_WINDOW = ConditionalContainer(content=Window(content=STATUS,
                                                    height=1,
                                                    ignore_content_height=True,
                                                    wrap_lines=False),
                                     filter=statis_is_visible)
Beispiel #17
0
no_notes_text = Window(
    FormattedTextControl(
        HTML(
            '\n\n\nNo notes!\nCreate a new one by hitting <style color="blue"><b>Ctrl-N</b></style>'
        )),
    align=WindowAlign.CENTER,
)

main_window = VSplit([
    sidebar,
    Window(width=2, char=f"{borders.VERTICAL} ", style="class:line"),
    text_window,
])

body = HSplit([
    ConditionalContainer(main_window,
                         filter=Condition(lambda: state.current_note)),
    ConditionalContainer(no_notes_text,
                         filter=Condition(lambda: not state.current_note)),
    Window(
        content=FormattedTextControl(get_notification_text),
        height=1,
        style="class:notification",
        align=WindowAlign.CENTER,
    ),
    VSplit(
        [
            Window(
                FormattedTextControl(get_statusbar_text),
                style="class:status",
                width=11,
            ),
Beispiel #18
0
from xradios.tui.buffers.display import buffer as display_buffer
from xradios.tui.buffers.popup import buffer as popup_buffer
from xradios.tui.buffers.prompt import buffer as prompt_buffer
from xradios.tui.buffers.listview import buffer as listview_buffer

layout = Layout(
    FloatContainer(
        content=HSplit([
            TopBar(message="Need help! Press `F1`."),
            Display(display_buffer),
            ListView(listview_buffer),
            Prompt(prompt_buffer),
        ]),
        modal=True,
        floats=[
            # Help text as a float.
            Float(
                top=3,
                bottom=2,
                left=2,
                right=2,
                content=ConditionalContainer(
                    content=PopupWindow(popup_buffer, title="Help"),
                    filter=has_focus(popup_buffer),
                ),
            )
        ],
    ))

layout.focus(prompt_buffer)