-
Notifications
You must be signed in to change notification settings - Fork 87
Views and layout system
In borealis, elements on screen are called "views": text, buttons, lists, tabs, layouts... Every application is made of a view tree, rooting from one "big" view all the way through the smallest ones (labels, buttons...).
Each view is either:
- a view "group" containing other views (like
BoxLayout
), making a node in the tree - a single view (like
Button
), making a leaf in the tree
We call "parent <-> child" the relation between a view and its containing view in the tree.
To write a borealis application, you start by creating every view. The recommended way to do so is to inherit the parent view class and add your stuff here.
For instance if your app uses tabs, you want to create one custom class for the TabFrame
in which you add your tabs. Each tab is going to be an instance of another custom class of yours - one for each tab. In each of those classes, you will add the components of the corresponding tab, and so on and so on until everything is defined.
Here's what a simple tab app would look like (custom class name: super class):
- MainFrame: TabFrame
- WelcomeTab: List
- list items...
- BrowserTab: BoxLayout
- box layout items...
- AboutTab: View
- custom about page layout
You are not forced to create one class per component in your app but it's the cleanest way to sort things in the code. You can create and assemble views as you want, like the example app does.
Each view should inherit the abstract View
class. All the useful methods you can reimplement and use are documented in the corresponding header.
The layout system is quite simple: every view has coordinates on screen (top-left origin), a width and a height.
The layout()
method is called every time the view is resized by its parent. It is responsible for resizing / rearranging the different components of the view (using setBoundaries
) as well as calling layout()
on the children (if any).
The point is to call layout()
as few as possible to do the calculations once and allow the draw loop to only draw.
To trigger a layout on a view, use invalidate()
. The immediate
parameter allows you to layout immediately or on next frame (prevents calling it multiple times on the same view on the same frame).
The draw()
method is called every frame on every view of the tree (even off screen). You should draw the view and its children, if any. You must call frame()
on the children to draw them (instead of draw()
directly).