This module depends on the event_loop
module, so it must only be imported after event_loop
is imported.
It is highly recommended to familiarize yourself with the event loop first before doing GUI-related things.
The canvas is just a drawing area with no abstractions over it. Drawing on the canvas directly (i.e. not through a viewport) is useful in case you want to implement a custom design element, but this is rather uncommon.
A viewport is a window into a rectangular portion of the canvas. Applications always access the canvas through a viewport.
In Flipper's terminology, a "View" is a fullscreen design element that assumes control over the entire viewport and all input events. Different types of views are available (not all of which are unfortunately currently implemented in JS):
View | Has JS adapter? |
---|---|
button_menu | ❌ |
button_panel | ❌ |
byte_input | ❌ |
dialog_ex | ✅ (as dialog ) |
empty_screen | ✅ |
file_browser | ❌ |
loading | ✅ |
menu | ❌ |
number_input | ❌ |
popup | ❌ |
submenu | ✅ |
text_box | ✅ |
text_input | ✅ |
variable_item_list | ❌ |
widget | ❌ |
In JS, each view has its own set of properties (or just "props"). The programmer can manipulate these properties in two ways:
View
using the makeWith(props)
method, passing an object with the initial propertiesset(name, value)
to modify a property of an existing View
The view dispatcher holds references to all the views that an application needs and switches between them as the application makes requests to do so.
The scene manager is an optional add-on to the view dispatcher that makes managing applications with complex navigation flows easier. It is currently inaccessible from JS.
In total, there are three different approaches that you may take when writing a GUI application:
Approach | Use cases | Available from JS |
---|---|---|
ViewPort only | Accessing the graphics API directly, without any of the nice UI abstractions | ❌ |
ViewDispatcher | Common UI elements that fit with the overall look of the system | ✅ |
SceneManager | Additional navigation flow management for complex applications | ❌ |
An example with three different views using the ViewDispatcher approach:
viewDispatcher
The viewDispatcher
constant holds the ViewDispatcher
singleton.
viewDispatcher.switchTo(view)
Switches to a view, giving it control over the display and input
view
: the View
to switch toviewDispatcher.sendTo(direction)
Sends the viewport that the dispatcher manages to the front of the stackup (effectively making it visible), or to the back (effectively making it invisible)
direction
: either "front"
or "back"
viewDispatcher.sendCustom(event)
Sends a custom number to the custom
event handler
event
: number to sendviewDispatcher.custom
An event loop Contract
object that identifies the custom event source, triggered by ViewDispatcher.sendCustom(event)
viewDispatcher.navigation
An event loop Contract
object that identifies the navigation event source, triggered when the back key is pressed
ViewFactory
When you import a module implementing a view, a ViewFactory
is instantiated. For example, in the example above, loadingView
, submenuView
and emptyView
are view factories.
ViewFactory.make()
Creates an instance of a View
ViewFactory.make(props)
Creates an instance of a View
and assigns initial properties from props
props
: simple key-value object, e.g. { header: "Header" }