There is a singleton instance of GuiGlobals that you must initialize in order to use Loris. Once initialized, this instance can be referenced by the class method GuiGlobals.getInstance(). The assumption is that you are doing this setup in .simpleInitApp(). In order to leverage any of the XML based processing supported by Loris, you must inform jMonkey about XMLLoader. You need to register it before doing anything else in Loris.
assetManager.registerLoader( com.jme3.export.xml.XMLLoader.class, "xml" );
All of Loris operates with an active GuiContext. The context manages the visuals wired into the jMonkey scene. There can be multiple GuiContexts defined, but only one of which is active at a given time. Switching contexts is like switching windows. Multiple contexts are not required, you can create and operate off a single one. But assuming that you want multiples, and that they are defined within an XML configuration file, you will do the following:
GuiContext aTemplate = new GuiContext( this.getGuiViewPort(), this.guiNode, true, true );
GuiGlobals theGui = GuiGlobals.initialize( this, "myconfigfile.xml", aTemplate );
In this case, the template will be cloned for every context defined within the XML config file. It is the template that knows how to connect into jMonkey. You can reference the active context at any time via the class method GuiGlobals.getContext(). The context has a single Loris element which is the root of the visual hierarchy of Loris controls.
If you are configuring your various GuiContexts via XML, you can locate the context via its name after initialization. Use:
GuiContext aContext = GuiGlobals.getInstance().getContext( "MyContextName" );
to find your context. You can then wire up a GuiContextListener whose methods will be called as the context is made active. The listener is a good place to establish initial values and connect the context back into your Model data values. You can make your context the active context via:
GuiGlobals.getInstance().setActiveContext( aContext );
As a context becomes active for the first time, styling will be applied to the entire hierarchy. In this way, the full parent/child relationship of every control is known and appropriate styling selectors will be applied.
The GuiContext contains a tree of Loris controls, each of which is an instance of the interface Viewable. Controls that respond to user changes (rather than act as simple displays) are instances of Interactable, which extends Viewable. Currently, all Viewables are implemented by ViewElement and its subclasses. A ViewElement is a subtype of jMonkey Node.
A simple Viewable is represented by a layered set of visual Components. It is these components, sharing a common position and related size, that the end user actually sees. The Container type of Viewable also supports a set of child Viewables, organized visually by a Layout.
Every context knows how to locate a Viewable by its given jme name and control type. To locate a button:
Button aButton = aContext.findByName( "MyButton", Button.class );
if ( aButton != null ) {
// Do something to the button, maybe wire up an action
....
}
The interface Actionable defines a callback mechanism used by your application to notice changes in data. The Actionable can be a simple trigger caused by a button being pressed, or it can include an actual data value reflecting an end user change. Actionables can be wired up by locating the appropriate Interactable and providing the callback.
A mechanism you can use for associating actions with your XML configured controls is to define a string action code on any given control directly within the XML. This will often be a Button, but can be any interactive control. Within the context, you will map the code to a callback handler:
aContext.registerActionable( new Actionable() {
@Override
public String getActionCode() { return "doSomeAction"; }
@Override
public void takeAction( Interactable pControl, String pActionCode, Object pDataValue ) {
System.out.println( "Action[" + pActionCode + "] on " + pControl );
}
} );
While the main design thrust of Loris has been for XML based configurations, it is still possible to create controls directly from Java code. These controls are created using the constructor that follows the pattern:
Button aButton = new Button( false // to suppress immediate styling
, "font", "Interface/Fonts/Default.fnt"
, "fontSize", 18f
, "text", "Push Me"
);
This pattern starts with a boolean that controls immediate styling (typically false) which is followed by a set of name:value pairs. The name must be styling attribute supported by the target control, and the value must be of a type matching what the name expects. Styling is typically applied to the context as whole when the context is first made active. But if you are adding an element into a context that has already been styled, you can trigger immediate styling here.