Evenly spaced columns using prompt-toolkit full-screen application, regardless of content width

721 views Asked by At

Using prompt_toolkit, I'd like to create an evenly-spaced vertical layout, regardless of width of content in each window (full-screen app). Undesired behavior - when changing content in one [or more] controls, layout is recalculated to accommodate for wider or narrower dynamic content.

Is there a way to make layout static for a given screen size; namely, only render windows on initialization or resize, keeping layout columns evenly spaced?

Example code below (press c to inject random-length content on either columns, layout width changes). Even adding a user message may cause un-even width initialization on a narrow enough terminal..

from random import randint

from prompt_toolkit.application import Application
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.layout.containers import VSplit, Window
from prompt_toolkit.layout.controls import FormattedTextControl
from prompt_toolkit.layout.layout import Layout

user_msg = "press 'c' to change, 'q' to quit"

body = VSplit(
    [
        Window(FormattedTextControl(text=user_msg)),
        Window(width=1, char="|"),
        Window(FormattedTextControl()),
    ]
)

kb = KeyBindings()


@kb.add("c")
def change_content(event):
    for w in event.app.layout.find_all_windows():
        prev_width = f"prev_width: {w.render_info.window_width}"
        rand_str = "*" * randint(1, 50)
        w.content.text = "\n".join([prev_width, rand_str])


@kb.add("q")
def quit(event):
    event.app.exit()


layout = Layout(body)
app = Application(layout=layout, key_bindings=kb, full_screen=True)
app.run()
1

There are 1 answers

0
Mann Jani On

Passing the argument ignore_content_width works.

body = VSplit(
    [
        Window(FormattedTextControl(text=user_msg), ignore_content_width=True),
        Window(width=1, char="|"),
        Window(FormattedTextControl(), ignore_content_width=True),
    ]
)