mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-29 13:03:54 +00:00
229 lines
12 KiB
TeX
229 lines
12 KiB
TeX
\chapter{Overall design}
|
|
|
|
This chapter takes a deeper look into the overall design of the library. Before
|
|
we can explain how things work, we'll have a look at the features; both
|
|
implemented and planned for the future. Once we know what the gui should be able
|
|
to do I'll explain how these goals are achieved. The chapter ends with a short
|
|
explanation of the directory structure so you'll be able to find the parts of
|
|
the library.
|
|
|
|
\section{Features}
|
|
|
|
Wesnoth runs on a large amount of devices, with an even larger amount of display
|
|
resolutions, from $320\times 240$ on hand-held devices to $2560\times 1600$ on
|
|
large 30" screens. The gui should look appealing on all these devices. Therefore
|
|
there are three resolution groups:
|
|
\begin{description}
|
|
\item[hand-held devices] For these devices the code needs to be compiled with
|
|
\textbf{TINY\_GUI}. This forces all images to be scaled down by a factor two.
|
|
The typical resolutions on these devices are $320\times 240$ -- $640\times
|
|
480$.
|
|
\item[PC] For the usage on PC's Wesnoth offers the resolutions $800\times 600$
|
|
-- $2560\times 1600$\footnote{And larger once screens that size become
|
|
available.}.
|
|
\item[Netbooks] When the first netbooks were introduced the normal resolution
|
|
was $800\times 480$, which is slightly smaller as the minimum PC resolution.
|
|
Therefore a start option \textsc{--smallgui} was added making minimal
|
|
modifications to the layout\footnote{Actually this is gui1 only.}.
|
|
\end{description}
|
|
|
|
In order to facilitate this range of resolutions the gui2 code allows several
|
|
definitions of a window, tuned for a specific resolution. The reason is twofold;
|
|
first to make a difference between the hand-held devices and PCs, second allow
|
|
different views for different resolutions.
|
|
|
|
The main example of this feature\footnote{Not yet implemented, but one of the
|
|
main reasons to add this feature.} is the attack dialogue. The dialogue has a
|
|
button to show the damage calculation, which shows a new dialogue with the
|
|
calculation overview. From an UI point of view I consider that rather ugly and
|
|
rather have tabs to switch between the view. But when I have a larger screen the
|
|
dialogue only fills a small part and I need to switch between tabs to see the
|
|
info, in that case I rather have one dialogue without tabs, which directly shows
|
|
all information. When the user changes the resolution the dialogue should switch
|
|
between these two views, depending on the current resolution.
|
|
|
|
\paragraph{}
|
|
|
|
The gui should be able to adapt to the size actually needed, the current gui
|
|
uses fixed sizes at some places. This leads to problems that when the screen
|
|
resolution is reduced widgets end up outside the dialogue or get truncated. The
|
|
same for some translated texts, where the translation is much longer as the
|
|
English original. Gui2 solves this problem by dynamically determining the size
|
|
of a widget and adjust the layout until it fits. This has the disadvantage that
|
|
dialogues with a lot of dynamic content, resize at random times and changing the
|
|
layout of the dialogue slightly. Another disadvantage is that when a dialogue
|
|
doesn't fit Wesnoth terminates. This problem can be fixed by adding scrollbars
|
|
to every window. When the dialogue doesn't fit the scrollbars are used and the
|
|
dialogue fits again, might be a bit ugly but at least everything fits again.
|
|
|
|
\paragraph{}
|
|
|
|
It must be possible for WML designers to change the entire gui of Wesnoth with
|
|
their own version. For example Spacenoth\footnote{That project is dead, but
|
|
that doesn't matter for this example.} is Wesnoth is a space setting, so the
|
|
project might want to use a more fitting user interface.
|
|
|
|
Adding a new gui is a lot of work and can't be done in one fell swoop, so the
|
|
code needs to support a gradual conversion. Therefore when you select your own
|
|
theme\footnote{Support for this selection and the entire fall-back haven't been
|
|
added yet. Obviously I want to add support, but it remains low priority until
|
|
somebody really wants to add their own gui.} the engine first searches in the
|
|
new theme for items\footnote{A widget or window.}. When an item is not found it
|
|
uses that item from the default theme. Therefore it's mandatory that every item
|
|
is defined for the default gui, which the engine validates at
|
|
startup\footnote{That causes the problem that Wesnoth sometimes refused to start
|
|
when the source and data are out-of-sync.}.
|
|
|
|
\section{The big picture}
|
|
|
|
First we dive into the components that define the gui.
|
|
|
|
\subsection{Widget}
|
|
|
|
A widget is the basic user interface element, like a label, a button or a text
|
|
entry. Every widget has its own behaviour, which sometimes can be influenced by
|
|
certain settings, but the main behaviour is fixed per widget. Next to behaviour
|
|
a widget also has a visual representation so the user can see and interact with
|
|
the widget.
|
|
|
|
Before the widget is shown to the user it needs to be created first, the
|
|
creation happens in the window builder class. This class reads the definition of
|
|
a widget and fills in the blanks et voil\`a the widget is there. Let's go over
|
|
this part in more slow-motion.
|
|
|
|
\paragraph{The definition}
|
|
The definition determines how a widget looks and some basic properties, these
|
|
properties are the same for all instances of that widget. For example a button
|
|
has a minimum size so the decoration can be drawn. It's possible to make
|
|
multiple definitions of a button. These different definitions, can look
|
|
different have different minimum sizes and other properties.
|
|
|
|
These definitions are written in WML and a small loader class loads and
|
|
validates the definition. The definition is then added to the list of known
|
|
widgets of this type.
|
|
|
|
The definition of the widget depends on the resolution, this is for example used
|
|
in the button. It has a minimum size depending on the decoration used, in
|
|
\textbf{TINY\_GUI} mode the decoration is scaled down, so the minimum size can
|
|
also be reduced.
|
|
|
|
\paragraph{The builder}
|
|
The builder is started from the C++ code, started while building a window. This
|
|
window definition contains a list of widget to build with more instance specific
|
|
values. For example a label builder has the text to show to the user as
|
|
parameter.
|
|
|
|
These builder ``scripts'' are also written in WML and loaded by as small loader
|
|
class that does the validation and build the needed widget.
|
|
|
|
\paragraph{Widget}
|
|
The widget itself is written in a larger C++ class and it defines the behaviour
|
|
and provide various hooks to modify the properties of that widget. These hooks
|
|
are used by the builder, but can also be modified later by the engine.
|
|
|
|
Other hooks provide bindings to react to events. The bindings are now rather
|
|
static, but with the new event handling added late in the 1.8 release series
|
|
more things are possible. The plan is to enhance this part during the 1.9
|
|
release series and deprecate and remove the current interface.
|
|
|
|
Of course the question ``why wait until 1.9'' raises. The reason is simple it
|
|
was added late in the 1.8 cycle to fix certain issues with the MP lobby at that
|
|
time I had no time to convert the rest of the code, since I was working on the
|
|
MP lobby instead.
|
|
|
|
\subsection{Window}
|
|
|
|
A window can mean two things, the window widget and the window definition. In
|
|
this section the window definition is meant. Already discussed before, but a bit
|
|
more verbose this time.
|
|
|
|
The window definition defines a window and which widgets are placed in the
|
|
window. This window definition also depends on the resolution. This allows the
|
|
window to look different depending on the resolution. The changes can be small
|
|
or the window can look completely different.
|
|
|
|
\subsection{Dialogue}
|
|
|
|
A dialogue is a pure C++ thing. A dialogue shows a window, but is not a window.
|
|
So what's the difference\footnote{These are the definitions used in the gui2
|
|
code and not the definition of other window toolkits.}? A window is a dumb
|
|
combination of widgets created depending on the definitions in a WML file. After
|
|
the window is created it often needs extra content and react to certain events.
|
|
For example the language dialogue after building has an empty list of languages.
|
|
This is where the dialogue comes into play. The user asks for the language
|
|
selection dialogue. The code creates and shows a dialogue. The dialogue code
|
|
builds a window, then fills the language list with the available languages and
|
|
selects the current language and then shows it to the user.
|
|
|
|
In other dialogues the code also needs to wire in event handlers or build other
|
|
structures. It searches the wanted widget by id, in some cases it doesn't even
|
|
care what kind of widget is used. In other cases it needs to be of a certain
|
|
class or ``concept''. This allows a flexible design and let the user select the
|
|
kind of widget used in some cases.
|
|
|
|
So the dialogue is the sugar between the WML window and an interactive dialogue
|
|
shown in the game.
|
|
|
|
\section{Directory structure}
|
|
|
|
This section describes the directories available, instead of listing them in
|
|
alphabetic order I list them in a order that makes explaining them more natural.
|
|
|
|
\begin{description}
|
|
\item[src/gui] The general source code directory with all parts used for the gui.
|
|
|
|
\begin{description}
|
|
\item[dialogs] This directory contains all dialogues used in Wesnoth, in
|
|
general every file contains one dialogue, the name of the file being the
|
|
logical name of what the dialogue does. Some dialogues have a helper
|
|
dialogue, which is sometimes embedded in the same file.
|
|
\item[widgets] This directory contains all widgets used in the library. Every
|
|
file contains one widget. Also base classes or concepts of widgets are
|
|
stored in this directory. During the development it also accumulated some
|
|
helper files, which don't fit in the aforementioned descriptions, this lead
|
|
to the creation of the auxiliary directory. Some files haven't been moved to
|
|
this new directory yet.
|
|
\item[auxiliary] This directory contains items auxiliary classes. Some helper
|
|
parts are so large that they got their own subdirectory.
|
|
|
|
\begin{description}
|
|
\item[event] Contains all event handling code, the translation from SDL events
|
|
to the internal events and their dispatching.
|
|
\item[widget\_definition] Contains the code to serialize the WML to an internal
|
|
data structure, needed to define that kind of widget. The names of the files
|
|
match the widget names. (Most files are rather small, but I prefer small
|
|
single tasked files over huge files controlling a lot of code\footnote{Some
|
|
might remember I started with a single file, which did exactly that, but the
|
|
file got too large to maintain efficiently.}.
|
|
\item[window\_builder] Contains the code to create a widget object, from the
|
|
widget definition and the data supplied in the window definition. Again the
|
|
name of the file matches the name of widget they build. (These files are
|
|
also mostly small.)
|
|
\end{description}
|
|
|
|
\end{description}
|
|
|
|
\item[data/gui] The general data directory with all parts used for the gui. All
|
|
guis shipped with Wesnoth should be in a sub-directory of this one, with a
|
|
config file with the name of the directory as main entry point and include
|
|
the sub-directory. At the time of writing only one gui is shipped, the
|
|
default one.
|
|
|
|
\begin{description}
|
|
\item[default] This directory is the bases for the default gui.
|
|
|
|
\begin{description}
|
|
\item[macro] This directory contains some helper macros, for default font sizes.
|
|
\item[widget] This directory contains the definitions of widgets. Since there
|
|
can be multiple definitions of a widget their name is the name of the widget
|
|
with a suffix. The suffix for the default widgets is, \textsc{default} for
|
|
the others an appropriate name is picked.
|
|
\item[window] Contains the definitions of windows, the name of the files is the
|
|
name of the dialogue they represent.
|
|
\end{description}
|
|
|
|
\end{description}
|
|
|
|
\end{description}
|
|
|