Skip to content
Will Thomas edited this page Feb 4, 2015 · 4 revisions

##Overview

GSS, or gui style sheets, are a special format of file designed to allow custom styling of essentially every visual property of any gui element in any program using gml. It is based on css, so if you're familiar with css, you shouldn't have many problems.

What? You're not familiar with css? Well, crap.

###Basics Ok. In a nutshell, a gss file has one or more of these:

label {
  text-color: 0xffffff;
  text-background: 0x000000;
}

Not so scary, eh? in this example, "label" is what's called a selector. It tells what kind of things this bit applies to. There's a selector for every type of gui element; label, textfield, button, listbox, scrollbar, even gui for the parent gui container itself. If you want to set a property globally, you can use the special selector *, which will apply to all elements regardless of type (though only if there is not a more specific property overriding it - more on that later)

The selector is followed by {} containing a list of properties and values. Any number of properties can be specified in one block, though only the properties relevant to the selector really matter. Not much point in putting, say, grip-color-fg, which controls the foreground color of the "grip" on a scrollbar, in a block of properties that apply to labels, which have no grips. The list of properties that apply to each type of element can be found on that element's page in this wiki, along with the type of value expected for that property and a general description so you can figure out what the hell "bar-ch" is.

###Advanced Selectors Ok, so this all sounds simple enough so far, I imagine you're thinking. If CSS were that easy, people who aren't professional web designers wouldn't hate it so much, though, so there must be more to this. Well, there is.

To ease into this, first, an easy one. You can actually have a block of properties apply to a group of element types just by listing them together, separated by a comma. Example:

label, button {
  text-color: 0xffffff;
  text-background: 0x000000;
}

This would apply these text color properties to both labels and buttons. But then...

####Priority Remember that * selector I talked about earlier? It's not as useful as you might think. See, when searching the gss for a property, the gss engine will give priority to the best possible matching selector. So, a property in a * selector will apply only if that property can't be found anywhere else, including any inherited styles or the default style.

This gets even more complicated when we add in...

####Selector modifiers There are also selector modifiers. Three kinds of selector modifiers, in fact: class, state, and one unique to gss, depth.

#####Class modifier Class is simply a property that is set on the object. By default, elements generally have no class, but in designing a gui, you can choose to set the element.class field on any element you've created to whatever string you want. If an element has a class specified, it'll look first for blocks with selectors that match that class, and only settle for a generic, classless selector block if no match is found.

Classes are specified by adding "." after the selector, like so:

label.awesome {
  text-color: 0xFF8888;
  text-background: 0x00ffff;
}

these properties would only affect labels that have had their class set to "awesome", but for those it would override any normal label style blocks anywhere in their style tree.

#####State modifier States are the second kind of selector modifier. Unlike classes, which are usually set when designing your gui and don't change during the program, states do change. There are only a few valid states recognized by gss, and any others will throw an error while loading the style. The valid states are:

  • enabled
  • disabled
  • checked
  • focus
  • selected

The meanings of these should be fairly self-explanatory, but to give some examples, a component has focus when you have tabbed to or clicked on it, and only one element ever has focus at a time. More than one can be selected, though, and selected is used by listboxes to indicate which label in their list is selected.

States are applied similarly to classes, just using a ":" instead of a "."

label:selected {
  text-color: 0x0;
  text-background: 0xffffff;
}

states and classes can also be combined, with class going first

label.awesome:selected {
  text-color: 0xFF00FF;
  text-background: 0x00FF00;
}

#####Depth modifier The depth modifier has no equivalent in CSS (that I'm aware of), but is introduced to gss to allow for styling to adapt to 1, 4, and 8-bit color on tier 1, 2, and 3 monitors and graphics cards. There are only three valid depth values, 1, 4, and 8, and they are always added to the end of the selector, separated by a !.

label!1 {
  text-color: 0xFF8888;
  text-background: 0x00ffff;
}

####Priority again Now that I've explained all the modifiers, we get to revisit the idea of priorities. The highest priority modifier is depth; depth trumps all. If you're on a 1bit display, selectors with the modifier "!1" will apply over all other blocks, even those with matching class and states. Note, even the global selector, *, with a bit modifier, will trump blocks matching the specific element!

The next highest priority is state, which trumps everything except depth. Class is the lowest of modifiers, beating out only un-modified selectors, but yielding to matching class or depth blocks. And the lowly element-only blocks, they are trumped by all.

##Still confused? Don't panic, that's normal. Go take a look at the default style in the repo, see if you can recognize some of what's going on now, then come back and read this again. Then take a walk, get some fresh air, perhaps some food, a good night's sleep, and then come back and read this again. Repeat until you either figure it out or you decide the default style is pretty damned good and you don't want to change the appearance of your guis.

Clone this wiki locally