|« Main Page|
Getting Started with XFC
Table of Contents
GTK+ programming in C++ is more efficient and more powerful than programming in C, and with the Xfce Foundation Classes (XFC) it's easier and a lot more fun. By combining the power of GTK+ and the power of C++, XFC provides the programmer with a well integrated set of C++ classes that wrap most of the functionality found in the GTK+ libraries. The Xfce Foundation Classes is divided into two main libraries: libXFCcore and libXFCui, but other add-on libraries planned, such as libXFCde which will provide a C++ interface for the Xfce core libraries.
The libXFCcore library wraps the GLib object system and selected objects from the GLIb utility library. Essentially, it provides a low level object system that can be used to build other libraries; libXFCui depends on this library. libXFCcore uses the new libsigc++ 2.0 callback library to implement a typesafe system of signals and slots that makes using native GObject signals or creating your own very easy. There is a standard string compatible UTF-8 string class, a complete reference manual and several test programs.
The libXFCui library is a state-of-the-art graphical user interface toolkit for developing GTK+ applications in C++. There are more than 420 classes that wrap most of the objects found in the ATK, GDK, Gdk-Pixbuf, GTK and Pango libraries. Included is a C++ version of the GTK+ widget demonstration program, a full set of simple example programs, several test applications, an extensive reference manual and a tutorial.
The Xfce Foundation Classes is released under the GNU Lesser General Public License so it can be used to develop open software, free software, or even commercial non-free software without having to spend anything for licenses or royalties.
The first thing to do of course is download the XFC source code and install it. You can always get the latest version from http://xfc.xfce.org. You can also view other sources of information online. XFC uses GNU autoconf for configuration, so once untar'd run configure with the --help argument to see a list of options. You should use the GNU compiler version 3.3.2 (or higher) to compile XFC.
The libXFCcore library has the following dependancies:
The libXFCui library depends on libXFCcore and the following:
Most Linux distributions include these packages. Just make sure that the development packages are also installed on your system. Once XFC is installed you will find a complete reference manual and a tutorial in the <docs> directory. If the API reference manual is missing for some reason, don't worry. It's very likely your Linux distribution comes with a program called Doxygen, which should be in your <usr/bin> directory. XFC will use Doxygen to compile the API reference manual from special comments in the header files, when you run make for the first time.
You can compile and install XFC with the following commands run in the top-level source directory:
The '--prefix' argument takes the directory where you want XFC installed. If the directory is omitted XFC will install itself into the <usr/local> directory. By default, configure builds libXFCcore and libXFCui with debugging and compiler symbols so you can debug your applications during development. If you want libXFCcore and libXFCui built without debugging symbols, run configure with the following option:
Alternativley, you can install the libXFCcore and libXFCui libraries with all debugging symbols stripped out by calling:
The stripped libraries are much smaller, and faster: libXFCcore is just 220 kbytes and libXFCui is 2.3 megabytes.
If you don't want to build the API reference, or if you don't have Doxygen installed, run configure with the following option:
Other configure options include: --disable-demos, --disable-examples and --disable-tests, which disable the implied feature so it wont get compiled.
The Xfce Foundation Classes comes with extensive documentation that you can refer to when you need help. You will find all the documentation in the XFC <docs> directory. The documentation is divided into a FAQ sheet, numerous HOWTOs with examples, an API reference manual and a tutorial.
The <docs/faq> subdirectory has a FAQ sheet that answers several commonly asked questions about XFC generally, and about GTK+ programming with XFC. The <docs/howto> subdirectory is a respository for a large number of HOWTOs that cover everything from general information and library structure to individual widget programming. The <docs/reference> subdirectory contains a complete API reference manual. This manual is compiled by Doxygen from special comments in the XFC header files. Every typedef, enum and class is documented, including all public and protected member functions and signals.
There is a good GTK+ programming tutorial in the <docs/tutorial> subdirectory. This tutorial was designed with new GTK+ programmers in mind, so if that's you, and you take the time to work through each chapter you should gain a clear understanding of the basics of GTK+ programming in C++ using XFC. If you are already familiar with GTK+ progamming in C you should still find the first seven chapters helpful because they take you through you the basics of XFC programming.
The tutorial starts off in chapter one by creating a basic application, XfcApp, which is nothing more than an empty main window. In chapters two and three, two simple applications are created: Hello World and Hello Buttons, which serve to introduce you to important topics such as packing widgets, libsigc++ signals and slots, and virtual signal classes. The concept of 'packing widgets' is especially important because it forms the basis of user interface design in GTK+. The interesting stuff really begins in chapter four. Starting with the XfcApp program from chapter one, successive chapters take you through the process of enhancing XfcApp, adding features such as an action-based menubar and toolbar, a composite statusbar that looks and behaves just like a GNOME appbar, and a client area that responds to mouse button events by displaying a pop up context menu.
The tutorial finishes off by covering two important topics that are essential for new programmers. Chapter eight takes you step-by-step through the process of turning XfcApp into a GNU compliant autotools project. Then chapter nine shows you how to add international support. If you already know how to build a GNU autotools project and how to add international support, you can skip these two chapters.
Several sources of well documented example code are provided to help you get started with XFC programming. There is the widget demonstration program (xfc-demo) in the <demos/xfc-demo> subdirectory that uses many of the available widgets, including newer ones like EntryCompletion, Expander and UIManager. In the <examples> directory there are a lot of example programs. Each program focuses on the use of a particular widget group and has an associated widget HOWTO in the <docs/howto> subdirectory. In the <tests> directory there are several test programs that take you step-by-step through the process of using the latest GTK+ widgets, like action-based menus and toolbars, combo boxes and the new FileChooser widget. The <tutorial> directory contains the full source code for the examples used in the XFC tutorial.
The XFC header files are well set out and easy to read. Each header file wraps one GTK+ object along with any helper classes, enums and typedefs it needs. Any other header files included are wrapped in an include guard to prevent multiple inclusions when compiling. The header file of a derived class always includes the header file of its immediate base class. This means you only have to include the most derived header file to include all the header files in an object's inheritance path. For example, including <xfc/gtk/dialog.hh> also includes <xfc/gtk/window.hh>, <xfc/gtk/bin.hh>, <xfc/gtk/container.hh> and <xfc/gtk/widget.hh> so you wouldn't need to include these header files.
A typical header file has the following layout:
This cut down version of <xfc/gtk/button.hh> should help you better understand the XFC header files. As you can see the class members have a specific organization. First all private members are declared, then any protected members, and last the public members. I find this layout helpful in understanding how an unfamiliar object works.
The copy constructor and assignment operator are declared private to prevent inadvertent copying. Most objects will have a protected constructor like Gtk::Button's. This constructor wraps a pointer to a new GtkButton object and sets its 'owns_reference' flag to false, telling XFC that initially the button is in an unowned floating state with a reference count of 1. Next any protected accessors and methods are declared and then any properties and signals. The button class declares no properties. Gtk::Button has six protected signals but only one is shown here: the clicked_signal. You would not connect a function slot to a protected signal directly because it requires an object instance. If you did, you would do it like this:
Instead, you would use the signal's public proxy function, signal_clicked():
As you possibly guessed, signal_clicked() is a convenience method that passes the button's 'this' pointer implicitly to the protected clicked_signal.
In the public section of the button class any constructors and the destructor are declared first, followed by any accessors, then any methods, and last any proxy property and proxy signal functions. Most classes have two public accessor functions similar to these:
The first function, gtk_button(), is an inline function that returns a pointer to the underlying GtkButton object. The last function is Gtk::Button's conversion operator. It does an implicit conversion from a Gtk::Button object to a GtkButton pointer safely, by testing for null. The proxy signal functions are declared last and are inline functions that return a temporary proxy object that makes the signal connection.
XFC does not declare virtual signal handlers in the widget classes. Instead, they are declared in a separate class hierarchy to minimize the overhead associated with implementing large numbers of virtual functions. If you want to override one or more virtual signal handlers for a widget class, your class must multiplely inherit from an appropriate signal handler class.
For example, if you wanted to override the "delete_event" signal handler you would declare your window class like this:
and you would define the window constructor like this:
Each widget that receives GTK+ signals has a corresponding signal class. Your class can multiplely inherit from this signal class or one of its ancestor signal classes. In the above example, MyWindow could have inherited from Gtk::WindowSignals but it only needs to override on_delete_event(), so it inherits from Gtk::WidgetSignals. There is one important point to note here. A signal class header file should be included after the include for the corresponding widget class header file. This is because signal class header files do not include widget class header files.
To compile an XFC application you need to use pkg-config which can be obtained from http://www.freedesktop.org. pkg-config is a tool for managing library compile and link flags during make file exceution. It reads the xfcui-X.X.pc file (X.X is the version number) which comes with XFC to determine what compiler switches are needed to compile an XFC program. The --cflags option will output a list of include directories for the compiler to look in, and the --libs option will output the list of libraries for the compiler to link with and the directories to find them in. For example, a typical compile command would look like this:
Replace X.X with the major and minor version numbers of the libXFCui library installed on your system. Note that the type of single quote used in the compile command above is significant. The libraries that are linked by this command are: