Page 1 of 1

New graphical set type for layering multiple images

Posted: Mon Apr 25, 2016 11:14 pm
by JasonC
0.12.29; Some GUI elements, such as buttons, use "graphical sets" to specify their images. These take the form:

Code: Select all

GraphicalSet = {
  type = <set type>,
  everything else depending on set type
}
Currently the two types I am aware of are:
I would like to propose a new type, called "layered" (actually I'd call it a "composition" but... that name's in use, heh...), which can take an array of other GraphicalSets and draw them on top of each other, in the order specified, with alpha blending. Specification would be something like:

Code: Select all

LayeredGraphicalSet = {
  type = "layered",
  layers = {
    GraphicalSet,
    GraphicalSet,
    ...
  }
}
I don't think support for exotic blend modes is necessary, the game can just use whatever alpha-blending mode it currently uses for drawing icons and such. Setting a layer's opacity might be useful to some folks, I don't know.

I think this would add some incredibly powerful features to the current GUI elements. In particular, one would now be able to create a button with an image on it from an existing graphic with an alpha channel, without having to create custom versions of the graphic for every border style and a specific size. It also makes it extremely straightforward to use existing graphics that may not be known at run-time (e.g. registered entity icons), and to update your own graphics / UI style in your mod without having to redraw all of your sprites (this is a big benefit):

Code: Select all

local style = {
  type = "button_style",
  parent = "button_style",
  default_graphical_set = {
    type = "layered",
    layers = {
      { type = "composition", ... } -- A composition for border and background
      { type = "monolith", ... } -- A monolith rendered on top of it
    }
  }
  ...
}
For example, a button with an image on it and the built-in look-and-feel would then be specifiable from a single icon, e.g. (sorry for syntax errors, just typing this here):

Code: Select all

-- a composition from the game's main gui spritesheet, with an icon on top of it
function make_graphical_set (compx, compy, iconfile)
  return {
    type = "layered",
    layers = {
      { -- the border and background are a composition
        type = "composition",
        filename = "__core__/graphics/gui.png",
        corner_size = {3, 3},
        position = {compx, compy}
      },
      { -- the image is the same icon in all cases
        type = "monolith",
        monolith_image = { filename = iconfile }
      }
    }
  }
end

my_button_style = {
  type = "button_style",
  parent = "button_style",
  default_graphical_set = make_graphical_set(0, 0, ICON_FILENAME),
  hovered_graphical_set = make_graphical_set(0, 8, ICON_FILENAME),
  clicked_graphical_set = make_graphical_set(0, 16, ICON_FILENAME),
  disabled_graphical_set = make_graphical_set(0, 0, ICON_FILENAME)
}
This would greatly simplify a few tasks, and also unlocks a lot of the potential of the "composition" type, which has many strengths but currently can only be used on text buttons.

Additionally, with the scaling changes that seem to have taken place recently (0.12.31 I believe), letting buttons have compositions for borders with monoliths for images layered on top might help increase scaling quality by allowing the border to remain pixel-accurate and only scaling the image.

There is an entirely different approach that accomplishes this same thing, by the way, which is somewhat more limiting but still at least accomplishes the basic task of images on buttons, and that is to simply give buttons an "icon" property, where that icon is rendered over top of the background graphical set. That would be a powerful alternative to the above, although having a new graphical set type, combined with unifying GUI element background image specifications (to give them all graphical set support), unlocks a lot of new possibilities (another thing you can do with the "layered" set instead of just button icons is e.g. draw other little indicators on top of icons for whatever reason you could think of, like how Windows sticks the shortcut arrow on top of desktop shortcut icons, the Dropbox sync status on top of file icons, etc).