UXRscGem
UXRscGem loads an interface from a .rsc file on GEM. The rest of the design
follows from one property: there is no inflation step. Until 0.7 this
class was UXRsc; UXRsc is now the loader for
every backend, GEM included, and reads layout themes and scoped connections,
which this one does not.
#use <UXKit> // or #import "UXRscGem.xc"Overview
Section titled “Overview”A GEM resource already contains an OBJECT tree, and a
UXView is backed by an OBJECT. Loading a
rsc means loading that tree and binding a view onto each entry. Nothing is
copied or rebuilt, and on GEM the AES walks the resource’s own array
directly.
Rocks (macOS) --writes--> app.rsc --load--> OBJECT[] --bind--> UXViewTreeThe resource editor is the interface builder. A dialog designed there becomes a live view hierarchy with no conversion, rather than a description that a loader reconstructs.
UXViewTree* tree = UXRscGem.load((u8*)"app.rsc", 0); // tree 0 of the fileViews are chosen by ob_type. The resource supplies the type, frame, flags
and state; your code supplies the behaviour.
Wiring by name
Section titled “Wiring by name”Loading gives you a hierarchy. Connecting it to a controller is the other half, and it needs no per-application code:
UXViewTree* tree = UXRscGem.loadWired((u8*)"app.rsc", 0, (UXDesignable*)controller);loadWired reaches your controller through
UXDesignable and connects the rsc’s
outlets and actions by name.
Your controller declares, the compiler generates
Section titled “Your controller declares, the compiler generates”class MainController : Object{ outlet UXLabel* statusLabel; outlet UXView* canvas;
void onSave(UXControl* sender) :action { … } void onQuit(UXControl* sender) :action { … }}Declaring any outlet field or :action method auto-conforms the class to
UXDesignable, and the compiler generates both method bodies from the
decorations:
setOutlet(name, value): a checked assignment per outlet, returning false on an unknown name or a type mismatchwireAction(name, control):control.setAction(&self.<method>)per action
There is no reflection beyond what the decorations declare, and the compiler checks every connection. An rsc file naming an outlet your controller does not have fails at load with a false return, instead of leaving a null field that crashes later.
Topics
Section titled “Topics”load · loadWired · loadWiredMem · loadDoc · viewForType · classOverride
static UXViewTree* load(u8* path, i32 treeIndex)Loads one tree from a .rsc file and binds views onto it. A resource holds
several trees (a dialog, a menu, an about box), addressed by index.
loadWired
Section titled “loadWired”static UXViewTree* loadWired(u8* path, i32 treeIndex, UXDesignable* owner)load, then connect outlets and actions on owner by name.
loadWiredMem
Section titled “loadWiredMem”static UXViewTree* loadWiredMem(u8* data, i32 len, i32 treeIndex, UXDesignable* owner)The same from bytes already in memory: a resource compiled into the binary, or fetched rather than read from disk.
loadDoc
Section titled “loadDoc”static UXViewTree* loadDoc(pointer doc, i32 treeIndex, UXDesignable* owner)From an already-parsed document, when you load several trees out of one file and do not want to re-read it per tree.
viewForType
Section titled “viewForType”static UXView* viewForType(u16 gtype)The type-to-view mapping: G_BUTTON becomes a
UXButton, and every other type a plain
UXView that the AES draws from the resource.
Classes named by the document are made through
UXRsc.make.
classOverride
Section titled “classOverride”static u8* classOverride(pointer doc, i32 ncl, i32 tree, i32 obj)The class name a resource records for a particular object, when it wants
something other than the default for that type. This is the stored form of
“this button is a FancyButton”.
Two things to know before you rely on it
Section titled “Two things to know before you rely on it”The resource owns the layout; you own the behaviour. Frames, flags and initial state come from the file, so moving a control is an edit in the editor instead of a recompile. Anything you set in code after load is overwritten on the next load, because the file is the source of truth for those fields.
A tree index is positional. Trees are addressed by number, not name, because
.rsc does not store tree names. If you delete a tree in the editor, every index
after it shifts. Rocks renumbers the links it owns, but you must keep any index
hard-coded in your source correct.
See also
Section titled “See also”-
UXRsc: the loader for every backend -
UXDesignable: the two generated methods, and theoutlet/:actiondecorations -
UXRscV2: the newer format, with variants per form factor -
UXViewTree: what a load produces -
UXView:adoptObject, the binding step