Difference between revisions of "GUIToolkit"

From The Battle for Wesnoth Wiki
m (Typos)
(Undo revision 72911 by Bssarkar (talk))
(Tag: Undo)
 
(28 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= Introduction =
+
[[File:Character selection dialog.png|frame|right|An Example of a Dialog, created using Wesnoth's new GUI toolkit, GUI2]]
  
This is a new toolkit aiming to make it possible to make the look of Wesnoth fully skinnable.
+
== Introduction to GUI2 ==
This will be used in Wesnoth the make it easier to optimize for different screen resolutions.
+
This is a new toolkit aiming to make it possible to make the look of Wesnoth fully skinnable. As such, it separates the actual appearance and layout of the ''user interface'' (defined using WML) and the ''control logic'' (such as event handling, done using C++ or Lua). The C++ or Lua code is also reponsible for actually loading the WML and showing the widget on the screen.
The initial work in progress version has been released with Wesnoth 1.6. Since the development
+
 
isn't done yet, these pages reflect the state of the trunk.
+
This is being used in Wesnoth the make it easier to optimize for different screen resolutions, and to simplify and make it easier to maintain GUI code.
 +
 
 +
Initially released with Wesnoth 1.6, it is now the default and being used for the majority of dialogs as of Wesnoth 1.18.
  
 
The engine has two parts:
 
The engine has two parts:
* Widget definition, which defines how a widget looks.
+
* Widget definition, which defines how a widget looks and how it is laid out, if it contains multiple widgets inside (''containers'', see below). ([[GUIWidgetDefinitionWML|Reference]])
* Window definition, which defines how a certain window looks and it uses the widget definitions.
+
* Window definition, which defines how a certain window looks and how it uses the widget definitions. ([[GUIWindowDefinitionWML|Reference]])
 +
 
 +
== Basic Structure ==
 +
 
 +
The basic structure of a WML file that defines a dialog consists of a toplevel <code>[window]</code> tag, with one or more nested <code>[resolution]</code> tags, inside which the actual content of the window resides. The multiple resolution tags allow the designer to specify various interfaces for various screen sizes and resolutions. So a basic template for a WML file that defines the layout of an user interface would be :
 +
<syntaxhighlight lang=wml>
 +
[window]
 +
    # Window attributes/keys
 +
    # such as id and description
 +
   
 +
    [resolution]
 +
        # Resolution keys
 +
       
 +
        # Tooltip and Helptip subtags, mandatory
 +
        # just specifying an id is enough.
 +
        [tooltip]
 +
            id = "tooltip"
 +
        [/tooltip]
 +
       
 +
        [helptip]
 +
            id = "tooltip"
 +
        [/helptip]
 +
       
 +
        # the main contents
 +
        [grid]
 +
        [/grid]
 +
    [/resolution]
 +
   
 +
    # More resolution tags can be added here
 +
    # to support different layouts for different
 +
    # screen resolutions.
 +
[/window]
 +
</syntaxhighlight>
 +
 
 +
== Layouting ==
 +
Wesnoth's UI toolkit, GUI2, has a rather simple layout system. Instead of allowing dialogs to specify exact coordinates, it only deals with relative sizes and locations. It is based on a grid based system, with complicated layouts being specified by multiple levels of nested <code>[grid]</code>s.
 +
 
 +
The UI is constructed from various UI widgets. Some of them can contain other widgets, such as <code>window</code> or <code>grid</code>, so we will call them ''Container-type widgets'' or just ''Containers'' for short, and we will use ''Widget'' to refer to the rest of them, which cannot contain other widgets inside themselves.
 +
 
 +
There are 5 keys relevant to positioning widgets in a GUI2 container:
 +
 
 +
* <code>grow_factor</code>
 +
* <code>horizontal_grow</code>
 +
* <code>vertical_grow</code>
 +
* <code>horizontal_alignment</code>
 +
* <code>vertical_alignment</code>
 +
 
 +
Where these keys can be used are detailed below. Usually, they are used inside a <code>[row]</code> or <code>[column]</code>.
 +
 
 +
It is to be kept in mind that GUI2 functions on a grid system. Each grid is made up of rows, and ''every row must have the same number of columns''. The columns may contain either other grids or widgets, such as buttons.
 +
 
 +
<syntaxhighlight lang=wml>
 +
[grid]
 +
    [row]
 +
    # row keys here
 +
        [column]
 +
        # column keys here
 +
        # the widget or a subgrid goes here
 +
            [button]
 +
            # button keys
 +
            [/button]
 +
        [/column]
 +
        # More columns here
 +
    [/row]
 +
    # More rows here
 +
[/grid]
 +
</syntaxhighlight>
 +
 
 +
 
 +
Now, let's talk about each of the above keys:
 +
 
 +
=== grow_factor ===
 +
This key can be present in either rows or cells, as so:
 +
 
 +
<syntaxhighlight lang=wml>
 +
[row]
 +
    grow_factor = 1
 +
[/row]</syntaxhighlight>
  
= Todo list =
+
Or
 +
 
 +
<syntaxhighlight lang=wml>
 +
[column]
 +
    grow_factor = 1
 +
[/column]</syntaxhighlight>
 +
 
 +
Growth factors control the relative growth size of the row or column. It's important to remember that the grow_factor of a row controls <b>vertically</b> growth, while the grow_factor of a column controls <b>horizontal</b> growth.
 +
 
 +
For example, if two columns were positioned next to each other, the first with a growth factor of 0 and the second with 1, the second column would grow at a regular rate, while the first would not grow at all. This holds true for rows, and it is important to get grow_factor values right. An easy way to remember how to use this key is to assign it a value of 0 if you want that row or column to grow much less relative to another.
 +
 
 +
Keep in mind, this key only controls the growth of the rows and columns themselves. Control over the widgets' sizes is dictated by the remaining keys.
 +
 
 +
=== horizontal_grow and vertical_grow ===
 +
Boolean keys that decide whether the contained widgets grow or not. Mutually exclusive with horizontal_alignment and vertical_alignment.
 +
 
 +
=== horizontal_alignment and vertical_alignment ===
 +
String keys that set the alignment of the contained widget. Possible values :
 +
 
 +
<code>
 +
horizontal_alignment : "left", "center", "right"
 +
</code>
 +
 
 +
<code>
 +
vertical_alignment : "top", "center", "bottom"
 +
</code>
 +
 
 +
== Links ==
 +
* [[GUIWidgetInstanceWML]] - Reference for the various widgets and the keys that can be used with them.
 +
 
 +
* [[GUIVariable]] - Documents the types of GUI2 variables available.
 +
 
 +
* [[GUILayout]] - Describes how to place widgets in a window.
 +
 
 +
* [[GUIWindowDefinitionWML]] - Describes the windows available and which widgets the engine 'knows' about.
 +
 +
* [[GUIToolkitWML]] - Describes the basics of the engine.
 +
 
 +
* [[GUICanvasWML]] - Describes how the drawing system works. Useful if you want to use the [drawing] widget to show some custom drawing or if you're building a new widget definition (aka a new theme for a widget.)
 +
 
 +
== Todo list ==
 
Here's a(n incomplete) list of items which still need to be done.
 
Here's a(n incomplete) list of items which still need to be done.
 
* The layout engine can still have problems with not finding a solution and stop.
 
* The layout engine can still have problems with not finding a solution and stop.
Line 19: Line 138:
 
* Improve the markup for the text
 
* Improve the markup for the text
 
* Convert more dialogs
 
* Convert more dialogs
 
= Links =
 
* [[GUIVariable]] describes the variable used for the parts of WML.
 
* [[GUILayout]] describes how to place widgets in a window.
 
* [[GUIWidgetDefinitionWML]] describes how the various widgets are defined.
 
* [[GUIWidgetInstanceWML]] describes the options which can be used when a widget is "instantiated" in a window definition.
 
* [[GUIWindowDefinitionWML]] describes the windows available and which widgets the 'know' about.
 
* [[GUIToolkitWML]] describes the basics of the engine.
 
* [[GUICanvasWML]] describes what to draw on a widget.
 
* [[Wiki_grabber]] describes the tool to generate the wiki pages.
 
 
  
 
[[Category:WML Reference]]
 
[[Category:WML Reference]]
 
[[Category: GUI WML Reference]]
 
[[Category: GUI WML Reference]]

Latest revision as of 15:47, 29 April 2024

An Example of a Dialog, created using Wesnoth's new GUI toolkit, GUI2

Introduction to GUI2

This is a new toolkit aiming to make it possible to make the look of Wesnoth fully skinnable. As such, it separates the actual appearance and layout of the user interface (defined using WML) and the control logic (such as event handling, done using C++ or Lua). The C++ or Lua code is also reponsible for actually loading the WML and showing the widget on the screen.

This is being used in Wesnoth the make it easier to optimize for different screen resolutions, and to simplify and make it easier to maintain GUI code.

Initially released with Wesnoth 1.6, it is now the default and being used for the majority of dialogs as of Wesnoth 1.18.

The engine has two parts:

  • Widget definition, which defines how a widget looks and how it is laid out, if it contains multiple widgets inside (containers, see below). (Reference)
  • Window definition, which defines how a certain window looks and how it uses the widget definitions. (Reference)

Basic Structure

The basic structure of a WML file that defines a dialog consists of a toplevel [window] tag, with one or more nested [resolution] tags, inside which the actual content of the window resides. The multiple resolution tags allow the designer to specify various interfaces for various screen sizes and resolutions. So a basic template for a WML file that defines the layout of an user interface would be :

[window]
    # Window attributes/keys
    # such as id and description
    
    [resolution]
        # Resolution keys
        
        # Tooltip and Helptip subtags, mandatory
        # just specifying an id is enough.
        [tooltip]
            id = "tooltip"
        [/tooltip]
        
        [helptip]
            id = "tooltip"
        [/helptip]
        
        # the main contents
        [grid]
        [/grid]
    [/resolution]
    
    # More resolution tags can be added here
    # to support different layouts for different
    # screen resolutions.
[/window]

Layouting

Wesnoth's UI toolkit, GUI2, has a rather simple layout system. Instead of allowing dialogs to specify exact coordinates, it only deals with relative sizes and locations. It is based on a grid based system, with complicated layouts being specified by multiple levels of nested [grid]s.

The UI is constructed from various UI widgets. Some of them can contain other widgets, such as window or grid, so we will call them Container-type widgets or just Containers for short, and we will use Widget to refer to the rest of them, which cannot contain other widgets inside themselves.

There are 5 keys relevant to positioning widgets in a GUI2 container:

  • grow_factor
  • horizontal_grow
  • vertical_grow
  • horizontal_alignment
  • vertical_alignment

Where these keys can be used are detailed below. Usually, they are used inside a [row] or [column].

It is to be kept in mind that GUI2 functions on a grid system. Each grid is made up of rows, and every row must have the same number of columns. The columns may contain either other grids or widgets, such as buttons.

[grid]
    [row]
    # row keys here
        [column]
        # column keys here
        # the widget or a subgrid goes here
            [button]
            # button keys
            [/button]
        [/column]
        # More columns here
    [/row]
    # More rows here
[/grid]


Now, let's talk about each of the above keys:

grow_factor

This key can be present in either rows or cells, as so:

[row]
    grow_factor = 1
[/row]

Or

[column]
    grow_factor = 1
[/column]

Growth factors control the relative growth size of the row or column. It's important to remember that the grow_factor of a row controls vertically growth, while the grow_factor of a column controls horizontal growth.

For example, if two columns were positioned next to each other, the first with a growth factor of 0 and the second with 1, the second column would grow at a regular rate, while the first would not grow at all. This holds true for rows, and it is important to get grow_factor values right. An easy way to remember how to use this key is to assign it a value of 0 if you want that row or column to grow much less relative to another.

Keep in mind, this key only controls the growth of the rows and columns themselves. Control over the widgets' sizes is dictated by the remaining keys.

horizontal_grow and vertical_grow

Boolean keys that decide whether the contained widgets grow or not. Mutually exclusive with horizontal_alignment and vertical_alignment.

horizontal_alignment and vertical_alignment

String keys that set the alignment of the contained widget. Possible values :

horizontal_alignment : "left", "center", "right"

vertical_alignment : "top", "center", "bottom"

Links

  • GUIVariable - Documents the types of GUI2 variables available.
  • GUILayout - Describes how to place widgets in a window.
  • GUICanvasWML - Describes how the drawing system works. Useful if you want to use the [drawing] widget to show some custom drawing or if you're building a new widget definition (aka a new theme for a widget.)

Todo list

Here's a(n incomplete) list of items which still need to be done.

  • The layout engine can still have problems with not finding a solution and stop.
    • Make sure labels buttons etc can shrink and show ellipses to shrink small enough
    • Optimize the shrink algorithm
  • The code for the events is not entirely to my liking and I want to look at using signals instead, events are there bug not yet used everywhere.
  • EasyCoding#GUI2_related_features
  • Improve the markup for the text
  • Convert more dialogs
This page was last edited on 29 April 2024, at 15:47.