jMonkey LorisGUI - Styles

CSS-like styling to control the visual appearance

Home Overview Visuals XML Style Model Controls Components Layouts
 

Selectors

Loris can apply visual attributes to its various elements via its CSS-like styling mechanism. Every GUI control has an inherent ElementID, based on the type of control (i.e. a Button) or on an explicitly assigned ID. The 'dot' combined ElementIDs of a hierarchy of controls form a selector which maps to a set of visual attributes.

So a Button within a Panel within a Tab within a Screen has the fully qualified selector of "Screen.Tab.Panel.Button". The key design concept is that partial matches are supported. In this case, any button anywhere will match the simple selector "Button". The selector "Panel.Button" is a more restrictive match, and attributes associated with this selector will override any defined with "Button". The selector "Tab.Panel.Button" is even more restrictive, and overrides anything from the other two.

You can also have gaps. So the selector "Tab.Button" can provide its own set of customizations. The deeper matches have higher priority than shallower matches and those attributes will apply. So you could define a basic appearance at the Button level, but then customize the border for Buttons within any Panel, and further customize font size for Buttons within a Tab.

jMonkey provides for unique item names assigned to individual items. Any such name is blended into the selector using a '#' rather than a '.', so a button whose name is 'quit' has the core selector of "Button#quit", which is then blended into the fully qualified, hierarchical selector. You can assign attributes to selectors that include this unique name. For example, using a bold font for the quit button.

The Loris controls have an inherent ElementID, typically matching the Java class name that supports the control. You can always provide your own custom ElementID, effectively defining a new grouping based on this custom selector. For example, you may want to define a set of buttons whose appearance is controlled strictly by a background image, with no text. You still construct an instance of a Java Button, but assign it the ElementID of Image. The inherent selector of "Button", and the custom selector of "Image" share no attributes.

But there is also the case where you want a minor variant of a Button that share many of the attributes of the core Button, but with a few minor twists. In that case, you do not use a custom ElementID, but rather use a elementSubID. A subID uses a '+' separator rather than a '.' and the original core id is retained. So if you instantiate a Button, and assign it a subID of "PushButton", then the "Button+PushButton" selector matches, as well as the original "Button" selector.

 

Attributes

Each attribute is a name:value pair assigned to a given selector. Supported attribute names are determined by the underlying Java control class, and its value must match the type expected by the Java code. Many attribute values are taken from a simple string, and then interpreted based on what is expected. So the attribute fontSize had better be an integer value.

Complex attributes can be defined via a Savable. In this case, the name still matches the attribute name, but the value is decoded from the XML and an object is instantiated. Loris has defined a comprehensive set of class name abbreviations that match the various attribute names. So if you are defining the attribute background, the system knows to instantiate
net.wcomohundro.jme3.loris.component.BackgroundComponent
without you having to type in the full Java class name. The complete XML import mechanism is then available to configure the various settings within a BackgroundComponent.

 

Style Sheets

A style sheet is a related set of selectors with their associated attributes. You can define any number of different sheets, and declare one as the default. Every control can explicitly call out by name to use a specific sheet, or it can say nothing and use the default.

XML is used to define the style sheets. Selectors match on id= and attributes either have a string specified by value= or are a Savable of a given class (where the attribute name textColor is an abbreviation for the jme class ColorRGBA).

An example looks something like (sample from test harness):

<?xml version='1.0' encoding='UTF-8'?>
<globals>
    <styles defaultStyle='TestSheet'>
        <styleSheet styleID='TestSheet'>
            <!-- A selector without an id defines generic values used when nothing else applies -->
            <selector>
                <attributes>
                    <font value='Interface/Fonts/Default.fnt' />
                    <textColor r='0.5' g='0.5' b='0.5' a='1.0' />
                </attributes>
            </selector>
            
            <!-- This selector applies to Buttons, and changes the text color -->
            <selector id='Button'>
                <attributes>
                    <textColor r='0.85' g='0.2' b='0.2' a='1.0' />
                </attributes>
            </selector>
            
            <!-- This selector applies only to the Quit button -->
            <selector id='Button#quit'>
                <attributes>
                    <fontSize value='24' />
                </attributes>
            </selector>
            
            <!-- This selector applies to any button with the subID of PushButton -->
            <selector id='Button+PushButton'>
                <attributes>
                    <font value='Interface/Fonts/Consol.fnt' />
                </attributes>
            </selector>

            <!-- This selector applies to any button within a Tab -->
            <selector id='Tab.Button'>
                <attributes>
                    <font value='Interface/Fonts/Serif.fnt' />
                    <fontSize value='14' />
                </attributes>
            </selector>
            <!-- This is an alternate to the above with the same result -->
            <selector id='Tab'>
                <selector id='Button'>
                    <attributes>
                        <font value='Interface/Fonts/Serif.fnt' />
                        <fontSize value='14' />
                    </attributes>
                </selector>
             </selector>
        </styleSheet>
    </styles>
</globals>
    	

A style can also be created as an extension of another style. Once a style has been define, another style can be seeded with all the selectors/attributes of the first, and then blend in its own definitions and overrides.
You can also choose to modify an existing sheet, rather than creating a new one. This is typically used to break a complex sheet into multiple, smaller .xml files which are imported to form a single definition. For example:

<?xml version='1.0' encoding='UTF-8'?>
<globals>
    <styles defaultStyle='TestSheet'>
        <import name='Styles/SomeOtherSheet.xml'/>
        <import name='Styles/YetAnotherSheet.xml'/>

        <styleSheet styleID='TestSheet' extendID='SomeOtherSheet'>
            <!-- Clone the definitions in SomeOtherSheet to form the basis of TestSheet -->
            <selector id='Button'>
                <attributes>
                    <textColor r='0.5' g='0.5' b='0.5' a='1.0' />
                </attributes>
            </selector>
        </styleSheet>
        
        <styleSheet modifyID='YetAnotherSheet'>
            <!-- These definitions are added to YetAnotherSheet -->
            <selector id='Button'>
                <attributes>
                    <fontSize value='14' />
                </attributes>
            </selector>
        </styleSheet>
    </styles>
</globals>
        
 

Predefined Styles

The Loris distribution .jars include some sample style sheets to get you started. They define borders, backgrounds, and insets to construct a reasonable looking set of controls you can experiment with. This includes dynamic state processing so the user can see what interactions are taking place.

SimpleBox
The file Styles/SimpleBox.xml includes a very simple style based on colored, rectangular backgrounds and borders, with a minimal use of images. It is mainly designed to give you a jumping off point for creating your own style.
NiftyBlack
The file Styles/NiftyBlack.xml and its subdirectory Styles/NiftyBlack/*.xml defines a style resembling the sample Nifty style of "black". It utilizes many of the Nifty provided images for backgrounds, buttons, tabs, etc, and tries to match the basic colors. This style should help anyone migrating from Nifty to Loris achieve a 'look' they are already familiar with.
...futures...
It is my hope that other, more artistically gifted users will create more styles and make them available to all Loris users.

You can utilize these predefined styles by the following (sample from test harness):

<?xml version='1.0' encoding='UTF-8'?>
<globals>
    <styles defaultStyle='NiftyBlack'>
        <import name='Styles/NiftyBlack.xml'/>
        <import name='Styles/SimpleBox.xml'/>
    </styles>
    <!--   your control configuration goes here   -->
</globals>