Open main menu

To Do

  • Add possibility to specify shadow types to widget classes and to individual widgets
  • Theme hints too
  • List widget
    • get mock-up from Krest
    • shadows under lists. We do not enable those because of missing scrollbar mock-up
    • list highlight (greenish one) should be exactly width of the list. Now it is 2px narrower
    • more padding in list contents on all edges
  • PopUp widget (aka drop-down list)
    • get mock-up from Krest
    • less round corners
      • to do that we need to be able to define gfx for each widget class separately
    • text padding
    • arrows to make it distinguishable from editable textboxes
    • make it taller
  • Tab widget
    • tab widget is drawn completely wrong now
    • though it would be nice to leave current drawing style and select them via widget property
  • Editable text widget
    • add regular font. Now we have just the bold
    • embossing (not shadow)
    • less round corners
      • to do that we need to be able to define gfx for each widget class separately
  • Text widget
    • less round corners
      • to do that we need to be able to define gfx for each widget class separately
  • Button widget
    • probably tame colors for buttons to match mock-ups
    • top line should be drawn with lighter color to make it look more natural
  • Checkbox widget
    • smaller version of widget for 320xY resolution
  • Slider widget
    • remove border
    • less round corners
      • to do that we need to be able to define gfx for each widget class separately
    • embossing
  • Dialogs
    • Scumm save/load dialog
      • put thumbnail and save properties inside one container. Container code is missing now
      • center dialog title agains list widget
    • Scumm help dialog
      • correct buttons widths
    • About dialog
      • looks bad. Probably add some shadows and text padding
      • fix glitch at the top of the dialog where part of the characters get stuck
      • [Classic theme] Turning aspect ratio correction on/off sometimes causes the frame around the dialog to disappear.
      • [Classic theme] Text seems to be drawn over the dialog frame. At least at the top of the dialog.
    • Chooser dialog (add game)
      • proper coloring and list shadow
    • Options dialog
      • do something with buttons on the right when dialog is on
      • buttons are too wide on paths tab in global options
    • Scumm options dialog.
      • add space after volume control

GUI Themes config file format

Overview

We always have a built-in theme. It is used when there is no external .ini file. For simplicity it uses exactly same format as external .ini but is defined in Theme::_defaultConfigINI string in gui/theme-config.cpp file.

Config file consists of at least one section. These sections can override one another. This is used to make a slight alteration of base theme possible without duplicating all element whose position is not changed.

NOTE: if you want to add new widgets, pay attention to correspondent section below

Section names

They are defined with this regexp: (X|[0-9]+)x(Y|[0-9+]+). I.e. possible names are:

  • [XxY] -- universal one which can be used for any resolution
  • [640xY] -- could be used for 640x400 and 640x480
  • [Xx400] -- could be used for 640x400 only (or any other resolution with height 400)
  • [640x480] -- could be used for 640x480 only

Expressions

To add most flexibility arbitrary arithmetic expressions can be used for specifying any element. Allowed operations are '(', ')', '+', '-', '*', '/'. unary '+' and unary '-'. Atoms are either number or symbolic names.

Built-in Constants

Currently there are these built-in constants defined:

  • kButtonWidth
  • kButtonHeight
  • kSliderWidth
  • kSliderHeight
  • kBigButtonWidth
  • kBigButtonHeight
  • kBigSliderWidth
  • kBigSliderHeight
  • kTextAlignLeft
  • kTextAlignCenter
  • kTextAlignRight

These correspond to constants defined in gui/widget.h file. There is no restriction on constants names.

  • kThumbnailWidth -- defined in graphics/scaler.h
  • false = 0
  • true = 1

Built-in Variables

Built-in variables are symbolic names for ScummVM variables whose value is determined at run-time. These are:

  • w -- current GUI width
  • h -- current GUI height

Defining widget positions

Widgets are specified by following construction:

 widget_name=X Y [W H]

X, Y, W and H are whitespace-delimited expressions. W and H are optional.

This construct effectively defines

  • widget_name.x
  • widget_name.y
  • widget_name.w
  • widget_name.h

If W and H are present, also these get defined:

  • widget_name.x2 = widget_name.x + widget_name.w
  • widget_name.y2 = widget_name.y + widget_name.h

Example:

 chooser_headline=10 6 (w - 2 * 16) (kLineHeight)

Widget properties

Above mentioned constructions with dots are called widget properties.

Example:

 chooser_list.x

Also there are following additional widget properties:

  • .visible -- if set to 0, then widget is not drawn
  • .align -- for text widgets defines text alignment (kTextAlignLeft, kTextAlignRight or kTextAlignCenter). Default is kTextAlignLeft

Special variables

Special variables are:

  • self
  • prev

It is reference to current and last defined widget special variables respectively, i.e. .x, .y, .w and .h

Example:

 chooser_list=10 (6 + kLineHeight + 2) (w - 2 * 16) (h - self.y - buttonHeight - 12)

Denote self.y which equals to computed value of (6 + kLineHeight + 2).

You cannot use these references forward, i.e. refer to .w in .x. They get defined from left to right.

Defining variables

Example:

  def_kLineHeight=16 * 2
  OneThirdWidth=(w / 3)

variable kLineHeight gets value 32. OneThirdWidth will be GUI width divided by 3. Note use of parens in last example. Definitions with 'def_' prefix have a special meaning and get skipped with USE keyword (see below).

Defining aliases

You can define alias to any symbolic atom, i.e. constants, variables and widget properties.

Example:

 set_headerBottomX=headline.x2

Now you can use headerBottomX everywhere.

Special alias

 set_parent=chooser_list

It sets 6 aliases for each widget property, i.e.

  • parent.x = chooser_list.x
  • parent.y = chooser_list.y

etc for .w, .h, .x2 and .y2

Example:

 set_parent=tabMidi
 midi_checkbox=(parent.x + 10) (parent.y + 20)
 roland_checkbox=midi_checkbox.x (parent.y + 50)

USE keyword

You can request loading of some particular section at any time within another section. But all variable definitions with def_ prefix get skipped. If you want to define a variable, use plain VAR=VAL construction.

Example:

 [640xY]
 def_buttonHeight=kBigButtonHeight
 def_kLineHeight=16
 listW=(w - 2 * 16)
 chooser_headline=10 6 listW (kLineHeight)
 chooser_list=10 (6 + kLineHeight + 2) listW (h - self.y - buttonHeight - 12)
 
 [320xY]
 def_buttonHeight=kButtonHeight
 def_kLineHeight=9
 use=640xY

In this example for 320xY resolution chooser_headline and chooser_list will be loaded from [640xY] section, though buttonHeight and kLineHeight will be different. listW will get the value.

USEWITHPREFIX keyword

This keyword is similiar to above described USE keyword. The difference is that all defined widgetset will get specified prefix. Example:

 [XxY]
 yoffset=10
 useWithPrefix=audioControls global_
 yoffset=50
 useWithPrefix=audioControls game_
 [audioControls]
 myx=10
 myw=(options_dialog.w - 20)
 midipopup=(myx -5) yoffset (myw + 5)

Here you will get global_midipopup and game_midipopup widgets defined.

Inactive dialog effects (new theme only)

For using an effect change the "inactive_dialog_shading" option in the "[extra]" section of default-theme.ini. Possible values are: "luminance", "dim" and "custom".

  • "luminance" will change all inactive screen areas to black and white.
    • Example (enables it)
 [extra]
 inactive_dialog_shading=luminance
  • "dim" will dim the screen with the given percentage value.
    • "shading_dim_percent" in the "[extra]" section sets the dimming value 0 means no dim, 100 complete black
    • Example (30% screen dim):
 [extra]
 inactive_dialog_shading=dim
 shading_dim_percent=30
  • "custom" will let you decide how the color is calculated.
    • "shading_custom_r" is used to evaluate the R component [0 to 255]
    • "shading_custom_g" is used to evaluate the G component [0 to 255]
    • "shading_custom_b" is used to evaluate the B component [0 to 255]
    • the vars 'r', 'g', 'b' are the input color components, you can use them in every of the shading_custom_* expressions
    • Example (inverts all color values)
 [extra]
 inactive_dialog_shading=custom
 shading_custom_r=255-r
 shading_custom_g=255-g
 shading_custom_b=255-b

Evaluation precedence

Within one section everything is computed left to right down to top. No forward references are allowed. Only exception is aliases which can refer to not yet defined variables and widget properties, but at time of useage those variables should be defined, otherwise you will get an error.

Currently any error in evaluation will lead to error() and ScummVM will be closed. So be careful, especially with built-in theme.

On each resolution change all user-defined variables and aliases get cleared and all sections get recomputed. When sections get loaded for a single resolution, all of them are kept, so you can specify a generic [XxY] scheme and then overwrite only some widgets, thus simplifying whole thing.

Sections loading order is always the same. For resolution 640x480 it is:

  1. Built-in theme
    1. [XxY]
    2. [640xY]
    3. [Xx480]
    4. [640x480]
  2. Custom theme
    1. [XxY]
    2. [640xY]
    3. [Xx480]
    4. [640x480]

Only present sections are loaded. If section is not defined, no error message is generated

Widget name conventions

Widget names are in form:

 dialog_widget

where dialog_ is dialog name, and widget is a distinguishable name within that dialog. Be discreet and give meaningful names.

Example:

 chooser_headline
 chooser_list

What to do if I need to add new widgets to GUI

First thing to mention, is that all real GU behaviour is not described in theme config. Only thing which you can alter is look, not feel. So all real coding should go to correspondent files in gui/ directory.

When you add new widget, you should check it with following checklist before committing:

  • Does it look right in 320xY (./scummvm --force-1x-overlay)
    • To do this you should either have no absolute positions in your config file or create [320xY] section
  • Does it look right with classic theme (./scummvm --gui-theme=classic)
    • that is [XxY] section in gui/theme-config.cpp
  • Does it look right both with classic theme and 320xY resolution (./scummvm --force-1x-overlay --gui-theme=classic)
    • that is [320xY] section in gui/theme-config.cpp

Currently classic theme has following most notable differences from default theme:

  • Line spacing everywhere is narrower
  • Indentation is lesser in most cases, besides in Game Options dialog