diff --git a/documentation/FL.gif b/documentation/FL.gif new file mode 100644 index 000000000..7e542b8ae Binary files /dev/null and b/documentation/FL.gif differ diff --git a/documentation/Fl_Adjuster.html b/documentation/Fl_Adjuster.html new file mode 100644 index 000000000..d7cdf0a90 --- /dev/null +++ b/documentation/Fl_Adjuster.html @@ -0,0 +1,61 @@ + +
+ ++Fl_Valuator + | + +----Fl_Adjuster ++ +
+#include <FL/Fl_Adjuster.H> ++ +
+Fl_Widget + | + +----Fl_Box ++ +
+#include <FL/Fl_Box.H> ++ +
The second form of the constructor sets the box to the specified box type. + +
+Fl_Browser_ + | + +----Fl_Browser + | + +----Fl_Hold_Browser, Fl_Multi_Browser, Fl_Select_Browser ++ +
+#include <FL/Fl_Browser.H> ++ +
Each line in the browser is identified by number. The numbers +start at one (this is so that zero can be reserved for "no line" +in the selective browsers). Unless otherwise noted, the methods do +not check to see if the passed line number is in range and legal. It +must always be greater than zero and <= size(). + +
Each line contains a null-terminated string of text and a void +* data pointer. The text string is displayed, the void * +pointer can be used by the callbacks to reference the object the text +describes. + +
The base class does nothing when the user clicks on it. The subclasses +Fl_Select_Browser, +Fl_Hold_Browser, and +Fl_Multi_Browser +react to user clicks to select lines in the browser and do callbacks. + +
The base class called +Fl_Browser_ provides the scrolling and selection +mechanisms of this and all the subclasses, but the dimensions and +appearance of each item are determined by the subclass. You can use +Fl_Browser_ to display information other than text, or text +that is dynamically produced from your own data structures. If you find +that loading the browser is a lot of work or is inefficient, you may +want to make a subclass of Fl_Browser_. + +
+
|
+
+
|
++ + | ++ + | ++ + | +
The second form sets the column separator to c. This will only +have an effect if you also set column_widths(). + +
The second form sets the current array to w. Make sure the last +entry is zero. + +
The second form sets the data for line n. + +
@. Print rest of line, don't look for more '@' signs
+
+ @@ Print rest of line starting with '@'
+
+ @l Use a large (24 point) font
+
+ @m Use a medium large (18 point) font
+
+ @s Use a small (11 point) font
+
+ @b Use a bold font (adds FL_BOLD to font)
+
+ @i Use an italic font (adds FL_ITALIC to font)
+
+ @f or @t Use a fixed-pitch
+ font (sets font to FL_COURIER)
+
+ @c Center the line horizontally
+
+ @r Right-justify the text
+
+ @B0, @B1, ... @B255 Fill the backgound with fl_color(n)
+
+ @C0, @C1, ... @C255 Use fl_color(n) to draw the text
+
+ @F0, @F1, ... Use fl_font(n) to draw the text
+
+ @S1, @S2, ... Use point size n to draw the text
+
+ @u or @_ Underline the text.
+
+ @- draw an engraved line through the middle.
+@. command can be used to reliably
+terminate the parsing. To print a random string in a random color,
+use sprintf("@C%d@.%s", color, string) and it will work even
+if the string starts with a digit or has the format character in it.
+
+The second form sets the current prefix to c. Set the prefix +to 0 to disable formatting. + +
The second form sets the text for line n. + +
The second form sets the top line in the browser to n. + +
The second form sets the vertical scrollbar position to p. + +
+Fl_Widget + | + +----Fl_Browser_ + | + +----Fl_Browser ++ +
+#include <FL/Fl_Browser_.H> ++ +
This has been designed so that the subclass has complete control +over the storage of the data, although because next() and +prev() functions are used to index, it works best as a linked +list or as a large block of characters in which the line breaks must be +searched for. + +
A great deal of work has been done so that the "height" of a data +object does not need to be determined until it is drawn. This is +useful if actually figuring out the size of an object requires +accessing image data or doing stat() on a file or doing some +other slow operation. + +
+
|
+
+
|
+
+
|
+
+
|
+
+
|
+
0 - No scrollbars
+
+ Fl_Browser_::HORIZONTAL - Only a horizontal scrollbar.
+
+ Fl_Browser_::VERTICAL - Only a vertical scrollbar.
+
+ Fl_Browser_::BOTH - The default is both scrollbars.
+
+ Fl_Browser_::HORIZONTAL_ALWAYS - Horizontal
+ scrollbar always on, vertical always off.
+
+ Fl_Browser_::VERTICAL_ALWAYS - Vertical
+ scrollbar always on, horizontal always off.
+
+ Fl_Browser_::BOTH_ALWAYS - Both always on.
+The second form sets the default text color to color + +
The second form sets the default text font to font + +
The second form sets the default text size to size + + + diff --git a/documentation/Fl_Button.html b/documentation/Fl_Button.html new file mode 100644 index 000000000..3ed301853 --- /dev/null +++ b/documentation/Fl_Button.html @@ -0,0 +1,176 @@ + +
+ ++Fl_Widget + | + +----Fl_Button + | + +----Fl_Check_Button, Fl_Light_Button, Fl_Repeat_Button, + Fl_Return_Button, Fl_Round_Button ++ +
+#include <FL/Fl_Button.H> ++ +
Buttons generate callbacks when they are clicked by the user. You +control exactly when and how by changing the values for type() and +when(). + +
Buttons can also generate callbacks in response to +FL_SHORTCUT events. The button can either have an explicit +shortcut() value or a letter +shortcut can be indicated in the label() with an '&' character +before it. For the label shortcut it does not matter if Alt is +held down, but if you have an input field in the same window, the user +will have to hold down the Alt key so that the input field does +not eat the event first as an FL_KEYBOARD event. + +
+
|
++ + | ++ + | ++ + | ++ + | +
The second form sets the down box type. The default value of 0 +causes FLTK to figure out the correct matching down version of +box(). + +
The second form sets the shortcut key to key. Setting this
+overrides the use of '&' in the label(). The value is a
+bitwise OR of a key and a set of shift flags, for example FL_ALT
+| 'a', FL_ALT | (FL_F + 10), or just
+'a'. A value of 0 disables the shortcut.
+
+
The key can be any value returned by +Fl::event_key(), but will usually be an ASCII letter. Use a +lower-case letter unless you require the shift key to be held down. + +
The shift flags can be any set of values accepted by +Fl::event_state(). If the bit is on +that shift key must be pushed. Meta, Alt, Ctrl, and Shift must be off +if they are not in the shift flags (zero for the other bits indicates +a "don't care" setting). + +
0: The value is unchanged.
+
+ FL_TOGGLE_BUTTON: The value is inverted.
+
+ FL_RADIO_BUTTON: The value is set to 1, and all
+ other buttons in the current group with
+ type() == FL_RADIO_BUTTON are set to zero.
+FL_WHEN_RELEASE:
+
+0: The callback is not done, instead changed() is
+ turned on.
+
+ FL_WHEN_RELEASE: The callback is done after the user
+ successfully clicks the button, or when a shortcut is typed.
+
+ FL_WHEN_CHANGED : The callback is done each time the
+ value() changes (when the user pushes and releases the button, and as
+ the mouse is dragged around in and out of the button).
++Fl_Widget + | + +----Fl_Chart ++ +
+#include <FL/Fl_Chart.H> ++ +
| + + | ++ + | ++ + | ++ + | ++ + | +
The second form of autosize sets the auto-sizing property to +onoff. + +

+Fl_Button + | + +----Fl_Check_Button ++ +
+#include <FL/Fl_Check_Button.H> ++ +
The Fl_Check_Button subclass display the "on" state by
+turning on a light, rather than drawing pushed in. The shape of the
+"light" is initially set to FL_DIAMOND_DOWN_BOX. The color of the
+light when on is controlled with selection_color(), which defaults to
+FL_RED.
+
+Methods
+
+
+
+Fl_Check_Button::Fl_Check_Button(int x, int y, int w, int h, const char *label = 0)
+
+Creates a new Fl_Check_Button widget using the given position,
+size, and label string.
+
+Fl_Check_Button::~Fl_Check_Button()
+
+The destructor deletes the check button.
+
+
+
diff --git a/documentation/Fl_Choice.html b/documentation/Fl_Choice.html
new file mode 100644
index 000000000..96b4337dc
--- /dev/null
+++ b/documentation/Fl_Choice.html
@@ -0,0 +1,110 @@
+
+
+
+
+
+class Fl_Choice
+
+
+
+Class Hierarchy
+
+
+Fl_Menu_
+ |
+ +----Fl_Choice
+
+
+Include Files
+
+
+#include <FL/Fl_Choice.H>
+
+
+Description
+
+This is a button that when pushed pops up a menu (or hierarchy of
+menus) defined by an array of Fl_Menu_Item
+objects. Motif calls this an OptionButton.
+
+
The only difference between this and a +Fl_Menu_Button is that the name of the most recent chosen +menu item is displayed inside the box, while the label is displayed +outside the box. However, since the use of this is most often to +control a single variable rather than do individual callbacks, some of +the Fl_Menu_Button methods are redescribed here in those terms. + +
When the user picks an item off the menu the value() is set +to that item and then the callback is done. + +
All three mouse buttons pop up the menu. The Forms behavior of the +first two buttons to increment/decrement the choice is not +implemented. This could be added with a subclass, however. + +
The menu will also pop up in response to shortcuts indicated by +putting a '&' character in the label(). See +Fl_Button for a description of this. + +
Typing the shortcut() of any of the items will do exactly +the same as when you pick the item with the mouse. The '&' character +in item names are only looked at when the menu is popped up, however. + +
The constructor sets menu() to NULL. See Fl_Menu_ for the methods to set or change +the menu. + +
+Fl_Widget + | + +----Fl_Clock ++ +
+#include <FL/Fl_Clock.H> ++ +
The third form of value returns the displayed time in seconds +since the UNIX epoch (January 1, 1970). + + + diff --git a/documentation/Fl_Color_Chooser.html b/documentation/Fl_Color_Chooser.html new file mode 100644 index 000000000..5f9a0ed53 --- /dev/null +++ b/documentation/Fl_Color_Chooser.html @@ -0,0 +1,103 @@ + +
+ ++Fl_Group + | + +----Fl_Color_Chooser ++ +
+#include <FL/Fl_Color_Chooser.H> ++ +
+Fl_Valuator + | + +----Fl_Counter ++ +
+#include <FL/Fl_Counter.H> ++ +
+Fl_Valuator + | + +----Fl_Dial ++ +
+#include <FL/Fl_Dial.H> ++ +
+Fl_Window + | + +----Fl_Double_Window +
+#include <FL/Fl_Double_Window.H> ++ +
It is highly recommended that you put the following code before the +first show() of any window in your program: + +
+Fl::visual(FL_DOUBLE|FL_INDEX) ++ +This makes sure you can use Xdbe on servers where double buffering does +not exist for every visual. + +
+Fl_Group----Fl_End ++ +
+#include <FL/Fl_Group.H> ++ +
class MyClass {
+ Fl_Group group;
+ Fl_Button button_in_group;
+ Fl_End end;
+ Fl_Button button_outside_group;
+ MyClass();
+};
+MyClass::MyClass() :
+ group(10,10,100,100),
+ button_in_group(20,20,60,30),
+ end(),
+ button_outside_group(10,120,60,30)
+{}
+
++Fl_Input + | + +----Fl_Float_Input ++ +
+#include <FL/Fl_Input.H> ++ +
+Fl_Widget + | + +----Fl_Free ++ +
+#include <FL/Fl_Free.H> ++ +
There are five types of free, which determine when the handle +function is called: + +
+#define FL_NORMAL_FREE 1 +#define FL_SLEEPING_FREE 2 +#define FL_INPUT_FREE 3 +#define FL_CONTINUOUS_FREE 4 +#define FL_ALL_FREE 5 ++ +
An FL_INPUT_FREE accepts FL_FOCUS events. A FL_CONTINUOUS_FREE +sets a timeout callback 100 times a second and provides a FL_STEP +event, this has obvious detrimental effects on machine performance. +FL_ALL_FREE does both. FL_SLEEPING_FREE are deactivated. + +
+int +handle_function(Fl_Widget *w, + int event, + float event_x, + float event_y, + char key) ++ +This function is called from the the handle() method in +response to most events, and is called by the draw() method. +The event argument contains the event type: + +
+// old event names for compatability: +#define FL_MOUSE FL_DRAG +#define FL_DRAW 0 +#define FL_STEP 9 +#define FL_FREEMEM 12 +#define FL_FREEZE FL_UNMAP +#define FL_THAW FL_MAP ++ +
+Fl_Widget + | + +----Fl_Gl_Window + | + +----Fl_Pack, Fl_Scroll, Fl_Tabs, Fl_Tile, Fl_Window ++ +
+#include <FL/Fl_Gl_Window.H> ++ +
OpenGL hardware typically provides some overlay bit planes, which +are very useful for drawing UI controls atop your 3D graphics. If the +overlay hardware is not provided, FLTK tries to simulate the overlay, +This works pretty well if your graphics are double buffered, but not +very well for single-buffered. + +
+
|
+
+
|
+
+
|
+
+
|
+
+
|
+
The draw() method can only use OpenGL calls. Do not +attempt to call X, any of the functions in <FL/fl_draw.H>, or +glX directly. Do not call gl_start() or +gl_finish(). + +
If double-buffering is enabled in the window, the back and front buffers +are swapped after this function is completed. + +
If the desired combination cannot be done, FLTK will try turning off +FL_MULTISAMPLE. If this also fails the show() will call +Fl::error() and not show the window. + +
You can change the mode while the window is displayed. This +is most useful for turning double-buffering on and off. Under +X this will cause the old X window to be destroyed and a new one to be +created. If this is a top-level window this will unfortunately also +cause the window to blink, raise to the top, and be de-iconized, and +the xid() will change, possibly breaking other code. It is best to +make the GL window a child of another window if you wish to do this! + +
+void mywindow::draw() {
+ if (!valid()) {
+ glViewport(0,0,w(),h());
+ glFrustum(...);
+ glLight(...);
+ ...other initialization...
+ }
+ ... draw your geometry here ...
+}
+
+
void Fl_Gl_Window::invalidate();
+
void Fl_Gl_Window::valid(char i);
+
+Fl_Gl_Window::valid() is turned off when FLTK creates a
+new context for this window and by the window resizing, and is turned
+on after draw() is called. You can use this inside your draw()
+method to avoid unneccessarily initializing the OpenGL context. Just
+do this:
+
+void mywindow::draw() {
+ if (!valid()) {
+ glViewport(0,0,w(),h());
+ glFrustum(...);
+ glLight(...);
+ ...other initilization...
+ }
+ ... draw your geometry here ...
+}
+
+
+You can turn valid() on by calling valid(1). You
+should only do this after fixing the transformation inside a
+draw() or after make_current(). This is done
+automatically after draw() returns.
+
+void Fl_Gl_Window::invalidate()
+
+The invalidate() method turns off valid() and is
+equivalent to calling value(0).
+
+void Fl_Gl_Window::ortho()
+
+Set the projection so 0,0 is in the lower left of the window and each
+pixel is 1 unit wide/tall. If you are drawing 2D images, your
+draw() method may want to call this if valid() is
+false.
+
+void Fl_Gl_Window::make_current()
+
+The make_current() method selects the OpenGL context for the
+widget. It is called automatically prior to the draw() method
+being called and can also be used to implement feedback and/or selection
+within the handle() method.
+
+void Fl_Gl_Window::make_overlay_current()
+
+The make_overlay_current() method selects the OpenGL context
+for the widget's overlay. It is called automatically prior to the
+draw_overlay() method being called and can also be used to
+implement feedback and/or selection within the handle()
+method.
+
+void Fl_Gl_Window::swap_buffers()
+
+The swap_buffers() method swaps the back and front buffers.
+It is called automatically after the draw() method is called.
+
+void Fl_Gl_Window::hide()
+
+Hides the window and destroys the OpenGL context.
+
+int Fl_Gl_Window::can_do_overlay()
+
+Returns true if the hardware overlay is possible. If this is false,
+FLTK will try to simulate the overlay, with significant loss of update
+speed. Calling this will cause FLTK to open the display.
+
+void Fl_Gl_Window::redraw_overlay()
+
+This method causes draw_overlay to be called at a later time.
+Initially the overlay is clear, if you want the window to display
+something in the overlay when it first appears, you must call this
+immediately after you show() your window.
+
+virtual void Fl_Gl_Window::draw_overlay()
+
+You must implement this virtual function if you want to draw into the
+overlay. The overlay is cleared before this is called. You should
+draw anything that is not clear using OpenGL. You must use
+gl_color(i) to choose colors (it allocates them from the colormap
+using system-specific calls), and remember that you are in an indexed
+OpenGL mode and drawing anything other than flat-shaded will probably
+not work.
+
+Both this function and Fl_Gl_Window::draw() should check
+Fl_Gl_Window::valid() and set the same transformation. If you
+don't your code may not work on other systems. Depending on the OS,
+and on whether overlays are real or simulated, the OpenGL context may
+be the same or different between the overlay and main window.
+
+
+
diff --git a/documentation/Fl_Group.html b/documentation/Fl_Group.html
new file mode 100644
index 000000000..315ce1b37
--- /dev/null
+++ b/documentation/Fl_Group.html
@@ -0,0 +1,178 @@
+
+
+
+
+
+class Fl_Group
+
+
+
+Class Hierarchy
+
++Fl_Widget + | + +----Fl_Group + | + +----Fl_Pack, Fl_Scroll, Fl_Tabs, Fl_Tile, Fl_Window ++ +
+#include <FL/Fl_Group.H> ++ +
| + + | +
+
|
++ + | ++ + | ++ + | +
Don't forget to end() the group or window! + +
In these examples the gray area is the resizable:
+
+
+
+
+
The resizable may be set to the group itself (this is the default value +for an Fl_Group, although NULL is the default for an +Fl_Window), in which case all the contents are resized. If the +resizable is NULL then all widgets remain a fixed size and +distance from the top-left corner. + +
It is possible to achieve any type of resize behavior by using an +invisible Fl_Box as the resizable and/or by using a hierarchy of +child Fl_Group's. + + + diff --git a/documentation/Fl_Hold_Browser.html b/documentation/Fl_Hold_Browser.html new file mode 100644 index 000000000..591d61a27 --- /dev/null +++ b/documentation/Fl_Hold_Browser.html @@ -0,0 +1,74 @@ + +
+ ++Fl_Browser + | + +----Fl_Hold_Browser ++ +
+#include <FL/Fl_Hold_Browser.H> ++ +
See Fl_Browser for methods to add +and remove lines from the browser. + +
+Fl_Input_ + | + +----Fl_Input + | + +----Fl_Float_Input, Fl_Int_Input, + Fl_Multiline_Input, Fl_Secret_Input ++ +
+#include <FL/Fl_Input.H> ++ +
| Mouse button 1 | +Moves the cursor to this point. Drag selects characters. Double +click selects words. Triple click selects all text. Shift+click +extends the selection. | + +
| Mouse button 2 | +Insert the current X selection at the cursor (unlike Motif this +does not move the insertion point to the mouse). If the widget does +not have the input focus (and thus no cursor) it puts the cursor where +clicked and inserts the selection there. | + +
| Mouse button 3 | +Currently acts like button 1. | + +
| Backspace | +Deletes one character to the left, or deletes the +selected region. | + +
| Enter | +May cause the callback, see when(). | + +
| ^A or Home | +Go to start of line. | + +
| ^B or Left | +Move left | + +
| ^C | +Copy the selection to the clipboard | + +
| ^D or Delete | +Deletes one character to the right or deletes the selected region. +Due to silly historical X problems, the Delete key will act like +Backspace until you type a "real" backspace. | + +
| ^E or End | +Go to the end of line. | + +
| ^F or Right | +Move right | + +
| ^K | +Delete to the end of line (next \n character) or deletes +a single \n character. These deletions are all concatenated into the +clipboard. | + +
| ^N or Down | +Move down (for Fl_Multiline_Input only, otherwise it moves to the +next input field). | + +
| ^P or Up | +Move up (for Fl_Multiline_Input only, otherwise it moves to the +previous input field). | + +
| ^Q or RightCtrl or Compose |
+Start a compose-character sequence. The +next one or two keys typed define the character to insert. This also +can be used to "quote" control characters. | + +
| ^U | +Delete everything. | + +
| ^V or ^Y | +Paste the clipboard | + +
| ^X or ^W | +Copy the region to the clipboard and delete it. | + +
| ^Z or ^_ | +Undo. This is a single-level undo mechanism, but all adjacent +deletions and insertions are concatenated into a single "undo". Often +this will undo a lot more than you expected. | + +
| Shift+move | +Move the cursor but also extend the selection. | + +
+
|
++ + | +
+
|
++ + | ++ + | +
The second two forms change the text and set the mark and the point +to the end of it. The string is copied to the internal buffer. Passing +NULL is the same as "". This returns non-zero if the new +value is different than the current one. You can use the second +version to directly set the length if you know it already or want to +put nul's in the text. + +
+Fl_Widget + | + +----Fl_Input_ + | + +----Fl_Input ++ +
+#include <FL/Fl_Input_.H> ++ +
This can act like any of the subclasses of Fl_Input, by setting +type() to one of the following values: + +
+#define FL_NORMAL_INPUT 0 +#define FL_FLOAT_INPUT 1 +#define FL_INT_INPUT 2 +#define FL_MULTILINE_INPUT 4 +#define FL_SECRET_INPUT 5 ++ +
+
|
+
+
|
+
+
|
+
+
|
+
+
|
+
Changing these values causes a redraw(). The new values +are bounds checked. The return value is non-zero if the new position +is different than the old one. position(n) is the same as +position(n,n). mark(n) is the same as +position(position(),n). + +
Set start and end equal to not delete anything. Set +insert to NULL to not insert anything. + +
length must be zero or strlen(insert), this saves +a tiny bit of time if you happen to already know the length of the +insertion, or can be used to insert a portion of a string or a string +containing nul's. + +
a and b are clamped to the 0..size() +range, so it is safe to pass any values. + +
cut() and insert() are just inline functions that +call replace(). + +
If you want the data to go into the clipboard, do +Fl_Input_::copy() before calling Fl_Input_::cut(), or +do Fl_Input_::copy_cuts() afterwards. + +
+Fl_Input + | + +----Fl_Int_Input ++ +
+#include <FL/Fl_Input.H> ++ +
+Fl_Button + | + +----Fl_Light_Button ++ +
+#include <FL/Fl_Light_Button.H> ++ +
The Fl_Light_Button subclass display the "on" state by
+turning on a light, rather than drawing pushed in. The shape of the
+"light" is initially set to FL_DOWN_BOX. The color of the
+light when on is controlled with selection_color(), which defaults to
+FL_YELLOW.
+
+Methods
+
+
+
+Fl_Light_Button::Fl_Light_Button(int x, int y, int w, int h, const char *label = 0)
+
+Creates a new Fl_Light_Button widget using the given position,
+size, and label string.
+
+Fl_Light_Button::~Fl_Light_Button()
+
+The destructor deletes the check button.
+
+
+
diff --git a/documentation/Fl_Menu_.html b/documentation/Fl_Menu_.html
new file mode 100644
index 000000000..f35816496
--- /dev/null
+++ b/documentation/Fl_Menu_.html
@@ -0,0 +1,220 @@
+
+
+
+
+
+class Fl_Menu_
+
+
+
+Class Hierarchy
+
+
+Fl_Widget
+ |
+ +----Fl_Menu_----Fl_Menu_Item
+ |
+ +----Fl_Choice, Fl_Menu_Bar, Fl_Menu_Button
+
+
+Include Files
+
+
+#include <FL/Fl_Menu_.H>
+
+
+Description
+
+All widgets that have a menu in FLTK are subclassed off of this class.
+Currently FLTK provides you with
+Fl_Menu_Button,
+Fl_Menu_Bar, and
+Fl_Choice.
+
+
The class contains a pointer to an array of structures of type +Fl_Menu_Item. +These describe the contents of the menu. Usually the array is a large +initialization constant, but there are methods to build it +dynamically. + +
| + + | ++ + | ++ + | +
+
|
++ + | +
Currently there can be only one global() menu. Setting a new one
+will replace the old one. There is no way to remove the global()
+setting (including destroying the menu).
+
+const char* Fl_Menu_::text() const
+
+Returns the title of the last item chosen, or of item i.
+
+
+const char* Fl_Menu_::text(int i) constint Fl_Menu_::size() const
+
+This returns menu()->size(), which is how many entries are in
+the array, not counting the NULL ending, but including all
+submenus titles and the NULL's that end them. If the menu is
+NULL this returns zero.
+
+int Fl_Menu_::add(const char *,const char *,Fl_Callback *,void *v=0,int f=0)
+
+The first form adds a new menu item, with a title string,
+shortcut string, callback, argument to the callback,
+and flags. If menu() was originally set with NULL
+then space is allocated for the new item. If instead you gave it an
+array then the array must have enough empty space for the new item.
+The title string is copied, but the shortcut is not.
+
+
+int Fl_Menu_::add(const char *)
The second form splits the string at any | characters and then does +add(s,0,0,0,0) with each section. This is often useful if you +are just using the value, and is compatable with some Forms programs. + +
Text is a string of the form "foo/bar/baz", this example will result +in a submenu called "foo" and one in that called "bar" and and entry +called "baz". The text is copied to new memory and can be freed. The +other arguments are copied into the menu item unchanged. + +
If an item exists already with that name then it is replaced with +this new one. Otherwise this new one is added to the end of the +correct menu or submenu. The return value is the offset into the +array that the new entry was placed at. + +
No bounds checking is done, the table must be big enough for all the +entries you plan to add. Don't forget that there is a NULL terminator +on the end, and the first time a item is added to a submenu three +items are added (the title and the NULL terminator, as well as the +actual menu item) + +
The return value is the index into the array that the entry was put. + +
+Fl_Menu_ + | + +----Fl_Menu_Bar ++ +
+#include <FL/Fl_Menu_Bar.H> ++ +
The items on the bar and the menus they bring up are defined by a +single Fl_Menu_Item array. Because a +Fl_Menu_Item array defines a hierarchy, the top level menu defines the +items in the menubar, while the submenus define the pull-down menus. +Sub-sub menus and lower pop up to the right of the submenus. + +
+
+
If there is an item in the top menu that is not a title of a +submenu, then it acts like a "button" in the menubar. Clicking on +it will pick it. + +
When the user picks an item off the menu, the item's callback is +done with the menubar as the Fl_Widget* argument. If the item +does not have a callback the menubar's callback is done instead. + +
Submenus will also pop up in response to shortcuts indicated by +putting a '&' character in the name field of the menu item. If you +put a '&' character in a top-level "button" then the shortcut picks +it. The '&' character in submenus is ignored until the menu is popped +up. + +
Typing the shortcut() of any of the menu items will cause callbacks +exactly the same as when you pick the item with the mouse. + +
The constructor sets menu() to NULL. See Fl_Menu_ for the methods to set or change +the menu. + +
labelsize(), labelfont(), and +labelcolor() are used to control how the menubar items are +drawn. They are initialized from the Fl_Menu static +variables, but you can change them if desired. + +
label() is ignored unless you change align() to +put it outside the menubar. + +
+Fl_Menu_ + | + +----Fl_Menu_Button ++ +
+#include <FL/Fl_Menu_Button.H> ++ +
+
+
Normally any mouse button will pop up a menu and it is lined up +below the button as shown in the picture. However an Fl_Menu_Button +may also control a pop-up menu. This is done by setting the +type(), +see below. + +
The menu will also pop up in response to shortcuts indicated by +putting a '&' character in the label(). + +
Typing the shortcut() of any of the menu items will cause +callbacks exactly the same as when you pick the item with the mouse. +The '&' character in menu item names are only looked at when the menu +is popped up, however. + +
When the user picks an item off the menu, the item's callback is +done with the menu_button as the Fl_Widget* argument. If the item +does not have a callback the menu_button's callback is done instead. + +
The constructor sets menu() to NULL. See Fl_Menu_ for the methods to set or change +the menu. + +
A popup menu button is invisible and does not interfere with any +events other than the mouse button specified (and any shortcuts). The +widget can be stretched to cover all your other widgets by putting it last +in the hierarchy so it is "on top". You can also make several widgets +covering different areas for context-sensitive popup menus. + +
The popup menus appear with the cursor pointing at the previously +selected item. This is a feature. If you don't like it, do +value(0) after the menu items are picked to forget the current +item. + + + diff --git a/documentation/Fl_Menu_Item.html b/documentation/Fl_Menu_Item.html new file mode 100644 index 000000000..4dc738c26 --- /dev/null +++ b/documentation/Fl_Menu_Item.html @@ -0,0 +1,366 @@ + +
+ ++Fl_Widget + | + +----Fl_Menu_Item----Fl_Menu_ ++ +
+#include <FL/Fl_Menu_Item.H> ++ +
+struct Fl_Menu_Item {
+ const char* text; // label()
+ ulong shortcut_;
+ Fl_Callback* callback_;
+ void* user_data_;
+ int flags;
+ uchar labeltype_;
+ uchar labelfont_;
+ uchar labelsize_;
+ uchar labelcolor_;
+};
+
+enum { // values for flags:
+ FL_MENU_INACTIVE = 1,
+ FL_MENU_TOGGLE = 2,
+ FL_MENU_VALUE = 4,
+ FL_MENU_RADIO = 8,
+ FL_MENU_INVISIBLE = 0x10,
+ FL_SUBMENU_POINTER = 0x20,
+ FL_SUBMENU = 0x40,
+ FL_MENU_DIVIDER = 0x80,
+ FL_MENU_HORIZONTAL = 0x100
+};
+
+
+Typically menu items are statically defined; for example:
+
+![]() |
+
+Fl_Menu_Item popup[] = {
+ {"&alpha", FL_ALT+'a', the_cb, (void*)1},
+ {"&beta", FL_ALT+'b', the_cb, (void*)2},
+ {"gamma", FL_ALT+'c', the_cb, (void*)3, FL_MENU_DIVIDER},
+ {"&strange", 0, strange_cb},
+ {"&charm", 0, charm_cb},
+ {"&truth", 0, truth_cb},
+ {"b&eauty", 0, beauty_cb},
+ {"sub&menu", 0, 0, 0, FL_SUBMENU},
+ {"one"},
+ {"two"},
+ {"three"},
+ {0},
+ {"inactive", FL_ALT+'i', 0, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER},
+ {"invisible",FL_ALT+'i', 0, 0, FL_MENU_INVISIBLE},
+ {"check", FL_ALT+'i', 0, 0, FL_MENU_TOGGLE|FL_MENU_VALUE},
+ {"box", FL_ALT+'i', 0, 0, FL_MENU_TOGGLE},
+{0}};
+ |
+
You should use the method functions to access structure members and +not access them directly to avoid compatibility problems with future +releases of FLTK. + +
| + + | ++ + | ++ + | +
+
|
+
+
|
+
The key can be any value returned by Fl::event_key(), but will usually be an +ASCII letter. Use a lower-case letter unless you require the shift key +to be held down. + +
The shift flags can be any set of values accepted by Fl::event_state(). If the bit is on +that shift key must be pushed. Meta, Alt, Ctrl, and Shift must be off +if they are not in the shift flags (zero for the other bits indicates +a "don't care" setting). + +
X,Y is the position of the mouse cursor, relative to the +window that got the most recent event (usually you can pass +Fl::event_x() and Fl::event_y() unchanged here). + +
title is a character string title for the menu. If non-zero +a small box appears above the menu with the title in it. + +
The menu is positioned so the cursor is centered over the item +picked. This will work even if picked is in a submenu. +If picked is zero or not in the menu item table the menu is +positioned with the cursor in the top-left corner. + +
button is a pointer to an Fl_Menu_ +from which the color and boxtypes for the menu are pulled. If NULL +then defaults are used. + +
The title and menubar arguments are used internally by +the Fl_Menu_ widget. + +
+Fl_Single_Window + | + +----Fl_Menu_Window ++ +
+#include <FL/Fl_Menu_Window.H> ++ +
+Fl_Browser + | + +----Fl_Multi_Browser ++ +
+#include <FL/Fl_Multi_Browser.H> ++ +
See Fl_Browser for methods to add +and remove lines from the browser. + +
+Fl_Input + | + +----Fl_Multiline_Input ++ +
+#include <FL/Fl_Input.H> ++ +
This is far from the nirvana of text editors, and is probably only +good for small bits of text, 10 lines at most. I think FLTK can be +used to write a powerful text editor, but it is not going to be a +built-in feature. Powerful text editors in a toolkit are a big source +of bloat. + +
+Fl_Output + | + +----Fl_Multiline_Output ++ +
+#include <FL/Fl_Multiline_Output.H> ++ +
+Fl_Input_ + | + +----Fl_Output + | + +----Fl_Multiline_Output ++ +
+#include <FL/Fl_Output.H> ++ +
+
+
There is a single subclass, Fl_Multiline_Output, which allows you to +display multiple lines of text. + +
The text may contain any characters except \0, and will correctly +display anything, using ^X notation for unprintable control characters +and \nnn notation for unprintable characters with the high bit set. It +assummes the font can draw any characters in the ISO-Latin1 character +set. + +
The second two forms change the text and set the mark and the point +to the end of it. The string is copied to the internal buffer. Passing +NULL is the same as "". This returns non-zero if the new +value is different than the current one. You can use the second +version to directly set the length if you know it already or want to +put nul's in the text. + +
+Fl_Double_Window + | + +----Fl_Overlay_Window ++ +
+#include <FL/Fl_Overlay_Window.H> ++ +
If no hardware support is found the overlay is simulated by drawing +directly into the on-screen copy of the double-buffered window, and +"erased" by copying the backbuffer over it again. This means the +overlay will blink if you change the image in the window. + +
+Fl_Group + | + +----Fl_Pack ++ +
+#include <FL/Fl_Pack.H> ++ +
If type() is FL_HORIZONTAL all the children are resized to the +height of the Fl_Pack, and are moved next to each other horizontally. +If type() is not FL_HORIZONTAL then the children are resized to the +width and are stacked below each other. Then the Fl_Pack resizes +itself to surround the child widgets. + +
This widget is needed for the Fl_Tab. In +addition you may want to put the Fl_Pack inside an +Fl_Scroll. + +
| + + | +
+
|
++ + | ++ + | +
+
|
+
+Fl_Widget + | + +----Fl_Positioner ++ +
+#include <FL/Fl_Positioner.H> ++ +
+
+
+
|
+
Fl_Button + | + +----Fl_Repeat_Button ++ +
#include <FL/Fl_Repeat_Button.H>+ +
Fl_Button + | + +----Fl_Return_Button ++ +
#include <FL/Fl_Return_Button.H>+ +
+Fl_Valuator + | + +----Fl_Roller ++ +
+#include <FL/Fl_Roller.H> ++ +
+Fl_Button + | + +----Fl_Round_Button ++ +
+#include <FL/Fl_Round_Button.H> ++ +
The Fl_Round_Button subclass display the "on" state by
+turning on a light, rather than drawing pushed in. The shape of the
+"light" is initially set to FL_ROUND_DOWN_BOX. The color of the
+light when on is controlled with selection_color(), which defaults to
+FL_RED.
+
+Methods
+
+
+
+Fl_Round_Button::Fl_Round_Button(int x, int y, int w, int h, const char *label = 0)
+
+Creates a new Fl_Round_Button widget using the given position,
+size, and label string.
+
+Fl_Round_Button::~Fl_Round_Button()
+
+The destructor deletes the check button.
+
+
+
diff --git a/documentation/Fl_Scroll.gif b/documentation/Fl_Scroll.gif
new file mode 100644
index 000000000..c1a959578
Binary files /dev/null and b/documentation/Fl_Scroll.gif differ
diff --git a/documentation/Fl_Scroll.html b/documentation/Fl_Scroll.html
new file mode 100644
index 000000000..41136476c
--- /dev/null
+++ b/documentation/Fl_Scroll.html
@@ -0,0 +1,135 @@
+
+
+
+
+
+class Fl_Scroll
+
+
+
+Class Hierarchy
+
+
+Fl_Group
+ |
+ +----Fl_Scroll
+
+
+Include Files
+
+
+#include <FL/Fl_Scroll.H>
+
+
+Description
+
+This container widget lets you maneuver around a set of widgets
+much larger than your window. If the child widgets are larger than
+the size of this object then scrollbars will appear so that you can
+scroll over to them:
+
+
+
+
If all of the child widgets are packed together into a solid +rectangle then you want to set box() to FL_NO_BOX or +one of the _FRAME types. This will result in the best output. +However, if the child widgets are a sparse arrangment you must set +box() to a real _BOX type. This can result in some +blinking during redrawing, but that can be solved by using a +Fl_Double_Window. + +
This widget can also be used to pan around a single child widget +"canvas". This child widget should be of your own class, with a +draw() method that draws the contents. The scrolling is done +by changing the x() and y() of the widget, so this +child must use the x() and y() to position it's +drawing. To speed up drawing it should test fl_clip(). + +
Another very useful child is a single Fl_Pack, which is itself a group that +packs it's children together and changes size to surround them. +Filling the Fl_Pack with Fl_Tab +groups (and then putting normal widgets inside those) gives you a very +powerful scrolling list of individually-openable panels. + +
Fluid lets you create these, but you can only lay out objects that +fit inside the Fl_Scroll without scrolling. Be sure to leave +space for the scrollbars, as Fluid won't show these either. + +
You cannot use Fl_Window as a child of this since the +clipping is not conveyed to it when drawn, and it will draw over the +scrollbars and neighboring objects. + +
+Fl_Slider + | + +----Fl_Scrollbar ++ +
+#include <FL/Fl_Scrollbar.H> ++ +
Scrollbars have step(1) preset (they always return +integers). If desired you can set the step() to non-integer +values. You will then have to use casts to get at the floating-point +versions of value() from Fl_Slider. + +
+Fl_Input + | + +----Fl_Secret_Input ++ +
+#include <FL/Fl_Input.H> ++ +
+Fl_Browser + | + +----Fl_Select_Browser ++ +
+#include <FL/Fl_Select_Browser.H> ++ +
See Fl_Browser for methods to add +and remove lines from the browser. + +
+Fl_Window + | + +----Fl_Single_Window ++ +
+#include <FL/Fl_Single_Window.H> ++ +
+Fl_Valuator + | + +----Fl_Slider + | + +----Fl_Scrollbar, Fl_Value_Slider ++ +
+#include <FL/Fl_Slider.H> ++ +
For the "fill" sliders this is the size of the area around the end +that causes a drag effect rather than causing the slider to jump to +the mouse. + +
+Fl_Group + | + +----Fl_Tabs ++ +
+#include <FL/Fl_Tab.H> ++ +
+
+
Clicking the tab makes a child visible() (by calling +show() on it) and all other children are invisible (by calling +hide() on them). Usually the children are Fl_Group widgets containing several +widgets themselves. + +
Each child makes a card, and it's label() is printed on the +card tab (including the label font and style). The color of that child +is used to color the card as well. Currently this only draws nicely if +you set box() to the default +FL_THIN_UP_BOX or to FL_FLAT_BOX, which gets rid of +the edges drawn on the sides and bottom. + +
The size of the tabs is controlled by the bounding box of the +children (there should be some space between the children and the edge +of the Fl_Tabs), and the tabs may be placed "inverted" on the +bottom, this is determined by which gap is larger. It is easiest to +lay this out in fluid, using the fluid browser to select each child +group and resize them until the tabs look the way you want them to. + +
Use add(Fl_Widget *) to add +each child (which is probably itself a Fl_Group). The +children should be sized to stay away from the top or bottom edge of +the Fl_Tabs, which is where the tabs are drawn. + +
+Fl_Widget + | + +----Fl_Tile + | + +----Fl_Pack, Fl_Scroll, Fl_Tabs, Fl_Tile, Fl_Window ++ +
+#include <FL/Fl_Tile.H> ++ +
+
+
Fl_Tile allows objects to be resized to zero dimensions. +To prevent this you can use the resizable() to limit where +corners can be dragged to. + +
Even though objects can be resized to zero sizes, they must +initially have non-zero sizes so the Fl_Tile can figure out +their layout. If desired, call position() after creating the +children but before displaying the window to set the borders where you +want. + +
The "borders" are part of the children, an Fl_Tile does not
+draw any graphics of it's own. In the above example all the final
+children have FL_DOWN_BOX types, and the "ridges" you see are
+two adjacent FL_DOWN_BOX's drawn next to each other.
+
+Methods
+
+
+
+
+Fl_Tile::Fl_Tile(int x, int y, int w, int h, const char *label = 0)
+
+Creates a new Fl_Tile widget using the given position, size, and
+label string. The default boxtype is FL_NO_BOX.
+
+virtual Fl_Tile::~Fl_Tile()
+
+The destructor also deletes all the children. This allows a
+whole tree to be deleted at once, without having to keep a pointer to all
+the children in the user code. A kludge has been done so the
+Fl_Tile and all of it's children can be automatic (local)
+variables, but you must declare the Fl_Tile first, so
+that it is destroyed last.
+
+void Fl_Tile::position(from_x, from_y, to_x, to_y)
+
+Drag the intersection at from_x,from_y to to_x,to_y.
+This redraws all the necessary children.
+
+void Fl_Tile::resizable(Fl_Widget&)
+
+The "resizable" child widget (which should be invisible) limits where
+the border can be dragged to. If you don't set it, it will be possible
+to drag the borders right to the edge, and thus resize objects on the
+edge to zero width or height. The resizable() widget is not
+resized by dragging any borders.
+
+
+
diff --git a/documentation/Fl_Timer.html b/documentation/Fl_Timer.html
new file mode 100644
index 000000000..950ec82a3
--- /dev/null
+++ b/documentation/Fl_Timer.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+class Fl_Timer
+
+
+
+Class Hierarchy
+
+
+Fl_Widget
+ |
+ +----Fl_Timer
+
+
+Include Files
+
+
+#include <FL/Fl_Timer.H>
+
+
+Description
+
+This is provided only to emulate the Forms Timer widget. It works by
+making a timeout callback every 1/5 second. This is wasteful and
+inaccurate if you just want something to happen a fixed time in the
+future. You should directly call Fl::add_timeout() instead.
+
+Methods
+
+
+
+Fl_Timer::Fl_Timer(uchar type, int x, int y, int w, int h, const char *label = 0)
+
+Creates a new Fl_Timer widget using the given type, position, size, and
+label string. The type parameter can be any of the following symbolic
+constants:
+
+
+
+
+virtual Fl_Timer::~Fl_Timer()
+
+Destroys the timer and removes the timeout.
+
+char direction() const
+
+Gets or sets the direction of the timer. If the direction is zero then
+the timer will count up, otherwise it will count down from the initial
+value().
+
+
+void direction(char d)char suspended() const
+
+Gets or sets whether the timer is suspended.
+
+
+void suspended(char d)float value() const
+
+Gets or sets the current timer value.
+
+
+
diff --git a/documentation/Fl_Valuator.html b/documentation/Fl_Valuator.html
new file mode 100644
index 000000000..584c91270
--- /dev/null
+++ b/documentation/Fl_Valuator.html
@@ -0,0 +1,182 @@
+
+
+
+
+void value(float)
+
+class Fl_Valuator
+
+
+
+Class Hierarchy
+
+
+Fl_Widget
+ |
+ +----Fl_Valuator
+ |
+ +----Fl_Adjuster, Fl_Counter, Fl_Dial, Fl_Roller,
+ Fl_Slider, Fl_Value_Input, Fl_Value_Output,
+
+
+Include Files
+
+
+#include <FL/Fl_Valuator.H>
+
+
+Description
+
+The Fl_Valuator class controls a single floating-point value
+and provides a consistent interface to set the value, range, and step,
+and insures that callbacks are done the same for every object.
+
+
There are probably more of these classes in fltk than any others: + +
+
+
In the above diagram each box surrounds an actual subclass. These
+are further differentiated by setting the type() of the widget to the symbolic
+value labeling the widget. The ones labelled "0" are the default
+versions with a type(0). For consistency the symbol
+FL_VERTICAL is defined as zero.
+
+Methods
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fl_Valuator::Fl_Valuator(int x, int y, int w, int h, const char *label = 0)
+
+Creates a new Fl_Valuator widget using the given position, size, and
+label string. The default boxtype is FL_NO_BOX.
+
+virtual Fl_Valuator::~Fl_Valuator()
+
+Destroys the valuator.
+
+double Fl_Valuator::value() const
+
+Get or set the current value. The new value is not clamped or
+otherwise changed before storing it. Use clamp() or
+round() to modify the value before calling this if you want.
+If the new value is different than the current one the object is
+redrawn. The initial value is zero.
+
+
+int Fl_Valuator::value(double)double Fl_Valuator::minimum() const
+
+Gets or sets the minimum value for the valuator.
+
+
+void Fl_Valuator::minimum(double)double Fl_Valuator::maximum() const
+
+Gets or sets the maximum value for the valuator.
+
+
+void Fl_Valuator::maximum(double)void Fl_Valuator::range(double min, double max);
+
+Sets the minimum and maximum values for the valuator. When the user
+manipulates the widget, the value is limited to this range. This
+clamping is done after rounding to the step value (this makes a
+difference if the range is not a multiple of the step).
+
+
The minimum may be greater than the maximum. This has the effect +of "reversing" the object so the larger values are in the opposite +direction. This also switches which end of the filled sliders is +filled. + +
Some widgets consider this a "soft" range. This means they will +stop at the range, but if the user releases and grabs the control +again and tries to move it further, it is allowed. + +
The range may affect the display. You must redraw() the +widget after changing the range. + +
For precision the step is stored as the ratio of two integers, +A/B. You can set these integers directly. Currently setting a +floating point value sets the nearest A/1 or 1/B value possible. + +
+Fl_Valuator + | + +----Fl_Value_Input ++ +
+#include <FL/Fl_Value_Input.H> ++ +
If step() is not zero, the user can also drag the mouse +across the object and thus slide the value. The left button moves one +step() per pixel, the middle by 10 * step(), and the +left button by 100 * step(). It is then impossible to select +text by dragging across it, although clicking can still move the +insertion cursor. + +
+Fl_Valuator + | + +----Fl_Value_Output ++ +
+#include <FL/Fl_Value_Output.H> ++ +
This is much lighter-weight than Fl_Value_Input because it contains no +text editing code or character buffer. + +
+Fl_Slider + | + +----Fl_Value_Slider ++ +
+#include <FL/Fl_Value_Slider.H> ++ +
+
+
+Fl_Widget + | + +----Fl_Box, Fl_Browser, Fl_Button, Fl_Chart, Fl_Clock, + Fl_Free, Fl_Group, Fl_Input, Fl_Menu_, Fl_Positioner, + Fl_Timer, Fl_Valuator ++ +
+#include <FL/Fl_Widget.H> ++ +
All "property" accessing methods, such as color(), +parent(), or argument() are implemented as trivial inline +functions and thus are as fast and small as accessing fields in a structure. +Unless otherwise noted, the property setting methods such as color(n) +or label(s) are also trivial inline functions, even if they change +the widget's appearance. It is up to the user code to call redraw() +after these. + +
+
|
+
+
|
++ + | +
+
|
++ + | +
position(x,y) is a shortcut for resize(x,y,w(),h()), +and size(w,h) is a shortcut for resize(x(),y(),w,h). + +
init_size() calls resize() with the passed sizes, +and then replaces the initial size with the new values. If this widget +is a group you will have to init_size all the children as well or +unpredictable results will occur. + +
Most widgets turn this flag off when they do the callback, and when +the program sets the stored value. + +
Currently you cannot deactivate Fl_Window widgets. + +
+Fl_Group + | + +----Fl_Window + | + +----Fl_Double_Window, Fl_Gl_Window, + Fl_Overlay_Window, Fl_Single_Window ++ +
+#include <FL/Fl_Window.H> ++ +
Once you create a window, you usually add children +Fl_Widget's to it by using window->add(child) for +each new widget. See Fl_Group for +more information on how to add and remove children. + +
There are several subclasses of Fl_Window that provide +double-buffering, overlay, menu, and OpenGL support. + +
The window's callback is done if the user tries to close a window +using the window manager and Fl::modal() +is zero or equal to the window. Fl_Window has a default +callback that calls Fl_Window::hide() and calls +exit(0) if this is the last top-level window. + +
+
|
+
+
|
+
+
|
+
+
|
+
+
|
+
Fl_Widget::box() is set to FL_FLAT_BOX. If you +plan to completely fill the window with children widgets you should +change this to FL_NO_BOX. If you turn the window border off +you may want to change this to FL_UP_BOX. + +
If the window is already shown then it is restored and raised to the +top. This is really convenient because your program can call +show() at any time, even if the window is already up. It also +means that show() serves the purpose of raise() in +other toolkits. + +
Call show() to restore the window. + +
When a window is iconified/restored (either by these calls or by the +user) the handle() method is called with FL_HIDE and +FL_SHOW events and visible() is turned on and off. + +
There is no way to control what is drawn in the icon except with the +string passed to Fl_Window::xclass(). You should not rely on +window managers displaying the icons. + +
You can also call the Fl_Widget methods size(x,y) +and position(w,h), which are inline wrappers for this virtual +function. + +
This method has no effect under Microsoft Windows. + +
This method only works for the Fl_Window and Fl_Gl_Window +classes. + +
+#include <FL/Fl_xyz.H> ++ +Microsoft Windows developers please note: case *is* significant +under other operating systems, and the C standard uses the forward +slash (/) to separate directories. The following #include +directives are *not* recommended for portability reasons: + +
+#include <fl\fl_xyz.h> +#include <fl/fl_xyz.h> +#include <FL\Fl_xyz.H> ++ +
+CC -I/usr/local/include ... +gcc -I/usr/local/include ... ++ +Similarly, when linking your application you will need to tell the compiler +to use the FLTK library: + +
+CC ... -L/usr/local/lib -lfltk -lXext -lX11 -lm +gcc ... -L/usr/local/lib -lfltk -lXext -lX11 -lm ++ +
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, enter the name mainCRTStartup in +the "Entry-point symbol" field in the "Output" settings under the +"Link" tab. + +
Note: The Visual C++ optimizer is known to cause problems with
+many programs. We only recommend using the "Favor Small Code"
+optimization setting.
+
+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.
+
+
+Listing 1 - "hello.cxx"
+
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+
+int main(int argc, char **argv) {
+ Fl_Window *window = new Fl_Window(300,180);
+ Fl_Box *box = new Fl_Box(FL_UP_BOX,20,40,260,100,"Hello, World!");
+ box->labelsize(36);
+ box->labelfont(FL_BOLD+FL_ITALIC);
+ box->labeltype(FL_SHADOW_LABEL);
+ window->end();
+ window->show(argc, argv);
+ return Fl::run();
+}
+
+
+After including the required header files, the program then creates a
+window:
+
+
+Fl_Window *window = new Fl_Window(300,180);
+
+
+and a box with the "Hello, World!" string in it:
+
+
+Fl_Box *box = new Fl_Box(FL_UP_BOX,20,40,260,100,"Hello, World!");
+
+
+Next, we set the size, font, and style of the label:
+
+
+box->labelsize(36);
+box->labelfont(FL_BOLD+FL_ITALIC);
+box->labeltype(FL_SHADOW_LABEL);
+
+
+Finally, we show the window and enter the FLTK event loop:
+
+
+window->end();
+window->show(argc, argv);
+return Fl::run();
+
+
+The resulting program will display the window below. You can quit
+the program by closing the window or pressing the ESCape key.
+
+

+Fl_Widget(boxtype, x, y, width, height) +Fl_Widget(x, y, width, height) +Fl_Widget(width, height) ++ +The boxtype value is the style of the box that is drawn around +the widget. Usually this is 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. + +
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. + +
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, shadowed, symbol, and image labels. + +
A complete list of all label options can be found in +Chapter 3. + +
+while (Fl::wait()); ++ +Fl::run() does not return until all of the windows under FLTK control +are closed (either by the user or your program). + + + diff --git a/documentation/bglogo.gif b/documentation/bglogo.gif new file mode 100644 index 000000000..748f71395 Binary files /dev/null and b/documentation/bglogo.gif differ diff --git a/documentation/boxtypes.gif b/documentation/boxtypes.gif new file mode 100644 index 000000000..ff4d3a473 Binary files /dev/null and b/documentation/boxtypes.gif differ diff --git a/documentation/button.C.gif b/documentation/button.C.gif new file mode 100644 index 000000000..bbfda3eee Binary files /dev/null and b/documentation/button.C.gif differ diff --git a/documentation/buttons.gif b/documentation/buttons.gif new file mode 100644 index 000000000..6b405f400 Binary files /dev/null and b/documentation/buttons.gif differ diff --git a/documentation/charts.gif b/documentation/charts.gif new file mode 100644 index 000000000..f204e14f4 Binary files /dev/null and b/documentation/charts.gif differ diff --git a/documentation/choice.gif b/documentation/choice.gif new file mode 100644 index 000000000..83247dffd Binary files /dev/null and b/documentation/choice.gif differ diff --git a/documentation/clock.gif b/documentation/clock.gif new file mode 100644 index 000000000..41e8f1967 Binary files /dev/null and b/documentation/clock.gif differ diff --git a/documentation/common.html b/documentation/common.html new file mode 100644 index 000000000..2f75ea98b --- /dev/null +++ b/documentation/common.html @@ -0,0 +1,389 @@ + + + +
+Fl_Button *button = new Fl_Button(x, y, width, height, "label"); +Fl_Light_Button *lbutton = new Fl_Light_Button(x, y, width, height); +Fl_Round_Button *rbutton = new Fl_Round_Button(x, y, width, height, "label"); ++ +Each button has an associated type() +which allows it to behave as a push button, toggle button, or radio button: + +
+button->type(0); +lbutton->type(FL_TOGGLE_BUTTON); +rbutton->type(FL_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 current group. + +
The value() method is used to get or +set the string that is displayed: + +
+Fl_Input *input = new Fl_Input(x, y, width, height, "label");
+input->value("Now is the time for all good men...");
+
+
++button->position(x, y); +group->resize(x, y, width, height); +window->size(width, height); ++ +Changing the size or position of a widget will cause a redraw of that widget +and its children. + +
+button->color(FL_RED); ++ +Similarly, the label color can be set using the labelcolor() method: + +
+button->labelcolor(FL_WHITE); ++ +
The type Fl_Boxtype stored and returned in +Fl_Widget::box() is an enumeration defined in +<FL/Enumerations.H>: + +

+void xyz_draw(int x, int y, int w, int h, Fl_Color c) {
+...
+}
+
+
+A simple drawing function might fill a rectangle with the given
+color and then draw a black outline:
+
+
+void xyz_draw(int x, int y, int w, int h, Fl_Color c) {
+ fl_color(c);
+ fl_rectf(x, y, w, h);
+ fl_color(FL_BLACK);
+ fl_rect(x, y, w, h);
+}
+
+
++#define XYZ_BOX FL_FREE_BOXTYPE + +Fl::set_boxtype(XYZ_BOX, xyz_draw, 1, 1, 2, 2); ++ +The last 4 arguments to Fl::set_boxtype() are the offsets +for the bounding box that should be subtracted when drawing the label +inside the box. + +
+void xyz_draw(Fl_Label *label, int x, int y, int w, int h, Fl_Align align) {
+...
+}
+
+
+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: + +
+void xyz_measure(Fl_Label *label, int &w, int &h) {
+...
+}
+
+
+It should measure the size of the label and set w and h to
+the size it will occupy.
+
++#define XYZ_LABEL FL_FREE_LABELTYPE + +Fl::set_labeltype(XYZ_LABEL, xyz_draw, xyz_measure); ++ +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. + +
The FL_SYMBOL_LABEL label type uses the label() +string to look up a small drawing procedure in a hash table. For +historical reasons the string always starts with '@', if it starts with +something else (or the symbol is not found) the label is drawn +normally: + +

+void xyz_callback(Fl_Widget *w, void *data) {
+...
+}
+
+
+The callback() method sets the callback function for a widget. You
+can optionally pass a pointer to some data needed for the callback:
+
++int xyz_data; + +button->callback(xyz_callback, &xyz_data); ++ +Normally callbacks are performed only when the value of the widget +changes. You can change this using the +when() method: + +
+button->when(FL_WHEN_NEVER); +button->when(FL_WHEN_CHANGED); +button->when(FL_WHEN_RELEASE); +button->when(FL_WHEN_RELEASE_ALWAYS); +button->when(FL_WHEN_ENTER_KEY); +button->when(FL_WHEN_ENTER_KEY_ALWAYS); +button->when(FL_WHEN_CHANGED | FL_WHEN_NOT_CHANGED); ++ +
+button->shortcut(FL_Enter); +button->shortcut(FL_SHIFT + 'b'); +button->shortcut(FL_CTRL + 'b'); +button->shortcut(FL_ALT + 'b'); +button->shortcut(FL_CTRL + FL_ALT + 'b'); ++ +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/counter.gif b/documentation/counter.gif new file mode 100644 index 000000000..9784e467e Binary files /dev/null and b/documentation/counter.gif differ diff --git a/documentation/dial.gif b/documentation/dial.gif new file mode 100644 index 000000000..68b09c032 Binary files /dev/null and b/documentation/dial.gif differ diff --git a/documentation/drawing.html b/documentation/drawing.html new file mode 100644 index 000000000..2e78a7086 --- /dev/null +++ b/documentation/drawing.html @@ -0,0 +1,1295 @@ + + + +
+ +
+ +
You can limit all your drawing to a rectangular region by calling +fl_clip, and put the drawings back by using fl_pop_clip. This +rectangle is measured in pixels (it is unaffected by the current +transformation matrix). + +
In addition, the system may provide clipping when updating windows, +this clip region may be more complex than a simple rectangle. + +
void fl_clip(int x, int y, int w, int h);void fl_pop_clip();int fl_not_clipped(int x, int y, int w, int h);int fl_clip_box(int x, int y, int w, int h,
+    int& X, int& Y, int& W, int& H);void fl_color(Fl_Color);Set the color for all subsequent drawing operations. Fl_Color is +an enumeration type, all values are in the range 0-255. This is +not the X pixel, it is an internal table! The table provides +several general colors, a 24-entry gray ramp, and a 5x8x5 color cube. +All of these are named with poorly-documented symbols in <FL/Enumerations.H>. + +
Under X, a color cell will be allocated out of fl_colormap each +time you request an fl_color the first time. If the colormap fills up +then a least-squares algorithim is used to find the closest color. + +
Fl_Color fl_color();void Fl::set_color(Fl_Color, uchar r, uchar g, uchar b);
+
void Fl::get_color(Fl_Color, uchar &, uchar &, uchar &);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. Under X this works +perfectly for TrueColor visuals. For colormap visuals the nearest index +in the gray ramp or color cube is figured out, and fl_color(i) is done +with that, this can result in two approximations of the color and is +very inaccurate! + +
All arguments are integers. + +
void fl_rectf(x, y, w, h);void fl_rectf(x, y, w, h, uchar r, uchar g, uchar b);void fl_rect(x, y, w, h);void fl_line(x, y, x1, y1);
+
void fl_line(x, y, x1, y1, x2, y2);void fl_loop(x, y, x1, y1, x2, y2);
+
void fl_loop(x, y, x1, y1, x2, y2, x3, y3);
+void fl_polygon(x, y, x1, y1, x2, y2);
+
void fl_polygon(x, y, x1, y1, x2, y2, x3, y3);
+void fl_xyline(x, y, x1, y1);
+
void fl_xyline(x, y, x1, y1, x2);
+
void fl_xyline(x, y, x1, y1, x2, y3);
+void fl_yxline(x, y, y1);
+
void fl_yxline(x, y, y1, x2);
+
void fl_yxline(x, y, y1, x2, y3);
+
+void fl_arc(x, y, w, h, double a1, double a2);
+void fl_pie(x, y, w, h, double a1, double a2);
+void fl_chord(x, y, w, h, double a1, double a2);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 1-pixel thick line (notice this has a different +number of arguments than the fl_arc described +below. + +
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. + +
fl_chord is not yet implemented. + +
All arguments are float. + +
void fl_push_matrix();
+
void fl_pop_matrix();void fl_scale(x, y);
+
void fl_scale(x);
+
void fl_translate(x, y);
+
void fl_rotate(d);
+
void fl_mult_matrix(a, b, c, d, x, y);void fl_begin_line();
+
void fl_end_line();void fl_begin_loop();
+
void fl_end_loop();void fl_begin_polygon();
+
void fl_end_polygon();void fl_begin_complex_polygon();
+
void fl_gap();
+
void fl_end_complex_polygon();fl_gap() should only be called between +fl_begin/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(x, y);void fl_curve(int x,int y,int x1,int y1,int x2,int
+y2,int x3,int y3);void fl_arc(x, y, r, start, end);void fl_circle(x, y, r);void fl_draw(const char*, float x, float y);
+
void fl_draw(const char*, int n, float x, float y);void fl_draw(const char*, int x,int y,int w,int h, Fl_Align);void fl_measure(const char*, int& w, int& h);int fl_height();int fl_descent();float fl_width(const char*);
+
float fl_width(const char*, int n);
+
float fl_width(uchar);const char* fl_shortcut_label(ulong);void fl_font(int face, int size);The font is identified by a face and a size. The +size of the font is measured in pixels (ie. it is not +"resolution [in]dependent"). Lines should be spaced size +pixels apart (or more). + +
The face is an index into an internal 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 it stores the index as a byte. + +
int fl_font();
+int fl_size();const char* Fl::get_font(int face);const char* Fl::get_font_name(int face, int* attributes=0);The integer pointed to by attributes (if the pointer is not
+zero) is set to zero, FL_BOLD(1) or
+FL_ITALIC(2) or FL_BOLD|FL_ITALIC (maybe
+more attributes will be defined in the future). To locate a "family"
+of fonts, search forward and back for a set with non-zero attributes,
+these faces along with the face with a zero attribute before them
+constitute a family.
+
+
int get_font_sizes(int face, int*& sizep);int Fl::set_font(int face, const char*);int Fl::set_font(int face, int from);int Fl::set_fonts(const char* = 0);The optional argument is a string to describe the set of fonts to +add. Passing NULL will select only fonts that have the ISO8859-1 +character set (and are thus usable by normal text). Passing "-*" will +select all fonts with any encoding as long as they have normal X font +names with dashes in them. Passing "*" will list every font that +exists (on X this may produce some strange output). Other values may +be useful but are system dependent. On MSWindows NULL selects fonts +with ISO8859-1 encoding and non-NULL selects all fonts. + +
Return value is how many faces are in the table after this is done. + +
void fl_cursor(Fl_Cursor, Fl_Color=FL_WHITE, Fl_Color=FL_BLACK);The type Fl_Cursor is an enumeration defined in <Enumerations.H>. The
+double-headed arrows are bitmaps provided by FLTK on X, the others are
+provided by system-defined cursors. Under X you can get any XC_cursor
+value by passing Fl_Cursor((XC_foo/2)+1).
+
+
FL_CURSOR_DEFAULT (0) usually an arrow
+FL_CURSOR_ARROW
+FL_CURSOR_CROSS - crosshair
+FL_CURSOR_WAIT - watch or hourglass
+FL_CURSOR_INSERT - I-beam
+FL_CURSOR_HAND - hand (uparrow on MSWindows)
+FL_CURSOR_HELP - question mark
+FL_CURSOR_MOVE - 4-pointed arrow
+FL_CURSOR_NS - up/down arrow
+FL_CURSOR_WE - left/right arrow
+FL_CURSOR_NWSE - diagonal arrow
+FL_CURSOR_NESW - diagonal arrow
+FL_CURSOR_NONE - invisible
+void fl_overlay_rect(int x, int y, int w, int h);
+void fl_overlay_clear();Big kludge to draw interactive selection rectangles without using +the overlay. FLTK will xor a single rectangle outline over a window. +Calling this will erase any previous rectangle (by xor'ing it), and +then draw the new one. Calling fl_overlay_clear() will erase the +rectangle without drawing a new one. Using this 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. + +
(back to contents) + + +
It is undefined whether the location or drawing of the image is +affected by the current transformation, so you should only call these +when it is the identity. + +
All untyped arguments are integers. + +
+void fl_draw_bitmap(const uchar*, X, Y, W, H, LD = 0);
+void fl_draw_image(const uchar*, X, Y, W, H, D = 3, LD = 0);
+void fl_draw_image_mono(const uchar*, X, Y, W, H, D = 1, LD = 0);
+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: + +
Fl::visual(FL_RGB)
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.
+
+
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*, x, y, w, uchar*);
+void fl_draw_image(fl_draw_image_cb, void*, X, Y, W, H, D = 3);
+void fl_draw_image_mono(fl_draw_image_cb, void*, X, Y, W, H, D = 1);
+The callback is called with the void* user data pointer (this 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 (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 convienence 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, memcpy the data over so the x'th +pixel is at the start of the buffer. + +
You can assumme 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, X, Y, Fl_Color=FL_GRAY);To use an XPM, do "#include "foo.xpm"" and then
+"fl_draw_pixmap(foo, X, Y)".
+
+
In the current version the XPM data is converted to 8-bit full +color and passed through fl_draw_image(). This is obviously not the +most efficient way to do it, and has the same visual limitations as +listed above for fl_draw_image(). Transparent colors are replaced by +the optional Fl_Color argument (this may change in the future). + +
FLTK supports some (questionable) enhancements to +the XPM format. + +
+int fl_measure_pixmap(char** data, int &w, int
+&h);Fl_Bitmap(const char *bits, int W, int H);
+
Fl_Bitmap(const uchar *bits, int W, int H);#include "foo.xbm", and then do "new
+Fl_Bitmap(foo_bits,foo_width,foo_height)"
+
+~Fl_Bitmap()void draw(int x, int y, int w, int h, int ox=0, int oy=0);void draw(int x, int y);draw(x,y,this->w,this->h,0,0).
+
+void label(Fl_Widget *);The current implementation converts the pixmap to 8 bit color data +and uses fl_draw_image() to draw +it. Thus you will get dithered colors on an 8 bit screen. + +
Fl_Pixmap(char * const * data);#include "foo.xpm", and then do "new
+Fl_Pixmap(foo)"
+
+~Fl_Pixmap()void draw(int x, int y, int w, int h, int ox=0, int oy=0);void draw(int x, int y);draw(x,y,this->w,this->h,0,0).
+
+void label(Fl_Widget *);See fl_draw_image() for what +happens. On 8 bit screens dithering is used. + +
Fl_Image(char uchar *data, int W, int H, int D=3, int LD=0);~Fl_Image()void draw(int x, int y, int w, int h, int ox=0, int oy=0);void draw(int x, int y);draw(x,y,this->w,this->h,0,0).
+
+void label(Fl_Widget *);I made some additions to XPM that may be good, or intensely +disliked by X purists. I do not know if the changes are compatable +with current XPM. + +
The change was to make a "compressed colormap" that avoids +XParseColor(), and gives the actual color values (which is really what +everybody wants!). Only colormaps of this form, and ones where the +colors are named as "#rrggbb", will be portable to non-X platforms. + +
A compressed colormap is indicated by the number of colors being +negative. The colormap is then given as an array of 4*numcolors +characters. Each color is described by 4 characters: the index +character, and the red, green, and blue value (for 2-character indexes +each color needs 5 characters). + +
XPM files support a single transparent index. I require this index +to be ' ' (space). To indicate that ' ' is transparent, it should be +first in the color table. To make ' ' not be transparent, put it +somewhere other than first in the table. + +
To make the XPM files easily parseable, but still portable to most +C compilers, I suggest the following format: + +
+/* XPM */
+static char * name[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 -4 1 ",
+/* colormap */
+"\
+ \x50\x50\x80\
+.\xff\xff\x00\
+r\xff\x00\x00\
+b\x00\x00\x00",
+/* pixels */
+" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ",
+" bb............................................bb ",
+...
+
+
+All lines starting with "/*" are optional. Parsers should handle +'\' at the end of the line and \xNN and \NNN characters. This +requires the C compiler to parse \xNN characters. + +
+ ++ +
+ +
You can limit all your drawing to a rectangular region by calling +fl_clip, and put the drawings back by using fl_pop_clip. This +rectangle is measured in pixels (it is unaffected by the current +transformation matrix). + +
In addition, the system may provide clipping when updating windows, +this clip region may be more complex than a simple rectangle. + +
void fl_clip(int x, int y, int w, int h);void fl_pop_clip();int fl_not_clipped(int x, int y, int w, int h);int fl_clip_box(int x, int y, int w, int h,
+    int& X, int& Y, int& W, int& H);void fl_color(Fl_Color);Set the color for all subsequent drawing operations. Fl_Color is +an enumeration type, all values are in the range 0-255. This is +not the X pixel, it is an internal table! The table provides +several general colors, a 24-entry gray ramp, and a 5x8x5 color cube. +All of these are named with poorly-documented symbols in <FL/Enumerations.H>. + +
Under X, a color cell will be allocated out of fl_colormap each +time you request an fl_color the first time. If the colormap fills up +then a least-squares algorithim is used to find the closest color. + +
Fl_Color fl_color();void Fl::set_color(Fl_Color, uchar r, uchar g, uchar b);
+
void Fl::get_color(Fl_Color, uchar &, uchar &, uchar &);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. Under X this works +perfectly for TrueColor visuals. For colormap visuals the nearest index +in the gray ramp or color cube is figured out, and fl_color(i) is done +with that, this can result in two approximations of the color and is +very inaccurate! + +
All arguments are integers. + +
void fl_rectf(x, y, w, h);void fl_rectf(x, y, w, h, uchar r, uchar g, uchar b);void fl_rect(x, y, w, h);void fl_line(x, y, x1, y1);
+
void fl_line(x, y, x1, y1, x2, y2);void fl_loop(x, y, x1, y1, x2, y2);
+
void fl_loop(x, y, x1, y1, x2, y2, x3, y3);
+void fl_polygon(x, y, x1, y1, x2, y2);
+
void fl_polygon(x, y, x1, y1, x2, y2, x3, y3);
+void fl_xyline(x, y, x1, y1);
+
void fl_xyline(x, y, x1, y1, x2);
+
void fl_xyline(x, y, x1, y1, x2, y3);
+void fl_yxline(x, y, y1);
+
void fl_yxline(x, y, y1, x2);
+
void fl_yxline(x, y, y1, x2, y3);
+
+void fl_arc(x, y, w, h, double a1, double a2);
+void fl_pie(x, y, w, h, double a1, double a2);
+void fl_chord(x, y, w, h, double a1, double a2);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 1-pixel thick line (notice this has a different +number of arguments than the fl_arc described +below. + +
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. + +
fl_chord is not yet implemented. + +
All arguments are float. + +
void fl_push_matrix();
+
void fl_pop_matrix();void fl_scale(x, y);
+
void fl_scale(x);
+
void fl_translate(x, y);
+
void fl_rotate(d);
+
void fl_mult_matrix(a, b, c, d, x, y);void fl_begin_line();
+
void fl_end_line();void fl_begin_loop();
+
void fl_end_loop();void fl_begin_polygon();
+
void fl_end_polygon();void fl_begin_complex_polygon();
+
void fl_gap();
+
void fl_end_complex_polygon();fl_gap() should only be called between +fl_begin/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(x, y);void fl_curve(int x,int y,int x1,int y1,int x2,int
+y2,int x3,int y3);void fl_arc(x, y, r, start, end);void fl_circle(x, y, r);void fl_draw(const char*, float x, float y);
+
void fl_draw(const char*, int n, float x, float y);void fl_draw(const char*, int x,int y,int w,int h, Fl_Align);void fl_measure(const char*, int& w, int& h);int fl_height();int fl_descent();float fl_width(const char*);
+
float fl_width(const char*, int n);
+
float fl_width(uchar);const char* fl_shortcut_label(ulong);void fl_font(int face, int size);The font is identified by a face and a size. The +size of the font is measured in pixels (ie. it is not +"resolution [in]dependent"). Lines should be spaced size +pixels apart (or more). + +
The face is an index into an internal 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 it stores the index as a byte. + +
int fl_font();
+int fl_size();const char* Fl::get_font(int face);const char* Fl::get_font_name(int face, int* attributes=0);The integer pointed to by attributes (if the pointer is not
+zero) is set to zero, FL_BOLD(1) or
+FL_ITALIC(2) or FL_BOLD|FL_ITALIC (maybe
+more attributes will be defined in the future). To locate a "family"
+of fonts, search forward and back for a set with non-zero attributes,
+these faces along with the face with a zero attribute before them
+constitute a family.
+
+
int get_font_sizes(int face, int*& sizep);int Fl::set_font(int face, const char*);int Fl::set_font(int face, int from);int Fl::set_fonts(const char* = 0);The optional argument is a string to describe the set of fonts to +add. Passing NULL will select only fonts that have the ISO8859-1 +character set (and are thus usable by normal text). Passing "-*" will +select all fonts with any encoding as long as they have normal X font +names with dashes in them. Passing "*" will list every font that +exists (on X this may produce some strange output). Other values may +be useful but are system dependent. On MSWindows NULL selects fonts +with ISO8859-1 encoding and non-NULL selects all fonts. + +
Return value is how many faces are in the table after this is done. + +
void fl_cursor(Fl_Cursor, Fl_Color=FL_WHITE, Fl_Color=FL_BLACK);The type Fl_Cursor is an enumeration defined in <Enumerations.H>. The
+double-headed arrows are bitmaps provided by FLTK on X, the others are
+provided by system-defined cursors. Under X you can get any XC_cursor
+value by passing Fl_Cursor((XC_foo/2)+1).
+
+
FL_CURSOR_DEFAULT (0) usually an arrow
+FL_CURSOR_ARROW
+FL_CURSOR_CROSS - crosshair
+FL_CURSOR_WAIT - watch or hourglass
+FL_CURSOR_INSERT - I-beam
+FL_CURSOR_HAND - hand (uparrow on MSWindows)
+FL_CURSOR_HELP - question mark
+FL_CURSOR_MOVE - 4-pointed arrow
+FL_CURSOR_NS - up/down arrow
+FL_CURSOR_WE - left/right arrow
+FL_CURSOR_NWSE - diagonal arrow
+FL_CURSOR_NESW - diagonal arrow
+FL_CURSOR_NONE - invisible
+void fl_overlay_rect(int x, int y, int w, int h);
+void fl_overlay_clear();Big kludge to draw interactive selection rectangles without using +the overlay. FLTK will xor a single rectangle outline over a window. +Calling this will erase any previous rectangle (by xor'ing it), and +then draw the new one. Calling fl_overlay_clear() will erase the +rectangle without drawing a new one. Using this 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. + +
(back to contents) + + diff --git a/documentation/editor-replace.gif b/documentation/editor-replace.gif new file mode 100644 index 000000000..6098ead60 Binary files /dev/null and b/documentation/editor-replace.gif differ diff --git a/documentation/editor.gif b/documentation/editor.gif new file mode 100644 index 000000000..3f3301e47 Binary files /dev/null and b/documentation/editor.gif differ diff --git a/documentation/editor.html b/documentation/editor.html new file mode 100644 index 000000000..60dca040c --- /dev/null +++ b/documentation/editor.html @@ -0,0 +1,603 @@ + +
+ ++Fl_Window *window; + +window = new Fl_Window(640, 480, "Text Editor"); ++ +
+Fl_Window *window; +Fl_Menu_Bar *menubar; +Fl_Multiline_Input *input; +Fl_Window *replace_dlg; +Fl_Input *replace_find; +Fl_Input *replace_with; +Fl_Button *replace_all; +Fl_Return_Button *replace_next; +Fl_Button *replace_cancel; + +int changed = 0; +char filename[1024] = ""; +char search[256] = ""; ++ +The window variable is our top-level window described previously. +We'll cover the other variables as we build the application. + +
+Fl_Menu_Item menuitems[] = {
+ { "&File", 0, 0, 0, FL_SUBMENU },
+ { "&New", FL_ALT + 'n', new_cb },
+ { "&Open...", FL_ALT + 'o', open_cb, 0, FL_MENU_DIVIDER },
+ { "&Save", FL_ALT + 's', save_cb },
+ { "Save &As...", FL_ALT + FL_SHIFT + 's', saveas_cb, 0, FL_MENU_DIVIDER },
+ { "&Quit", FL_ALT + 'q', quit_cb },
+ { 0 },
+
+ { "&Edit", 0, 0, 0, FL_SUBMENU },
+ { "&Undo", FL_ALT + 'z', undo_cb, 0, FL_MENU_DIVIDER },
+ { "Cu&t", FL_ALT + 'x', cut_cb },
+ { "&Copy", FL_ALT + 'c', copy_cb },
+ { "&Paste", FL_ALT + 'v', paste_cb },
+ { "&Delete", 0, delete_cb },
+ { 0 },
+
+ { "&Search", 0, 0, 0, FL_SUBMENU },
+ { "&Find...", FL_ALT + 'f', find_cb },
+ { "F&ind Again", FL_ALT + 'g', find2_cb },
+ { "&Replace...", FL_ALT + 'r', replace_cb },
+ { "Re&place Again", FL_ALT + 't', replace2_cb },
+ { 0 },
+
+ { 0 }
+};
+
+
+Once we have the menus defined we can create the Fl_Menu_Bar widget
+and assign the menus to it with:
+
++Fl_Menu_Bar *menubar = new Fl_Menu_Bar(0, 0, 640, 30); +menubar->menu(menuitems); ++ +We'll define the callback functions later. + +
+Fl_Multiline_Input *input = new Fl_Multiline_Input(0, 30, 640, 450); ++ +So that we can keep track of changes to the file, we also want to add a +"changed" callback: + +
+input->callback(changed_cb); +input->when(FL_WHEN_CHANGED); ++ +Finally, we want to use a mono-spaced font like FL_COURIER: + +
+input->textfont(FL_COURIER); ++ +

+Fl_Window *replace_dlg = new Fl_Window(300, 105, "Replace"); +Fl_Input *replace_find = new Fl_Input(70, 10, 200, 25, "Find:"); +Fl_Input *replace_with = new Fl_Input(70, 40, 200, 25, "Replace:"); +Fl_Button *replace_all = new Fl_Button(10, 70, 90, 25, "Replace All"); +Fl_Button *replace_next = new Fl_Button(105, 70, 120, 25, "Replace Next"); +Fl_Button *replace_cancel = new Fl_Button(230, 70, 60, 25, "Cancel"); ++ +
+void changed_cb(void) {
+ set_changed(1);
+}
+
+
+The set_changed() function is one that we will write to set the
+changed status on the current file. We're doing it this way because some
+of the other callbacks will set the changed status to 0, and also because
+we want to show the changed status in the window's title bar.
+
+
+void copy_cb(void) {
+ input->copy();
+}
+
+
+
+void cut_cb(void) {
+ input->copy();
+ input->cut();
+}
+
+
+
+void delete_cb(void) {
+ input->cut();
+}
+
+
+
+void find_cb(void) {
+ const char *val;
+
+ val = fl_input("Search String:", search);
+ if (val != NULL) {
+ // User entered a string - go find it!
+ strcpy(search, val);
+ find2_cb();
+ }
+}
+
+
+
+void find2_cb(void) {
+ const char *val, *found;
+ int pos;
+
+ if (search[0] == '\0') {
+ // Search string is blank; get a new one...
+ find_cb();
+ return;
+ }
+
+ val = input->value() + input->mark();
+ found = strstr(val, search);
+
+ if (found != NULL) {
+ // Found a match; update the position and mark...
+ pos = input->mark() + found - val;
+ input->position(pos, pos + strlen(search));
+ }
+ else fl_alert("No occurrences of \'%s\' found!", search);
+}
+
+
+If the search string cannot be found we use the
+fl_alert() convenience function to display a message to
+that effect.
+
+
+void new_cb(void) {
+ if (changed)
+ if (!check_save()) return;
+
+ filename[0] = '\0';
+ input->value("");
+ set_changed(0);
+}
+
+
+
+void open_cb(void) {
+ char *newfile;
+
+ if (changed)
+ if (!check_save()) return;
+
+ newfile = fl_file_chooser("Open File?", "*", filename);
+ if (newfile != NULL) load_file(newfile);
+}
+
+
+We call the load_file() function to actually load the file.
+
+
+void paste_cb(void) {
+ Fl::paste(*input);
+}
+
+
+
+void quit_cb(void) {
+ if (changed)
+ if (!check_save())
+ return;
+
+ window->hide();
+}
+
+
+
+void replace_cb(void) {
+ replace_dlg->show();
+}
+
+
+
+void replace2_cb() {
+ const char *find, *val, *found;
+ int pos;
+
+ find = replace_find->value();
+ if (find[0] == '\0') {
+ // Search string is blank; get a new one...
+ replace_dlg->show();
+ return;
+ }
+
+ val = input->value() + input->position();
+ found = strstr(val, find);
+
+ if (found != NULL) {
+ // Found a match; update the position and replace text...
+ pos = input->position() + found - val;
+ input->replace(pos, pos + strlen(find), replace_with->value());
+ input->position(pos + strlen(replace_with->value()));
+ }
+ else fl_alert("No occurrences of \'%s\' found!", find);
+}
+
+
+
+void replall_cb() {
+ const char *find, *val, *found;
+ int pos;
+ int times;
+
+ find = replace_find->value();
+ if (find[0] == '\0') {
+ // Search string is blank; get a new one...
+ replace_dlg->show();
+ return;
+ }
+
+ input->position(0);
+ times = 0;
+
+ // Loop through the whole string
+ do {
+ val = input->value() + input->position();
+ found = strstr(val, find);
+
+ if (found != NULL) {
+ // Found a match; update the position and replace text...
+ times ++
+ pos = input->position() + found - val;
+ input->replace(pos, pos + strlen(find), replace_with->value());
+ input->position(pos + strlen(replace_with->value()));
+ }
+ } while (found != NULL);
+
+ if (times > 0) fl_message("Replaced %d occurrences.", times);
+ else fl_alert("No occurrences of \'%s\' found!", find);
+}
+
+
+
+void replcan_cb() {
+ replace_dlg->hide();
+}
+
+
+
+void save_cb(void) {
+ if (filename[0] == '\0') {
+ // No filename - get one!
+ saveas_cb();
+ return;
+ }
+ else save_file(filename);
+}
+
+
+The save_file() function saves the current file to the specified
+filename.
+
+
+void saveas_cb(void) {
+ char *newfile;
+
+ newfile = fl_file_chooser("Save File As?", "*", filename);
+ if (newfile != NULL) save_file(newfile);
+}
+
+
+The save_file() function saves the current file to the specified
+filename.
+
+
+void undo_cb(void) {
+ input->undo();
+}
+
+
+
+int check_save(void) {
+ if (!changed) return 1;
+
+ if (fl_ask("The current file has not been saved.\n"
+ "Would you like to save it now?")) {
+ // Save the file...
+ save_cb();
+
+ return !changed;
+ }
+ else return (1);
+}
+
+
+
+void load_file(char *newfile) {
+ FILE *fp;
+ char buffer[8192];
+ int nbytes;
+ int pos;
+
+ input->value("");
+
+ fp = fopen(newfile, "r");
+ if (fp != NULL) {
+ // Was able to open file; let's read from it...
+ strcpy(filename, newfile);
+ pos = 0;
+
+ while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
+ input->replace(pos, pos, buffer, nbytes);
+ pos += nbytes;
+ }
+
+ fclose(fp);
+ input->position(0);
+ set_changed(0);
+ } else {
+ // Couldn't open file - say so...
+ fl_alert("Unable to open \'%s\' for reading!");
+ }
+}
+
+
+When loading the file we use the
+input->replace() method to "replace" the text at the end of
+the buffer. The pos variable keeps track of the end of the
+buffer.
+
+
+void save_file(char *newfile) {
+ FILE *fp;
+
+ fp = fopen(newfile, "w");
+ if (fp != NULL) {
+ // Was able to create file; let's write to it...
+ strcpy(filename, newfile);
+
+ if (fwrite(input->value(), 1, input->size(), fp) < 1) {
+ fl_alert("Unable to write file!");
+ fclose(fp);
+ return;
+ }
+
+ fclose(fp);
+ set_changed(0);
+ } else {
+ // Couldn't open file - say so...
+ fl_alert("Unable to create \'%s\' for writing!");
+ }
+}
+
+
+
+void set_changed(int c) {
+ if (c != changed) {
+ char title[1024];
+ char *slash;
+
+ changed = c;
+
+ if (filename[0] == '\0') strcpy(title, "Untitled");
+ else {
+ slash = strrchr(filename, '/');
+ if (slash == NULL) slash = strrchr(filename, '\\');
+
+ if (slash != NULL) strcpy(title, slash + 1);
+ else strcpy(title, filename);
+ }
+
+ if (changed) strcat(title, " (modified)");
+
+ window->label(title);
+ }
+}
+
+
++CC -o editor editor.cxx -lfltk -lXext -lX11 -lm ++ +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! + +

+#include <FL/Enumerations.H>
+
+//
+// The FLTK version number; this is changed slightly from the beta versions
+// because the old "const double" definition would not allow for conditional
+// compilation...
+//
+// FL_VERSION is a double that describes the major and minor version numbers.
+// Version 1.1 is actually stored as 1.01 to allow for more than 9 minor
+// releases.
+//
+// The FL_MAJOR_VERSION, FL_MINOR_VERSION, and FL_PATCH_VERSION constants
+// give the integral values for the major, minor, and patch releases
+// respectively.
+//
+
+#define FL_MAJOR_VERSION 1
+#define FL_MINOR_VERSION 0
+#define FL_PATCH_VERSION 0
+#define FL_VERSION ((double)FL_MAJOR_VERSION + \
+ (double)FL_MINOR_VERSION * 0.01)
+
+typedef unsigned char uchar;
+typedef unsigned long ulong;
+typedef unsigned int u32; // you must fix if not 32 bits on your machine!
+
+enum Fl_Event { // events
+ FL_NO_EVENT = 0,
+ FL_PUSH = 1,
+ FL_RELEASE = 2,
+ FL_ENTER = 3,
+ FL_LEAVE = 4,
+ FL_DRAG = 5,
+ FL_FOCUS = 6,
+ FL_UNFOCUS = 7,
+ FL_KEYBOARD = 8,
+ FL_CLOSE = 9,
+ FL_MOVE = 10,
+ FL_SHORTCUT = 11,
+ FL_DEACTIVATE = 13,
+ FL_ACTIVATE = 14,
+ FL_HIDE = 15,
+ FL_SHOW = 16,
+ FL_PASTE = 17,
+ FL_SELECTIONCLEAR = 18
+};
+
+enum Fl_When { // Fl_Widget::when():
+ FL_WHEN_NEVER = 0,
+ FL_WHEN_CHANGED = 1,
+ FL_WHEN_RELEASE = 4,
+ FL_WHEN_RELEASE_ALWAYS= 6,
+ FL_WHEN_ENTER_KEY = 8,
+ FL_WHEN_ENTER_KEY_ALWAYS=10,
+ FL_WHEN_NOT_CHANGED = 2 // modifier bit to disable changed() test
+};
+
+// Fl::event_key() and Fl::get_key(n) (use ascii letters for all other keys):
+#define FL_Button 0xfee8 // use Fl_Button+n for mouse button n
+#define FL_BackSpace 0xff08
+#define FL_Tab 0xff09
+#define FL_Enter 0xff0d
+#define FL_Pause 0xff13
+#define FL_Scroll_Lock 0xff14
+#define FL_Escape 0xff1b
+#define FL_Home 0xff50
+#define FL_Left 0xff51
+#define FL_Up 0xff52
+#define FL_Right 0xff53
+#define FL_Down 0xff54
+#define FL_Page_Up 0xff55
+#define FL_Page_Down 0xff56
+#define FL_End 0xff57
+#define FL_Print 0xff61
+#define FL_Insert 0xff63
+#define FL_Menu 0xff67 // the "menu/apps" key on XFree86
+#define FL_Num_Lock 0xff7f
+#define FL_KP 0xff80 // use FL_KP+'x' for 'x' on numeric keypad
+#define FL_KP_Enter 0xff8d // same as Fl_KP+'\r'
+#define FL_KP_Last 0xffbd // use to range-check keypad
+#define FL_F 0xffbd // use FL_F+n for function key n
+#define FL_F_Last 0xffe0 // use to range-check function keys
+#define FL_Shift_L 0xffe1
+#define FL_Shift_R 0xffe2
+#define FL_Control_L 0xffe3
+#define FL_Control_R 0xffe4
+#define FL_Caps_Lock 0xffe5
+#define FL_Meta_L 0xffe7 // the left MSWindows key on XFree86
+#define FL_Meta_R 0xffe8 // the right MSWindows key on XFree86
+#define FL_Alt_L 0xffe9
+#define FL_Alt_R 0xffea
+#define FL_Delete 0xffff
+
+// Fl::event_state():
+#define FL_SHIFT 0x00010000
+#define FL_CAPS_LOCK 0x00020000
+#define FL_CTRL 0x00040000
+#define FL_ALT 0x00080000
+#define FL_NUM_LOCK 0x00100000 // most X servers do this?
+#define FL_META 0x00400000 // correct for XFree86
+#define FL_SCROLL_LOCK 0x00800000 // correct for XFree86
+#define FL_BUTTON1 0x01000000
+#define FL_BUTTON2 0x02000000
+#define FL_BUTTON3 0x04000000
+
+enum Fl_Boxtype { // boxtypes (if you change these you must fix fl_boxtype.C):
+ FL_NO_BOX = 0, FL_FLAT_BOX,
+
+ FL_UP_BOX, FL_DOWN_BOX,
+ FL_UP_FRAME, FL_DOWN_FRAME,
+ FL_THIN_UP_BOX, FL_THIN_DOWN_BOX,
+ FL_THIN_UP_FRAME, FL_THIN_DOWN_FRAME,
+ FL_ENGRAVED_BOX, FL_EMBOSSED_BOX,
+ FL_ENGRAVED_FRAME, FL_EMBOSSED_FRAME,
+ FL_BORDER_BOX, _FL_SHADOW_BOX,
+ FL_BORDER_FRAME, _FL_SHADOW_FRAME,
+ _FL_ROUNDED_BOX, _FL_RSHADOW_BOX,
+ _FL_ROUNDED_FRAME, _FL_RFLAT_BOX,
+ _FL_ROUND_UP_BOX, _FL_ROUND_DOWN_BOX,
+ _FL_DIAMOND_UP_BOX, _FL_DIAMOND_DOWN_BOX,
+ _FL_OVAL_BOX, _FL_OSHADOW_BOX,
+ _FL_OVAL_FRAME, _FL_OFLAT_BOX
+};
+extern Fl_Boxtype define_FL_ROUND_UP_BOX();
+#define FL_ROUND_UP_BOX define_FL_ROUND_UP_BOX()
+#define FL_ROUND_DOWN_BOX (Fl_Boxtype)(define_FL_ROUND_UP_BOX()+1)
+extern Fl_Boxtype define_FL_SHADOW_BOX();
+#define FL_SHADOW_BOX define_FL_SHADOW_BOX()
+#define FL_SHADOW_FRAME (Fl_Boxtype)(define_FL_SHADOW_BOX()+2)
+extern Fl_Boxtype define_FL_ROUNDED_BOX();
+#define FL_ROUNDED_BOX define_FL_ROUNDED_BOX()
+#define FL_ROUNDED_FRAME (Fl_Boxtype)(define_FL_ROUNDED_BOX()+2)
+extern Fl_Boxtype define_FL_RFLAT_BOX();
+#define FL_RFLAT_BOX define_FL_RFLAT_BOX()
+extern Fl_Boxtype define_FL_RSHADOW_BOX();
+#define FL_RSHADOW_BOX define_FL_RSHADOW_BOX()
+extern Fl_Boxtype define_FL_DIAMOND_BOX();
+#define FL_DIAMOND_UP_BOX define_FL_DIAMOND_BOX()
+#define FL_DIAMOND_DOWN_BOX (Fl_Boxtype)(define_FL_DIAMOND_BOX()+1)
+extern Fl_Boxtype define_FL_OVAL_BOX();
+#define FL_OVAL_BOX define_FL_OVAL_BOX()
+#define FL_OSHADOW_BOX (Fl_Boxtype)(define_FL_OVAL_BOX()+1)
+#define FL_OVAL_FRAME (Fl_Boxtype)(define_FL_OVAL_BOX()+2)
+#define FL_OFLAT_BOX (Fl_Boxtype)(define_FL_OVAL_BOX()+3)
+
+// conversions of box types to other boxtypes:
+inline Fl_Boxtype down(Fl_Boxtype b) {return (Fl_Boxtype)(b|1);}
+inline Fl_Boxtype frame(Fl_Boxtype b) {return (Fl_Boxtype)(b|2);}
+
+// back-compatability box types:
+#define FL_FRAME FL_ENGRAVED_FRAME
+#define FL_FRAME_BOX FL_ENGRAVED_BOX
+#define FL_CIRCLE_BOX FL_ROUND_DOWN_BOX
+#define FL_DIAMOND_BOX FL_DIAMOND_DOWN_BOX
+
+enum Fl_Labeltype { // labeltypes:
+ FL_NORMAL_LABEL = 0,
+ FL_NO_LABEL,
+ _FL_SYMBOL_LABEL,
+ _FL_SHADOW_LABEL,
+ _FL_ENGRAVED_LABEL,
+ _FL_EMBOSSED_LABEL,
+ _FL_BITMAP_LABEL,
+ _FL_PIXMAP_LABEL,
+ _FL_IMAGE_LABEL,
+ _FL_MULTI_LABEL,
+ FL_FREE_LABELTYPE
+};
+extern Fl_Labeltype define_FL_SYMBOL_LABEL();
+#define FL_SYMBOL_LABEL define_FL_SYMBOL_LABEL()
+extern Fl_Labeltype define_FL_SHADOW_LABEL();
+#define FL_SHADOW_LABEL define_FL_SHADOW_LABEL()
+extern Fl_Labeltype define_FL_ENGRAVED_LABEL();
+#define FL_ENGRAVED_LABEL define_FL_ENGRAVED_LABEL()
+extern Fl_Labeltype define_FL_EMBOSSED_LABEL();
+#define FL_EMBOSSED_LABEL define_FL_EMBOSSED_LABEL()
+
+enum Fl_Align { // align() values
+ FL_ALIGN_CENTER = 0,
+ FL_ALIGN_TOP = 1,
+ FL_ALIGN_BOTTOM = 2,
+ FL_ALIGN_LEFT = 4,
+ FL_ALIGN_RIGHT = 8,
+ FL_ALIGN_INSIDE = 16,
+ FL_ALIGN_CLIP = 64,
+ FL_ALIGN_WRAP = 128,
+ FL_ALIGN_TOP_LEFT = FL_ALIGN_TOP | FL_ALIGN_LEFT,
+ FL_ALIGN_TOP_RIGHT = FL_ALIGN_TOP | FL_ALIGN_RIGHT,
+ FL_ALIGN_BOTTOM_LEFT = FL_ALIGN_BOTTOM | FL_ALIGN_LEFT,
+ FL_ALIGN_BOTTOM_RIGHT = FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT,
+ FL_ALIGN_LEFT_TOP = FL_ALIGN_TOP_LEFT,
+ FL_ALIGN_RIGHT_TOP = FL_ALIGN_TOP_RIGHT,
+ FL_ALIGN_LEFT_BOTTOM = FL_ALIGN_BOTTOM_LEFT,
+ FL_ALIGN_RIGHT_BOTTOM = FL_ALIGN_BOTTOM_RIGHT,
+ FL_ALIGN_NOWRAP = 0 // for back compatability
+};
+
+enum Fl_Font { // standard fonts
+ FL_HELVETICA = 0,
+ FL_HELVETICA_BOLD,
+ FL_HELVETICA_ITALIC,
+ FL_HELVETICA_BOLD_ITALIC,
+ FL_COURIER,
+ FL_COURIER_BOLD,
+ FL_COURIER_ITALIC,
+ FL_COURIER_BOLD_ITALIC,
+ FL_TIMES,
+ FL_TIMES_BOLD,
+ FL_TIMES_ITALIC,
+ FL_TIMES_BOLD_ITALIC,
+ FL_SYMBOL,
+ FL_SCREEN,
+ FL_SCREEN_BOLD,
+ FL_ZAPF_DINGBATS,
+
+ FL_FREE_FONT = 16, // first one to allocate
+ FL_BOLD = 1, // add this to helvetica, courier, or times
+ FL_ITALIC = 2 // add this to helvetica, courier, or times
+};
+
+#define FL_NORMAL_SIZE 14 // default size of all labels & text
+
+enum Fl_Color { // standard colors
+ FL_BLACK = 0,
+ FL_RED = 1,
+ FL_GREEN = 2,
+ FL_YELLOW = 3,
+ FL_BLUE = 4,
+ FL_MAGENTA = 5,
+ FL_CYAN = 6,
+ FL_WHITE = 7,
+ FL_INACTIVE_COLOR = 8,
+ FL_SELECTION_COLOR = 15,
+
+ FL_FREE_COLOR = 16,
+ FL_NUM_FREE_COLOR = 16,
+
+ FL_GRAY_RAMP = 32,
+
+ // boxtypes limit themselves to these colors so whole ramp is not allocated:
+ FL_GRAY0 = 32, // 'A'
+ FL_DARK3 = 39, // 'H'
+ FL_DARK2 = 45, // 'N'
+ FL_DARK1 = 47, // 'P'
+ FL_GRAY = 49, // 'R' default color
+ FL_LIGHT1 = 50, // 'S'
+ FL_LIGHT2 = 52, // 'U'
+ FL_LIGHT3 = 54, // 'W'
+
+ FL_COLOR_CUBE = 56
+};
+
+inline Fl_Color inactive(Fl_Color c) {return (Fl_Color)(c|8);}
+Fl_Color contrast(Fl_Color fg, Fl_Color bg);
+#define FL_NUM_GRAY 24
+inline Fl_Color fl_gray_ramp(int i) {return (Fl_Color)(i+FL_GRAY_RAMP);}
+#define FL_NUM_RED 5
+#define FL_NUM_GREEN 8
+#define FL_NUM_BLUE 5
+inline Fl_Color fl_color_cube(int r, int g, int b) {
+ return (Fl_Color)((b*FL_NUM_RED + r) * FL_NUM_GREEN + g + FL_COLOR_CUBE);}
+
+enum Fl_Cursor { // standard cursors
+ FL_CURSOR_DEFAULT = 0,
+ FL_CURSOR_ARROW = 35,
+ FL_CURSOR_CROSS = 66,
+ FL_CURSOR_WAIT = 76,
+ FL_CURSOR_INSERT = 77,
+ FL_CURSOR_HAND = 31,
+ FL_CURSOR_HELP = 47,
+ FL_CURSOR_MOVE = 27,
+ // fltk provides bitmaps for these:
+ FL_CURSOR_NS = 78,
+ FL_CURSOR_WE = 79,
+ FL_CURSOR_NWSE = 80,
+ FL_CURSOR_NESW = 81,
+ FL_CURSOR_NONE = 255,
+ // for back compatability (non MSWindows ones):
+ FL_CURSOR_N = 70,
+ FL_CURSOR_NE = 69,
+ FL_CURSOR_E = 49,
+ FL_CURSOR_SE = 8,
+ FL_CURSOR_S = 9,
+ FL_CURSOR_SW = 7,
+ FL_CURSOR_W = 36,
+ FL_CURSOR_NW = 68
+ //FL_CURSOR_NS = 22,
+ //FL_CURSOR_WE = 55,
+};
+
+enum { // values for "when" passed to Fl::add_fd()
+ FL_READ = 1,
+ FL_WRITE = 4,
+ FL_EXCEPT = 8
+};
+
+enum Fl_Mode { // visual types and Fl_Gl_Window::mode() (values match Glut)
+ FL_RGB = 0,
+ FL_INDEX = 1,
+ FL_SINGLE = 0,
+ FL_DOUBLE = 2,
+ FL_ACCUM = 4,
+ FL_ALPHA = 8,
+ FL_DEPTH = 16,
+ FL_STENCIL = 32,
+ FL_RGB8 = 64,
+ FL_MULTISAMPLE= 128
+};
+
+// damage masks
+
+enum Fl_Damage {
+ FL_DAMAGE_CHILD = 0x01,
+ FL_DAMAGE_EXPOSE = 0x02,
+ FL_DAMAGE_SCROLL = 0x04,
+ FL_DAMAGE_OVERLAY = 0x08,
+ FL_DAMAGE_ALL = 0x80
+};
+
+
+
diff --git a/documentation/events.html b/documentation/events.html
new file mode 100644
index 000000000..b4b5f1513
--- /dev/null
+++ b/documentation/events.html
@@ -0,0 +1,499 @@
+
+
+
+Events are identified the small integer argument passed to the Fl_Widget::handle() virtual method.
+Other information about the most recent event is stored in static
+locations and aquired by calling Fl::event_*(). This static
+information remains valid until the next event is read from the X
+server (that is, it is ok to look at it outside the handle() method).
+
+
FL_PUSH (1)A widget indicates that it "wants" the mouse click by returning +non-zero from it's 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 (5)FL_RELEASE (2)FL_ENTER (3)FL_MOVE (10)FL_LEAVE (4)FL_FOCUS (6)If a widget wants the focus, it should change itself to display the +fact that it has the focus, and return non-zero from it's handle() method. It then becomes the Fl::focus() widget and gets FL_KEYBOARD 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, for instructions from the +window manager it will be zero. + +
FL_UNFOCUS (7)FL_KEYBOARD (8)FL_SHORTCUT (11)If the Fl::event_text() is a lower or +upper-case letter, and nothing wants the shortcut + +
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. + +
FL_DEACTIVATE (13)FL_ACTIVATE (14)FL_HIDE (15)FL_SHOW (16)FL_PASTE (17)FL_SELECTIONCLEAR (18)These are all trivial inline functions and thus very fast and
+small. The data is stored in static locations and remains valid until
+the next X event is handled.
+
+
+ Return where the mouse is on the screen by doing a round-trip query
+to the server. You should use Fl::event_x/y_root() if possible, but this is
+necessary if you are not sure if a mouse event has been processed
+recently (such as to position your first window). If the display is
+not open, this will open it.
+
+
+ X servers do not agree on shift states and FL_NUM_LOCK, FL_META,
+and FL_SCROLL_LOCK may not work. The values were selected to match
+the XFree86 server on Linux. In addition there is a bug in the way
+Xlib works so that the shift state is not correctly reported until the
+first event after the shift key is pressed or released.
+
+
+ Fl::event_key(int) returns true if the given key was held down (or
+pressed) during the last event. This is constant until the
+next event is read from the server.
+
+ Fl::get_key(int) returns true if the given key is held down
+now. Under X this requires a round-trip to the server and is
+much slower than Fl::event_key(int).
+
+ Keys are identified by the unshifted X keysym values.
+However fltk defines a set of symbols that should work on most modern
+machines for every key on the generic PC keyboard:
+
+ Known bugs: on X ASCII text (in the future this may be UTF-8) produced by the last
+FL_KEYBOARD or FL_PASTE or possibly other event. A zero-length string
+is returned for any keyboard function keys that do not produce text.
+This pointer points at a static buffer and is only valid until the
+next event is processed.
+
+ Under X this is the result of XLookupString.
+
+
+ Length of the text in Fl::event_text(). There will always be a
+null at this position in the text. However there may be a nul before
+that if the keystroke translates to a nul character or you paste a nul
+character.
+
+ 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 X toolkits.
+
+ Most events are sent directly to the handle() method of the
+Fl_Window that X 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, FL_LEAVE) directly to leaf
+widgets. These procedures control those leaf widgets:
+
+
+ If you change Fl::focus(), the old one and all parents (that don't
+contain the new widget) are sent FL_UNFOCUS events. Changing the
+focus does not send FL_FOCUS to this or any widget, because
+sending FL_FOCUS is supposed to test if the widget wants the
+focus (by it returning non-zero from handle()).
+
+ Try to make this widget be the Fl::focus(), by first sending it an
+FL_FOCUS event, and if it returns non-zero, setting Fl::focus() to
+this widget. You should use this method to assign the focus to an
+widget. Returns true if the widget accepted the focus.
+
+
+ If you change the belowmouse widget, the old one and all parents (that
+don't contain the new widget) are sent FL_LEAVE events. Changing this
+does not send FL_ENTER to this or any widget, because
+sending FL_ENTER is supposed to test if the widget wants the
+mouse (by it returning non-zero from handle()).
+
+
+ Get or set the widget that is being pushed. FL_DRAG or FL_RELEASE
+(and any more FL_PUSH) events will be sent to this widget.
+
+ If you change the pushed widget, the old one and all parents (that
+don't contain the new widget) are sent FL_RELEASE events. Changing
+this does not send FL_PUSH to this or any widget, because
+sending FL_PUSH is supposed to test if the widget wants the
+mouse (by it returning non-zero from handle()).
+
+
+ Fl::event_x() and y() are undefiend if the passed widget is not a
+mapped Fl_Window. Use Fl::event_x_root() and Fl::event_y_root()
+instead.
+
+ Be careful that your program does not enter an infinite loop
+while grab() is on. On X this will lock up your screen!
+
+ The second function returns the current grab window, or null if
+none.
+
+
+ (back to contents)
diff --git a/documentation/filechooser.gif b/documentation/filechooser.gif
new file mode 100644
index 000000000..44a786176
Binary files /dev/null and b/documentation/filechooser.gif differ
diff --git a/documentation/fl_alert.gif b/documentation/fl_alert.gif
new file mode 100644
index 000000000..6313c0774
Binary files /dev/null and b/documentation/fl_alert.gif differ
diff --git a/documentation/fl_ask.gif b/documentation/fl_ask.gif
new file mode 100644
index 000000000..aa999e37f
Binary files /dev/null and b/documentation/fl_ask.gif differ
diff --git a/documentation/fl_choice.gif b/documentation/fl_choice.gif
new file mode 100644
index 000000000..9a879c841
Binary files /dev/null and b/documentation/fl_choice.gif differ
diff --git a/documentation/fl_color_chooser.jpg b/documentation/fl_color_chooser.jpg
new file mode 100644
index 000000000..18cde83be
Binary files /dev/null and b/documentation/fl_color_chooser.jpg differ
diff --git a/documentation/fl_input.gif b/documentation/fl_input.gif
new file mode 100644
index 000000000..8c7ebd328
Binary files /dev/null and b/documentation/fl_input.gif differ
diff --git a/documentation/fl_message.gif b/documentation/fl_message.gif
new file mode 100644
index 000000000..711cd607c
Binary files /dev/null and b/documentation/fl_message.gif differ
diff --git a/documentation/fl_password.gif b/documentation/fl_password.gif
new file mode 100644
index 000000000..6e972dee7
Binary files /dev/null and b/documentation/fl_password.gif differ
diff --git a/documentation/fl_show_colormap.gif b/documentation/fl_show_colormap.gif
new file mode 100644
index 000000000..5ac3f64c7
Binary files /dev/null and b/documentation/fl_show_colormap.gif differ
diff --git a/documentation/fluid.gif b/documentation/fluid.gif
new file mode 100644
index 000000000..99f085f36
Binary files /dev/null and b/documentation/fluid.gif differ
diff --git a/documentation/fluid.html b/documentation/fluid.html
new file mode 100644
index 000000000..47cb7d7fd
--- /dev/null
+++ b/documentation/fluid.html
@@ -0,0 +1,894 @@
+
+ Fluid (the Fast Light User Interface Designer) is a graphical
+editor that is used to produce fltk source code.
+
+ Fluid edits and saves it's state in ".fl" files. These files are
+text, and you could (with care) edit them in a text editor, perhaps to
+get some special effects.
+
+ Fluid can "compile" the .fl file into a .C and a .H file. The .C
+file defines all the objects from the .fl file and the .H file
+declares all the global ones.
+
+ A simple program can be made by putting all your code (including a
+main() function) into the .fl file and thus making the .C file a
+single source file to compile. Normally though you write other .C
+files that call the fluid functions. These .C files must #include the
+.H file output (or they can #include the .C file so it still appears
+to make to be a single source file).
+
+ Normally the fluid file defines one or more "functions", which
+output C++ functions. 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 it's
+name (ie only alphanumeric and underscore). In this case fluid
+defines a global variable 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 it's 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 to
+them 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 .C file.
+
+
+ Type
+
+ to edit the .fl file <name>.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 setup 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 name:
+
+ Changing the colors may be useful to see what your interface will
+look at if the user calls it with the same switches.
+
+ In the current version, if you don't go into the background (with
+'&') then you will be able to abort fluid by typing ^C on the terminal.
+It will exit immediately, losing any changes.
+
+
+ Fluid can also be called as a command-line "compiler" to create the
+.C and .H file from a .fl file. To do this type
+
+ This will read the .fl file and write <name>.C and
+<name>.H (the directory will be stripped, they are written to the
+current directory always), and then exit. If there are any errors
+reading or writing the files it will print the error and exit with a
+non-zero code. This is useful in a makefile. A line like this will
+work:
+
+ Some versions of Make will accept rules like this to allow all .fl
+files found to be compiled:
+
+ Some versions of Make (gnumake) may prefer this syntax:
+
+ 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. This
+widget is the parent, and all the widgets listed below it are it's
+children. There can be zero children.
+
+ The top level of the hierarchy is functions. Each of these
+will produce a single C++ public function in the output .C file.
+Calling the function will create all of it's child windows.
+
+ The second level of the hierarchy is 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 as either their name (such
+as "main_panel" in the example), or if unnamed as 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. Notice that
+hidden children may be selected and there is no visual indication of
+this.
+
+ You open widgets by double clicking them, or (to open several
+widgets you have picked) by typing the F1 key. This will bring up a
+control panel or window from which you can change the widget.
+
+
+ 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:
+
+ fluid can also read .fd files produced by the Forms and XForms
+"fdesign" programs. It is best to read them with Merge. 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 it's own format, which fdesign
+cannot read!
+
+ The output file names are the same as the .fl file, with the
+leading directory and trailing ".fl" stripped, and ".H" or ".C"
+appended. Currently there is no way to override this.
+
+ If the widget is a window, it is added to whatever function is
+selected, or contains 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.
+
+ If they are all selected already then this selects all widgets in
+that group's parent. Repeatedly typing Alt+a will select larger and
+larger groups of widgets until everything is selected.
+
+ If the function contains any unnamed windows, it will be declared
+as returning an Fl_Window*. 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 void.
+
+ It is possible to make the .C output be a self-contained program
+that can be compiled and executed. This is done by deleting the
+function name, in which case "main(argc,argv)" is used. The function
+will call show() on all the windows it creates and then call
+Fl::run(). This can be used to test resize behavior or other parts of
+the user interface. I'm not sure if it is possible to create really
+useful programs using just Fluid.
+
+ You can change the function name by double clicking the function.
+
+ You also get the window's control panel, which is almost exactly
+the same as any other Fl_Widget, and is described in the next chapter.
+
+ When you create the widget you will get the widget's control panel,
+described in the next chapter.
+
+ 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 Alt+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 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 in any code (such as mismatched parenthesis) 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
+is undone, however.
+
+
+ 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.
+
+ 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 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
+(notice that this checkerboard is not drawn by the resulting program,
+instead random garbage is left there).
+
+ The color to draw the box with.
+
+ 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.
+
+ You can put newlines into the string to make multiple lines, the
+easiest way is by typing ctrl+j.
+
+ From this menu you can also pick "Image...". This lets you use the contents
+of an image file (currently an xpm pixmap or xbm bitmap) to label the
+widget.
+
+ Only one child can be resizable. Turning this on turns it off for
+other children.
+
+ You can get more complex behavior by making invisible boxes the
+resizable widget, or by using hierarchies of groups. Unfortunatley
+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.
+
+ In addition, no #include header file is put in the .H file. You
+must provide a #include line as the first of the "extra code" which
+declares your subclass.
+
+ The class had better 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.
+
+ 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 widget being constructed 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 4 lines you probably should call a function in
+your own .C 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 .C output
+file. The function prototype is
+"void f(<class>* o, void* v)", so 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.
+
+ 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 put "(void*)(<here>)".
+
+ There are rare but useful other values for the when() field that
+are not in the menu. You should use the extra code fields to put
+these values in.
+
+ 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 Alt+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:
+
+ Selecting "Image..." off the label style pull-down menu will bring
+up a file chooser from which you pick the image file. If an image has
+already been chosen, you can change the image used by picking
+"Image..." again. The name of the image will appear in the "label"
+field, but you can't edit it.
+
+ The contents of the image file are written to the .C file,
+so if you wish to distribute the C code, you only need to copy the .C
+file, not the images. If many widgets share the same image then only
+one copy is written.
+
+ However the file name is stored in the .fl file, so to read
+the .fl file you need the image files as well. Filenames are relative
+to the location the .fl file is (not necessarily the current
+directory). I recommend you either put the images in the same
+directory as the .fl file, or use absolute path names.
+
+ 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 are using a painting program to edit an image: the only way
+to convince Fluid to read the image file again is to remove the image
+from all widgets that are using it (including ones in closed windows),
+which will cause it to free it's internal copy, and then set the image
+again. You may find it easier to exit Fluid and run it again.
+
+ 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. This is also how you can put both an
+image and text label on the same widget. If your widget is a button,
+and you want the image inside it, you must change the button's boxtype
+to FL_UP_FRAME (or another frame), otherwise when it is pushed it will
+erase the image.
+
+ Fluid will read X bitmap files. These files have C source code to
+define a bitmap. Sometimes they are stored with the ".h" or ".bm"
+extension rather than the standard ".xbm".
+
+ Fluid will output code to construct an Fl_Bitmap widget 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 the color in Fluid. The
+'0' bits are transparent.
+
+ The program "bitmap" on the X distribution does an ok job of
+editing bitmaps.
+
+ Fluid will read X pixmap files as used by the libxpm library.
+These files have C source code to define a pixmap. The filenames
+usually have a ".xpm" extension.
+
+ Fluid will output code to construct an Fl_Pixmap widget 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. Currently
+fltk and Fluid simulate this transparency rather badly. It will use the
+color() of the widget as the background, and all widgets using the
+same pixmap are assummed to have the same color. This may be fixed in
+the future or on non-X systems.
+
+ I have not found any good editors for small iconic pictures. For
+pixmaps I have used XPaint. This
+(and most other) painting programs are designed for large full color
+images and are difficult to use to edit an image of small size and few
+colors.
+
+ Fluid will also read GIF image files. These files are often used
+on html documents to make icons. This lets you use nice icons that
+you steal off the net in your user interface.
+
+ Fluid converts these into (modified) xpm
+format and uses an Fl_Pixmap widget to label the widget. Transparency
+is handled the same as for xpm files. Notice that the conversion
+removes the compression, so the code may be much bigger than the .gif
+file. Only the first image of an animated gif file is used.
+
+ Behavior and performance with large .gif files is not guaranteed!
+
+ (back to contents)
diff --git a/documentation/fluid_main.gif b/documentation/fluid_main.gif
new file mode 100644
index 000000000..ab72873c5
Binary files /dev/null and b/documentation/fluid_main.gif differ
diff --git a/documentation/fluid_widget.gif b/documentation/fluid_widget.gif
new file mode 100644
index 000000000..5c9964f0c
Binary files /dev/null and b/documentation/fluid_widget.gif differ
diff --git a/documentation/forms.html b/documentation/forms.html
new file mode 100644
index 000000000..1d6614581
--- /dev/null
+++ b/documentation/forms.html
@@ -0,0 +1,230 @@
+
+ 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 compatability header,
+<FL/forms.H>.
+
+ You should be able to compile existing Forms or XForms source code
+by changing the -I 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.
+
+ Although FLTK was designed to be compatable with the GL Forms library
+(version 0.3 or so), XForms has bloated severely and it's interface is
+X specific. Therefore, XForms compatability is no longer a goal of
+FLTK. Compatability was limited to things that were free, or that
+would add code that would not be linked in if the feature is unused.
+I did not add anything that would make the FLTK widgets bigger, or that
+used X types as arguments.
+
+ 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 I
+expeceted and even our inhouse code still uses forms.H a lot.
+
+
+
+ These notes were written for porting programs written with the
+older GL version of Forms. Most of these problems are the same ones
+encountered when going from old Forms to XForms:
+
+ If a Forms (not XForms) program if you wanted your own window for
+displaying things you would create a GL 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 GL 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. See the example program shape.C for
+how this is structured.
+
+ If you draw into the overlay planes you will have to also write a
+draw_overlay() routine and call redraw_overlay() on the gl 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.
+
+ The file <FL/gl.h> defines replacements for a lot of gl calls,
+translating them to OpenGL. There are much better translators
+available that you might want to investigate.
+
+ 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.
+
+int Fl::event_button();
+
+Returns which mouse button was pressed. This returns garbage if the
+most recent event was not a FL_PUSH or FL_RELEASE.
+
+
+
int Fl::event_x()
+int Fl::event_y()
+
+Returns the mouse position of the event (relative to the Fl_Window it
+was passed to).
+
+
int Fl::event_x_root()
+int Fl::event_y_root()
+
+Returns the mouse position on the screen of the event. To find the
+absolute position of an Fl_Window on the screen, use the difference
+between event_x_root and event_x.
+
+
+
void Fl::get_mouse(int &,int &)
+
+
ulong Fl::event_state();
+
unsigned int Fl::event_state(int);
+
+This is a bitfield of what shift states were on and what mouse buttons
+were held down during the most recent event. The second version
+returns non-zero if any of the passed bits are turned on. The legal
+bits are
FL_SHIFT, FL_CAPS_LOCK, FL_CTRL, FL_ALT, FL_NUM_LOCK,
+FL_META, FL_SCROLL_LOCK, FL_BUTTON1, FL_BUTTON2, FL_BUTTON3.
+
+int Fl::event_key();
+
int Fl::event_key(int);
+
int Fl::get_key(int);
+
+Fl::event_key() returns which key on the keyboard was last pushed.
+
+
+
+
+
+FL_KP. The highest possible value is
+FL_KP_Last so you can range-check to see if something is
+on the keypad.
+
+FL_F. The highest possible number is
+FL_F_Last, so you can range-check a value.
+
+FL_Button.
+
+FL_Escape,
+FL_BackSpace, FL_Tab, FL_Enter, FL_Print, FL_Scroll_Lock, FL_Pause,
+FL_Insert, FL_Home, FL_Page_Up, FL_Delete, FL_End, FL_Page_Down,
+FL_Left, FL_Up, FL_Right, FL_Down, FL_Shift_L, FL_Shift_R,
+FL_Control_L, FL_Control_R, FL_Caps_Lock, FL_Alt_L, FL_Alt_R,
+FL_Meta_L, FL_Meta_R, FL_Menu, FL_Num_Lock, FL_KP_Enter. Be
+careful not to confuse these with the very similar, but all-caps,
+symbols used by Fl::event_state().
+
+Fl::get_key(FL_Button+n) does not
+work. On MSWindows Fl::get_key(FL_KP_Enter) and
+Fl::event_key(FL_KP_Enter) do not work.
+
+
+char * Fl::event_text()
+
+
char * Fl::event_length()
+
+
int Fl::event_is_click()
+
+Returns non-zero if the mouse has not moved far enough and not enough
+time has passed since the last FL_PUSH or FL_KEYBOARD event for it
+to be considered a "drag" rather than a "click". You can test this on
+FL_DRAG, FL_RELEASE, and FL_MOVE events.
+
+
void Fl::event_is_click(0)
+
+Clear the value returned by Fl::event_is_click(). Useful to prevent
+the next click from being counted as a double-click or to make
+a popup menu pick an item with a single click. Don't pass non-zero to
+this.
+
+
int Fl::event_clicks()
+
+Returns non-zero if the most recent FL_PUSH or FL_KEYBOARD was a
+"double click". Returns N-1 for N clicks. A double click is counted
+if the same button is pressed again while event_is_click() is true.
+
+
void Fl::event_clicks(int)
+
+Directly set the number returned by Fl::event_clicks(). This can be
+used to set it to zero so that later code does not think an item was
+double-clicked.
+
+
int Fl::event_inside(const Fl_Widget *) const ;
+
int Fl::event_inside(int,int,int,int);
+
+Returns non-zero if the current event_x and event_y put it inside the
+widget or inside an arbitrary bounding box. You should always call
+this rather than doing your own comparison so you are consistent about
+edge effects.
+
+
int Fl::test_shortcut(ulong) const ;
+
+Test the current event, which must be an FL_KEYBOARD or FL_SHORTCUT,
+against a shortcut value (described in Fl_Button). Returns non-zero if
+there is a match. Not to be confused with Fl_Widget::test_shortcut().
+
+
+
+
+Event Propagation
+
+Fl_Widget *Fl::focus() const;
+
void Fl::focus(Fl_Widget *);
+
+Get or set the widget that will receive FL_KEYBOARD events.
+
+
int Fl_Widget::take_focus();
+
+
Fl_Widget *Fl::belowmouse() const;
+
void Fl::belowmouse(Fl_Widget *);
+
+Get or set the widget that is below the mouse. This is for
+highlighting buttons. It is not used to send FL_PUSH or FL_MOVE
+directly, for several obscure reasons, but those events typically go
+to this widget. This is also the first widget tried for FL_SHORTCUT
+events.
+
+
Fl_Widget *Fl::pushed() const;
+
void Fl::pushed(Fl_Widget *);
+
+
void Fl::add_handler(int (*f)(int));
+
+Install a function to parse unrecognized events. If fltk cannot figure
+out what to do with an event, it calls each of these functions (most
+recent first) until one of them returns non-zero. If none of them
+returns non zero then the event is ignored. Events that cause this to
+be called are:
+
+
+
+
+
+Fl_Window* Fl::modal();
+
+The modal() window has it's handle() method called for all events, and
+no other windows will have handle() called. If grab() has been done then this is equal to grab().
+Otherwise this is the most recently shown() window with modal() true, or null if there are no
+modal() windows shown().
+
+
+
void Fl::grab(Fl_Window&);
+Fl_Window* Fl::grab();
+
+This is used when pop-up menu systems are active. Send all events to
+the passed window no matter where the pointer or focus is (including
+in other programs). The window does not have to be shown(),
+this lets the handle() method of a "dummy" window override all event
+handling and allows you to map and unmap a complex set of windows
+(under both X and NT some window must be mapped because the
+system interface needs a window id).
+
+
void Fl::release()
+
+Turn off the grab() behavior.
+
+
6 - Programming with FLUID
+
+This chapter shows how to use the Fast Light User-Interface Designer ("FLUID") to create
+your GUIs.
+
+What is FLUID?
+
+Creating A Simple Program
+
+Functions
+
+Windows
+
+Groups
+
+Tabs
+
+Menus
+
+Using Custom Widgets
+
+Classes
+
+
+
+
What is Fluid?
+
+
+ _________
+ / /
+ __________ +->/.C file /--------+
+ / / / /________/ |
+ /.fl file /<==>[fluid]< #include |
+ /_________/ \ ___v_____ |
+ \ / / |
+ +>/.H file / |
+ /________/ |
+ ^ |
+ #include |
+ ___|_____ | __________
+ / / V / /
+ / main.C /--->[c++,link]-->/ program /
+ /________/ /_________/
+
+
+Worlds shortest tutorial
+
+
+
+
+
+
+Running fluid
+
+
+ fluid <name>.fl &
+
+
+
+ -display host:n.n
+ -geometry WxH+X+Y
+ -title windowtitle
+ -name classname
+ -iconic
+ -fg color
+ -bg color
+ -bg2 color
+
+
+Compiling .fl files
+
+
+ fluid -c <name>.fl
+
+
+
+my_panels.H my_panels.C : my_panels.fl
+ fluid -c my_panels.fl
+
+
+
+.SUFFIXES : .fl .C .H
+.fl.H :
+ fluid -c $<
+.fl.C :
+ fluid -c $<
+
+
+
+%.H: %.fl
+ fluid -c $<
+
+%.C: %.fl
+ fluid -c $<
+
+
+
+The Widget Browser
+
+
+
+Menu Items
+
+File/Open... (Alt+Shift+O)
+
+Discard the current editing session and read in a different .fl file.
+You are asked for confirmation if you have changed the current data.
+
+
File/Save (Alt+s)
+
+Write the current data to the .fl file. If the file is unnamed
+(because fluid was started with no name) then ask for a file name.
+
+
File/Save As...(Alt+Shift+S)
+
+Ask for a new name to save the file as, and save it.
+
+
File/Merge... (Alt+i)
+
+Insert 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, you will have to use cut/paste
+to put the widgets where you want.
+
+
File/Write code (Alt+Shift+C)
+
+"Compiles" the data into a .C and .H file. These are exactly the same
+as the files you get when you run fluid with the -c switch.
+
+
File/Quit (Alt+q)
+
+Exit fluid. You are asked for confirmation if you have changed the
+current data.
+
+
Edit/Undo (Alt+z)
+
+Don't you wish... This isn't implemented yet. You should do save
+often so that any mistakes you make don't irretrivably destroy your
+data.
+
+
Edit/Cut (Alt+x)
+
+Delete the selected widgets and all their children. These are saved
+to a "clipboard" file (/usr/tmp/cut_buffer.fl) and can be pasted back
+into this fluid or any other one.
+
+
Edit/Copy (Alt+c)
+
+Copy the selected widgets and all their children to the "clipboard" file.
+
+
Edit/Paste (Alt+c)
+
+Paste in the widgets in the clipboard file.
+
+
Edit/Select All (Alt+a)
+
+Select all widgets in the same group as the current selection.
+
+
Edit/Open... (F1 or double click)
+
+If the current widget is a window and it is not displayed, display it.
+Otherwise open a control panel for the most recent (and possibly all)
+selected widgets.
+
+
Edit/Sort
+
+All the selected widgets are sorted 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)
+
+All the selected widgets are moved one earlier in order amoung 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 and windows within functions.
+
+
Edit/Later (F3)
+
+All the selected widgets are moved one later in order amoung the
+children of their parent (if possible).
+
+
Edit/Group (F7)
+
+Create a new Fl_Group and make all the currently selected widgets be
+children of it.
+
+
Edit/Ungroup (F8)
+
+If all the children of a group are selected, delete that group and
+make them all be children of it's parent.
+
+
Edit/Overlays on/off (Alt+o)
+
+Toggle 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/Preferences (Alt+p)
+
+Currently the only preferences are for the "alignment grid" that all
+widgets snap to when you move them and resize them, and for the "snap"
+which is how far a widget has to be dragged from it's original
+position to actually change.
+
+
New/code/Function
+
+Create 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, they can be referred to by
+code you type into the individual widgets.
+
+
New/Window
+
+Create a new Fl_Window. It is added to the currently selected
+function, or to the function containing the currently selected item.
+The window will appear, sized to 100x100. You will want to resize it
+to whatever size you require.
+
+
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.
+
+
Help/About fluid
+
+Pops up a panel showing the version of fluid.
+
+
Help/Manual
+
+Not yet implemented. Use netscape to read these pages instead.
+
+
+
+
+The Widget Panel
+
+When you double-click a widget or a set of widgets you will get the
+"widget attribute panel":
+
+
+
+Widget Attributes
+
+Name (text field)
+
+Name of a global C 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.
+
+
Type (upper-right pulldown menu)
+
+Some classes have subtypes that modify their appearance or behavior.
+You pick the subtype off of this menu.
+
+
Box (pulldown menu)
+
+The boxtype to draw as a background for the widget.
+
+
Color
+
+
Color2
+
+
Label
+
+String to print next to or inside the button.
+
+
Label style (pull down menu)
+
+How to draw the label. Normal, shadowned, engraved, and embossed
+change the appearance of the text. "symbol" requires the label to
+start with an '@' sign to draw a named symbol.
+
+
Label alignement (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.
+
+
Label font
+
+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
+
+Point size 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
+
+Color to draw the label. Ignored by pixmaps (bitmaps, however, do use
+this color as the foreground color).
+
+
Text font, size, color
+
+Some widgets display text, such as input fields, pull-down menus,
+browsers. You can change this here.
+
+
Visible
+
+If you turn this off the widget is hidden initially. Don't change
+this for windows or for the immediate children of a Tabs group.
+
+
Active
+
+If you turn this off the widget is deactivated initially. Currently
+no fltk widgets display the fact that they are inactive (like by graying
+out), but this may change in the future.
+
+
Resizable
+
+If a window is resizable or has an immediate child that is resizable,
+then the user will be able to resize it. 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.
+
+
Hotspot
+
+Each window may have exactly one hotspot (turning this on will turn
+off any others). This will cause it 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().
+
+
subclass
+
+This is how you put your own subclasses of Fl_Widget in. Whatever
+identifier you type in here will be the class that is instantiated.
+
+
Extra code
+
+These four fields let you type in literal lines of code to dump into
+the .H or .C files.
+
+
Callback
+
+This can either be the name of a function, or a small snippet of
+code. Fluid thinks that if there is any punctuation then it is code.
+
+
user_data
+
+
User data type
+
+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 by the C++ spec!
+However on most architectures other pointer types are ok, and long is
+usually ok.
+
+
When
+
+When to do the callback. Can be "never", "changed", "release". The
+value of "enter key" is only useful for text input fields. The "no
+change" button means the callback is done on the matching event even
+if the data is not changed.
+
+
+
+
+Selecting & Moving Widgets
+
+Border
+
+This 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.
+
+
xclass
+
+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.
+
+
+
+
+Image Labels
+
+Notes for all image types
+
+
XBM (X bitmap files)
+
+
XPM (X pixmap files)
+
+
GIF files
+
+
+
+E - Forms Compatibility
+
+Fluid (the Fast Light User Interface Designer)
+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.
+
+Problems you will encounter
+
+
+
+
+
+FL_VERSION, FL_REVISION, fl_library_version()
+FL_RETURN_DBLCLICK (use Fl::event_clicks())
+Additional notes for porting old Forms programs
+
+Does not go into background
+
+The GL 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 GL windows or fl_queue
+
+You must use OpenGL to draw everything
+
+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.
+
+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:
+
+
| Forms | FLTK + |
| MOUSE_X | Fl::event_x_root() + |
| MOUSE_Y | Fl::event_y_root() + |
| LEFTSHIFTKEY,RIGHTSHIFTKEY | Fl::event_shift() + |
| CAPSLOCKKEY | Fl::event_capslock() + |
| LEFTCTRLKEY,RIGHTCTRLKEY | Fl::event_ctrl() + |
| LEFTALTKEY,RIGHTALTKEY | Fl::event_alt() + |
| MOUSE1,RIGHTMOUSE | Fl::event_state()&(1<<10) + |
| MOUSE2,MIDDLEMOUSE | Fl::event_state()&(1<<9) + |
| MOUSE3,LEFTMOUSE | Fl::event_state()&(1<<8) + |
Anything else in getvaluator and you are on your own... + +
+fl_font_name(3,"*courier-medium-r-no*"); +fl_font_name(4,"*courier-bold-r-no*"); +fl_font_name(5,"*courier-medium-o-no*"); +fl_font_name(6,"*times-medium-r-no*"); +fl_font_name(7,"*times-bold-r-no*"); +fl_font_name(8,"*times-medium-i-no*"); +fl_font_name(9,"*bookman-light-r-no*"); +fl_font_name(10,"*bookman-demi-r-no*"); +fl_font_name(11,"*bookman-light-i-no*"); ++ + + diff --git a/documentation/functions.html b/documentation/functions.html new file mode 100644 index 000000000..6dfe9a0cf --- /dev/null +++ b/documentation/functions.html @@ -0,0 +1,768 @@ + + + +
All the widgets have several attributes and there is a method for
+setting and getting the current value of each of them.
+ labelfont() is
+set to a symbolic value which is compiled into a constant integer, 3
+in this case. All properties that cannot be described by a single
+small number use a 1-byte index into a table. This makes the widget
+smaller, allows the actual definition of the property to be deferred
+until first use, and you can redefine existing entries to make global
+style changes.
+
+ labeltype(FL_SHADOW_LABEL)
+also stores a 1-byte symbolic value, in this case indicating a
+procedure to draw drop shadows under the letters should be called to
+draw the label.
+
+ The constructor for widgets adds them as children of the "current
+group" (usually a window). window->end() stops adding
+them to this window. For more control over the construction of
+objects, you can end() the window immediately, and then add the
+objects with window->add(box). You can
+also do window->begin()
+to switch what window new objects are added to.
+
+ Fl::run() makes FLTK
+enter a loop to update the screen and respond to events. By
+default when the user closes the last window FLTK exits by calling exit(0). run() does not
+actually return, it is declared to return an int so you can end your
+main() function with "return Fl::run()" and outwit the stupid compiler
+made by a certain very large software company.
+
+ The following command compiles this program, assuming the FLTK
+library has been put in /usr/local/lib and the header files in
+/usr/local/include/FL:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The first thing your program should do is construct one or more
+trees of Fl_Widgets. The base widget of each of these is
+an Fl_Window widget. The constructors for widgets
+automatically add them as children of the most recent created window
+widget (use window->end() to stop this). Constructing the widgets
+does not require the display to be open and does not open it,
+unless you purposely open it to get information such as the width of a
+font.
+
+ Fl_Windows are displayed on the screen with
+Fl_Window::show(). For the first window you may also use
+Fl_Window::show(argc,argv) and FLTK will automatically
+parse some startup arguments such as -display.
+
+ Then the program repeatedly calls Fl::wait(). Each
+time "something happens" Fl::wait() returns, usually after
+a block of X events have been read and processed. It is often useful
+for a program to check global state after each event, and FLTK makes
+this easy by leaving the main loop under your control.
+
+ Each widget has a single "callback". This is a function that
+is called when something happens (such as the user pressing a button).
+FLTK avoids all the complexities of signals/slots by having only a
+single callback. Instead a when() method on the object selects when
+the callback is done (ie. when a slider is moved or when the mouse is
+released).
+
+ The callback is passed a pointer to the widget and a void* user_data
+field. This is redundant, as the user_data can be determined from the
+widget, but was done for XForms compatability and to make the same
+callbacks useful for menu items. Typically you want to turn the
+callback into a method on some C++ object. A simple way is to use the
+user_data as a pointer to the object. A more common but harder to
+understand way is to store the object in the parent widget's
+user_data field, since usually all the controls on a window are for the
+same object, this lets you use the user_data for an abitrary method
+argument.
+
+ To display graphic data, you must subclass either
+Fl_Window or Fl_Widget and define the virtual
+draw() method. This can use functions defined in
+<FL/fl_draw.H>, or can use system-specific calls such as Xlib. If
+the data being displayed changes, your main program calls the
+redraw() method on your widget, and FLTK will call
+draw() while waiting for the next event. Subclassing
+Fl_Window or Fl_Widget is so easy that I felt
+it unnecessary to provide the "canvas" widget that most toolkits have.
+
+ If your program needs to monitor another device (such as stdin) you
+can provide a callback routine for when it becomes ready, by using
+Fl::add_fd(i). If your program needs something to happen
+at regular intervals you can define a timeout callback with Fl::add_timeout(time).
+
+ Building a large hierarchy is made much easier with fluid
+(the Fast Light User Interface Designer). This is a program that lets
+you interactively design the widget layout and set all the properties
+visually. It outputs C++ source code that you compile and link with
+your program. All you have to write is the main loop and any
+callbacks.
+
+
+
+
+ Widgets don't need to have callback() set. The default callback puts a
+pointer to the widget on a "queue" from which it can later be read
+with Fl::readqueue(). This was
+done for Forms compatibility but it is useful for modal windows. In this example the
+"get_string" function puts up a modal window and loops until one of
+the buttons is pushed.
+
+Fl::wait() does exactly one cycle of
+what Fl::run() does repeatedly: it updates the screen and then waits
+for and responds to an event (or several events if they are all ready
+at the same time). It then returns, allowing the user program to
+check any state information it wants to after each group of events.
+One thing the user program can check is Fl::readqueue() which returns each
+object without a callback that was triggered. It returns null when
+the queue is empty. It is possible for more than one object to be on
+the queue (or the same object several times) so if your program wants
+to read the queue it should always read it until empty and ignore
+unrecognized widgets (don't look at them as they may have been
+deleted).
+
+ modal() on a window prevents any
+interaction with other program windows below it, and prevents the user
+from raising a program window above it (well, it tries, but X is
+broken). It won't make any difference in this program because there
+is only one window, but this allows the "get_string" function to be
+used as subroutine by a larger program and have the expected behavior.
+
+ This program also demonstrates that FLTK widgets may be constructed
+as C++ automatic objects (local variables). You have to be careful
+about destruction, however.
+Always make sure all automatic children are destructed before the
+container (by declaring the children after the container),
+since the destructor for a container will attempt to delete all
+remaining children, and you don't want to delete automatic objects.
+
+ [Next example]
+ In this example we make some button widgets and make them do
+something through callbacks.
+
+ All widgets have a single callback() function. It is called in
+response to an event on that widget, exactly which event depends on
+the type of widget. The function takes two arguments: a pointer to
+the widget (you will usually need to cast this to the correct
+subclass) and a void* pointer to a piece of arbitrary user_data.
+
+ You don't have to give all the widgets a callback, as the "no op" b2
+widget demonstrates. What these do is described in the next program.
+
+ [Next example]
+ You will have to include at least this header file in your main
+code so that you can call the methods described here.
+
+ You can construct all your widgets (and menus and boxtypes and
+images and other FLTK types) without "initializing". The
+constructors do not require a connection to the X display. This makes
+it a lot easier, especially if your program has a mode where it does
+not use a gui, and guarantees that code you don't use is not linked
+in.
+
+ FLTK is usually "initialized" when you show() the first window. At
+this time the X display is opened and everything is set up so the
+calls described in the rest of this document work. A few other calls
+can open the X display, amoung them are fl_width() to measure the
+size of a font. Be careful that the following calls are done before
+the display is opened, if not you will get lots of strange X errors.
+
+ Most of these "initialization" calls are to get around stupid X
+things. I have tried to make these as simple to call as possible and
+they have no effect on systems which aren't as badly designed as X.
+But you should call them to make your program as portable as possible.
+
+
+ Only the following combinations do anything useful:
+
+ This returns true if the system has the capabilities by default or
+FLTK suceeded in turing them on. Your program will still work even if
+this returns false (it just won't look as good).
+
+ See here for ways to select the visual
+using your own code.
+
+
+ See Fl_Gl_Window for a list of
+additional values for the argument.
+
+ This does nothing if the current visual is not colormapped or on
+MSWindows (even though it probably should if your display is in 8-bit
+mode).
+
+ Currently this only works on MSWindows. In future versions on X it
+may read the KDE or Gnome setup, but for now it does nothing.
+
+ FLTK provides an entirely optional command-line switch
+parser. You don't have to call it if you don't like them!
+Everything it can do can be done with other calls to FLTK.
+
+ To use the switch parser, call Fl::args(...) near the start of
+your program. This does not open the display, instead switches
+that need the display open are stashed into static variables. Then
+you must display your first window by calling Fl_Window::show(argc,argv), which will do anything
+stored in the static variables.
+
+ callback lets you define your own switches. It is called
+with the same argc and argv, and with i the index of each word.
+The callback should return zero if the switch is unrecognized, and not
+change i. It should return non-zero if the switch is recognized, and
+add at least 1 to i (it can add more to consume words after the
+switch). This function is called before any other tests, so you can
+override any FLTK switch.
+
+ On return i is set to the index of the first non-switch.
+This is either:
+
+ The return value is i unless an unrecognized switch is
+found, in which case it is zero. If your program takes no arguments
+other than switches you should produce an error if the return value is
+less than argc.
+
+ All switches may be abbreviated to one letter and case is ignored:
+
+ -display host:n.n The X display to use (ignored
+by MSWindows).
+
+ -geometry WxH+X+Y The window position and size
+will be modified according the the standard X geometry string.
+
+ -name string Fl_Window::xclass(string) will be
+done to the window, this will change it's icon.
+
+ -title string Fl_Window::label(string) will be
+done to the window, changing both it's title and the icontitle.
+
+ -iconic Fl_Window::iconize() will be done to
+the window.
+
+ -bg color XParseColor is used to lookup the
+passed color and then Fl::background() is done. On MSWindows
+only color names of the form "#xxxxxx" are understood.
+
+ -bg2 color XParseColor is used to lookup the
+passed color and then Fl::background2() is done.
+
+ -fg color XParseColor is used to lookup the
+passed color and then Fl::foreground() is done.
+
+ If Fl::args() or Fl::arg() have never been called, this calls
+Fl::args(argc,argv) automatically. This is convienent for very small
+programs that just want to put up a single window and take no
+switches.
+
+ Your program can check it's global state and update things after
+each call to Fl::wait(), which can be very useful in complex programs.
+
+ If there are no windows (this is checked after the idle and
+timeouts are called) then Fl::wait() returns zero without waiting for
+any events. Your program can either exit at this point, or call
+show() on some window so the UI can continue to operate.
+
+ If you do several wait(time) calls in a row, the subsequent ones
+are measured from when the first one is called, even if you do
+time-consuming calculations after they return. This allows you to
+accurately make something happen at regular intervals. This code will
+accurately call A() once per second (as long as it takes less than a
+second to execute):
+
+ This returns non-zero if any windows are displayed, and 0 if no
+windows are displayed.
+
+ This code will print "TICK" each second on stdout, no matter what
+else the user or program does:
+
+ Only Fl::wait(void) calls the idle callback. Fl::wait(time),
+Fl::check(), and Fl::ready() ignore it. This is so that these
+functions may be called by the idle callback itself without having to
+worry about recursion.
+
+ The idle callback can call any FLTK functions. However if you call
+something that calls Fl::wait() (such as a message pop-up) you should
+first set the idle callback to zero so it does not recurse.
+
+
+ The second version takes a when bitfield, with the bits
+FL_READ, FL_WRITE, and FL_EXCEPT defined, to indicate when the
+callback should be done. This probably only works on Unix.
+
+ There can only be one callback of each type for a file descriptor.
+Fl::remove_fd() gets rid of all the callbacks for a given file
+descriptor.
+
+ To stop a window from closing, or conversely to make the closing of
+a particular window exit the program you must change the callback()
+function. Here is a typical use:
+
+ Supposedly Fl::warning means that there was a recoverable problem,
+the display may be messed up but the user can probably keep working
+(all X protocol errors call this). Fl::error means there is a
+recoverable error, but the display is so messed up it is unlikely the
+user can continue (very little calls this now). Fl::fatal must not
+return, as FLTK is in an unusable state (however your version may be
+able to use longjmp or an exception to continue, as long as it does
+not call FLTK again).
+
+box->labelsize(36) sets the labelsize() to 36. You could get
+the value with box->labelsize(). Often you have to set
+many properties, so you will be relieved to know that almost all of
+these methods are trivial inline functions.
+
+window->show() finally
+puts the window on the screen. It is not until this point that the X
+server is opened. FLTK provides some optional and rather
+simple command-line parsing if you call show(argv,argc). If you don't want this, just
+call show() with no arguments, and the unused argument code is not
+linked into your program, making it smaller!
+
+Compiling a FLTK Program
+
+Include Files
+
+Library Files
+
+A "Hello, World" Program
+
+Creating the Window
+
+The Main Loop
+
+
+
+ask.C
+
+
+
+
+#include <stdio.h>
+#include <string.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+
+int get_string(char*buffer, const char *from) {
+ Fl_Window window(320,75);
+ window.set_modal();
+ Fl_Input input(60, 40, 250, 25,"Input:");
+ input.value(buffer);
+ Fl_Button cancel(60, 10,80, 25,"cancel");
+ Fl_Return_Button ok(150, 10,80, 25,"OK");
+ window.end();
+ window.show();
+ for (;;) {
+ Fl::wait();
+ Fl_Widget *o;
+ while (o = Fl::readqueue()) {
+ if (o == &ok) {
+ strcpy(buffer, input.value());
+ return 1;
+ } else if (o == &cancel || o == &window) {
+ return 0;
+ }
+ }
+ }
+}
+
+int main(int argc, char **argv) {
+ char buffer[128];
+ if (get_string(buffer, argv[1])) {
+ puts(buffer);
+ return 0;
+ } else {
+ return 1; // exit with error
+ }
+}
+
+
+
[back to contents]
+button.C
+
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+
+void beepcb(Fl_Widget *, void *) {
+ printf("\007"); fflush(stdout);
+}
+
+void exitcb(Fl_Widget *, void *) {
+ exit(0);
+}
+
+int main(int argc, char ** argv) {
+ Fl_Window *window = new Fl_Window(320,65);
+ window->begin();
+ Fl_Button *b1 = new Fl_Button(20, 20, 80, 25, "Beep");
+ b1->callback(beepcb,0);
+ Fl_Button *b2 = new Fl_Button(120,20, 80, 25, "no op");
+ Fl_Button *b3 = new Fl_Button(220,20, 80, 25, "Exit");
+ b3->callback(exitcb,0);
+ window->end();
+ window->show(argc,argv);
+ return Fl::run();
+}
+
+
+
[back to contents]
+#include <FL/Fl.H>
+
+Initialization
+
+int Fl::visual(int)
+
+Selects an X visual so that your graphics are drawn correctly. This
+does nothing if the default visual satisfies the capabilities, or if
+no visual satisfies the capabilities, or on systems that don't have
+such brain-dead notions.
+
+
+
+
+
+
Full/true color (if there are several depths FLTK chooses the
+largest). Do this if you use fl_draw_image for much better
+(non-dithered) output.
+
+
Full color with at least 24 bits of color. FL_RGB will always
+pick this if available, but if not it will happily return a
+less-than-24 bit deep visual. This call fails if 24 bits are not
+available.
+
+
Hardware double buffering. Call this if you are going to use
+Fl_Double_Window.
+
+
Hardware double buffering and full color.
+
+int Fl::gl_visual(int)
+
+This does the same thing as Fl::visual(int) but also requires OpenGL
+drawing to work. This must be done if you want to draw in
+normal windows with OpenGL with gl_start()
+and gl_end(). It may be useful to call this so your X windows use
+the same visual as an Fl_Gl_Window, on
+some servers the windows will drag around easier then.
+
+
void Fl::own_colormap();
+
+Makes FLTK use it's own X colormap. This may make FLTK display
+better and will reduce conflicts with other programs that want lots of
+colors. However the colors may flash as you drag the cursor between
+windows.
+
+
void Fl::get_system_colors();
+
+Read the user preference colors from the system and use them to call
+Fl::foreground(), Fl::background(), and Fl::background2(). This is
+done by Fl_Window::show(argc,argv) before applying the -fg and -bg
+switches.
+
+
void Fl::background(uchar, uchar, uchar);
+
+Changes fl_color(FL_GRAY) to the given color, and changes
+the gray ramp from 32 to 56 to black to white. These are the colors
+used as backgrounds by almost all widgets and used to draw the edges
+of all the boxtypes.
+
+
void Fl::foreground(uchar, uchar, uchar);
+
+Changes fl_color(FL_BLACK). Also changes
+FL_INACTIVE_COLOR and FL_SELECTION_COLOR to
+be a ramp between this and FL_WHITE.
+
+
void Fl::background2(uchar, uchar, uchar);
+
+Changes fl_color(FL_WHITE) and the same colors as
+Fl::foreground(). This color is used as a background by Fl_Input and
+other text widgets.
+
+
int Fl::args(int argc, char** argv, int
+&i, int (*callback)(int,char**,int&)=0)
+
+
+
+
+
+int Fl::arg(int argc, char** argv, int &i)
+
+Consume a single switch from argv, starting at word i. Returns the
+number of words eaten (1 or 2, or 0 if it is not recognized) and adds
+the same value to i. You can use this function if you prefer to
+control the incrementing through the arguments yourself.
+
+
void Fl::args(int argc, char** argv)
+
+This method is useful if your program does not have command line
+switches of it's own. It parses all the switches, and if any are not
+recognized it calls Fl::abort(Fl::help).
+
+
const char* const Fl::help;
+
+A string descibing the switches understood by Fl::arg(), useful for
+printing as an error message.
+
+
+
int Fl_Window::show(int argc, char** argv)
+
+show() a window and set the XA_WM_COMMAND attribute to
+the passed argc/argv. If this is the first time this has been called
+since Fl::args() or Fl::arg(), the results of those switches are used
+to set the xclass(), label(), and other attributes of this window.
+
+
+
+Running
+
+After FLTK is "initialized" by calling show() on some window, you get
+FLTK to wait for and respond to events by calling the following
+methods:
+
+
+int Fl::run()
+
+Runs FLTK until there are no windows displayed, and then returns a zero.
+Fl::run() is exactly equivalent to:
+
+
+
+
+
+while (Fl::wait());
+return 0;
+
int Fl::wait()
+
+Calls the idle function if any, then calls any pending timeout
+functions, then calls Fl::flush(). If there are
+any windows displayed it then waits some time for events (zero if
+there is an idle(), the shortest timeout if there are any timeouts, or
+forever) and calls the handle() function on those events, and then
+returns non-zero.
+
+
float Fl::wait(float time)
+
+Wait only a certain amount of time for anything to happen. This does
+the same as wait() except if the given time (in seconds) passes it
+returns. The return value is how much time remains. If the return
+value is zero or negative then the entire time period elapsed.
+
+
+
+
+for (;;) {
+ for (float time = 1.0; time > 0; ) time = Fl::wait(time);
+ A();
+}
+int Fl::check()
+
+This does the same thing as Fl::wait(0), except because it does not
+have to return the elapsed time value it can be implemented faster on
+certain systems. Use this to interrupt a big calculation:
+
+
+
+
+while (!calculation_done()) {
+ calculate();
+ Fl::check();
+ if (user_hit_abort_button()) break;
+}
+int Fl::ready();
+
+Returns non-zero if there are pending timeouts or X events or file
+descriptors. This does not call Fl::flush() or any callbacks,
+which is useful if your program is in a state where such callbacks are
+illegal:
+
+
+
+
+while (!calculation_done()) {
+ calculate();
+ if (Fl::ready()) {
+ do_expensive_cleanup();
+ Fl::check();
+ if (user_hit_abort_button()) break;
+ }
+}
+
+void Fl::add_timeout(float t,void (*cb)(void*),void* v=0);
+
void Fl::remove_timeout(void (*cb)(void*), void* = 0);
+
+Add or remove a one-shot timeout callback. The timeout will happen as
+soon as possible after t seconds after the last time wait() was
+called. The optional void* argument is passed to the callback. It is
+harmless to remove a timeout callback that no longer exists.
+
+
+
+
+
+void callback(void *) {
+ printf("TICK\n");
+ Fl::add_timeout(1.0,callback);
+}
+main() {...
+ Fl::add_timeout(1.0,callback);
+ Fl::run();
+}
+void Fl::set_idle(void (*cb)());
+
+If the idle callback is set it will be called by Fl::wait() and
+Fl::wait() will return immediately. This can be used for background
+processing. This will absorb all your machine's time! There is
+only one idle callback, changing it will replace the old one. To turn
+off the idle processing use Fl::set_idle(0).
+
+
void Fl::flush()
+
+Causes all the windows that need it to be redrawn and graphics forced
+out through the pipes. This is what wait() does before looking for
+events.
+
+
int Fl::damage()
Fl_Widget *Fl::readqueue();
+
+All Fl_Widgets that don't have a callback defined use a default callback
+that puts a pointer to the widget in this queue, and this method reads
+the oldest widget out of this queue.
+
+
+
+Listening to other file descriptors (Unix only)
+
+
+void Fl::add_fd(int fd, void (*cb)(int, void*), void* = 0);
+void Fl::add_fd(int fd, int when, void (*cb)(int, void*), void* = 0);
+void Fl::remove_fd(int);
+
+Add file descriptor fd to listen to. When the fd becomes ready
+for reading the callback is done. The callback is passed the fd and
+the arbitrary void* argument. Fl::wait() will return immediately
+after calling the callback.
+
+
+
+Exiting
+
+When all windows are closed Fl::wait() and Fl::run() return zero. If
+your main() routine then returns the program exits. You can also call
+exit(0) at any time in your program. You do not need to do any
+cleanup code for FLTK. In particular you do not have to destroy
+any widgets you have created. FLTK also does not sneak any atexit
+functions in on you either. You will need to do
+#include <stdlib.h> to call exit().
+
+
+
+
+
+static void main_window_cb(Fl_Widget*, void*) {
+ if (document_changed()) {
+ if (!fl_ask("Exit without saving changes?")) return;
+ // window will not go away as hide() has not been called...
+ }
+ exit(0);
+}
+
+...somewhere in main():
+ main_window->callback(window_cb);
+void (*Fl::warning)(const char*,...);
+
void (*Fl::error)(const char*,...);
+
void (*Fl::fatal)(const char*,...);
+
+FLTK will call these to print messages when unexpected conditions
+occur. By default they fprintf to stderr, and Fl::error and Fl::fatal
+call exit(1). You can override the behavior by setting the function
+pointers to your own routines.
+
+
hello.C
+
+
+