|
Aurore
A Switch-like interface for your app, on every screen
|
From nothing to a screen of your own on the Switch: build the demo, describe a screen in XML, add a view of your own, restyle it with a theme, and ship it as a .nro. The API reference is built from the headers (doxygen docs/Doxyfile, then build_docs/html/index.html).
On Linux (Debian, Ubuntu), the packages first:
Then:
The arrows move the focus, Enter is A, Escape is B, X, Y, L and R are themselves (the other keys), the mouse and a controller work too. -DAURORE_LIBROMFS=ON builds the resources/ folder into the program; without it, the folder is copied next to it. Press F12: that is the inspector, showing the views on screen, the focus and what a frame costs. Press it twice more to close it.
The demo's code is in demo/, its screens in resources/xml/: they are the examples for what follows.
Add Aurore to your project as a submodule, and its resources next to yours:
Aurore's template/ folder (see its README.md) is such an app, with the CMakeLists.txt for the desktop and the Switch (platforms.md has the other platforms'). The program itself starts the app, pushes a first screen and runs the loop:
A screen is an activity. Its content can come from an XML file in resources/xml/:
Every XML tag is a view (aurore:Box, aurore:Label, aurore:Button, aurore:Image, aurore:ScrollingFrame, aurore:TabFrame…); its attributes are the yoga layout (width, height, grow, margin, padding, gap, axis, alignItems…) and the view's own (text, fontSize, backgroundColor, cornerRadius…). @i18n/… reads a translation, @theme/… a theme colour, @style/… a metric, @res/… a resource. AURORE_BIND finds a view by its id the first time it is used. A second screen is pushed with aurore::Application::pushActivity(new OtherActivity()), and B takes it off.
While you work on the XML, start the app with AURORE_HOT_RELOAD=$PWD/resources ./build/my_app: each save builds the screen again, the focus where it was (hot reload).
A view of your own is a Box that fills itself from its own XML, and is registered under a tag name:
Register it before the first screen that uses it, aurore::Application::registerXMLView("ScoreCard", ScoreCard::create);, and it can be written in any XML: <ScoreCard id="p1" player="Ada" />. Override draw() for a view that draws itself with nanovg (demo/src/view/ has both kinds), and onFocusGained(), registerAction() or gesture recognizers to react.
Slow work (a file, the network) runs on the task thread with aurore::async, and its result comes back to the UI thread with aurore::sync; views are only touched there. The view may be gone by then: capture its aliveToken() and check it first.
ASYNC_RETAIN, ASYNC_TOKEN and ASYNC_RELEASE (from borealis) still work and do the same; they are kept for older code.
Colours and metrics come from the theme (light or dark, following the system) and can be changed without rebuilding, from a file:
An app adds its own values with aurore::Theme::getDarkTheme().addColor("my_app/score", nvgRGB(…)) and aurore::getStyle().addMetric(…), and its XML reads them with @theme/my_app/score. With hot reload on, a save of the theme file restyles the screen at once. Aurore draws everything in Cadran's look by default; aurore::Application::setCadran(false) before init() keeps borealis' own.
Install devkitPro with the switch-dev group and the portlibs Aurore uses (switch-glfw, switch-mesa, switch-glm; or nothing more with deko3d), then:
The .nro holds the program, its icon and its resources (built in with romfs). Copy it to /switch/ on the SD card and start it from the Homebrew Menu, or send it to a console running the menu with nxlink -s build_switch/aurore_demo.nro (the app's logs come back to the terminal). Without -DAURORE_GRAPHICS=DEKO3D it builds the OpenGL driver instead. The inspector works there too, with L3 + R3.
The same project builds for Windows, macOS, PS4, PS Vita, Android, iOS and a browser: platforms.md has their toolchains and commands, porting.md what an app should mind on each.