Show GGDoc.txt syntax highlighted
/*
This file contains documentation for GG that doesn't fit in the source code.
*/
/** \page design Design
\section design_purpose Purpose
GG is designed to achieve several goals:
- Platform-independence: GG should be buildable on any platform that supports OpenGL
- Driver-independence: GG should be a standalone GUI framework that does not require any particular application framework;
though an SDL driver is supplied, GG should be usable with any driver code the user wishes to supply
- Easy extensibility: new controls and GUI behavior should be easy to incorporate
- Complete graphical control for the user/designer: the user should not be limited by the authors' lack of artistic skill!
- Independence of UI elements from the source code: GG UI elements should be configurable as text files, so that UI design
and alteration should not require a recompilation
- Overall time efficiency: an application with a reasonable number of GG UI elements should not slow down significantly
because of the rendering or handling of those elements
- Overall space efficiency: each GG UI element should have a reasonably small data size
- Efficient mixture of 2D and 3D graphical elements: it should be appropriate to use GG in any frame-based 3D application,
even a realtime 3D video game
- Simplicity of use: GG UI elements should be able to send arbitrary messages when manipulated by the user; there should be
no message passing hierarchy imposed on the user
\section design_features Features
GG has the following features and services:
- Communication of UI controls via signals and slots
- Support for 2D-, 3D-, and mixed-mode rendering
- Managment of textures and fonts
- Serialization of UI elements
\section nonfeatures Non-Features
- GG is not fully threadsafe, due to its use of signals and slots
- No sound support is provided
*/
/** \page building Building GG
\section building_reqs Requirements
GG requires GCC 3.4 or later, or MSVC++ 8.0 SP1 or later. Note that both are available for free download.
<p>
GG relies on a few other open-source libraries:
- DevIL 1.6.1 - http://openil.sourceforge.net
- FreeType 2.1.2 - http://www.freetype.org
- boost 1.34 - http://www.boost.org
Optional libraries:
- SDL 1.2.7 - http://www.libsdl.org
GG's documentation relies on Doxygen (http://www.stack.nl/~dimitri/doxygen). In the GG/doc directory, run Doxygen; the
documentation will appear in the GG/doc/html directory.
<br>
\section howto_build How To Build GG
\subsection howto_build_all_platforms All Platforms
You will need to have first built the buildable portions of the boost libraries. See http://boost.org/more/getting_started/index.html for details on building boost. There are usually pre-built binaries available for download for the latest Microsoft C++ compiler.
\subsection howto_build_linux Linux
To build GG, you will need to have SCons installed. These libraries and all the boost
includes should be available in your path. You will of course also need to build and make available all of
the libraries listed in the requirements above.
Once this is done, Linux, Cygwin, and MinGW users can simply type
\verbatim
scons
scons install [as root, if necessary]\endverbatim
from within the root of the GG directory tree. Type
\verbatim
scons -h\endverbatim
to see all the options for the build, including specifying nonstandard locations for libraries required by GG, which may
be especially useful on Cygwin/MinGW systems.
\subsection howto_build_win32_gcc Windows (GCC)
GG works quite well with GCC on Windows, under MinGW or Cygwin, using SCons. See the SCons documentation for how to
force SCons to use Cygwin or MinGW on the Windows platform (this will probably only be necessary if you also have
the MSVC compiler), then refer to the Linux section above. Also note that the DLLs for all the required libraries
except the boost libraries can be found on the net pre-compiled. You can just use the ones for win32/MSVC; since
they're all C code, there will be no ABI compatibility issues. You must compile the boost libraries yourself, since
they are C++ code.
\subsection howto_build_win32_microsoft Windows (Microsoft C++)
For those of you who use the Microsoft compiler, SCons will also work from the command line. You need to install
SCons and Python, and make sure that python is in your path. There is also a standalone version of SCons available
somewhere on the SCons site. Then you just open up a command prompt window, cd to the root of the GG directory
tree, and type scons. I have only been able to get the current version of GG to compile on MSVC++ 8.0 SP1, the version
that comes with .NET 2005.
<p>There is experimental support for generated MSVC project files. To enable this, you can uncomment the large
block of commented-out lines at the end of SConstruct and near the top of build_support.py (all the lines starting
with "##"). After this, assuming you are using a recent-enough version of SCons, scons --help should give you all
the instructions you need ot generate MSVC project files. Note that you can get precompiled MSVC-compatible DLLs
for many of the required libraries. DevIL's 1.6.5 pre-compiled library can be substituted for the latest one, if
there is no pre-compiled version available.
<p>
Finally, note that the solution file is set up to grab all include and library directories rooted at c:\, not just the boost
ones. If you'd like to keep them somewhere else, you'll need to change the project settings.
\subsection howto_build_macos Macintosh
It would be nice to have access to a Mac OS X and/or Classic Mac box, to be able to ensure that GG even compiles on such a
thing. Let me know if you have or are interested in testing out a Mac build, or even taking on porting duties.
*/
/** \page architecture Architecture
\section arch_rendering Rendering Overview
GG uses OpenGL to render its graphics; it is assumed that the entire GUI is being redrawn multiple times each second.
Each GG UI element is draw using calls to OpenGL. Therefore, each element can be rendered as a pre-rendered pixmap, flat 2D
mode graphic, or even a 3D mode rendering; the complexity of the graphics used to represent the UI elements is only limited
by the target rendering hardware and the user's skill.
\section arch_UI_overview UI Overview
\subsection arch_input_events Input Events
GG is organized as a layer on top of an existing user input framework. GG has no way of determining that a mouse click, mouse move,
or any other user input event, has taken place. To use GG, one must subclass off of the abstract class GG::GUI, and define several
of GG::GUI's pure virtual functions. These functions poll the underlying operating system or input framework (by default the SDL),
and generate GG input messages from them. Such messages are mouse moves and clicks, key presses and releases, joystick movement,
etc. GG maintains internal state as to what part of the GUI is being dragged, clicked, etc.
\subsection arch_UI_overview_example Example:
Suppose the user clicks
the left mouse button at screen position (50, 37). GG will receive a message from the underlying application framework that a
left mouse click has occurred; it then determines what UI element is under that screen location, if any. If it turns out there is
a button under that spot, GG sets internal state indicating that the left mouse button is being held down, and that it is over the
button. GG then sends a message to the button that it is depressed. The button sets its own internal state and returns. All
processing is complete for this input; the next time the button is redrawn, it knows to draw itself in a depressed state. Very
little computation is involved in processing a single user input event. GG's performance is therefore usually limited only by the
application-defined processing that is associated with manipulating the controls (e.g., a button click may trigger disk IO).
\subsection arch_UI_element_conns UI Element Connections
GG UI elements are connected using signals and slots, using the boost.signals library implementation. This allows arbitrary
connections between one control and another, and between a control and other code; there is no hierarchy of passed messages
as there is in some other GUIs, and there are no unsafe callbacks used. Refer to the \ref sigs_n_slots documentation for details.
\subsection arch_gui_services GG::GUI Services
The singleton GG::GUI object is globally available through a static member function, GG::GUI::GetGUI(). This allows all code
in the application to rely on GG::GUI for certain essential services. GUI-specific services include registering windows into
the GUI, registering windows as always-on-top or modal windows, moving windows up or down in the z-order layers of the GUI,
removing windows from the GUI, getting mouse state (position and button depression), setting mouse delay repeat (see GG::GUI
for a description of this), entering and exiting from an orthographic projection (2D) rendering mode, and creating polymorphic
GUI elements from XML-formatted text. Most of these services must be provided by the user when subclassing from GG::GUI;
if SDLGUI is used, these services are already implemented.
<p>
GG::GUI does a variety of things for the user, some of which are not strictly necessary for the core GUI functionality.
GG::GUI provides limited timing info via FPS() and DeltaT(). These are provided to indicate how fast the GUI is rendering,
and how long it has been since the last frame was rendered. There is also a font manager, an application-wide font "pool",
from which the user can request fonts. The font pool loads and stores the fonts as needed by the application, and multiple
requests for the same font at the same size will result in the creation of only one rendered font object. A texture manager
exists which does a similar job with textures. If the user wants to programmatically create textures, she can also add them
to the texture pool, provide a name, and request that texture as many times as needed. OpenGL texture objects are used as
the underlying texture rendering method.
*/
/** \page sigs_n_slots Signals and Slots
\section sigs_n_slots_definition Sig-who? Slo-what?
If you've never been exposed to the signals and slots pattern before, it can be a little confusing. Simply put, a slot is a
function or funtion object that is "listening" for a signal. A slot "listening" to a certain signal is said to be connected
to that signal. When a signal is emitted, all slots that are connected to that signal invoke their function(s)/function
object(s). If a signal is emitted to which no slots are connected, nothing happens.
\section sigs_n_slots_motivation Motivation for the Signals and Slots Pattern
\subsection prob The Problem
Originally, GG used a very simple strategy for passing messages between windows/controls. The method was to call a
Command() function, which passed to the callee an integer representing the type of message (button click, scroll, or
whatever), an ID number associated with the calling control, and a single integer parameter. It could have been
made more general and even less typesafe by replacing the int parameter with a void pointer, but in either case it
suffers from two huge limitations. First, the type of message and the parameter must be known to both caller and
callee; this means that, for example, the user must keep track of the integer value representing a button click
message, and make sure that separate sections of code are using the same value to represent it. Second, any code
that doesn't contain a control, but that wants to know about button pushes, scrolling scrollbars, etc., must deal
with that control's parent (or break encapsulation). This creates a lot of chains of passed messages, and a large
number of kludges to get messages to the sections of code that need them.
\subsection sigs_n_slots_soln The Solution
Now, each control emits a signal every time a significant event occurs. If no processing needs to be associated
with such an event, its signal need not be connected to anything. Futhermore, no matter how many modules need to
react to a certain signal, they can all be connected.
\section sigs_n_slots_use Using Signals and Slots
\subsection sigs_n_slots_connecting Connecting Signals To Slots
There are two types of connections between signals and slots. The first type of connection is between a signal and
a slot, which may be a functor (which in turn may be a boost::bind object), a free function or a static member
function or function object. Just call Connect(sig, slot). The second type is between a signal and a non-static
member function. In this case, the call to Connect() requires a third parameter: a pointer to the object whose
member function is to be called. For instance, if I have a class Foo and an object foo1 of class Foo, I cannot call
foo1.bar() by simply knowing the address of bar(). I need to call Connect(sig, &Foo::bar, &foo1) so that the signal
knows which object's bar() to call. Both versions of Connect() return a connection object. By keeping this
connection object, you can later disconnect() the connection you made. In addition, signal-signal connections are
possible. Calling Connect(sig1, sig2) forwards all sig1's signal emissions to sig2. This is provided as a
convenience to avoid having to write dummy forwarding functions that do this.
\subsection sigs_n_slots_emitting Emitting Signals
To emit a signal, just call its () operator, like this: sig();
\subsection disconnecting Disconnecting Signals and Slots
If you kept the connection object returned by Connect(), a connection_obj.disconnect() call will disconnect the associated
signal and slot. Also, consider this: what happens if a non-static member function slot and signal are connected, the
object owning the slot is destructed, and the signal is emitted? A segfault, unless the object's class inherits from
boost::trackable, which auto-disconnects slots on object destruction. GG::Wnd is derived from boost::trackable, so all
GG::Wnd-derived classes should handle such situations gracefully. See the boost tutorial below for details.
\see http://boost.org/doc/html/signals.html for a tutorial on other aspects of signals and slots; you can create
connections that have scope, control the order of the invocation of multiple slots that are called by a signal, and combine
the return values of such slots (take the first return value, the last, the average of all of them, etc.).
*/
/** \page drag_n_drop Drag and Drop
\section drag_n_drop_basics Basics
GG has drag and drop support that allows you to drag any Wnd and drop it onto any other Wnd. The results of this
drop depend on the two Wnds involved. Each Wnd has a DragDropDataType() method that returns a string describing
what kind of data the Wnd represents. The string can be a MIME type or any arbitrary string the user likes. Upon
the drop, the Wnd receiving the drop has its AcceptDrop() method called, in which it can examine the data type or
any other relevant aspects of the dropped Wnd and decide whether or not to accept it. If the receiver accepts, the
dropped Wnd is removed from its parent, if it has one. Note that only Wnds with non-empty-string
DragDropDataType()s may be dragged, and that such Wnds may be, but do not need to be, created with the DRAGABLE
flag.
\section drag_n_drop_advanced Advanced Use
Sometimes it is desirable to have the drop-receiving Wnd emit a signal to which clients may attach slots. Further,
it may be desirable to allow the attached client slots to veto the drop. If this is desired, the recommended means
of accomplishing this is to follow the pattern of ListBox. ListBox catches ListBox::DontAcceptDrop exceptions that
are thrown in slots attached to its DroppedSignal signal. The signal is emitted after the drop is completed, and if
DontAcceptDrop is caught, the stack is unwound in two steps. First, the insertion of the dropped item is rolled
back, and then the exception is rethrown so that AcceptDrop() can return false. See the ListBox implementation for
further details.
*/
/** \page serialization Serialization
\section serialization_motivation Motivation
One of the main design goals for GG is the editability of UI elements without recompilation. Another main goal is the
capability of saving and restoring the state of the GUI. A secondary design goal is the capability of serializing UI
elements for network transmission and receipt. To satisfy all these requirements, GG uses the boost.serialization
library to serialize Wnd-derived objects.
\section serialization_approach Details
GG does not contain any actual code that will serialize a Wnd. Instead, each Wnd subclass contains a serialize() template
method which may be invoked by user code to perform serialization. The user must then create a boost serialization
archive, and save/load the desired windows to/from the archive. To be serializable, user-created subclasses need to define
a serialize method that first serializes its base class, then serializes any subclass-specific data; see any Wnd subclass
for example code. For full details on how the serialization works, see the serialization tutorial and the
boost.serialization documentation.
\section caveats Caveats
Signals are not currently serializable. This means that when a class is created from an input serialization
archive, all its signals must be reconnected to their slots (and any signals connected to it should be reconnected
as well). Many of the built-in GG controls must reconnect signals when loaded; such classes have a private
ConnectSignals() method that is called at load time. See RadioButtonGroup::serialize() in GGButton.h for an
example. Another caveat: Font and Texture objects that were part of the GUI's FontManager and TextureManager when
saved will not be added back to these two structures when they are loaded.
*/
/** \page tutorials Tutorials
\section tut_using Using the Tutorials
The following tutorials are available in the tutorial directory. You can build them all using SCons. SCons can be
found at http://www.scons.org . An MSVC solution file is also provided.
\section tut_1 Tutorial 1: Minimal (minimal.cpp)
This is the minimal interesting GG application, and uses the default input driver, SDL.
\section tut_2 Tutorial 2: Controls (controls.cpp)
This builds upon Tutorial 1 by adding one of every type of Control, and connecting some signals and slots.
\section tut_3 Tutorial 3: Serialization (serialization.cpp)
This builds upon Tutorial 2 by adding serialization code, and saving and loading all the controls at the start of the app's run.
*/
/** \mainpage GG Documentation Overviews
\section Overviews
-# \ref design
-# \ref architecture
-# \ref sigs_n_slots
-# \ref drag_n_drop
-# \ref serialization
-# \ref building
-# \ref tutorials
*/
See more files for this project here