From 8416a4012ecb985d150fad566659cf59ee1dc3aa Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Sat, 13 Sep 2008 15:55:32 +0000 Subject: Doxygen documentation - WP12 and WP13 - first step. Converted the descriptive chapters of the html docs to doxygen format and modified index.dox accordingly. This checkin includes only trivial reformatting, no major rewriting. Added a chapter "Migrating Code from FLTK 1.1 to 1.3". All links on the main page are working now. Todo: - Check doxygen error messages, rewrite pages (html tags, contents). - Fill the new "Migrating..." chapter. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6224 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- documentation/basics.dox | 362 +++++++++++ documentation/common.dox | 667 +++++++++++++++++++ documentation/drawing.dox | 967 ++++++++++++++++++++++++++++ documentation/editor.dox | 905 ++++++++++++++++++++++++++ documentation/enumerations.dox | 304 +++++++++ documentation/events.dox | 389 +++++++++++ documentation/examples.dox | 448 +++++++++++++ documentation/fluid.dox | 1359 +++++++++++++++++++++++++++++++++++++++ documentation/forms.dox | 201 ++++++ documentation/glut.dox | 193 ++++++ documentation/index.dox | 104 ++- documentation/intro.dox | 367 +++++++++++ documentation/license.dox | 437 +++++++++++++ documentation/migration_1_1.dox | 158 +++++ documentation/migration_1_3.dox | 11 + documentation/opengl.dox | 463 +++++++++++++ documentation/osissues.dox | 740 +++++++++++++++++++++ documentation/preface.dox | 2 +- documentation/subclassing.dox | 431 +++++++++++++ 19 files changed, 8454 insertions(+), 54 deletions(-) create mode 100644 documentation/basics.dox create mode 100644 documentation/common.dox create mode 100644 documentation/drawing.dox create mode 100644 documentation/editor.dox create mode 100644 documentation/enumerations.dox create mode 100644 documentation/events.dox create mode 100644 documentation/examples.dox create mode 100644 documentation/fluid.dox create mode 100644 documentation/forms.dox create mode 100644 documentation/glut.dox create mode 100644 documentation/intro.dox create mode 100644 documentation/license.dox create mode 100644 documentation/migration_1_1.dox create mode 100644 documentation/migration_1_3.dox create mode 100644 documentation/opengl.dox create mode 100644 documentation/osissues.dox create mode 100644 documentation/subclassing.dox diff --git a/documentation/basics.dox b/documentation/basics.dox new file mode 100644 index 000000000..3c330f907 --- /dev/null +++ b/documentation/basics.dox @@ -0,0 +1,362 @@ +/** + + \page basics 2 - FLTK Basics + +

This chapter teaches you the basics of compiling programs +that use FLTK.

+ +

Writing Your First FLTK Program

+ +

All programs must include the file <FL/Fl.H>. +In addition the program must include a header file for each +FLTK class it uses. Listing 1 shows a simple "Hello, +World!" program that uses FLTK to display the window.

+ + + + + +

After including the required header files, the program then creates a +window. All following widgets will automatically be children of this window.

+ + + +

Then we create a box with the "Hello, World!" string in it. FLTK automatically adds +the new box to window, the current grouping widget.

+ + + +

Next, we set the type of box and the size, font, and style of the label:

+ + + +

We tell FLTK that we will not add any more widgets to window.

+ + + +

Finally, we show the window and enter the FLTK event loop:

+ + + +

The resulting program will display the window in Figure 2-1. +You can quit the program by closing the window or pressing the +ESCape key.

+ +

Hello, World! Window
+Figure 2-1: The Hello, World! Window

+ +

Creating the Widgets

+ +

The widgets are created using the C++ new operator. For +most widgets the arguments to the constructor are:

+ + + +

The x and y parameters determine where the +widget or window is placed on the screen. In FLTK the top left +corner of the window or screen is the origin (i.e. x = 0, y = +0) and the units are in pixels.

+ +

The width and height parameters determine +the size of the widget or window in pixels. The maximum widget +size is typically governed by the underlying window system or +hardware.

+ +

label is a pointer to a character string to label +the widget with or NULL. If not specified the label +defaults to NULL. The label string must be in static +storage such as a string constant because FLTK does not make a +copy of it - it just uses the pointer.

+ +

Creating Widget hierarchies

+ +

Widgets are commonly ordered into functional groups, which +in turn may be grouped again, creating a hierarchy of widgets. +FLTK makes it easy to fill groups by automatically adding all widgets +that are created between a myGroup->begin() and +myGroup->end(). In this example, myGroup +would be the current group.

+ +

Newly created groups and their derived widgets implicitly call +begin() in the constructor, effectively adding all +subsequently created widgets to itself until end() +is called.

+ +

Setting the current group to NULL will stop automatic +hierarchies. New widgets can now be added manually using +Fl_Group::add(...) and Fl_Group::insert(...).

+ +

Get/Set Methods

+ +

box->box(FL_UP_BOX) sets the type of box the +Fl_Box draws, changing it from the default of +FL_NO_BOX, which means that no box is drawn. In our +"Hello, World!" example we use FL_UP_BOX, +which means that a raised button border will be drawn around +the widget. You can learn more about boxtypes in +Chapter 3.

+ +

You could examine the boxtype in by doing +box->box(). FLTK uses method name overloading to make +short names for get/set methods. A "set" method is always of +the form "void name(type)", and a "get" method is always +of the form "type name() const".

+ +

Redrawing After Changing Attributes

+ +

Almost all of the 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 exceptions are value() which calls +redraw() and label() which calls +redraw_label() if necessary.

+ +

Labels

+ +

All widgets support labels. In the case of window widgets, +the label is used for the label in the title bar. Our example +program calls the +labelfont, + labelsize, +and labeltype +methods.

+ +

The labelfont method sets the typeface and style +that is used for the label, which for this example we are using +FL_BOLD and FL_ITALIC. You can also specify +typefaces directly.

The labelsize method sets +the height of the font in pixels.

The labeltype +method sets the type of label. FLTK supports normal, embossed, +and shadowed labels internally, and more types can be added as +desired.

+ +

A complete list of all label options can be found in +Chapter 3.

+ +

Showing the Window

+ +

The show() method shows the widget or window. For windows +you can also provide the command-line arguments to allow users to +customize the appearance, size, and position of your windows.

+ +

The Main Event Loop

+ +

All FLTK applications (and most GUI applications in general) +are based on a simple event processing model. User actions such +as mouse movement, button clicks, and keyboard activity generate +events that are sent to an application. The application may then +ignore the events or respond to the user, typically by redrawing +a button in the "down" position, adding the text to an input +field, and so forth.

+ +

FLTK also supports idle, timer, and file pseudo-events that +cause a function to be called when they occur. Idle functions +are called when no user input is present and no timers or files +need to be handled - in short, when the application is not doing +anything. Idle callbacks are often used to update a 3D display +or do other background processing.

+ +

Timer functions are called after a specific amount of time +has expired. They can be used to pop up a progress dialog after +a certain amount of time or do other things that need to happen +at more-or-less regular intervals. FLTK timers are not 100% +accurate, so they should not be used to measure time intervals, +for example.

+ +

File functions are called when data is ready to read or +write, or when an error condition occurs on a file. They are +most often used to monitor network connections (sockets) for +data-driven displays.

+ +

FLTK applications must periodically check +(Fl::check()) or wait (Fl::wait()) for events +or use the Fl::run() +method to enter a standard event processing loop. Calling +Fl::run() is equivalent to the following code:

+ + + +

Fl::run() does not return until all of the windows +under FLTK control are closed by the user or your program.

+ +

Compiling Programs with Standard Compilers

+ +

Under UNIX (and under Microsoft Windows when using the GNU development +tools) you will probably need to tell the compiler where to find the +header files. This is usually done using the -I option:

+ + + +

The fltk-config script included with FLTK can be +used to get the options that are required by your compiler:

+ + + +

Similarly, when linking your application you will need to tell the +compiler to use the FLTK library:

+ + + +

Aside from the "fltk" library, there is also a "fltk_forms" +library for the XForms compatibility classes, "fltk_gl" for the +OpenGL and GLUT classes, and "fltk_images" for the image file +classes, Fl_Help_Dialog +widget, and system icon support. + +

+ + + +
Note: +

The libraries are named "fltk.lib", "fltkgl.lib", "fltkforms.lib", + and "fltkimages.lib", respectively under Windows. +

+ +

As before, the fltk-config script included with FLTK can be +used to get the options that are required by your linker:

+ + + + + +

The forms, GL, and images libraries are included with the "--use-foo" +options, as follows: + +

+ +

Finally, you can use the fltk-config script to +compile a single source file as a FLTK program: + +

+ +

Any of these will create an executable named filename. + +

Compiling Programs with Microsoft Visual C++

+ +

In Visual C++ you will need to tell the compiler where to +find the FLTK header files. This can be done by selecting +"Settings" from the "Project" menu and then +changing the "Preprocessor" settings under the +"C/C++" tab. You will also need to add the FLTK and +WinSock (WSOCK32.LIB) libraries to the "Link" +settings.

+ +

You can build your Microsoft Windows applications as Console or +WIN32 applications. If you want to use the standard C main() +function as the entry point, FLTK includes a WinMain() +function that will call your main() function for you.

+ +

Note: The Visual C++ 5.0 optimizer is known to cause problems with +many programs. We only recommend using the "Favor Small Code" +optimization setting. The Visual C++ 6.0 optimizer seems to be much +better and can be used with the "optimized for speed" setting.

+ +

Naming

+ +

All public symbols in FLTK start with the characters 'F' and 'L':

+ + + + + +

Header Files

+ +

The proper way to include FLTK header files is:

+ + + +
+ + + +
Note: + +

Case is significant on many operating systems, + and the C standard uses the forward slash (/) to + separate directories. Do not use any of the following + include lines:

+ +
    +	#include <FL\Fl_xyz.H>
    +	#include <fl/fl_xyz.h>
    +	#include <Fl/fl_xyz.h>
    +	
+ +
+ +*/ diff --git a/documentation/common.dox b/documentation/common.dox new file mode 100644 index 000000000..20553873e --- /dev/null +++ b/documentation/common.dox @@ -0,0 +1,667 @@ +/** + + \page common 3 - Common Widgets and Attributes + +

This chapter describes many of the widgets that are provided +with FLTK and covers how to query and set the standard +attributes.

+ +

Buttons

+ +

FLTK provides many types of buttons:

+ + + +

FLTK Buttons
+Figure 3-1: FLTK Button Widgets

+ +

All of these buttons just need the corresponding +<FL/Fl_xyz_Button.H> header file. The constructor +takes the bounding box of the button and optionally a label +string:

+ + + +

Each button has an associated +type() +which allows it to behave as a push button, toggle button, or +radio button:

+ + + +

For toggle and radio buttons, the +value() +method returns the current button state (0 = off, 1 = on). The +set() and +clear() +methods can be used on toggle buttons to turn a toggle button +on or off, respectively. Radio buttons can be turned on with +the +setonly() +method; this will also turn off other radio buttons in the same +group.

+ +

Text

+ +

FLTK provides several text widgets for displaying and receiving text:

+ + + +

The Fl_Output and Fl_Multiline_Output +widgets allow the user to copy text from the output field but +not change it.

+ +

The value() +method is used to get or set the string that is displayed:

+ + + +

The string is copied to the widget's own storage when you set +the value() of the widget.

+ +

The Fl_Text_Display and Fl_Text_Editor +widgets use an associated Fl_Text_Buffer class for the +value, instead of a simple string.

+ + + +

Valuators

+ +

Unlike text widgets, valuators keep track of numbers instead of +strings. FLTK provides the following valuators:

+ + + +

FLTK Valuators
+Figure 3-2: FLTK valuator widgets

+ +

The value() +method gets and sets the current value of the widget. The +minimum() +and maximum() +methods set the range of values that are reported by the +widget.

+ + + +

Groups

+ +

The Fl_Group widget class is used as a general +purpose "container" widget. Besides grouping radio +buttons, the groups are used to encapsulate windows, tabs, and +scrolled windows. The following group classes are available +with FLTK:

+ + + +

Setting the Size and Position of Widgets

+ +

The size and position of widgets is usually set when you +create them. You can access them with the x(), +y(), w(), and h() methods.

+ +

You can change the size and position by using the +position(), resize(), and size() +methods:

+ + + +

If you change a widget's size or position after it is +displayed you will have to call redraw() on the +widget's parent.

+ +

Colors

+ +

FLTK stores the colors of widgets as an 32-bit unsigned +number that is either an index into a color palette of 256 +colors or a 24-bit RGB color. The color palette is not +the X or WIN32 colormap, but instead is an internal table with +fixed contents.

+ +

There are symbols for naming some of the more common colors:

+ + + +

These symbols are the default colors for all FLTK widgets. They are +explained in more detail in the chapter +Enumerations

+ + + +

RGB colors can be set using the fl_rgb_color() +function:

+ + + +

The widget color is set using the color() method:

+ + + +

Similarly, the label color is set using the labelcolor() +method:

+ + + +

Box Types

+ +

The type Fl_Boxtype stored and returned in +Fl_Widget::box() +is an enumeration defined in <Enumerations.H>. +Figure 3-3 shows the standard box types included with FLTK.

+ +

FLTK Box Types
+Figure 3-3: FLTK box types

+ +

FL_NO_BOX means nothing is drawn at all, so whatever is +already on the screen remains. The FL_..._FRAME types only +draw their edges, leaving the interior unchanged. The blue color in +Figure 3-3 is the area that is not drawn by the frame types.

+ +

Making Your Own Boxtypes

+ +

You can define your own boxtypes by making a small function that draws +the box and adding it to the table of boxtypes.

+ +
+ + + +
Note: +

This interface has changed in FLTK 2.0!

+
+ +

The Drawing Function

+ +

The drawing function is passed the bounding box and background color +for the widget:

+ + + + + +

A simple drawing function might fill a rectangle with the +given color and then draw a black outline:

+ + + +

Fl_Boxtype fl_down(Fl_Boxtype)

+ +

fl_down returns the "pressed" or "down" version of a box. +If no "down" version of a given box exists, the behavior of this function +is undefined and some random box or frame is returned. +See also: fl_frame drawing. + +

Fl_Boxtype fl_frame(Fl_Boxtype)

+ +

fl_frame returns the unfilled, frame-only version of a box. +If no frame version of a given box exists, the behavior of this function +is undefined and some random box or frame is returned. +See also: fl_frame drawing. + +

Fl_Boxtype fl_box(Fl_Boxtype)

+ +

fl_box returns the filled version of a frame. +If no filled version of a given frame exists, the behavior of this function +is undefined and some random box or frame is returned. +See also: fl_frame. + +

Adding Your Box Type

+ +

The Fl::set_boxtype() method adds or replaces the +specified box type:

+ + + +

The last 4 arguments to Fl::set_boxtype() are the +offsets for the x, y, width, and height values that should be +subtracted when drawing the label inside the box.

+ +

A complete box design contains four box types in this order: +a filled, neutral box (UP_BOX), a filled, depressed box +(DOWN_BOX), and the same as outlines only (UP_FRAME +and DOWN_FRAME). The function +fl_down(Fl_Boxtype) +expects the neutral design on a boxtype with a numerical +value evenly divideable by two. +fl_frame(Fl_Boxtype) +expects the UP_BOX design at a value divideable by four.

+ +

Labels and Label Types

+ +

The label(), align(), labelfont(), +labelsize(), labeltype(), image(), and +deimage() methods control the labeling of widgets.

+ +

label()

+ +

The label() method sets the string that is displayed +for the label. Symbols can be included with the label string by +escaping them using the "@" symbol - "@@" displays a single at +sign. Figure 3-4 shows the available symbols.

+ +

FLTK Symbols
+Figure 3-4: FLTK label symbols

+ + + +

The @ sign may also be followed by the following optional +"formatting" characters, in this order:

+ + + +

Thus, to show a very large arrow pointing downward you would use the +label string "@+92->". + +

align()

+ +

The align() method positions the label. The following +constants are defined and may be OR'd together as needed:

+ + + +

labeltype()

+ +

The labeltype() method sets the type of the label. The +following standard label types are included:

+ + + +

image() and deimage()

+ +

The image() and deimage() methods set an image that +will be displayed with the widget. The deimage() method sets the +image that is shown when the widget is inactive, while the image() +method sets the image that is shown when the widget is active.

+ +

To make an image you use a subclass of +Fl_Image.

+ +

Making Your Own Label Types

+ +

Label types are actually indexes into a table of functions +that draw them. The primary purpose of this is to use this to +draw the labels in ways inaccessible through the +fl_font mechanisim (e.g. FL_ENGRAVED_LABEL) or +with program-generated letters or symbology.

+ +
+ + + +
Note: +

This interface has changed in FLTK 2.0!

+
+ +
Label Type Functions
+ +

To setup your own label type you will need to write two +functions: one to draw and one to measure the label. The draw +function is called with a pointer to a Fl_Label +structure containing the label information, the bounding box for +the label, and the label alignment:

+ + + +

The label should be drawn inside this bounding box, +even if FL_ALIGN_INSIDE is not enabled. The function +is not called if the label value is NULL.

+ +

The measure function is called with a pointer to a +Fl_Label structure and references to the width and +height:

+ + + +

The function should measure the size of the label and set +w and h to the size it will occupy.

+ +
Adding Your Label Type
+ +

The Fl::set_labeltype method creates a label type +using your draw and measure functions:

+ + + +

The label type number n can be any integer value +starting at the constant FL_FREE_LABELTYPE. Once you +have added the label type you can use the labeltype() +method to select your label type.

+ +

The Fl::set_labeltype method can also be used to overload +an existing label type such as FL_NORMAL_LABEL.

+ +

Making your own symbols

+ +

It is also possible to define your own drawings and add +them to the symbol list, so they can be rendered as part of +any label.

+ +

To create a new symbol, you implement a drawing function +void drawit(Fl_Color c) which typically uses the +complex drawing functions +to generate a vector shape inside a two-by-two units sized box +around the origin. This function is then linked into the symbols +table using fl_add_symbol:

+ + + +

name is the name of the symbol without the "@"; scalable +must be set to 1 if the symbol is generated using scalable vector drawing +functions.

+ + + +

This function draw a named symbol fitting the given rectangle. + +

Callbacks

+ +

Callbacks are functions that are called when the value of a +widget changes. A callback function is sent a Fl_Widget +pointer of the widget that changed and a pointer to data that +you provide:

+ + + +

The callback() method sets the callback function for a +widget. You can optionally pass a pointer to some data needed for the +callback:

+ + + +

Normally callbacks are performed only when the value of the +widget changes. You can change this using the +when() +method:

+ + + +
+ + + +
Note: + +

You cannot delete a widget inside a callback, as the + widget may still be accessed by FLTK after your callback + is completed. Instead, use the Fl::delete_widget() + method to mark your widget for deletion when it is safe + to do so.

+ +

Hint: + +

Many programmers new to FLTK or C++ try to use a + non-static class method instead of a static class method + or function for their callback. Since callbacks are done + outside a C++ class, the this pointer is not + initialized for class methods.

+ +

To work around this problem, define a static method + in your class that accepts a pointer to the class, and + then have the static method call the class method(s) as + needed. The data pointer you provide to the + callback() method of the widget can be a + pointer to the instance of your class.

+ +
+class Foo {
+  void my_callback(Fl_Widget *w);
+  static void my_static_callback(Fl_Widget *w, void *f) { ((Foo *)f)->my_callback(w); }
+  ...
+}
+
+...
+
+w->callback(my_static_callback, (void *)this);
+
+
+ +

Shortcuts

+ +

Shortcuts are key sequences that activate widgets such as +buttons or menu items. The shortcut() method sets the +shortcut for a widget:

+ + + +

The shortcut value is the key event value - the ASCII value +or one of the special keys like +FL_Enter - +combined with any modifiers like Shift, +Alt, and Control.

+ +*/ diff --git a/documentation/drawing.dox b/documentation/drawing.dox new file mode 100644 index 000000000..29694cc00 --- /dev/null +++ b/documentation/drawing.dox @@ -0,0 +1,967 @@ +/** + + \page drawing 5 - Drawing Things in FLTK + +

This chapter covers the drawing functions that are provided with FLTK. + +

When Can You Draw Things in FLTK?

+ +

There are only certain places you can execute drawing code in FLTK. +Calling these functions at other places will result in undefined +behavior! + +

+ +

FLTK Drawing Functions

+ +

To use the drawing functions you must first include the +<FL/fl_draw.H> header file. FLTK provides the +following types of drawing functions: + +

+ +

Boxes

+ +

FLTK provides three functions that can be used to draw boxes +for buttons and other UI controls. Each function uses the +supplied upper-lefthand corner and width and height to determine +where to draw the box. + +

void fl_draw_box(Fl_Boxtype b, int x, int y, int w, int h, Fl_Color c);

+ +

The first box drawing function is fl_draw_box() +which draws a standard boxtype c in the specified +color c. + +

void fl_frame(const char *s, int x, int y, int w, int h);

+ +

The fl_frame() function draws a series of line +segments around the given box. The string s must +contain groups of 4 letters which specify one of 24 standard +grayscale values, where 'A' is black and 'X' is white. The order +of each set of 4 characters is: top, left, bottom, right. The +results of calling fl_frame() with a string that is +not a multiple of 4 characters in length are undefined. + +

The only difference between this function and +fl_frame2() is the order of the line segments. + +

See also: fl_frame boxtype. + +

void fl_frame2(const char *s, int x, int y, int w, int h);

+ +

The fl_frame2() function draws a series of line +segments around the given box. The string s must +contain groups of 4 letters which specify one of 24 standard +grayscale values, where 'A' is black and 'X' is white. The order +of each set of 4 characters is: bottom, right, top, left. The +results of calling fl_frame2() with a string that is +not a multiple of 4 characters in length are undefined. + +

The only difference between this function and +fl_frame() is the order of the line segments. + +

Clipping

+ +

You can limit all your drawing to a rectangular region by calling +fl_push_clip, and put the drawings back by using fl_pop_clip. +This rectangle is measured in pixels and is unaffected by the current +transformation matrix. + +

In addition, the system may provide clipping when updating windows +which may be more complex than a simple rectangle.

+ +

void fl_clip(int x, int y, int w, int h)
+void fl_push_clip(int x, int y, int w, int h)

+ +

Intersect the current clip region with a rectangle and push this new +region onto the stack. The fl_clip() name is deprecated and +will be removed from future releases. + +

void fl_push_no_clip()

+ +

Pushes an empty clip region on the stack so nothing will be clipped. + +

void fl_pop_clip()

+ +

Restore the previous clip region. + +

+ + + +
Note: + +

You must call fl_pop_clip() once for every + time you call fl_push_clip(). If you return to FLTK + with the clip stack not empty unpredictable results + occur. + +

+ +

int fl_not_clipped(int x, int y, int w, int h)

+ +

Returns non-zero if any of the rectangle intersects the current clip +region. If this returns 0 you don't have to draw the object. + +

+ + + +
Note: + +

Under X this returns 2 if the rectangle is partially + clipped, and 1 if it is entirely inside the clip region. + +

+ +

int fl_clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, +int &H)

+ +

Intersect the rectangle x,y,w,h with the current +clip region and returns the bounding box of the result in +X,Y,W,H. Returns non-zero if the resulting rectangle is +different than the original. This can be used to limit the +necessary drawing to a rectangle. W and H are +set to zero if the rectangle is completely outside the region. + +

void fl_clip_region(Fl_Region r) +
Fl_Region fl_clip_region()

+ +

Replace the top of the clip stack with a clipping region of any shape. +Fl_Region is an operating system specific type. The second form returns +the current clipping region. + +

Colors

+ +

FLTK manages colors as 32-bit unsigned integers. Values from +0 to 255 represent colors from the FLTK 1.0.x standard colormap +and are allocated as needed on screens without TrueColor +support. The Fl_Color enumeration type defines the +standard colors and color cube for the first 256 colors. All of +these are named with symbols in <FL/Enumerations.H>. + +

Color values greater than 255 are treated as 24-bit RGB +values. These are mapped to the closest color supported by the +screen, either from one of the 256 colors in the FLTK 1.0.x +colormap or a direct RGB value on TrueColor screens. You can +generate 24-bit RGB color values using the fl_rgb_color() +function. + +

void fl_color(Fl_Color)

+ +

Sets the color for all subsequent drawing operations. + +

For colormapped displays, a color cell will be allocated out +of fl_colormap the first time you use a color. If the +colormap fills up then a least-squares algorithm is used to find +the closest color.

+ +

Fl_Color fl_color()

+ +

Returns the last fl_color() that was set. This can +be used for state save/restore. + +

void fl_color(uchar r, uchar g, uchar b)

+ +

Set the color for all subsequent drawing operations. The +closest possible match to the RGB color is used. The RGB color +is used directly on TrueColor displays. For colormap visuals the +nearest index in the gray ramp or color cube is used. + +

Line Dashes and Thickness

+ +

FLTK supports drawing of lines with different styles and +widths. Full functionality is not available under Windows 95, 98, +and Me due to the reduced drawing functionality these operating +systems provide. + +

void fl_line_style(int style, int width=0, char* dashes=0)

+ +

Set how to draw lines (the "pen"). If you change this it is your +responsibility to set it back to the default with +fl_line_style(0). + +

+ + + +
Note: + +

Because of how line styles are implemented on WIN32 + systems, you must set the line style after + setting the drawing color. If you set the color after + the line style you will lose the line style settings! + +

+ +

style is a bitmask which is a bitwise-OR of the following +values. If you don't specify a dash type you will get a solid +line. If you don't specify a cap or join type you will get a +system-defined default of whatever value is fastest. + +

+ +

width is the number of pixels thick to draw the lines. +Zero results in the system-defined default, which on both X and +Windows is somewhat different and nicer than 1. + + + +

dashes is a pointer to an array of dash lengths, measured in +pixels. The first location is how long to draw a solid portion, the +next is how long to draw the gap, then the solid, etc. It is +terminated with a zero-length entry. A NULL pointer or a zero-length +array results in a solid line. Odd array sizes are not supported and +result in undefined behavior. + +

+ + + +
Note: + +

The dashes array does not work under Windows 95, 98, + or Me, since those operating systems do not support + complex line styles. + +

+ +

Drawing Fast Shapes

+ +

These functions are used to draw almost all the FLTK widgets. +They draw on exact pixel boundaries and are as fast as possible. +Their behavior is duplicated exactly on all platforms FLTK is +ported. It is undefined whether these are affected by the transformation matrix, so you should only +call these while the matrix is set to the identity matrix (the +default). + +

void fl_point(int x, int y)

+ +

Draw a single pixel at the given coordinates. + +

void fl_rectf(int x, int y, int w, int h) +
void fl_rectf(int x, int y, int w, int h)

+ +

Color a rectangle that exactly fills the given bounding box. + +

void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b)

+ +

Color a rectangle with "exactly" the passed +r,g,b color. On screens with less than 24 bits of +color this is done by drawing a solid-colored block using fl_draw_image() so that +the correct color shade is produced. + +

void fl_rect(int x, int y, int w, int h) +
void fl_rect(int x, int y, int w, int h, Fl_Color c)

+ +

Draw a 1-pixel border inside this bounding box. + +

void fl_line(int x, int y, int x1, int y1) +
void fl_line(int x, int y, int x1, int y1, int x2, int y2)

+ +

Draw one or two lines between the given points. + +

void fl_loop(int x, int y, int x1, int y1, int x2, int y2) +
void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, +int y3)

+ +

Outline a 3 or 4-sided polygon with lines. + +

void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) +
void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int +x3, int y3)

+ +

Fill a 3 or 4-sided polygon. The polygon must be convex. + +

void fl_xyline(int x, int y, int x1) +
void fl_xyline(int x, int y, int x1, int y2) +
void fl_xyline(int x, int y, int x1, int y2, int x3)

+ +

Draw horizontal and vertical lines. A horizontal line is +drawn first, then a vertical, then a horizontal. + +

void fl_yxline(int x, int y, int y1) +
void fl_yxline(int x, int y, int y1, int x2) +
void fl_yxline(int x, int y, int y1, int x2, int y3)

+ +

Draw vertical and horizontal lines. A vertical line is drawn +first, then a horizontal, then a vertical. + +

void fl_arc(int x, int y, int w, int h, double a1, double a2) +
void fl_pie(int x, int y, int w, int h, double a1, double a2)

+ +

Draw ellipse sections using integer coordinates. These +functions match the rather limited circle drawing code provided +by X and WIN32. The advantage over using fl_arc with floating point +coordinates is that they are faster because they often use the +hardware, and they draw much nicer small circles, since the +small sizes are often hard-coded bitmaps. + +

If a complete circle is drawn it will fit inside the passed bounding +box. The two angles are measured in degrees counterclockwise from +3'oclock and are the starting and ending angle of the arc, a2 +must be greater or equal to a1.

+ +

fl_arc() draws a series of lines to approximate the arc. +Notice that the integer version of fl_arc() has a different +number of arguments than the fl_arc() +function described later in this chapter.

+ +

fl_pie() draws a filled-in pie slice. This slice may +extend outside the line drawn by fl_arc; to avoid this +use w - 1 and h - 1.

+ +

void fl_scroll(int X, int Y, int W, int H, int dx, int dy, +void (*draw_area)(void*, int,int,int,int), void* data)

+ +

Scroll a rectangle and draw the newly exposed portions. The contents +of the rectangular area is first shifted by dx and +dy pixels. The callback is then called for every newly +exposed rectangular area, + +

Drawing Complex Shapes

+ +

The complex drawing functions let you draw arbitrary shapes +with 2-D linear transformations. The functionality matches that +found in the Adobe® PostScriptTM language. The +exact pixels that are filled are less defined than for the fast +drawing functions so that FLTK can take advantage of drawing +hardware. On both X and WIN32 the transformed vertices are +rounded to integers before drawing the line segments: this +severely limits the accuracy of these functions for complex +graphics, so use OpenGL when greater accuracy and/or performance +is required. + +

void fl_push_matrix() +
void fl_pop_matrix()

+ +

Save and restore the current transformation. The maximum +depth of the stack is 4. + +

void fl_scale(float x, float y) +
void fl_scale(float x) +
void fl_translate(float x, float y) +
void fl_rotate(float d) +
void fl_mult_matrix(float a, float b, float c, float d, float +x, float y)

+ +

Concatenate another transformation onto the current one. The rotation +angle is in degrees (not radians) and is counter-clockwise. + +

double fl_transform_x(double x, double y) +
double fl_transform_y(double x, double y) +
double fl_transform_dx(double x, double y) +
double fl_transform_dy(double x, double y) +
void fl_transformed_vertex(double xf, double yf)

+ +

Transform a coordinate or a distance trough the current transformation matrix. +After transforming a coordinate pair, it can be added to the vertex +list without any forther translations using fl_transformed_vertex. + +

void fl_begin_points() +
void fl_end_points()

+ +

Start and end drawing a list of points. Points are added to +the list with fl_vertex. + +

void fl_begin_line() +
void fl_end_line()

+ +

Start and end drawing lines. + +

void fl_begin_loop() +
void fl_end_loop()

+ +

Start and end drawing a closed sequence of lines. + +

void fl_begin_polygon() +
void fl_end_polygon()

+ +

Start and end drawing a convex filled polygon. + +

void fl_begin_complex_polygon() +
void fl_gap() +
void fl_end_complex_polygon()

+ +

Start and end drawing a complex filled polygon. This polygon +may be concave, may have holes in it, or may be several +disconnected pieces. Call fl_gap() to seperate loops of +the path. It is unnecessary but harmless to call +fl_gap() before the first vertex, after the last one, +or several times in a row. + +

+ + + +
Note: + +

For portability, you should only draw polygons that + appear the same whether "even/odd" or + "non-zero" winding rules are used to fill + them. Holes should be drawn in the opposite direction of + the outside loop. + +

+ +

fl_gap() should only be called between +fl_begin_complex_polygon() and +fl_end_complex_polygon(). To outline the polygon, use +fl_begin_loop() and replace each fl_gap() with +fl_end_loop();fl_begin_loop().

+ +

void fl_vertex(float x, float y)

+Add a single vertex to the current path. + +

void fl_curve(float x, float y, float x1, float y1, float x2, float +y2, float x3, float y3)

+ +

Add a series of points on a Bezier curve to the path. The curve ends +(and two of the points) are at x,y and x3,y3. + +

void fl_arc(float x, float y, float r, float start, float end)

+ +

Add a series of points to the current path on the arc of a +circle; you can get elliptical paths by using scale and rotate +before calling fl_arc(). x,y are the center of +the circle, and r is its radius. fl_arc() +takes start and end angles that are measured +in degrees counter-clockwise from 3 o'clock. If end is +less than start then it draws the arc in a clockwise +direction. + +

void fl_circle(float x, float y, float r)

+ +

fl_circle() is equivalent to fl_arc(...,0,360) but +may be faster. It must be the only thing in the path: if you +want a circle as part of a complex polygon you must use fl_arc(). + +

+ + + +
Note: + +

fl_circle() draws incorrectly if the + transformation is both rotated and non-square scaled. + +

+ +

Drawing Text

+ +

All text is drawn in the current font. +It is undefined whether this location or the characters are +modified by the current transformation. + +

void fl_draw(const char *, int x, int y) +
void fl_draw(const char *, int n, int x, int y)

+ +

Draw a nul-terminated string or an array of n characters +starting at the given location. Text is aligned to the left and to +the baseline of the font. To align to the bottom, subtract fl_descent() from +y. To align to the top, subtract fl_descent() and add fl_height(). +This version of fl_draw provides direct access to +the text drawing function of the underlying OS. It does not apply any +special handling to control characters. + +

void fl_draw(const char *, int x, int y, int w, int h, +Fl_Align align, Fl_Image *img = 0, int draw_symbols = 1)

+ +

Fancy string drawing function which is used to draw all the +labels. The string is formatted and aligned inside the passed +box. Handles '\t' and '\n', expands all other control +characters to ^X, and aligns inside or against the edges of the +box described by x, y, w and h. See Fl_Widget::align() +for values for align. The value +FL_ALIGN_INSIDE is ignored, as this function always +prints inside the box. + +

If img is provided and is not NULL, the +image is drawn above or below the text as specified by the +align value. + +

The draw_symbols argument specifies whether or not +to look for symbol names starting with the "@" character. + +

The text length is limited to 1024 caracters per line. + +

void fl_measure(const char *, int &w, +int &h, int draw_symbols = 1)

+ +

Measure how wide and tall the string will be when printed by +the fl_draw(...align) function. If the incoming +w is non-zero it will wrap to that width. + +

int fl_height()

+ +

Recommended minimum line spacing for the current font. You +can also just use the value of size passed to fl_font(). + +

int fl_descent()

+ +

Recommended distance above the bottom of a +fl_height() tall box to draw the text at so it looks +centered vertically in that box. + +

float fl_width(const char*) +
float fl_width(const char*, int n) +
float fl_width(uchar)

+ +

Return the pixel width of a nul-terminated string, a sequence of n +characters, or a single character in the current font. + +

const char *fl_shortcut_label(ulong)

+ +

Unparse a shortcut value as used by Fl_Button +or Fl_Menu_Item +into a human-readable string like "Alt+N". This only +works if the shortcut is a character key or a numbered function +key. If the shortcut is zero an empty string is returned. The +return value points at a static buffer that is overwritten with +each call. + +

Fonts

+ +

FLTK supports a set of standard fonts based on the Times, +Helvetica/Arial, Courier, and Symbol typefaces, as well as +custom fonts that your application may load. Each font is +accessed by an index into a font table. + +

Initially only the first 16 faces are filled in. There are +symbolic names for them: FL_HELVETICA, +FL_TIMES, FL_COURIER, and modifier values +FL_BOLD and FL_ITALIC which can be added to +these, and FL_SYMBOL and FL_ZAPF_DINGBATS. +Faces greater than 255 cannot be used in Fl_Widget +labels, since Fl_Widget stores the index as a byte.

+ +

void fl_font(int face, int size)

+ +

Set the current font, which is then used by the routines +described above. You may call this outside a draw context if +necessary to call fl_width(), but on X this will open +the display. + +

The font is identified by a face and a +size. The size of the font is measured in +pixels and not "points". Lines should be spaced +size pixels apart or more.

+ +

int fl_font() +
int fl_size()

+ +

Returns the face and size set by the most recent call to +fl_font(a,b). This can be used to save/restore the +font. + +

Character Encoding

+ +

FLTK 1 supports western character sets using the eight bit encoding +of the user-selected global code page. For MS Windows and X11, the code +page is assumed to be Windows-1252/Latin1, a superset to ISO 8859-1. +On Mac OS X, we assume MacRoman. + +

FLTK provides the functions fl_latin1_to_local, +fl_local_to_latin1, fl_mac_roman_to_local, and +fl_local_to_mac_roman to convert strings between both +encodings. These functions are only required if your source +code contains "C"-strings with international characters and +if this source will be compiled on multiple platforms. + +

Assuming that the following source code was written on MS Windows, +this example will output the correct label on OS X and X11 as well. +Without the conversion call, the label on OS X would read +Fahrvergn¸gen with a deformed umlaut u. +

+  btn = new Fl_Button(10, 10, 300, 25);
+  btn->copy_label(fl_latin1_to_local("Fahrvergnügen"));
+
+ +

If your application uses characters that are not part of both +encodings, or it will be used in areas that commonly use different +code pages, yoou might consider upgrading to FLTK 2 which supports +UTF-8 encoding. + +

Drawing Overlays

+ +

These functions allow you to draw interactive selection rectangles +without using the overlay hardware. FLTK will XOR a single rectangle +outline over a window. + +

void fl_overlay_rect(int x, int y, int w, int h); +
void fl_overlay_clear();

+ +

fl_overlay_rect() draws a selection rectangle, erasing any +previous rectangle by XOR'ing it first. fl_overlay_clear() +will erase the rectangle without drawing a new one. + +

Using these functions is tricky. You should make a widget +with both a handle() and draw() method. +draw() should call fl_overlay_clear() before +doing anything else. Your handle() method should call +window()->make_current() and then +fl_overlay_rect() after FL_DRAG events, and +should call fl_overlay_clear() after a +FL_RELEASE event.

+ +

Drawing Images

+ +

To draw images, you can either do it directly from data in +your memory, or you can create a Fl_Image object. The advantage of +drawing directly is that it is more intuitive, and it is faster +if the image data changes more often than it is redrawn. The +advantage of using the object is that FLTK will cache translated +forms of the image (on X it uses a server pixmap) and thus +redrawing is much faster. + +

Direct Image Drawing

+ +

The behavior when drawing images when the current +transformation matrix is not the identity is not defined, so you +should only draw images when the matrix is set to the identity. + +

void fl_draw_image(const uchar *, int X, int Y, int W, int H, int D += 3, int LD = 0) +
void fl_draw_image_mono(const uchar *, int X, int Y, int W, int H, +int D = 1, int LD = 0)

+ +

Draw an 8-bit per color RGB or luminance image. The pointer +points at the "r" data of the top-left pixel. Color +data must be in r,g,b order. X,Y are where to +put the top-left corner. W and H define the +size of the image. D is the delta to add to the pointer +between pixels, it may be any value greater or equal to +3, or it can be negative to flip the image +horizontally. LD is the delta to add to the pointer +between lines (if 0 is passed it uses W * D), and may +be larger than W * D to crop data, or negative to flip +the image vertically. + +

It is highly recommended that you put the following code before the +first show() of any window in your program to get rid +of the dithering if possible:

+ + + +

Gray scale (1-channel) images may be drawn. This is done if +abs(D) is less than 3, or by calling +fl_draw_image_mono(). Only one 8-bit sample is used for +each pixel, and on screens with different numbers of bits for +red, green, and blue only gray colors are used. Setting +D greater than 1 will let you display one channel of a +color image. + +

+ + + +
Note: + +

The X version does not support all possible visuals. + If FLTK cannot draw the image in the current visual it + will abort. FLTK supports any visual of 8 bits or less, + and all common TrueColor visuals up to 32 bits.

+ +
+ +

typedef void (*fl_draw_image_cb)(void *, int x, int y, int w, uchar +*) +
void fl_draw_image(fl_draw_image_cb, void *, int X, int Y, int W, +int H, int D = 3) +
void fl_draw_image_mono(fl_draw_image_cb, void *, int X, int Y, +int W, int H, int D = 1)

+ +

Call the passed function to provide each scan line of the +image. This lets you generate the image as it is being drawn, +or do arbitrary decompression of stored data, provided it can be +decompressed to individual scan lines easily. + +

The callback is called with the void * user data +pointer which can be used to point at a structure of information +about the image, and the x, y, and w +of the scan line desired from the image. 0,0 is the upper-left +corner of the image, not X,Y. A pointer to a +buffer to put the data into is passed. You must copy w +pixels from scanline y, starting at pixel x, +to this buffer.

+ +

Due to cropping, less than the whole image may be requested. +So x may be greater than zero, the first y may +be greater than zero, and w may be less than +W. The buffer is long enough to store the entire W +* D pixels, this is for convenience with some decompression +schemes where you must decompress the entire line at once: +decompress it into the buffer, and then if x is not +zero, copy the data over so the x'th pixel is at the +start of the buffer.

+ +

You can assume the y's will be consecutive, except +the first one may be greater than zero.

+ +

If D is 4 or more, you must fill in the unused bytes +with zero.

+ +

int fl_draw_pixmap(char **data, int X, int Y, Fl_Color = FL_GRAY)

+ +

Draws XPM image data, with the top-left corner at the given position. +The image is dithered on 8-bit displays so you won't lose color space +for programs displaying both images and pixmaps. This function returns +zero if there was any error decoding the XPM data. + +

To use an XPM, do:

+ + + +

Transparent colors are replaced by the optional +Fl_Color argument. To draw with true transparency you must +use the Fl_Pixmap class. + +

int fl_measure_pixmap(char **data, int &w, int &h)

+ +

An XPM image contains the dimensions in its data. This +function finds and returns the width and height. The return +value is non-zero if the dimensions were parsed ok and zero if +there was any problem. + +

Direct Image Reading

+ +

FLTK provides a single function for reading from the current +window or off-screen buffer into a RGB(A) image buffer.

+ +

uchar *fl_read_image(uchar *p, int +X, int Y, int W, int H, int alpha = 0);

+ +

Read a RGB(A) image from the current window or off-screen +buffer. The p argument points to a buffer that can hold +the image and must be at least W*H*3 bytes when reading +RGB images and W*H*4 bytes when reading RGBA images. If +NULL, fl_read_image() will create an array of +the proper size which can be freed using delete[].

+ +

The alpha parameter controls whether an alpha +channel is created and the value that is placed in the alpha +channel. If 0, no alpha channel is generated.

+ +

Image Classes

+ +

FLTK provides a base image class called Fl_Image which supports +creating, copying, and drawing images of various kinds, along +with some basic color operations. Images can be used as labels +for widgets using the image() and +deimage() +methods or drawn directly. + +

The Fl_Image class +does almost nothing by itself, but is instead supported by three +basic image types: + +

+ +

The Fl_Bitmap class encapsulates a mono-color bitmap image. +The draw() method draws the image using the current drawing +color. + +

The Fl_Pixmap class encapsulates a colormapped image. +The draw() method draws the image using the colors in the +file, and masks off any transparent colors automatically. + +

The Fl_RGB_Image class encapsulates a full-color +(or grayscale) image with 1 to 4 color components. Images with +an even number of components are assumed to contain an +alpha channel that is used for transparency. The transparency +provided by the draw() method is either a 24-bit +blend against the existing window contents or a "screen door" +transparency mask, depending on the platform and screen color depth. + +

char fl_can_do_alpha_blending()

+ +

fl_can_do_alpha_blending() will return 1, if your +platform supports true alpha blending for RGBA images, or 0, +if FLTK will use screen door transparency. + +

FLTK also provides several image classes based on the three +standard image types for common file formats: + +

+ +

Each of these image classes load a named file of the +corresponding format. The Fl_Shared_Image class +can be used to load any type of image file - the class examines +the file and constructs an image of the appropriate type. + +

Finally, FLTK provides a special image class called Fl_Tiled_Image to tile +another image object in the specified area. This class can be +used to tile a background image in a Fl_Group widget, +for example. + +

virtual void copy();
+virtual void copy(int w, int h);

+ +

The copy() method creates a copy of the image. The second form +specifies the new size of the image - the image is resized using the +nearest-neighbor algorithm. + +

void draw(int x, int y, int w, int h, int ox = 0, int oy = 0);

+ +

The draw() method draws the image object. +x,y,w,h indicates a destination rectangle. +ox,oy,w,h is a source rectangle. This source rectangle +is copied to the destination. The source rectangle may extend +outside the image, i.e. ox and oy may be +negative and w and h may be bigger than the +image, and this area is left unchanged. + +

void draw(int x, int y)

+ +

Draws the image with the upper-left corner at x,y. +This is the same as doing draw(x,y,img->w(),img->h(),0,0). + +

Offscreen Drawing

+ +Sometimes it can be very useful to generate a complex drawing +in memory first and copy it to the screen at a later point in +time. This technique can significantly reduce the amount of +repeated drawing. Fl_Double_Window uses offscreen rendering +to avoid flickering on systems that don't support +double-buffering natively. + +

Fl_Offscreen fl_create_offscreen(int w, int h)

+ +

Create an RGB offscreen buffer with w*h pixels. + +

void fl_delete_offscreen(Fl_Offscreen)

+ +

Delete a previously created offscreen buffer. All drawings are lost. + +

void fl_begin_offscreen(Fl_Offscreen)

+ +

Send all subsequent drawing commands to this offscreen buffer. +FLTK can draw into a buffer at any time. There is no need to wait for +an Fl_Widget::draw() to occur. + +

void fl_end_offscreen()

+ +

Quit sending drawing commands to this offscreen buffer. + +

void fl_copy_offscreen(int x, int y, +int w, int h, Fl_Offscreen osrc, int srcx, int srcy)

+ +

Copy a rectangular area of the size w*h from srcx, srcy in the offscreen +buffer into the current buffer at x, y. + +*/ diff --git a/documentation/editor.dox b/documentation/editor.dox new file mode 100644 index 000000000..260c7a887 --- /dev/null +++ b/documentation/editor.dox @@ -0,0 +1,905 @@ +/** + + \page editor 4 - Designing a Simple Text Editor + +

This chapter takes you through the design of a simple +FLTK-based text editor. + +

Determining the Goals of the Text Editor

+ +

Since this will be the first big project you'll be doing with FLTK, +lets define what we want our text editor to do: + +

    + +
  1. Provide a menubar/menus for all functions.
  2. +
  3. Edit a single text file, possibly with multiple views.
  4. +
  5. Load from a file.
  6. +
  7. Save to a file.
  8. +
  9. Cut/copy/delete/paste functions.
  10. +
  11. Search and replace functions.
  12. +
  13. Keep track of when the file has been changed.
  14. + +
+ + + +

Designing the Main Window

+ +

Now that we've outlined the goals for our editor, we can begin with +the design of our GUI. Obviously the first thing that we need is a +window, which we'll place inside a class called EditorWindow: + +

+ +

Variables

+ +

Our text editor will need some global variables to keep track of +things: + +

+ +

The textbuf variable is the text editor buffer for +our window class described previously. We'll cover the other +variables as we build the application.

+ +

Menubars and Menus

+ +

The first goal requires us to use a menubar and menus that +define each function the editor needs to perform. The Fl_Menu_Item structure is +used to define the menus and items in a menubar:

+ + + +

Once we have the menus defined we can create the +Fl_Menu_Bar widget and assign the menus to it with:

+ + + +

We'll define the callback functions later. + +

Editing the Text

+ +

To keep things simple our text editor will use the +Fl_Text_Editor +widget to edit the text: + +

+ +

So that we can keep track of changes to the file, we also want to add +a "modify" callback:

+ + + +

Finally, we want to use a mono-spaced font like FL_COURIER: + +

+ +

The Replace Dialog

+ +

We can use the FLTK convenience functions for many of the +editor's dialogs, however the replace dialog needs its own +custom window. To keep things simple we will have a +"find" string, a "replace" string, and +"replace all", "replace next", and +"cancel" buttons. The strings are just +Fl_Input widgets, the "replace all" and +"cancel" buttons are Fl_Button widgets, and +the "replace next " button is a +Fl_Return_Button widget:

+ +

The search and replace dialog.
+Figure 4-1: The search and replace dialog.

+ + + +

Callbacks

+ +

Now that we've defined the GUI components of our editor, we +need to define our callback functions.

+ +

changed_cb()

+ +

This function will be called whenever the user changes any text in the +editor widget: + +

+ +

The set_title() function is one that we will write to set +the changed status on the current file. We're doing it this way +because we want to show the changed status in the window's +title bar. + +

copy_cb()

+ +

This callback function will call kf_copy() +to copy the currently selected text to the clipboard:

+ + + +

cut_cb()

+ +

This callback function will call kf_cut() +to cut the currently selected text to the clipboard:

+ + + +

delete_cb()

+ +

This callback function will call remove_selection() +to delete the currently selected text to the clipboard:

+ + + +

find_cb()

+ +

This callback function asks for a search string using the fl_input() +convenience function and then calls the find2_cb() +function to find the string: + +

+ +

find2_cb()

+ +

This function will find the next occurrence of the search +string. If the search string is blank then we want to pop up the +search dialog: + +

+ +

If the search string cannot be found we use the fl_alert() +convenience function to display a message to that effect. + +

new_cb()

+

This callback function will clear the editor widget and current +filename. It also calls the check_save() function to give the +user the opportunity to save the current file first as needed: + +

+ +

open_cb()

+ +

This callback function will ask the user for a filename and then load +the specified file into the input widget and current filename. It also +calls the check_save() function to give the user the +opportunity to save the current file first as needed: + +

+ +

We call the load_file() function to actually load the file. + +

paste_cb()

+ +

This callback function will call kf_paste() +to paste the clipboard at the current position:

+ + + +

quit_cb()

+ +

The quit callback will first see if the current file has been +modified, and if so give the user a chance to save it. It then exits +from the program: + +

+ +

replace_cb()

+ +

The replace callback just shows the replace dialog: + +

+ +

replace2_cb()

+ +

This callback will replace the next occurence of the replacement +string. If nothing has been entered for the replacement string, then +the replace dialog is displayed instead: + +

+ +

replall_cb()

+ +

This callback will replace all occurences of the search +string in the file: + +

+ +

replcan_cb()

+ +

This callback just hides the replace dialog: + +

+ +

save_cb()

+ +

This callback saves the current file. If the current filename is +blank it calls the "save as" callback: + +

+ +

The save_file() function saves the current file to the +specified filename. + +

saveas_cb()

+ +

This callback asks the user for a filename and saves the current file: + +

+ +

The save_file() function saves the current file to the +specified filename. + +

Other Functions

+ +

Now that we've defined the callback functions, we need our support +functions to make it all work: + +

check_save()

+ +

This function checks to see if the current file needs to be saved. If +so, it asks the user if they want to save it: + +

+ +

load_file()

+ +

This function loads the specified file into the textbuf class: + +

+ +

When loading the file we use the loadfile() +method to "replace" the text in the buffer, or the insertfile() +method to insert text in the buffer from the named file. + +

save_file()

+ +

This function saves the current buffer to the specified file: + +

+ +

set_title()

+ +

This function checks the changed variable and updates the +window label accordingly: +

+ +

The main() Function

+ +

Once we've created all of the support functions, the only thing left +is to tie them all together with the main() function. +The main() function creates a new text buffer, creates a +new view (window) for the text, shows the window, loads the file on +the command-line (if any), and then enters the FLTK event loop: + +

+ +

Compiling the Editor

+ +

The complete source for our text editor can be found in the test/editor.cxx source file. Both the Makefile and Visual C++ +workspace include the necessary rules to build the editor. You can +also compile it using a standard compiler with: + +

+ +

or by using the fltk-config script with: + +

+ +

As noted in Chapter 1, you may need to +include compiler and linker options to tell them where to find the FLTK +library. Also, the CC command may also be called gcc +or c++ on your system. + +

Congratulations, you've just built your own text editor!

+ +

The Final Product

+ +The final editor window should look like the image in Figure 4-2. + +

The completed editor window.
+Figure 4-2: The completed editor window

+ +

Advanced Features

+ +

Now that we've implemented the basic functionality, it is +time to show off some of the advanced features of the +Fl_Text_Editor widget. + +

Syntax Highlighting

+ +

The Fl_Text_Editor widget supports highlighting +of text with different fonts, colors, and sizes. The +implementation is based on the excellent NEdit text editor core, which +uses a parallel "style" buffer which tracks the font, color, and +size of the text that is drawn. + +

Styles are defined using the +Fl_Text_Display::Style_Table_Entry structure +defined in <FL/Fl_Text_Display.H>: + +

+ +

The color member sets the color for the text, +the font member sets the FLTK font index to use, +and the size member sets the pixel size of the +text. The attr member is currently not used. + +

For our text editor we'll define 7 styles for plain code, +comments, keywords, and preprocessor directives: + +

+ +

You'll notice that the comments show a letter next to each +style - each style in the style buffer is referenced using a +character starting with the letter 'A'. + +

You call the highlight_data() method to associate the +style data and buffer with the text editor widget: + +

+ +

Finally, you need to add a callback to the main text buffer so +that changes to the text buffer are mirrored in the style buffer: + +

+ +

The style_update() function, like the change_cb() +function described earlier, is called whenever text is added or removed from +the text buffer. It mirrors the changes in the style buffer and then updates +the style data as necessary: + +

+ +

The style_parse() function scans a copy of the +text in the buffer and generates the necessary style characters +for display. It assumes that parsing begins at the start of a line: + +

+ +*/ diff --git a/documentation/enumerations.dox b/documentation/enumerations.dox new file mode 100644 index 000000000..10ed628f5 --- /dev/null +++ b/documentation/enumerations.dox @@ -0,0 +1,304 @@ +/** + + \page enumerations C - FLTK Enumerations + +

This appendix lists the enumerations provided in the +<FL/Enumerations.H> header file, organized by +section. Constants whose value is zero are marked with "(0)", +this is often useful to know when programming. + +

Version Numbers

+ The FLTK version number is stored in a number of compile-time +constants: + +

Events

+ Events are identified by an Fl_Event enumeration value. The +following events are currently defined: + +

Callback "When" Conditions

+ The following constants determine when a callback is performed: + +

Fl::event_button() Values

+ +

The following constants define the button numbers for FL_PUSH and +FL_RELEASE events: + +

+ +

Fl::event_key() Values

+ The following constants define the non-ASCII keys on the keyboard for +FL_KEYBOARD and FL_SHORTCUT events: + +

Fl::event_state() Values

+ The following constants define bits in the Fl::event_state() + value: + + +

Alignment Values

+ The following constants define bits that can be used with +Fl_Widget::align() to control the positioning of the +label: + +

Fonts

+ The following constants define the standard FLTK fonts: + + +

Colors

+ +

The Fl_Color enumeration type holds a FLTK color value. +Colors are either 8-bit indexes into a virtual colormap or 24-bit RGB +color values. Color indices occupy the lower 8 bits of the value, while +RGB colors occupy the upper 24 bits, for a byte organization of RGBI. + +

Color Constants

+ +

Constants are defined for the user-defined foreground and background +colors, as well as specific colors and the start of the grayscale ramp +and color cube in the virtual colormap. Inline functions are provided to +retrieve specific grayscale, color cube, or RGB color values. + +

The following color constants can be used to access the user-defined +colors: + +

+ +

The following color constants can be used to access the colors from the +FLTK standard color cube: + +

+ +

The inline methods for getting a grayscale, color cube, or +RGB color value are described in Appendix B - Function +Reference. + +

Cursors

+ +

The following constants define the mouse cursors that are available in +FLTK. The double-headed arrows are bitmaps +provided by FLTK on X, the others are provided by system-defined +cursors.

+ + + +

FD "When" Conditions

+ + + +

Damage Masks

+ The following damage mask bits are used by the standard FLTK widgets: + + +*/ diff --git a/documentation/events.dox b/documentation/events.dox new file mode 100644 index 000000000..d2610064e --- /dev/null +++ b/documentation/events.dox @@ -0,0 +1,389 @@ +/** + + \page events 6 - Handling Events + +

This chapter discusses the FLTK event model and how to handle +events in your program or widget. + +

The FLTK Event Model

+ +

Every time a user moves the mouse pointer, clicks a button, +or presses a key, an event is generated and sent to your +application. Events can also come from other programs like the +window manager. + +

Events are identified by the integer argument passed to the +Fl_Widget::handle() virtual +method. Other information about the most recent event is stored in +static locations and acquired by calling the Fl::event_*() methods. This static +information remains valid until the next event is read from the window +system, so it is ok to look at it outside of the handle() +method. + +

Mouse Events

+ +

FL_PUSH

+ +

A mouse button has gone down with the mouse pointing at this +widget. You can find out what button by calling +Fl::event_button(). You find out the mouse position by +calling Fl::event_x() and Fl::event_y(). + +

A widget indicates that it "wants" the mouse click +by returning non-zero from its handle() method. It +will then become the +Fl::pushed() widget and will get FL_DRAG and +the matching FL_RELEASE events. If handle() +returns zero then FLTK will try sending the FL_PUSH to +another widget.

+ +

FL_DRAG

+ +

The mouse has moved with a button held down. The current +button state is in Fl::event_state(). +The mouse position is in Fl::event_x() and Fl::event_y(). + +

In order to receive FL_DRAG events, the widget must +return non-zero when handling FL_PUSH.

+ +

FL_RELEASE

+ +

A mouse button has been released. You can find out what +button by calling Fl::event_button(). + +

In order to receive the FL_RELEASE event, the widget must +return non-zero when handling FL_PUSH.

+ +

FL_MOVE

+ +

The mouse has moved without any mouse buttons held down. +This event is sent to the Fl::belowmouse() +widget.

+ +

In order to receive FL_MOVE events, the widget must +return non-zero when handling FL_ENTER.

+ +

FL_MOUSEWHEEL

+ +

The user has moved the mouse wheel. The Fl::event_dx() and Fl::event_dy() methods +can be used to find the amount to scroll horizontally and +vertically. + +

Focus Events

+ +

FL_ENTER

+ +

The mouse has been moved to point at this widget. This can +be used for highlighting feedback. If a widget wants to +highlight or otherwise track the mouse, it indicates this by +returning non-zero from its handle() method. It then +becomes the Fl::belowmouse() +widget and will receive FL_MOVE and FL_LEAVE +events. + +

FL_LEAVE

+ +

The mouse has moved out of the widget. + +

In order to receive the FL_LEAVE event, the widget must +return non-zero when handling FL_ENTER.

+ +

FL_FOCUS

+ +

This indicates an attempt to give a widget the +keyboard focus. + +

If a widget wants the focus, it should change itself to +display the fact that it has the focus, and return non-zero from +its handle() +method. It then becomes the Fl::focus() widget and gets +FL_KEYDOWN, FL_KEYUP, and FL_UNFOCUS +events. + +

The focus will change either because the window manager +changed which window gets the focus, or because the user tried +to navigate using tab, arrows, or other keys. You can check Fl::event_key() to +figure out why it moved. For navigation it will be the key +pressed and interaction with the window manager it will be +zero. + +

FL_UNFOCUS

+ +

This event is sent to the previous Fl::focus() widget when +another widget gets the focus or the window loses focus. + +

Keyboard Events

+ +

FL_KEYDOWN, FL_KEYUP

+ +

A key was pressed or released. The key can be found in Fl::event_key(). The +text that the key should insert can be found with Fl::event_text() and +its length is in Fl::event_length(). +If you use the key handle() should return 1. If you +return zero then FLTK assumes you ignored the key and will +then attempt to send it to a parent widget. If none of them want +it, it will change the event into a FL_SHORTCUT event. + +

To receive FL_KEYBOARD events you must also +respond to the FL_FOCUS and FL_UNFOCUS +events. + +

If you are writing a text-editing widget you may also want to +call the Fl::compose() +function to translate individual keystrokes into foreign +characters. + +

FL_KEYUP events are sent to the widget that +currently has focus. This is not necessarily the same widget +that received the corresponding FL_KEYDOWN event +because focus may have changed between events. + +

FL_SHORTCUT

+ +

If the Fl::focus() +widget is zero or ignores an FL_KEYBOARD event then +FLTK tries sending this event to every widget it can, until one +of them returns non-zero. FL_SHORTCUT is first sent to +the Fl::belowmouse() widget, then its parents and +siblings, and eventually to every widget in the window, trying +to find an object that returns non-zero. FLTK tries really hard +to not to ignore any keystrokes! + +

You can also make "global" shortcuts by using Fl::add_handler(). A +global shortcut will work no matter what windows are displayed +or which one has the focus.

+ +

Widget Events

+ +

FL_DEACTIVATE

+ +

This widget is no longer active, due to deactivate() +being called on it or one of its parents. active() may +still be true after this, the widget is only active if +active() is true on it and all its parents (use active_r() to check this). + +

FL_ACTIVATE

+ +

This widget is now active, due to activate() +being called on it or one of its parents. + +

FL_HIDE

+ +

This widget is no longer visible, due to hide() being +called on it or one of its parents, or due to a parent window +being minimized. visible() may still be true after +this, but the widget is visible only if visible() is +true for it and all its parents (use visible_r() to +check this). + +

FL_SHOW

+ +

This widget is visible again, due to show() being +called on it or one of its parents, or due to a parent window +being restored. Child Fl_Windows respond to this by +actually creating the window if not done already, so if you +subclass a window, be sure to pass FL_SHOW to the base +class handle() method! + +

Clipboard Events

+ +

FL_PASTE

+ +

You should get this event some time after you call Fl::paste(). The contents +of Fl::event_text() +is the text to insert and the number of characters is in Fl::event_length(). + +

FL_SELECTIONCLEAR

+ +

The Fl::selection_owner() +will get this event before the selection is moved to another +widget. This indicates that some other widget or program has +claimed the selection. Motif programs used this to clear the +selection indication. Most modern programs ignore this. + +

Drag And Drop Events

+ +

FLTK supports drag and drop of text and files from any +application on the desktop. Text is transfered using +the current code page. Files are received as a list of full path +and file names, seperated by newline. On some platforms, path +names are prepended with file://. + +

The drag and drop data is available in Fl::event_text() +at the concluding FL_PASTE. On some platforms, the +event text is also available for the FL_DND_* events, +however application must not depend on that behavior because it +depends on the protocol used on each platform. + +

FL_DND_* events cannot be used in widgets derived +from Fl_Group or Fl_Window. + +

FL_DND_ENTER

+ +

The mouse has been moved to point at this widget. A widget +that is interested in receiving drag'n'drop data must return 1 +to receive FL_DND_DRAG, FL_DND_LEAVE and FL_DND_RELEASE events. + +

FL_DND_DRAG

+ +

The mouse has been moved inside a widget while dragging data. +A widget that is interested in receiving drag'n'drop data should +indicate the possible drop position. + +

FL_DND_LEAVE

+ +

The mouse has moved out of the widget. + +

FL_DND_RELEASE

+ +

The user has released the mouse button dropping data into +the widget. If the widget returns 1, it will receive the data in +the immediatly following FL_PASTE event. + + + +

Fl::event_*() methods

+ +

FLTK keeps the information about the most recent event in +static storage. This information is good until the next event is +processed. Thus it is valid inside handle() and +callback() methods. + +

These are all trivial inline functions and thus very fast and small:

+ + + +

Event Propagation

+ +

FLTK follows very simple and unchangeable rules for sending +events. The major innovation is that widgets can indicate (by +returning 0 from the handle() method) that they are not +interested in an event, and FLTK can then send that event +elsewhere. This eliminates the need for "interests" +(event masks or tables), and this is probably the main reason +FLTK is much smaller than other toolkits. + +

Most events are sent directly to the handle() method +of the Fl_Window that the window system says they +belong to. The window (actually the Fl_Group that +Fl_Window is a subclass of) is responsible for sending +the events on to any child widgets. To make the +Fl_Group code somewhat easier, FLTK sends some events +(FL_DRAG, FL_RELEASE, FL_KEYBOARD, +FL_SHORTCUT, FL_UNFOCUS, and +FL_LEAVE) directly to leaf widgets. These procedures +control those leaf widgets: + +

+ +

FLTK Compose-Character Sequences

+ +

The foreign-letter compose processing done by the Fl_Input widget is provided in +a function that you can call if you are writing your own text editor +widget. + +

FLTK uses its own compose processing to allow "preview" of +the partially composed sequence, which is impossible with the +usual "dead key" processing. + +

Although currently only characters in the ISO-8859-1 +character set are handled, you should call this in case any +enhancements to the processing are done in the future. The +interface has been designed to handle arbitrary UTF-8 encoded +text. + +

The following methods are provided for character composition: + +

+ +*/ diff --git a/documentation/examples.dox b/documentation/examples.dox new file mode 100644 index 000000000..7ae2482d9 --- /dev/null +++ b/documentation/examples.dox @@ -0,0 +1,448 @@ +/** + + \page examples J - Example Source Code + +

March 19, 2005

+ +

The FLTK distribution contains over 60 sample applications written +in, or ported to, FLTK. If the FLTK archive you received does not +contain a 'test' directory, you can download the complete FLTK +distribution from +http://fltk.org/software.php.

+ +

Most of the example programs were created while testing a group of widgets. +They are not meant to be great achievements in clean C++ programming, but merely +a test platform to verify the functionality of the FLTK library.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Example Applications
adjusterarcaskbitmapblocksboxtype
browserbuttonbuttonscheckersclockcolbrowser
color_choosercubeCubeViewcursorcurvedemo
doublebuffereditorfast_slowfile_chooserfluidfonts
formsfractalsfullscreengl_overlayglpuzzlehello
helpiconizeimageinactiveinputinput_choice
keyboardlabelline_stylelist_visualsmandelbrotmenubar
messageminimumnavigationoutputoverlaypack
pixmap_browserpixmappreferencesradioresizeboxresize
scrollshapesubwindowsudokusymbolstabs
threadstiletiled_imagevaluators
+ +

adjuster

+adjuster shows a nifty little widget for quickly +setting values in a great range. + +

arc

+The arc demo explains how to derive your own widget to +generate some custom drawings. The sample drawings use the matrix +based arc drawing for some fun effects. + +

ask

+ask shows some of FLTK's standard dialog boxes. Click +the correct answers or you may end up in a loop, or you may end +up in a loop, or you... . + +

bitmap

+This simple test shows the use of a single color bitmap as a +label for a box widget. Bitmaps are stored in the X11 '.bmp' +file format and can be part of the source code. + +

blocks

+A wonderful and addictive game that shows the usage of FLTK +timers, graphics, and how to implement sound on all platforms. +blocks is also a good example for the Mac OS X specific +bundle format. + +

boxtype

+boxtype gives an overview of readily available boxes and +frames in FLTK. More types can be added by the application programmer. +When using themes, FLTK shuffles boxtypes around to give your program +a new look. + +

browser

+browser shows the capabilities of the Fl_Browser widget. +Important features tested are loading of files, line formatting, and +correct positioning of the browser data window. + +

button

+The button test is a simple demo of push-buttons and callbacks. + +

buttons

+buttons shows a sample of FLTK button types. + +

checkers

+Written by Steve Poulsen in early 1979, checkers shows +how to convert a VT100 text-terminal based program into a neat +application with a graphical UI. Check out the code that drags the +pieces, and how the pieces are drawn by layering. Then tell me +how to beat the computer at Checkers. + +

clock

+The clock demo shows two analog clocks. The innards of +the Fl_Clock widget are pretty interesting, explaining +the use of timeouts and matrix based drawing. + +

colbrowser

+colbrowser runs only on X11 systems. It reads +/usr/lib/X11/rgb.txt to show the color representation +of every text entry in the file. This is beautiful, but +only moderatly useful unless your UI is written in Motif. + +

color_chooser

+The color_chooser gives a short demo of FLTK's palette based +color chooser and of the RGB based color wheel. + +

cube

+The cube demo shows the speed of OpenGL. It also tests +the ability to render two OpenGL buffers into a single window, +and shows OpenGL text. + +

CubeView

+CubeView shows how to create a UI containing OpenGL with Fluid. + +

cursor

+The cursor demo show all mouse cursor shapes that come standard +with FLTK. The fgcolor and bgcolor sliders work only +on few systems (some version of Irix for example). + +

curve

+curve draws a nice Bezier curve into a custom widget. The +points option for splines is not supported on all platforms. + +

demo

+This tool allows quick access to all programs in the test directory. +demo is based on the visuals of the IrixGL demo program. The menu +tree can be changed by editing test/demo.menu. + +

doublebuffer

+The doublebuffer demo show the difference between a single +buffered window, which may flicker during a slow redraw, and a +double buffered window, which never flickers, but uses twice the +amount of RAM. Some modern OS's double buffer all windows automatically +to allow transparency and shadows on the desktop. FLTK is smart enough +to not tripple buffer a window in that case. + +

editor

+FLTK has two very different text input widgets. Fl_Input +and derived classes are rather leight weight, however +Fl_Text_Editor is a complete port of nedit (with permission). +The editor test is almost a full application, showing custom +syntax highlighting and dialog creation. + +

fast_slow

+fast_slow shows how an application can use then when() +setting to receive different kinds of callbacks. + +

file_chooser

+The standard FLTK file_chooser is the result of many +iterations, trying to find a middle ground between a complex +browser and a fast light implementation. + +

fonts

+fonts show all available text fonts on the host system. +If your machine still has some pixmap based fonts, the supported +sizes will be shown in bold face. Only the first 256 fonts will +be listed. + +

forms

+forms is an XForms program with very few changes. +Search for "fltk" to find all changes necessary to port to fltk. +This demo show the different boxtypes. Note that some +boxtypes are not appropriate for some objects. + +

fractals

+fractals shows how to mix OpenGL, Glut and FLTK code. +FLTK supports a rather large subset of Glut, so that many Glut +application compile just fine. + +

fullscreen

+This demo shows how to do many of the window manipulations that +are popular for games. +You can toggle the border on/off, switch between single- +and double-buffered rendering, and take over the entire +screen. More information in the source code. + +

gl_overlay

+gl_overlay shows OpenGL overlay plane rendering. If no +hardware overlay plane is available, FLTK will simulate it +for you. + +

glpuzzle

+The glpuzzle test shows how most Glut source code compiles +easily under FLTK. + +

hello

+hello: Hello, World. Need I say maore? Well, maybe. This +tiny demo shows how little is needed to get a functioning application +running with FLTK. Quite impressive, I'd say. + +

help

+help displays the built-in FLTK help browser. The +Fl_Help_Dialog understands a subset of html and renders +various image formats. This widget makes it easy to provide help +pages to the user without depending on the operating system's +html browser. + +

iconize

+iconize demonstrates the effect of the window functions +hide(), iconize(), and show(). + +

image

+The image demo shows how an image can be created on the fly. +This generated image contains an alpha (transparency) channel which +lets previous renderings 'shine through', either via true +transparency or by using screen door transparency (pixelation). + +

inactive

+inactive tests the correct rendering of inactive widgets. +To see the inactive version of images, you can check out the pixmap +or image test. + +

input

+This tool shows and tests different types of text input fields based on +Fl_Input_. The input program also tests various +settings of Fl_Input::when(). + +

input_choice

+input_choice tests the latest addition to FLTK1, a text input +field with an attached pulldown menu. Windows users will recognize +similarities to the 'ComboBox'. input_choice starts up in +'plastic' scheme, but the traditional scheme is also supported. + +

keyboard

+FLTK unifies keyboard events for all platforms. The keyboard +test can be used to check the return values of Fl::event_key() +and Fl::event_text(). It is also great to see the modifier +buttons and the scroll wheel at work. Quit this application by closing +the window. The ESC key will not work. + +

label

+Every FLTK widget can have a label attached to it. The label +demo shows alignment, clipping and wrapping of text labels. Labels +can contain symbols at the start and end of the text, like @FLTK +or @circle uh-huh @square. + +

line_style

+Advanced line drawing can be tested with line_style. +Not all platforms support all line styles. + +

list_visuals

+This little app finds all available pixel formats for the current X11 +screen. But since you are now an FLTK user, you don't have to worry +about any of this. + +

mandelbrot

+mandelbrot shows two advanced topics in one test. It creates +grayscale images on the fly, updating them via the idle callback +system. This is one of the few occasions where the idle callback +is very useful by giving all available processor time to the application +without blocking the UI or other apps. + +

menubar

+The menubar tests many aspects of FLTK's popup menu system. +Among the features are radio buttons, menus taller than the screen, +arbitrary sub menu depth, and global shortcuts. + +

message

+message pops up a few of FLTK's standars message boxes. + +

minimum

+The minimum test program verifies that the update regions +are set correctly. In a real life application, the trail would +be avoided by choosing a smaller label or by setting label clipping +differently. + +

navigation

+navigation demonstrates how the text cursor moves from +text field to text field when using the arrow keys, tab, and shift-tab. + +

output

+output shows the difference between the single line and +multi line mode of the Fl_Output widget. Fonts can be +selected from the FLTK standard list of fonts. + +

overlay

+The overlay test app show how easy an FLTK window can +be layered to display cursor and manipulator style elemnts. This +example derives a new class from Fl_Overly_WIndow and +provides a new function to draw custom overlays. + +

pack

+The pack test program demonstrates the resizing +and repositioning of children of the Fl_Pack group. +Putting an Fl_Pack into an Fl_Scroll is +a useful way to create a browser for large sets of data. + +

pixmap_browser

+pixmap_browser tests the shared-image interface. When using +the same image multiple times, Fl_Shared_Image will keep it +only once in memory. + +

pixmap

+This simple test shows the use of a LUT based pixmap as a +label for a box widget. Pixmaps are stored in the X11 '.xpm' +file format and can be part of the source code. Pixmaps support +one transparent color. + +

preferences

+I do have my preferences in the morning, but sometimes I +just can't remember a thing. This is where the Fl_Preferences +come in handy. They remember any kind of data between program launches. + +

radio

+The radio tool was created entirely with fluid. It +shows some of the available button types and tests radio +button behavior. + +

resizebox

+resizebox shows some possible ways of FLTK's automatic +resize bahavior.. + +

resize

+The resize demo tests size and position functions with +the given window manager. + +

scroll

+scroll shows how to scroll an area of widgets, one of +them beeing a slow custom drawing. Fl_Scroll uses +clipping and smart window area copying to improve redraw speed. +The buttons at the bottom of the window control decoration rendering +and updates. + +

shape

+shape is a very minimal demo that shows how to create +your own OpenGL rendering widget. Now that you know that, go ahead +and write that flight simulator you always dreamt of. + +

subwindow

+The subwindow demo tests messaging and drawing between +the main window and 'true' sub windows. A sub window is different +to a group by resetting the FLTK coordinate stystem to 0, 0 in the +top left corner. On Win32 and X11, subwindows have their own +operating system specific handle. + +

sudoku

+Another highly addictive game - don't play it, I warned you. +The implementation shows how to create application icons, +how to deal with OS specifics, and how to generate sound. + +

symbols

+symbols are a speciality of FLTK. These little vector +drawings can be integrated into labels. They scale and rotate, +and with a little patience, you can define your own. The rotation +number refers to 45 degree rotations if you were looking at a +numeric keypad (2 is down, 6 is right, etc.). + +

tabs

+The tabs tool was created with fluid. It tests +correct hiding and redisplaying of tabs, navigation across tabs, +resize behavior, and no unneeded redrawing of invisible widgets. + +

The tabs application shows the Fl_Tabs widget +on the left and the Fl_Wizard widget on the right side +for direct comparison of these two panel management widgets. + +

threads

+FLTK can be used in a multithreading environment. There are some +limitations, mostly due to the underlying operating system. +threads show how to use Fl::lock(), +Fl::unlock(), and Fl::awake() in secondary threads +to keep FLTK happy. Although locking works on all platforms, +this demo is not available on every machine. + +

tile

+The tile tool shows a nice way of using Fl_Tile. +To test correct resizing of subwindows, the widget for region +1 is created from an Fl_Window class. + +

tiled_image

+The tiled_image demo uses an image as the background +for a window by repeating it over the full size of the widget. +Thw window is resizable and shows how the image gets repeated. + +

valuators

+valuators shows all of FLTK's nifty widgets to change +numeric values. + +

fluid

+fuid is not only a big test program, but also a very +useful visual UI designer. Many parts of fluid were +created using fluid. + +*/ diff --git a/documentation/fluid.dox b/documentation/fluid.dox new file mode 100644 index 000000000..38a82c7c6 --- /dev/null +++ b/documentation/fluid.dox @@ -0,0 +1,1359 @@ +/** + + \page fluid 9 - Programming with FLUID + +

This chapter shows how to use the Fast Light User-Interface Designer +("FLUID") to create your GUIs.

+ +

Subchapters: +

+ +

What is FLUID?

+ +

The Fast Light User Interface Designer, or FLUID, is a +graphical editor that is used to produce FLTK source code. FLUID +edits and saves its state in .fl files. These files +are text, and you can (with care) edit them in a text editor, +perhaps to get some special effects.

+ +

FLUID can "compile" the .fl file into a +.cxx and a .h file. The .cxx file +defines all the objects from the .fl file and the +.h file declares all the global ones. FLUID also +supports localization (Internationalization) +of label strings using message files and the GNU gettext or +POSIX catgets interfaces. + +

A simple program can be made by putting all your code (including a +main() function) into the .fl file and thus making the .cxx file a +single source file to compile. Most programs are more complex than +this, so you write other .cxx files that call the FLUID functions. +These .cxx files must #include the .h file or they can +#include the .cxx file so it still appears to be a single source +file. + +

FLUID organization.
+Figure 9-1: FLUID organization.

+ +

Normally the FLUID file defines one or more functions or classes which +output C++ code. Each function defines a one or more FLTK +windows, and all the widgets that go inside those windows.

+

Widgets created by FLUID are either "named", "complex named" or +"unnamed". A named widget has a legal C++ variable identifier as its +name (i.e. only alphanumeric and underscore). In this case FLUID +defines a global variable or class member that will point at the widget +after the function defining it is called. A complex named object has +punctuation such as '.' or '->' or any other symbols in its name. In +this case FLUID assigns a pointer to the widget to the name, but does +not attempt to declare it. This can be used to get the widgets into +structures. An unnamed widget has a blank name and no pointer is stored.

+

Widgets may either call a named callback function that you write in +another source file, or you can supply a small piece of C++ source and +FLUID will write a private callback function into the .cxx file.

+

Running FLUID Under UNIX

+ To run FLUID under UNIX, type: + +to edit the .fl file filename.fl. If the file does not exist +you will get an error pop-up, but if you dismiss it you will be editing +a blank file of that name. You can run FLUID without any name, in +which case you will be editing an unnamed blank setup (but you can use +save-as to write it to a file). +

You can provide any of the standard FLTK switches before the filename:

+ + +

Changing the colors may be useful to see what your interface +will look at if the user calls it with the same switches. +Similarly, using "-scheme plastic" will show how the interface +will look using the "plastic" scheme. + +

In the current version, if you don't put FLUID into the +background with '&' then you will be able to abort FLUID by +typing CTRL-C on the terminal. It will exit +immediately, losing any changes.

+ +

Running FLUID Under Microsoft Windows

+ +

To run FLUID under WIN32, double-click on the FLUID.exe +file. You can also run FLUID from the Command Prompt window. +FLUID always runs in the background under WIN32. + +

Compiling .fl files

+ +

FLUID can also be called as a command-line +"compiler" to create the .cxx and .h +file from a .fl file. To do this type: + +

+ +

This will read the filename.fl file and write +filename.cxx and filename.h. Any leading +directory on filename.fl will be stripped, so they are +always written to the current directory. If there are any errors +reading or writing the files, FLUID will print the error and +exit with a non-zero code. You can use the following lines in a +makefile to automate the creation of the source and header +files: + +

+ +

Most versions of make support rules that cause .fl +files to be compiled: + +

+ +

A Short Tutorial

+ +

FLUID is an amazingly powerful little program. However, this +power comes at a price as it is not always obvious how to +accomplish seemingly simple tasks with it. This tutorial will +show you how to generate a complete user interface class with +FLUID that is used for the CubeView program provided with FLTK. + +

CubeView demo.
+Figure 9-2: CubeView demo.

+ +

The window is of class CubeViewUI, and is completely generated by FLUID, including +class member functions. The central display of the cube is a separate +subclass of Fl_Gl_Window called CubeView. CubeViewUI manages CubeView +using callbacks from the various sliders and rollers to manipulate the +viewing angle and zoom of CubeView. +

At the completion of this tutorial you will (hopefully) understand +how to: +

    +
  1. Use FLUID to create a complete user interface class, including +constructor and any member functions necessary. +
  2. Use FLUID to set callbacks member functions of a custom widget +classes. +
  3. Subclass an Fl_Gl_Window to suit +your purposes. +
+ +

The CubeView Class

+The CubeView class is a subclass of Fl_Gl_Window. It has methods for +setting the zoom, the x and y pan, and the rotation angle +about the x and yaxes. +

You can safely skip this section as long as you realize the CubeView +is a sublass of Fl_Gl_Window and will respond to calls from +CubeViewUI, generated by FLUID. +

The CubeView Class Definition

+Here is the CubeView class definition, as given by its header file +"test/CubeView.h": + + +

The CubeView Class Implementation

+ +

Here is the CubeView implementation. It is very similar to the +"cube" demo included with FLTK. + +

+ +

The CubeViewUI Class

+ +

We will completely construct a window to display and control the +CubeView defined in the previous section using FLUID. + +

Defining the CubeViewUI Class

+ +

Once you have started FLUID, the first step in defining a class is to +create a new class within FLUID using the New->Code->Class +menu item. Name the class "CubeViewUI" and leave the +subclass blank. We do not need any inheritance for this +window. You should see the new class declaration in the FLUID +browser window. + +

FLUID file for CubeView.
+Figure 9-3: FLUID file for CubeView.

+ +

Adding the Class Constructor

+ +

Click on the CubeViewUI class in the FLUID window and add a new method +by selecting New->Code->Function/Method. The name of the +function will also be CubeViewUI. FLUID will understands that this will +be the constructor for the class and will generate the appropriate +code. Make sure you declare the constructor public. + +

Then add a window to the CubeViewUI class. Highlight the name of +the constructor in the FLUID browser window and click on +New->Group->Window. In a similar manner add the +following to the CubeViewUI constructor: + +

+ +

None of these additions need be public. And they shouldn't be +unless you plan to expose them as part of the interface for +CubeViewUI. + +

When you are finished you should have something like this: + +

FLUID window containing CubeView demo.
+Figure 9-4: FLUID window containing CubeView demo.

+ +

We will talk about the show() method that is highlighted +shortly. + +

Adding the CubeView Widget

+ +

What we have is nice, but does little to show our cube. We have already +defined the CubeView class and we would like to show it within the +CubeViewUI. + +

The CubeView class inherits the Fl_Gl_Window class, which +is created in the same way as a Fl_Box widget. Use +New->Other->Box to add a square box to the main window. +This will be no ordinary box, however. + +

The Box properties window will appear. The key to letting CubeViewUI +display CubeView is to enter CubeView in the "Class:" text +entry box. This tells FLUID that it is not an Fl_Box, but a +similar widget with the same constructor. In the "Extra +Code:" field enter #include "CubeView.h" + +

This #include is important, as we have just included +CubeView as a member of CubeViewUI, so any public CubeView methods are +now available to CubeViewUI. + +

CubeView methods.
+Figure 9-5: CubeView methods.

+ +

Defining the Callbacks

+ +

Each of the widgets we defined before adding CubeView can have +callbacks that call CubeView methods. You can call an external +function or put in a short amount of code in the "Callback" +field of the widget panel. For example, the callback for the +ypan slider is: + +

+ +

We call cube->redraw() after changing the value to update +the CubeView window. CubeView could easily be modified to do this, but +it is nice to keep this exposed in the case where you may want to do +more than one view change only redrawing once saves a lot of time. + +

There is no reason no wait until after you have added CubeView to +enter these callbacks. FLUID assumes you are smart enough not to refer +to members or functions that don't exist. + +

Adding a Class Method

+ +

You can add class methods within FLUID that have nothing to do with the +GUI. An an example add a show function so that CubeViewUI can actually +appear on the screen. + +

Make sure the top level CubeViewUI is selected and select +New->Code->Function/Method. Just use the name +show(). We don't need a return value here, and since we will +not be adding any widgets to this method FLUID will assign it a return +type of void. + +

CubeView constructor.
+Figure 9-6: CubeView constructor.

+ +

Once the new method has been added, highlight its name and select +New->Code->Code. Enter the method's code in the code window. + +

Adding Constructor Initialization Code

+ +

If you need to add code to initialize class, for example setting +initial values of the horizontal and vertical angles in the +CubeView, you can simply highlight the Constructor and select +New->Code->Code. Add any required code. + +

Generating the Code

+ +

Now that we have completely defined the CubeViewUI, we have to generate +the code. There is one last trick to ensure this all works. Open the +preferences dialog from Edit->Preferences. + +

At the bottom of the preferences dialog box is the key: "Include +Header from Code". Select that option and set your desired file +extensions and you are in business. You can include the CubeViewUI.h +(or whatever extension you prefer) as you would any other C++ class. + + + +

FLUID Reference

+ +

The following sections describe each of the windows in FLUID. + +

The Widget Browser

+ +

The main window shows a menu bar and a scrolling browser of +all the defined widgets. The name of the .fl file being +edited is shown in the window title. + +

The widgets are stored in a hierarchy. You can open and close a +level by clicking the "triangle" at the left of a widget. +The leftmost widgets are the parents, and all the widgets +listed below them are their children. Parents don't have to have +any children.

+ +

The top level of the hierarchy is composed of functions and +classes. Each of these will produce a single C++ public +function or class in the output .cxx file. Calling the function or +instantiating the class will create all of the child widgets.

+ +

The second level of the hierarchy contains the windows. Each of these +produces an instance of class Fl_Window.

+ +

Below that are either widgets (subclasses of Fl_Widget) or +groups of widgets (including other groups). Plain groups are for +layout, navigation, and resize purposes. Tab groups provide the +well-known file-card tab interface.

+ +

Widgets are shown in the browser by either their name (such +as "main_panel" in the example), or by their type +and label (such as "Button "the green"").

+ +

You select widgets by clicking on their names, which highlights +them (you can also select widgets from any displayed window). You can +select many widgets by dragging the mouse across them, or by using +Shift+Click to toggle them on and off. To select no widgets, click in +the blank area under the last widget. Note that hidden children may +be selected even when there is no visual indication of this. + +

You open widgets by double-clicking on them, or (to open several +widgets you have picked) by typing the F1 key. A control panel will appear +so you can change the widget(s).

+ +

Menu Items

+ +

The menu bar at the top is duplicated as a pop-up menu on any +displayed window. The shortcuts for all the menu items work in any +window. The menu items are:

+ +

File/Open... (Ctrl+o)

+ +

Discards the current editing session and reads in a different +.fl file. You are asked for confirmation if you have +changed the current file. + +

FLUID can also read .fd files produced by the Forms +and XForms "fdesign" programs. It is best to +File/Merge them instead of opening them. FLUID does not +understand everything in a .fd file, and will print a +warning message on the controlling terminal for all data it does +not understand. You will probably need to edit the resulting +setup to fix these errors. Be careful not to save the file +without changing the name, as FLUID will write over the +.fd file with its own format, which fdesign cannot +read!

+ +

File/Insert... (Ctrl+i)

+ +

Inserts the contents of another .fl file, without +changing the name of the current .fl file. All the +functions (even if they have the same names as the current ones) +are added, and you will have to use cut/paste to put the widgets +where you want. + +

File/Save (Ctrl+s)

+ +

Writes the current data to the .fl file. If the +file is unnamed then FLUID will ask for a filename. + +

File/Save As...(Ctrl+Shift+S)

+ +

Asks for a new filename and saves the file. + +

File/Write Code (Ctrl+Shift+C)

+ +

"Compiles" the data into a .cxx and .h +file. These are exactly the same as the files you get when you run +FLUID with the -c switch. + +

The output file names are the same as the .fl file, with +the leading directory and trailing ".fl" stripped, and +".h" or ".cxx" appended.

+ +

File/Write Strings (Ctrl+Shift+W)

+ +

Writes a message file for all of the text labels defined in +the current file. + +

The output file name is the same as the .fl file, +with the leading directory and trailing ".fl" +stripped, and ".txt", ".po", or +".msg" appended depending on the Internationalization Mode.

+ +

File/Quit (Ctrl+q)

+ +

Exits FLUID. You are asked for confirmation if you have +changed the current file. + +

Edit/Undo (Ctrl+z)

+ +

This isn't implemented yet. You should do save often so you can +recover from any mistakes you make. + +

Edit/Cut (Ctrl+x)

+ +

Deletes the selected widgets and all of their children. +These are saved to a "clipboard" file and can be +pasted back into any FLUID window. + +

Edit/Copy (Ctrl+c)

+ +

Copies the selected widgets and all of their children to the +"clipboard" file. + +

Edit/Paste (Ctrl+c)

+ +

Pastes the widgets from the clipboard file. + +

If the widget is a window, it is added to whatever function +is selected, or contained in the current selection.

+ +

If the widget is a normal widget, it is added to whatever +window or group is selected. If none is, it is added to the +window or group that is the parent of the current selection.

+ +

To avoid confusion, it is best to select exactly one widget +before doing a paste.

+ +

Cut/paste is the only way to change the parent of a +widget.

+ +

Edit/Select All (Ctrl+a)

+ +

Selects all widgets in the same group as the current +selection. + +

If they are all selected already then this selects all +widgets in that group's parent. Repeatedly typing Ctrl+a will +select larger and larger groups of widgets until everything is +selected.

+ +

Edit/Open... (F1 or double click)

+ +

Displays the current widget in the attributes panel. If the +widget is a window and it is not visible then the window is +shown instead. + +

Edit/Sort

+ +

Sorts the selected widgets into left to right, top to bottom +order. You need to do this to make navigation keys in FLTK work +correctly. You may then fine-tune the sorting with +"Earlier" and "Later". This does not affect +the positions of windows or functions. + +

Edit/Earlier (F2)

+ +

Moves all of the selected widgets one earlier in order among +the children of their parent (if possible). This will affect +navigation order, and if the widgets overlap it will affect how +they draw, as the later widget is drawn on top of the earlier +one. You can also use this to reorder functions, classes, and +windows within functions. + +

Edit/Later (F3)

+ +

Moves all of the selected widgets one later in order among +the children of their parent (if possible). + +

Edit/Group (F7)

+ +

Creates a new Fl_Group and make all the currently +selected widgets children of it. + +

Edit/Ungroup (F8)

+ +

Deletes the parent group if all the children of a group are +selected. + +

Edit/Overlays on/off (Ctrl+Shift+O)

+ +

Toggles the display of the red overlays off, without changing +the selection. This makes it easier to see box borders and how +the layout looks. The overlays will be forced back on if you +change the selection. + +

Edit/Project Settings... (Ctrl+p)

+ +

Displays the project settings panel. +The output filenames control the extensions or names of the +files the are generated by FLUID. If you check the "Include .h +from .cxx" button the code file will include the header file +automatically. + +

The internationalization options are described later in this chapter. + +

FLUID Preferences Window.
+Figure 9-7: FLUID Preferences Window.

+ +

Edit/GUI Settings... (Shift+Ctrl+p)

+ +

Displays the GUI settings panel. This panel is used +to control the user interface settings. + +

New/Code/Function

+ +

Creates a new C function. You will be asked for a name for +the function. This name should be a legal C++ function +template, without the return type. You can pass arguments which +can be referred to by code you type into the individual widgets. + +

If the function contains any unnamed windows, it will be +declared as returning a Fl_Window pointer. The unnamed window +will be returned from it (more than one unnamed window is +useless). If the function contains only named windows, it will +be declared as returning nothing (void).

+ +

It is possible to make the .cxx output be a +self-contained program that can be compiled and executed. This +is done by deleting the function name so +main(argc,argv) is used. The function will call +show() on all the windows it creates and then call +Fl::run(). This can also be used to test resize +behavior or other parts of the user interface.

+ +

You can change the function name by double-clicking on the +function.

+ +

New/Window

+ +

Creates a new Fl_Window widget. The window is added +to the currently selected function, or to the function +containing the currently selected item. The window will appear, +sized to 100x100. You can resize it to whatever size you +require. + +

The widget panel will also appear and is described later in +this chapter.

+ +

New/...

+ +

All other items on the New menu are subclasses of +Fl_Widget. Creating them will add them to the +currently selected group or window, or the group or window +containing the currently selected widget. The initial +dimensions and position are chosen by copying the current +widget, if possible. + +

When you create the widget you will get the widget's control +panel, which is described later in this chapter.

+ + +

Layout/Align/...

+ +

Align all selected widgets to the first widget in the selection. + +

Layout/Space Evenly/...

+ +

Space all selected widgets evenly inside the selected space. +Widgets will be sorted from first to last. + +

Layout/Make Same Size/...

+ +

Make all slected widgets the same size as the first selected widget. + +

Layout/Center in Group/...

+ +

Center all selected widgets relative to their parent widget + +

Layout/Grid... (Ctrl+g)

+ +

Displays the grid settings panel. +This panel +controls the grid that all widgets snap to when you move and +resize them, and for the "snap" which is how far a widget has to +be dragged from its original position to actually change. + + +

Shell/Execute Command... (Alt+x)

+ +

Displays the shell command panel. The shell command +is commonly used to run a 'make' script to compile the FLTK output. + +

Shell/Execute Again (Alt+g)

+ +

Run the shell command again. + +

Help/About FLUID

+ +

Pops up a panel showing the version of FLUID. + +

Help/On FLUID

+ +

Shows this chapter of the manual. + +

Help/Manual

+ +

Shows the contents page of the manual + +

The Widget Panel

+ +

When you double-click on a widget or a set of widgets you +will get the "widget attribute panel". + +

When you change attributes using this panel, the changes are +reflected immediately in the window. It is useful to hit the +"no overlay" button (or type Ctrl+Shift+O) to hide the +red overlay so you can see the widgets more accurately, +especially when setting the box type. + +

If you have several widgets selected, they may have different +values for the fields. In this case the value for one of +the widgets is shown. But if you change this value, all +of the selected widgets are changed to the new value. + +

Hitting "OK" makes the changes permanent. +Selecting a different widget also makes the changes permanent. +FLUID checks for simple syntax errors such as mismatched +parenthesis in any code before saving any text. + +

"Revert" or "Cancel" put everything back +to when you last brought up the panel or hit OK. However in the +current version of FLUID, changes to "visible" +attributes (such as the color, label, box) are not undone by +revert or cancel. Changes to code like the callbacks are +undone, however. + + +

The FLUID widget GUI attributes.
+Figure 9-8: The FLUID widget GUI attributes.

+ +

GUI Attributes

+ +

Label (text field)

+ +

String to print next to or inside the button. You can put +newlines into the string to make multiple lines. The easiest way +is by typing Ctrl+j.

+ +

Symbols can be added to the +label using the at sign ("@"). + +

Label (pull down menu)

+ +

How to draw the label. Normal, shadowed, engraved, and +embossed change the appearance of the text. + +

Image

+ +

The active image for the widget. Click on the +Browse... button to pick an image file using the file +chooser. + +

Inactive

+ +

The inactive image for the widget. Click on the +Browse... button to pick an image file using the file +chooser. + +

Alignment (buttons)

+ +

Where to draw the label. The arrows put it on that side of +the widget, you can combine the to put it in the corner. The +"box" button puts the label inside the widget, rather +than outside. + +

The clip button clips the label to the widget box, the +wrap button wraps any text in the label, and the text +image button puts the text over the image instead of under +the image. + +

Position (text fields)

+ +

The position fields show the current position and size of the +widget box. Enter new values to move and/or resize a widget. + +

Values (text fields)

+ +

The values and limits of the current widget. Depending on the +type of widget, some or all of these fields may be inactive. + +

Shortcut

+ +

The shortcut key to activate the widget. Click on the +shortcut button and press any key sequence to set the shortcut. + +

Attributes (buttons)

+ +

The Visible button controls whether the widget is +visible (on) or hidden (off) initially. Don't change this for +windows or for the immediate children of a Tabs group. + +

The Active button controls whether the widget is +activated (on) or deactivated (off) initially. Most widgets +appear greyed out when deactivated. + +

The Resizable button controls whether the window is +resizeable. In addition all the size changes of a window or +group will go "into" the resizable child. If you have +a large data display surrounded by buttons, you probably want +that data area to be resizable. You can get more complex +behavior by making invisible boxes the resizable widget, or by +using hierarchies of groups. Unfortunately the only way to test +it is to compile the program. Resizing the FLUID window is +not the same as what will happen in the user program.

+ +

The Hotspot button causes the parent window to be +positioned with that widget centered on the mouse. This +position is determined when the FLUID function is called, +so you should call it immediately before showing the window. If +you want the window to hide and then reappear at a new position, +you should have your program set the hotspot itself just before +show(). + +

The Border button turns the window manager border on +or off. On most window managers you will have to close the +window and reopen it to see the effect. + +

X Class (text field)

+ +

The string typed into here is passed to the X window manager +as the class. This can change the icon or window decorations. +On most (all?) window managers you will have to close the window +and reopen it to see the effect. + + +

The FLUID widget Style attributes.
+Figure 9-9: The FLUID widget Style attributes.

+ +

Style Attributes

+ +

Label Font (pulldown menu)

+ +

Font to draw the label in. Ignored by symbols, bitmaps, and +pixmaps. Your program can change the actual font used by these +"slots" in case you want some font other than the 16 +provided. + +

Label Size (pulldown menu)

+ +

Pixel size (height) for the font to draw the label in. +Ignored by symbols, bitmaps, and pixmaps. To see the result +without dismissing the panel, type the new number and then Tab. + +

Label Color (button)

+ +

Color to draw the label. Ignored by pixmaps (bitmaps, +however, do use this color as the foreground color). + +

Box (pulldown menu)

+ +

The boxtype to draw as a background for the widget. + +

Many widgets will work, and draw faster, with a +"frame" instead of a "box". A frame does +not draw the colored interior, leaving whatever was already +there visible. Be careful, as FLUID may draw this ok but the +real program may leave unwanted stuff inside the widget.

+ +

If a window is filled with child widgets, you can speed up +redrawing by changing the window's box type to +"NO_BOX". FLUID will display a checkerboard for any +areas that are not colored in by boxes. Note that this +checkerboard is not drawn by the resulting program. Instead +random garbage will be displayed.

+ +

Down Box (pulldown menu)

+ +

The boxtype to draw when a button is pressed or for some +parts of other widgets like scrollbars and valuators. + +

Color (button)

+ +

The color to draw the box with.

+ +

Select Color (button)

+ +

Some widgets will use this color for certain parts. FLUID +does not always show the result of this: this is the color +buttons draw in when pushed down, and the color of input fields +when they have the focus.

+ +

Text Font, Size, and Color

+ +

Some widgets display text, such as input fields, pull-down +menus, and browsers. + + +

The FLUID widget C++ attributes.
+Figure 9-10: The FLUID widget C++ attributes.

+ +

C++ Attributes

+ +

Class

+ +

This is how you use your own subclasses of +Fl_Widget. Whatever identifier you type in here will +be the class that is instantiated. + +

In addition, no #include header file is put in the +.h file. You must provide a #include line as +the first line of the "Extra Code" which declares your +subclass.

+ +

The class must be similar to the class you are spoofing. It +does not have to be a subclass. It is sometimes useful to +change this to another FLTK class. Currently the only way to get +a double-buffered window is to change this field for the window +to "Fl_Double_Window" and to add "#include +<FL/Fl_Double_Window.h>" to the extra code.

+ +

Type (upper-right pulldown menu)

+ +

Some classes have subtypes that modify their appearance or behavior. +You pick the subtype off of this menu. + +

Name (text field)

+ +

Name of a variable to declare, and to store a pointer to this +widget into. This variable will be of type "<class>*". If the name is +blank then no variable is created. + +

You can name several widgets with "name[0]", "name[1]", "name[2]", +etc. This will cause FLUID to declare an array of pointers. The array +is big enough that the highest number found can be stored. All widgets +that in the array must be the same type.

+ +

Public (button)

+ +

Controls whether the widget is publicly accessible. When +embedding widgets in a C++ class, this controls whether the +widget is public or private in the class. +Otherwise is controls whether the widget is declared +static or global (extern). + +

Extra Code (text fields)

+ +

These four fields let you type in literal lines of code to +dump into the .h or .cxx files. + +

If the text starts with a # or the word +extern then FLUID thinks this is an "include" +line, and it is written to the .h file. If the same +include line occurs several times then only one copy is +written.

+ +

All other lines are "code" lines. The current +widget is pointed to by the local variable o. The +window being constructed is pointed to by the local variable +w. You can also access any arguments passed to the +function here, and any named widgets that are before this +one.

+ +

FLUID will check for matching parenthesis, braces, and +quotes, but does not do much other error checking. Be careful +here, as it may be hard to figure out what widget is producing +an error in the compiler. If you need more than four lines you +probably should call a function in your own .cxx +code.

+ +

Callback (text field)

+ +

This can either be the name of a function, or a small snippet +of code. If you enter anything but letters, numbers, and the +underscore then FLUID treats it as code. + +

A name names a function in your own code. It must be +declared as void name(<class>*,void*).

+ +

A code snippet is inserted into a static function in the +.cxx output file. The function prototype is void +name(class *o, void *v) so that you can refer to the +widget as o and the user_data() as +v. FLUID will check for matching parenthesis, braces, +and quotes, but does not do much other error checking. Be +careful here, as it may be hard to figure out what widget is +producing an error in the compiler.

+ +

If the callback is blank then no callback is set.

+ +

User Data (text field)

+ +

This is a value for the user_data() of the widget. +If blank the default value of zero is used. This can be any +piece of C code that can be cast to a void pointer. + +

Type (text field)

+ +

The void * in the callback function prototypes is +replaced with this. You may want to use long for old +XForms code. Be warned that anything other than void * +is not guaranteed to work! However on most architectures other +pointer types are ok, and long is usually ok, too. + +

When (pulldown menu)

+ +

When to do the callback. This can be Never, +Changed, Release, or Enter Key. The value of +Enter Key is only useful for text input fields. + +

There are other rare but useful values for the +when() field that are not in the menu. You should use +the extra code fields to put these values in.

+ +

No Change (button)

+ +

The No Change button means the callback is done on the +matching event even if the data is not changed. + +

Selecting and Moving Widgets

+ +

Double-clicking a window name in the browser will display it, +if not displayed yet. From this display you can select widgets, +sets of widgets, and move or resize them. To close a window +either double-click it or type ESC. + +

To select a widget, click it. To select several widgets drag +a rectangle around them. Holding down shift will toggle the +selection of the widgets instead.

+ +

You cannot pick hidden widgets. You also cannot choose some +widgets if they are completely overlapped by later widgets. Use +the browser to select these widgets.

+ +

The selected widgets are shown with a red "overlay" +line around them. You can move the widgets by dragging this +box. Or you can resize them by dragging the outer edges and +corners. Hold down the Alt key while dragging the mouse to +defeat the snap-to-grid effect for fine positioning.

+ +

If there is a tab box displayed you can change which child is +visible by clicking on the file tabs. The child you pick is +selected.

+ +

The arrow, tab, and shift+tab keys "navigate" the +selection. Left, right, tab, or shift+tab move to the next or +previous widgets in the hierarchy. Hit the right arrow enough +and you will select every widget in the window. Up/down widgets +move to the previous/next widgets that overlap horizontally. If +the navigation does not seem to work you probably need to +"Sort" the widgets. This is important if you have +input fields, as FLTK uses the same rules when using arrow keys +to move between input fields.

+ +

To "open" a widget, double click it. To open +several widgets select them and then type F1 or pick +"Edit/Open" off the pop-up menu.

+ +

Type Ctrl+o to temporarily toggle the overlay off without +changing the selection, so you can see the widget borders.

+ +

You can resize the window by using the window manager border +controls. FLTK will attempt to round the window size to the +nearest multiple of the grid size and makes it big enough to +contain all the widgets (it does this using illegal X methods, +so it is possible it will barf with some window managers!). +Notice that the actual window in your program may not be +resizable, and if it is, the effect on child widgets may be +different.

+ +

The panel for the window (which you get by double-clicking +it) is almost identical to the panel for any other Fl_Widget. +There are three extra items:

+ +

Images

+ +

The contents of the image files in the Image +and Inactive text fields are written to the .cxx +file. If many widgets share the same image then only one copy is +written. Since the image data is embedded in the generated +source code, you need only distribute the C++ code and not the +image files themselves.

+ +

However, the filenames are stored in the .fl +file so you will need the image files as well to read the +.fl file. Filenames are relative to the location of the +.fl file and not necessarily the current directory. We +recommend you either put the images in the same directory as the +.fl file, or use absolute path names.

+ +

Notes for All Image Types

+ +

FLUID runs using the default visual of your X server. This +may be 8 bits, which will give you dithered images. You may get +better results in your actual program by adding the code +"Fl::visual(FL_RGB)" to your code right before the +first window is displayed. + +

All widgets with the same image on them share the same code +and source X pixmap. Thus once you have put an image on a +widget, it is nearly free to put the same image on many other +widgets.

+ +

If you edit an image at the same time you are using it in FLUID, +the only way to convince FLUID to read the image file again is to +remove the image from all widgets that are using it or re-load the +.fl file.

+ +

Don't rely on how FLTK crops images that are outside the +widget, as this may change in future versions! The cropping of +inside labels will probably be unchanged.

+ +

To more accurately place images, make a new "box" +widget and put the image in that as the label.

+ +

XBM (X Bitmap) Files

+ +

FLUID reads X bitmap files which use C source code to define +a bitmap. Sometimes they are stored with the ".h" or +".bm" extension rather than the standard +".xbm" extension. + +

FLUID writes code to construct an Fl_Bitmap image and use it +to label the widget. The '1' bits in the bitmap are drawn using +the label color of the widget. You can change this color in the +FLUID widget attributes panel. The '0' bits are transparent.

+ +

The program "bitmap" on the X distribution does an +adequate job of editing bitmaps.

+ +

XPM (X Pixmap) Files

+ +

FLUID reads X pixmap files as used by the libxpm +library. These files use C source code to define a pixmap. The +filenames usually have the ".xpm" extension. + +

FLUID writes code to construct an Fl_Pixmap image and use it +to label the widget. The label color of the widget is ignored, +even for 2-color images that could be a bitmap. XPM files can +mark a single color as being transparent, and FLTK uses this +information to generate a transparency mask for the image.

+ +

We have not found any good editors for small iconic pictures. +For pixmaps we have used XPaint +and the KDE icon editor.

+ +

BMP Files

+ +

FLUID reads Windows BMP image files which are often used in +WIN32 applications for icons. FLUID converts BMP files into +(modified) XPM format and uses a Fl_BMP_Image image to label the +widget. Transparency is handled the same as for XPM files. All +image data is uncompressed when written to the source file, so +the code may be much bigger than the .bmp file.

+ +

GIF Files

+ +

FLUID reads GIF image files which are often used in HTML +documents to make icons. FLUID converts GIF files into +(modified) XPM format and uses a Fl_GIF_Image image to label the +widget. Transparency is handled the same as for XPM files. All +image data is uncompressed when written to the source file, so +the code may be much bigger than the .gif file. Only +the first image of an animated GIF file is used.

+ +

JPEG Files

+ +

If FLTK is compiled with JPEG support, FLUID can read JPEG +image files which are often used for digital photos. FLUID uses +a Fl_JPEG_Image image to label the widget, and writes +uncompressed RGB or grayscale data to the source file. + +

PNG (Portable Network Graphics) Files

+ +

If FLTK is compiled with PNG support, FLUID can read PNG +image files which are often used in HTML documents. FLUID uses a +Fl_PNG_Image image to label the widget, and writes uncompressed +RGB or grayscale data to the source file. PNG images can provide +a full alpha channel for partial transparency, and FLTK supports +this as best as possible on each platform. + +

Internationalization with FLUID

+ +

FLUID supports internationalization (I18N for short) of label +strings used by widgets. The preferences window +(Ctrl+p) provides access to the I18N options. + +

I18N Methods

+ +

FLUID supports three methods of I18N: use none, use GNU +gettext, and use POSIX catgets. The "use none" method is the +default and just passes the label strings as-is to the widget +constructors. + +

The "GNU gettext" method uses GNU gettext (or a similar +text-based I18N library) to retrieve a localized string before +calling the widget constructor. + +

The "POSIX catgets" method uses the POSIX catgets function to +retrieve a numbered message from a message catalog before +calling the widget constructor. + +

Using GNU gettext for I18N

+ +

FLUID's code support for GNU gettext is limited to calling a +function or macro to retrieve the localized label; you still +need to call setlocale() and textdomain() or +bindtextdomain() to select the appropriate language and +message file. + +

To use GNU gettext for I18N, open the preferences window and +choose "GNU gettext" from the "Use" chooser. Two new input +fields will then appear to control the include file and +function/macro name to use when retrieving the localized label +strings. + +

I18N using GNU gettext.
+Figure 9-11: Internationalization using GNU gettext.

+ +

The "#include" field controls the header file to include for +I18N; by default this is <libintl.h>, the +standard I18N file for GNU gettext. + +

The "Function" field controls the function (or macro) that +will retrieve the localized message; by default the +gettext function will be called. + +

Using POSIX catgets for I18N

+ +

FLUID's code support for POSIX catgets allows you to use a +global message file for all interfaces or a file specific to +each .fl file; you still need to call +setlocale() to select the appropriate language. + +

To use POSIX catgets for I18N, open the preferences window +and choose "POSIX catgets" from the "Use" chooser. Three new +input fields will then appear to control the include file, +catalog file, and set number for retrieving the localized label +strings. + +

I18N using POSIX catgets.
+Figure 9-12: Internationalization using POSIX catgets.

+ +

The "#include" field controls the header file to include for +I18N; by default this is <nl_types.h>, the +standard I18N file for POSIX catgets. + +

The "File" field controls the name of the catalog file +variable to use when retrieving localized messages; by default +the file field is empty which forces a local (static) catalog +file to be used for all of the windows defined in your +.fl file. + +

The "Set" field controls the set number in the catalog file. +The default set is 1 and rarely needs to be changed. + +

Know limitations

+ +Declaration Blocks can be used to temporarily block out already +designed code using #if 0 and #endif +type construction. This will effectively avoid compilation of +blocks of code. However, static code and data generated by this +segment (menu items, images, include statements, etc.) will still +be generated and likely cause compile-time warnings. + +*/ diff --git a/documentation/forms.dox b/documentation/forms.dox new file mode 100644 index 000000000..b2cb92ade --- /dev/null +++ b/documentation/forms.dox @@ -0,0 +1,201 @@ +/** + + \page forms E - Forms Compatibility + +

This appendix describes the Forms compatibility included with FLTK. +

Importing Forms Layout Files

+FLUID can read the .fd files put out by +all versions of Forms and XForms fdesign. However, it will mangle them +a bit, but it prints a warning message about anything it does not +understand. FLUID cannot write fdesign files, so you should save to a +new name so you don't write over the old one. +

You will need to edit your main code considerably to get it to link +with the output from FLUID. If you are not interested in this you may +have more immediate luck with the forms compatibility header, +<FL/forms.H>.

+

Using the Compatibility Header File

+ You should be able to compile existing Forms or XForms source code by +changing the include directory switch to your compiler so that the +forms.h file supplied with FLTK is included. Take a look at +forms.h to see how it works, but the basic trick is lots of inline +functions. Most of the XForms demo programs work without changes. +

You will also have to compile your Forms or XForms program using a +C++ compiler. The FLTK library does not provide C bindings or header +files.

+

Although FLTK was designed to be compatible with the GL Forms +library (version 0.3 or so), XForms has bloated severely and it's +interface is X-specific. Therefore, XForms compatibility is no longer +a goal of FLTK. Compatibility was limited to things that were free, or +that would add code that would not be linked in if the feature is +unused, or that was not X-specific.

+

To use any new features of FLTK, you should rewrite your code to not +use the inline functions and instead use "pure" FLTK. This will make +it a lot cleaner and make it easier to figure out how to call the FLTK +functions. Unfortunately this conversion is harder than expected and +even Digital Domain's inhouse code still uses forms.H a lot.

+

Problems You Will Encounter

+

Many parts of XForms use X-specific structures like XEvent + in their interface. I did not emulate these! Unfortunately these +features (such as the "canvas" widget) are needed by most large +programs. You will need to rewrite these to use FLTK subclasses.

+

Fl_Free widgets emulate +the old Forms "free" widget. It may be useful for porting +programs that change the handle() function on widgets, but you +will still need to rewrite things.

+

Fl_Timer widgets are +provided to emulate the XForms timer. These work, but are quite +inefficient and inaccurate compared to using +Fl::add_timeout().

+

All instance variables are hidden. If you directly refer to +the x, y, w, h, label, or other fields of your Forms widgets you will +have to add empty parenthesis after each reference. The easiest way to +do this is to globally replace "->x" with "->x()", etc. Replace +"boxtype" with "box()".

+

const char * arguments to most FLTK methods are simply +stored, while Forms would strdup() the passed string. This is +most noticable with the label of widgets. Your program must always +pass static data such as a string constant or malloc'd buffer to +label(). If you are using labels to display program output you +may want to try the Fl_Output + widget.

+

The default fonts and sizes are matched to the older GL version of +Forms, so all labels will draw somewhat larger than an XForms program +does.

+

fdesign outputs a setting of a "fdui" instance variable to the main +window. I did not emulate this because I wanted all instance variables +to be hidden. You can store the same information in the user_data() + field of a window. To do this, search through the fdesign output for +all occurances of "->fdui" and edit to use "->user_data()" instead. + This will require casts and is not trivial.

+

The prototype for the functions passed to fl_add_timeout() + and fl_set_idle_callback() callback are different.

+

All the following XForms calls are missing:

+ +

Additional Notes

+ These notes were written for porting programs written with the older +IRISGL version of Forms. Most of these problems are the same ones +encountered when going from old Forms to XForms: +

Does Not Run In Background

+ The IRISGL library always forked when you created the first window, +unless "foreground()" was called. FLTK acts like "foreground()" is +called all the time. If you really want the fork behavior do "if +(fork()) exit(0)" right at the start of your program. +

You Cannot Use IRISGL Windows or fl_queue

+ If a Forms (not XForms) program if you wanted your own window for +displaying things you would create a IRISGL window and draw in it, +periodically calling Forms to check if the user hit buttons on the +panels. If the user did things to the IRISGL window, you would find +this out by having the value FL_EVENT returned from the call to Forms. +

None of this works with FLTK. Nor will it compile, the necessary +calls are not in the interface.

+

You have to make a subclass of +Fl_Gl_Window and write a draw() method and +handle() method. This may require anywhere from a trivial to a +major rewrite.

+

If you draw into the overlay planes you will have to also write a +draw_overlay() method and call redraw_overlay() on the +OpenGL window.

+

One easy way to hack your program so it works is to make the +draw() and handle() methods on your window set some +static variables, storing what event happened. Then in the main loop +of your program, call Fl::wait() and then check these +variables, acting on them as though they are events read from +fl_queue.

+

You Must Use OpenGL to Draw Everything

+

The file <FL/gl.h> defines replacements for a lot of IRISGL +calls, translating them to OpenGL. There are much better translators +available that you might want to investigate.

+

You Cannot Make Forms Subclasses

+ Programs that call fl_make_object or directly setting the +handle routine will not compile. You have to rewrite them to use a +subclass of Fl_Widget. It is important to note that the +handle() method is not exactly the same as the handle() + function of Forms. Where a Forms handle() returned non-zero, +your handle() must call do_callback(). And your +handle() must return non-zero if it "understood" the event. +

An attempt has been made to emulate the "free" widget. This appears +to work quite well. It may be quicker to modify your subclass into a +"free" widget, since the "handle" functions match.

+

If your subclass draws into the overlay you are in trouble and will +have to rewrite things a lot.

+

You Cannot Use <device.h>

+ If you have written your own "free" widgets you will probably get a +lot of errors about "getvaluator". You should substitute: +
+ + + + + + + + + + +
FormsFLTK
MOUSE_XFl::event_x_root()
MOUSE_YFl::event_y_root()
LEFTSHIFTKEY,RIGHTSHIFTKEYFl::event_shift()
CAPSLOCKKEYFl::event_capslock()
LEFTCTRLKEY,RIGHTCTRLKEYFl::event_ctrl()
LEFTALTKEY,RIGHTALTKEYFl::event_alt()
MOUSE1,RIGHTMOUSEFl::event_state()
MOUSE2,MIDDLEMOUSEFl::event_state()
MOUSE3,LEFTMOUSEFl::event_state()
+ Anything else in getvaluator and you are on your own... +

Font Numbers Are Different

+ The "style" numbers have been changed because I wanted to insert +bold-italic versions of the normal fonts. If you use Times, Courier, +or Bookman to display any text you will get a different font out of +FLTK. If you are really desperate to fix this use the following code: +