The rendering flow¶
Understanding the rendering flow is important for understanding how
Container and
UIControl objects interact. We will demonstrate
it by explaining the flow around a
BufferControl.
Note
A BufferControl is a
UIControl for displaying the content of a
Buffer. A buffer is the object that holds
any editable region of text. Like all controls, it has to be wrapped into a
Window.
Let’s take the following code:
from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.layout.containers import Window
from prompt_toolkit.layout.controls import BufferControl
from prompt_toolkit.buffer import Buffer
b = Buffer(name=DEFAULT_BUFFER)
Window(content=BufferControl(buffer=b))
What happens when a Renderer objects wants a
Container to be rendered on a certain
Screen?
The visualization happens in several steps:
The
Renderercalls thewrite_to_screen()method of aContainer. This is a request to paint the layout in a rectangle of a certain size.The
Windowobject then requests theUIControlto create aUIContentinstance (by callingcreate_content()). The user control receives the dimensions of the window, but can still decide to create more or less content.Inside the
create_content()method ofUIControl, there are several steps:First, the buffer’s text is passed to the
lex_document()method of aLexer. This returns a function which for a given line number, returns a “formatted text list” for that line (that’s a list of(style_string, text)tuples).This list is passed through a list of
Processorobjects. Each processor can do a transformation for each line. (For instance, they can insert or replace some text, highlight the selection or search string, etc…)The
UIControlreturns aUIContentinstance which generates such a token lists for each lines.
The Window receives the
UIContent and then:
It calculates the horizontal and vertical scrolling, if applicable (if the content would take more space than what is available).
The content is copied to the correct absolute position
Screen, as requested by theRenderer. While doing this, theWindowcan possible wrap the lines, if line wrapping was configured.
Note that this process is lazy: if a certain line is not displayed in the
Window, then it is not requested
from the UIContent. And from there, the line is
not passed through the processors or even asked from the
Lexer.