| Parameters: |
|
|---|
A Root object will normally form the nucleus of your application. It performs three key roles:
A simple example of all three of these roles can be found in examples/quick_brown_fox.py:
from jcn import Root, Text
# The resulting StringWithFormatting passed to the Text element constructor
# below illustrates how we try to match up to blessings' ways of doing
# formatting.
text = Text(
Root.format.bold('The ') + 'quick ' +
Root.format.red('brown') + ' fox ' + Root.format.underline('jumps') +
Root.format.reverse(Root.format.green(' over ') + 'the lazy dog'))
root = Root(text)
root.run()
Draw the tree of UI elements once directly to the terminal. The root element of the UI is referenced by this instance’s element attribute. Layout is automatically calculated by the UI elements in the tree in reponse ultimately to the width and height attributes of this instances Terminal: instance. There is no async behaviour triggered from this method - see run() if you want to jcn to take care redrawing when required.
A reference to a single ABCUIElement instance, most likely a container element, that forms the foundation of your UI. This element will be drawn or updated whenever a request comes to this Root instance to do the same.
The main entry point of a jcn-based application. run() sets up the terminal and then runs then event loop, continually responding to user input and drawing UI element to the screen when required.
Specifically, jcn applications run the terminal full-screen and with the cursor hidden, and set sys.stdin to unbuffered and non-blocking so that we can respond immediately to any keystrokes from the user. We also correctly handle being suspended (Control-z, SIGTSTP) and resumed, and the terminal window being resized.
We run asyncio event loop inside context managers that will handle exceptions gracefully and return the terminal to the previous state before exiting. Aren’t we nice ;-)
Draws directly to the terminal any UI elements in the tree that are marked as having been updated. UI elements may have marked themselves as updated if, for example, notable attributes have been altered, or the updated element may be set to True explicitly by your program. The drawing and layout logic are exactly the same as for draw().
True if this element, or any of its children, have been updated, otherwise False.
Junction is loosely based on the blessings module, which provides easy, Pythonic access to escape squences for terminal colouring, styling and positioning. Central to blessings is its blessings.Terminal class, which is the hook for blessings‘ users to request escape sequences. Junction’s Terminal class extends blessings.Terminal to add some features requisite for handling some more ‘application level’ situations.
You could create Terminal instance manually, and use it independently or pass it to your applications Root instance if you want to override some default behaviours, but in the vast majority of cases you just need to know that this is where jcn‘s link to blessings lies, and the things this class takes care of so that you don’t have to worry about them. To gain access to terminal formatting in your application, you instead use Root.format.
Write a collection of lines to the terminal stream at the given location. The lines are written as one ‘block’ (i.e. each new line starts one line down from the previous, but each starts at the given x coordinate).
| Parameters: |
|
|---|
Context manager to set the Terminal‘s input file to read in a non-blocking way.
Normally, reading from sys.stdin blocks, which is bad if we want an interactive application that can also update information on the screen without any input from the user! Therefore, we need to make Terminal.infile.read() a non-blocking operation, which just returns nothing if we have no input.
Root.run() uses this context manager for you to make your application work in the correct way.
Context manager for setting the terminal to use unbuffered input.
Normally, your terminal will collect together a user’s input keystrokes and deliver them to you in one neat parcel when they hit the return/enter key. In a real-time interactive application we instead want to receive each keystroke as it happens.
This context manager achieves that by setting ‘cbreak’ mode on the the output tty stream. cbreak is a mode inbetween ‘cooked mode’, where all the user’s input is preprocessed, and ‘raw mode’ where none of it is. Basically, in cbreak mode input like Control-c will still interrupt (i.e. ‘break’) the process, hence the name. Wikipedia is your friend on this one!
Root.run() uses this context manager for you to make your application work in the correct way.
Explain why we have a get_terminal() - i.e. it’s like the asyncio.get_event_loop() in that it will always return us a singleton instance. (If indeed that’s something we actually care about any more?)