The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

FLTK::Basics - An introduction

Description

This chapter will show you how to write a very simple FLTK program.

A sample FLTK program

    use strict;
    use warnings;
    use FLTK qw[:style];

    my $window = FLTK::Window->new(300, 180);
    $window->begin();
    my $box = FLTK::Widget->new(20, 40, 260, 100, "Hello, World!");
    $box->box(UP_BOX);
    $box->labelfont(HELVETICA_BOLD_ITALIC);
    $box->labelsize(36);
    $box->labeltype(SHADOW_LABEL);
    $window->end();
    $window->show();
    exit FLTK::run();

The resulting program will display a window. You can quit the program by closing the window or pressing the ESCape key.

Using FLTK

The basic way to use FLTK is simply:

    use FLTK qw[:style];

Each widget in FLTK is represented by it's own class. This sample program uses a Window and Widgets.

In addition, several non-class functions and symbols can also be imported, they are grouped into tags with lower-case names. You should only include the ones you need. In our example, the label font and type are set using built in variables which we import for use with the :style tag. To import methods used by most programs, use the :default tag.

Creating the Widgets

After the use statement, the program then creates a window:

    my $window = FLTK::Window->new(300, 180);

It then calls begin on it, which indicates that all widgets constructed after this should be "children" of this window:

    $window->begin();

It then creates a box with the "Hello, World!" string in it, this new widget is made a "child" of the window we just created:

    my $box = FLTK::Widget->new(20, 40, 260, 100, "Hello, World!");

For most widgets the arguments to the constructor are:

    FLTK::Widget->new(x, y, width, height, label);

x and y are the location of the upper-left corner of the widget, measured in pixels. For windows this is measured from the upper-left corner of the screen, for widgets it is measured from the upper-left corner of the parent window.

width and height are the size of the widget.

label is a string to label the widget with or undef. If not given it defaults to undef for new widgets. The label defaults to your program's name for windows. The string is not copied, FLTK assummes it is static.

For example, this:

    my $label = 'Testing';
    FLTK::Button->new( $x, $y, $w, $h, $label );
    $label = 'Changed';

...would create a button with the label 'Testing' but on the next redraw, the button's label would read 'Changed'. This is true of almost all interfaces in FLTK that take strings and greatly speeds up FLTK. (see copy_label() for a method that has more traditional behavior).

Get/Set Methods

Next we set several "attributes" of the box:

    $box->box(UP_BOX);
    $box->labelfont(HELVETICA_BOLD_ITALIC);
    $box->labelsize(36);
    $box->labeltype(SHADOW_LABEL);

$box->box(UP_BOX) sets the type of box the box widget draws, changing it from the default of FLTK::DOWN_BOX. In our "Hello, World!" example we use FLTK::UP_BOX, which means that a raised button border will be drawn around the widget.

You can examine the boxtype in by doing $box-box()>. FLTK uses method name overloading to make short names for get/set methods. I really dislike mutators in Perl, but the underlying libraries use them so I brought them along for the ride.

Almost all of these set/get pairs are very fast, short, inline functions and thus very efficient. However, the "set" methods do not call redraw(), you have to call it yourself. This greatly reduces code size and execution time. The only common exception is value(), this does redraw() if necessary.

Begin/End of groups and windows

Then we indicate we are done adding widgets to the window:

    $window->end();

The method Group::end() restores the "current group" to the parent of itself, in this case it is set to null because the window has no parent. You may also find it useful to call FLTK::Group::current(0) to turn this off completely.

Showing the Window

Then we cause the window to appear on the screen:

    $window->show();

On some systems the window does not actually appear until FLTK::run() is called, which flushes the cached instructions to the window server).

The Main Event Loop

    exit FLTK::run();

This will repeatedly wait for and then process events from the user. FLTK::run() does not return until all of the windows under FLTK control are closed (either by the user or your program).

When the user attempts to close the window, the callback for the window is called. If you don't change it, the callback will remove the window from the screen.

You can replace this callback with your own code, so you can prevent the window from closing, or pop up a confirmation, or create another window, or you can call exit if you want to exit when the user closes the "main" window even if other windows are still open.

FLTK was designed to not take over the main event loop. Instead a program can call FLTK::wait(), which will pause until "something happens" and then return. A program can call FLTK::wait() repeatedly or mix it with other calculations. You can do this if there are no windows displayed. The FLTK::wait() method is equivalent to:

    FLTK::wait() while FLTK::first_window();
    return 0;