Skip to content
Pawel Pastuszak edited this page Dec 7, 2018 · 38 revisions

USL (UI Styling Language) is an alternative to writing JSON skins for scene2d.ui

USL syntax is very similar to JSON but it allows extending and inheriting other styles which results in cleaner and more readable skin file. Take a look at VisUI style written in USL, now look at the same skin in JSON.

USL is available in Maven Central:

compile 'com.kotcrab.vis:vis-usl:0.2.1'

Note that this is beta version, please report any issues you found.
Alternatively: Jar, Snapshots

USL files are converted to JSON by vis-usl.jar or by USL class when using from code. Jar usage: java -jar vis-usl-x.y.z.jar <input usl file path> <output json file path>

Examples
GDX default skin
VisUI skin

Language Reference

Comments

Line comments stars with // e.g. //this is a comment.

Including Other Files

Include directive allows to include other USL files. The path is relative to parsed file. USL also comes with premade skins that can be included from any file. Including premade skin allows to easily expand it, add new styles and so on.

Examples:

//including other usl files
include "other.usl"
include "dir/other2.usl"

//including built-in usl skins
include <gdx> 
include <visui-1.2.3>

If you want to use version from older VisUI just specify it in include for example: include <visui-0.7.7>. You can use all VisUI releases version starting from 0.7.7.

Style Blocks

Style blocks contains styles definition for single class in your code. Style blocks starts with #. The syntax is very similar to JSON.

#com.foo.bar.Button$ButtonStyle: {
	//... styles definition
}

Style blocks cannot be nested but they can extend other blocks, specifying full name with package is not required if you are sure that they won't be multiple style blocks with that name (USL will warn you in such situation):

#com.foo.bar.TextButton$TextButtonStyle extends ButtonStyle: {
	//... styles definition
}

Extending other block will merge all its other styles into this style block. If you add new style with the same name as in parent block then all properties from super style will by copied into new style. For example:

#Button$ButtonStyle: {
	default: { down: default-round-down, up: default-round }
}

#TextButton$TextButtonStyle extends ButtonStyle: {
	default: { font: default-font, fontColor: white } // `down` and `up` property will be inherited from parent block
}

Extending style blocks typically follow the same hierarchy as Java classes that they are representing. You can prefix the style name with ~ eg. TextButtonStyle extends ~ButtonStyle this means that only styled defined in TextButtonStyle will be inherited from ButtonStyle. For example:

#Button$ButtonStyle: {
	default: { ... }
	blue: { ... }
}

#TextButton$TextButtonStyle extends ButtonStyle: {
	default: { ... } // only `default` style will be in final json
}

Packages

Multiple styles block can be put into single package to avoid writing long names for every style block. Packages cannot be nested.

package com.foo.bar {
	#Button$ButtonStyle: {
		//... styles definition
	}
}

//is equivalent to writing:

#com.foo.bar.Button$ButtonStyle: {
	//... styles definition
}

Styles

Styles are defined inside style blocks (except global styles, see below).

#Button$ButtonStyle: {
	default: { down: default-round-down, up: default-round }
	toggle inherits default: { checked: default-round-down }
}

Internal styles can inherits form each other, the toggle style will have all properties of default.

Style can be defined as meta-style. Meta-style can be inherited by other styles but the meta-style itself won't be included in output file. Meta-styles starts with -

#Slider$SliderStyle: {
	-base: { knob: slider-knob, disabledKnob: slider-knob-disabled }
	default-horizontal inherits base: { background: slider }
	default-vertical inherits base: { background: slider-vertical }
}

Global Styles

Global styles can be inherited by any other style or identifier. Global styles always starts with . and should be placed in the top part of USL file. For example:

.font: { font: default-font, fontColor: white, disabledFontColor: grey }
.focus-border: { focusBorder: border }
.focus-border-circle: { focusBorder: border-circle }

Later you can inherit those styles, all properties from global styles will be placed inside style that inherits it:

#TextField$TextFieldStyle: {
	default inherits .font: { selection: selection, background: textfield, cursor: cursor }
}

Global style can be also inherited by nested identifiers:

#tabbedpane.TabbedPane$TabbedPaneStyle: {
	default: { background: menu-bg, bottomBar: list-selection,
	       	   buttonStyle inherits .font: { down: button-down, up: button, checked: button-down, over: button-over } }
}

Overriding Style Blocks

Block overriding is useful when extending premade skin such as default libGDX skin or VisUI skin. Block override section starts with ^ and it doesn't have to specify full block name.

For example:

include <visui-1.1.0>

^VisTextButtonStyle: {
	custom inherits default: { over: button-over }
	custom2 { up: button-up, down: button-down }
}

custom and custom2 will be merged into VisTextButtonStyle style block. New styles can also extend super-styles (custom inherits default). If you use a name that is already defined in block that you override then USL will print a warning during files converting.