UI Skins - Grisgram/gml-raptor GitHub Wiki
A set of sprites that define the look of all UI Elements throughout your game. You define the buttons, checkboxes, radiobuttons, window frames, etc...
Important
In raptor
, everything is skinnable! As long as you have _raptorBase somewhere in the inheritance chain of your object, you can skin it.
Even though this chapter is named UI Skins and down this page I will refer to controls mostly, keep in mind, that you can skin anything, that is a _raptorBase.
This includes your player object, enemies, weapons, furniture... it's up to you.
The skins are one of the most powerful features, raptor
has to offer!
When raptor
applies a skin to an object, it takes care of different sprite sizes and scalings and will scale the new sprite to the exact same size, the former sprite had. It also takes the sprite_xoffset/yoffset
into account, so even if they differ, the object will appear at the exact same position, after the skin is applied!
You literally throw "anything" on "any object"... raptor
will do its best, to make it look good.
To exclude an object from being skinnable, _raptorBase has a bool variable definition skinnable
, where you can turn off skinning for specific instances or entire object types. By default, skinnable
is true for all objects.
Because this is the most easy way to create a flavored look for the elements of your game.
If you set up multiple skins for your game, you may switch between them at will. As an example, imagine your game plays partially in the "underworld" and on the "surface" of the world. While in the underworld, the UI could look darker, demonic, with fire elements and on the surface it could have a friendly, clean look. Just switch the skin when you switch between surface and underworld, and an effect like this is only an effort of a single line of code!
Use skins, create a SPOT (Single Point of Truth), also called SSOT
(Single Source of Truth) for your UI appearance!
One instance of this class is created at game startup for you. You can reach it through the global UI_SKINS
macro.
It is used to manage all known skins and offers methods to switch, add, remove or get a skin reference.
/// @function add_skin(_skin, _activate_now = false)
/// @description Add a skin to the manager. If a skin with the same name already exists,
/// it is overwritten.
static add_skin = function(_skin, _activate_now = false) {
/// @function activate_skin(_skin_name)
/// @description Activate a registered skin. Does NOT requires room_restart, works instant!
static activate_skin = function(_skin_name) {
/// @function remove_skin(_skin_name)
/// @description Delete a registered skin from the manager.
static remove_skin = function(_skin_name) {
/// @function get_skin(_skin_name)
/// @description Access a registered skin through its name.
static get_skin = function(_skin_name) {
Similar to the THEME
macro, there is a SKIN
macro available, which points to the instance of the active skin.
As you can see in the DefaultSkin
class, you received with the project template in the _gml_raptor_ui_/skins
folder, this is a simple, straightforward class, which just holds a ds_map, that assigns a struct
to each control type.
Tip
Read it again: You assign a struct
, not just a sprite asset! This means, you can change anything in an object when you skin it!
You can even add/override methods in the object, raptor handles this and binds them through method(...)
to the object.
Change defaults, colors, animation times, methods, ... change anything in a skin!
Tip
As skins are just code classes, you can inherit them. If you use this clever, together with the inherit_skin
function of the UiSkin
class shown below, you can create css-like stylings for your game's assets!
This is the only function you will need for clever merging of skin parts:
/// @function inherit_skin(_skin_name)
/// @description Copy all values of the specified skin to the current skin
The most easy thinkable way of a skin is, to only change the sprite_index of an object, and maybe here and there change one or two other variable definitions.
It would look like this:
function MyBasicSkin() : UiSkin("basic") constructor {
asset_skin[? "CheckBox"] = { sprite_index: sprMyCoolCheckBox }
asset_skin[? "InputBox"] = { sprite_index: sprMyEvenCoolerInputBox }
asset_skin[? "Label"] = { sprite_index: sprBestOfAllLabels }
asset_skin[? "MouseCursor"] = {
sprite_index: sprDefaultMouseCursor,
mouse_cursor_sprite: sprDefaultMouseCursor,
mouse_cursor_sprite_sizing: sprDefaultMouseCursorSizing
}
asset_skin[? "Window"] = { sprite_index: sprFancyWindowFrame }
}
As mentioned above, you assign a struct
to a map entry, when you create a skin.
Here are some parts of the DefaultSkin
and WoodSkin
classes, that show you, how can create skins with little effort, by defining template structs or even small methods, that return a detail struct for the skinned elements:
function DefaultSkin() : UiSkin("default") constructor {
// First, define a template, you can use multiple times
var text_control = function(spr) {
return {
sprite_index: spr,
text_color: APP_THEME_MAIN,
text_color_mouse_over: APP_THEME_MAIN,
draw_color: APP_THEME_WHITE,
draw_color_mouse_over: APP_THEME_WHITE,
};
}
// ...you can use this then to apply the same structure to multiple elements
asset_skin[? "CheckBox"] = text_control(sprDefaultCheckbox);
asset_skin[? "InputBox"] = text_control(sprDefaultInputBox);
asset_skin[? "Label"] = text_control(sprDefaultLabel);
// You don't have to create a function, you may as well create a template struct
// (this is taken from the "wood" skin from the template project)
var window_def = {
sprite_index: sprWoodWindow,
draw_color: APP_THEME_WHITE,
draw_color_mouse_over: APP_THEME_WHITE,
focus_border_color: APP_THEME_WHITE,
titlebar_height: 38
}
asset_skin[? "Window"] = window_def;
asset_skin[? "MessageBoxWindow"] = window_def;
asset_skin[? "DemoLoginWindow"] = window_def;
}
As mentioned above, one theme is delivered to you with the project template as the default skin of raptor.
Caution
DO NOT DELETE THIS SKIN.
It is set/added to the UiSkinManager in the raptor core when the game starts.
You may adapt the sprite values in here at will, or simply derive your own skin and just use
this file as a template. Whatever you do, just do not delete this one!
To make designing your own theme easier, you can either look up the predefined default sprites in raptor, or in the repository in the _assets_/controls/flat_ui
folder.
They are there in .png
and .pdn
formats.
In case, you don't know, what .pdn
files are, these are done with paint.net, a great free graphics program.
As an overview, here are the sprites contained in the default skin:
It's as easy as adding the object's name as key and the struct to use to the ds_map of the skin.
Just add it.
When you activate a skin, raptor loops through the keys and applies all struct elements on them!