edelib basics

This tutorial describe the basics of coding and compiling programs that use FLTK and edelib. It is continuation of FLTK Basics document, introducing basic edelib usage with FLTK.

Writing Your First edelib Program

edelib headers are stored in edelib directory and that is the main prefix used when headers are included. Unlike FLTK header files that ends with .H extension, edelib uses more common approach, ending header files with .h extension.

Although FLTK install header aliases ending with .h extension when manually compiled, binary packages often comes without them, so the best advice is end FLTK specific header with .H anyway.

Here the example that showing a simple “Hello, World!” program that uses FLTK and edelib to display the window.

/* hello.cpp */
 
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <edelib/Window.h>
 
EDELIB_NS_USING_AS(Window, MainWindow)
 
int main(int argc, char **argv) {
  MainWindow *window = new MainWindow(300,180);
  Fl_Box *box = new Fl_Box(20,40,260,100,"Hello, World!");
  box->box(FL_UP_BOX);
  box->labelsize(36);
  box->labelfont(FL_BOLD+FL_ITALIC);
  box->labeltype(FL_SHADOW_LABEL);
  window->end();
  window->show(argc, argv);
  return Fl::run();
}

As you can see, it is much the same as example program from FLTK documentation, with one difference: it uses edelib Window class. This class behaves pretty much the same as Fl_Window and Fl_Double_Window classes, plus adding some features like internal usage of XSETTINGS protocol and automatic loading of appropriate icon theme.

The first noticeable line in this code is:

EDELIB_NS_USING_AS(Window, MainWindow)

This is actually a C++ macro that expands to something like:

typedef edelib::Window MainWindow;

All edelib code is placed under edelib namespace and edelib is written so namespace name can be easily changed during compilation time. With this macro, the code will be compileable no matter what namespace name is used. Of course, you can always explicitly add namespace name (like edelib::Window) if that suits you.

Rest of the code is pretty much the same as given in FLTK example program.

Compiling

FLTK comes with handy script called fltk-config. It makes things easier by providing required include paths and linkage libraries to compiler, as shown in Compiling Programs with Standard Compilers in FLTK Basics.

edelib does not comes with such script, but uses pkg-config tool. pkg-config became de facto standard for these things and every recent library is using it, so it is great chance you have it already installed.

To compile hello.cpp example, you would use:

g++ hello.cpp -o hello `pkg-config edelib-gui --cflags --libs`

Troubleshooting

If edelib was installed on uncommon path, pkg-config can fail with message like:

Package edelib-gui was not found in the pkg-config search path.
Perhaps you should add the directory containing `edelib-gui.pc'
to the PKG_CONFIG_PATH environment variable
No package 'edelib-gui' found

This means edelib-gui.pc wasn't found, so you should adjust PKG_CONFIG_PATH environment variable to point to directory where it exists. If edelib was installed in /usr/local, which is default, you will do:

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

One common pattern used in C++ programs, when namespaces are used, is to introduce all symbols with “using namespace <name>”. You should be careful when using edelib::Window class with this. For example, if hello.cpp was written as:

/* hello.cpp */
 
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <edelib/Window.h>
 
using namespace edelib;
 
int main(int argc, char **argv) {
  Window *window = new Window(300,180);
  /* rest of the code... */
}

it would fail during compilation with message like:

hello.cpp: In function 'int main(int, char**)':
hello.cpp:13: error: reference to 'Window' is ambiguous
/usr/include/X11/X.h:101: error: candidates are: typedef XID Window
...

because X11 already provides Window name, implicitly introduced by edelib/Window.h header. This is known bug and will be fixed in upcomming versions.

For now, either explicitly use edelib::Window type or use EDELIB_NS_USING_AS() macro.

Print/export