The resources and styles for a skin are usually defined using JSON (or a format that is {@link OutputType#minimal JSON-like}), which is formatted in this way:
{ resources: { className: { name: value, ... }, ... }, styles: { className: { name: value, ... }, ... } }There are two sections, one named "resources" and the other "styles". Each section has a class name, which has a number of names and values. The name is the name of the resource or style for that class, and the value is the serialized resource or style. Here is a real example:
{ resources: { com.badlogic.gdx.graphics.g2d.TextureRegion: { check-on: { x: 13, y: 77, width: 14, height: 14 }, check-off: { x: 2, y: 97, width: 14, height: 14 } }, com.badlogic.gdx.graphics.Color: { white: { r: 1, g: 1, b: 1, a: 1 } }, com.badlogic.gdx.graphics.g2d.BitmapFont: { default-font: { file: default.fnt } } }, styles: { com.badlogic.gdx.scenes.scene2d.ui.CheckBox$CheckBoxStyle: { default: { checkboxOn: check-on, checkboxOff: check-off, font: default-font, fontColor: white } } } }Here some named resource are defined: texture regions, a color, and a bitmap font. Also, a {@link CheckBoxStyle} is definednamed "default" and it references the resources by name.
Styles and resources are retrieved from the skin using the type and name:
Color highlight = skin.getResource("highlight", Color.class); TextureRegion someRegion = skin.getResource("logo", TextureRegion.class); CheckBoxStyle checkBoxStyle = skin.getStyle("bigCheckbox", CheckBoxStyle.class); CheckBox checkBox = new CheckBox("Check me!", checkBoxStyle);For convenience, most widget constructors will accept a skin and look up the necessary style using the name "default".
The JSON required for a style is simply a JSON object with field names that match the Java field names. The JSON object's field values can be an object to define a new Java object, or a string to reference a named resource of the expected type. Eg, {@link LabelStyle} has two fields, font and fontColor, so the JSON could look like:
someLabel: { font: small, fontColor: { r: 1, g: 0, b: 0, a: 1 } }When this is parsed, the "font" field is a BitmapFont and the string "small" is found, so a BitmapFont resource named "small" is used. The "fontColor" field is a Color and a JSON object is found, so a new Color is created and the JSON object is used to populate its fields.
The order resources are defined is important. Resources may reference previously defined resources. This is how a BitmapFont can find a TextureRegion resource (see BitmapFont section below).
The following gives examples for the types of resources that are supported by default:
{@link Color}:
{ r: 1, g: 1, b: 1, a: 1 }{@link TextureRegion}:
{ x: 13, y: 77, width: 14, height: 14 }{@link NinePatch}:
[ { x: 2, y: 55, width: 5, height: 5 }, { x: 7, y: 55, width: 2, height: 5 }, { x: 9, y: 55, width: 5, height: 5 }, { x: 2, y: 60, width: 5, height: 11 }, { x: 7, y: 60, width: 2, height: 11 }, { x: 9, y: 60, width: 5, height: 11 }, { x: 2, y: 71, width: 5, height: 4 }, { x: 7, y: 71, width: 2, height: 4 }, { x: 9, y: 71, width: 5, height: 4 } ]{@link NinePatch} can also be specified as a single region, which is set as the center of the ninepatch:
[ { width: 20, height: 20, x: 6, y: 2 } ]This notation is useful to use a single region as a ninepatch. Eg, when creating a button made up of a single image for the {@link ButtonStyle#up} field, which is a ninepatch.
{@link BitmapFont}:
{ file: default.fnt }First the skin tries to find the font file in the directory containing the skin file. If not found there, it uses the specified path as an {@link FileType#Internal} path. The bitmap font will use a texture region with the same name as the font filewithout the file extension. If no texture region with that name is defined in the skin (note the order resources are defined is important), it will look in the same directory as the font file for a PNG with the same name as the font file but with a "png" file extension.
TintedNinePatch provides a mechanism for tinting an existing NinePatch:
{ name: whiteButton, color: blue }This would create a new NinePatch identical to the NinePatch named "whiteButton" and tint it with the color named "blue".
The skin JSON is extensible. Styles and resources for your own widgets may be included in the skin, usually without writing any code. Deserialization is handled by the {@link Json} class, which automatically serializes and deserializes most objects. Whilenearly any style object can be automatically deserialized, often resource objects require custom deserialization. Eg, TextureRegion, BitmapFont, and NinePatch need to reference the skin's single texture. If needed, {@link #getJsonLoader(FileHandle)} may be overridden to register additional custom {@link Serializer serializers}. See the source for {@link Skin#getJsonLoader(FileHandle)} for examples on how to write serializers.
Note that there is a SkinPacker class in the gdx-tools project that can take a directory of individual images, pack them into a single texture, and write the proper texture region and ninepatch entries to a skin JSON file. The styles and other resources sections still need to be written by hand, but SkinPacker makes the otherwise tedious entry of pixel coordinates unnecessary. @author Nathan Sweet
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|