From 87dd7f0d23eba5c09e71ec6efeb34c6844f5e95f Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Tue, 29 Dec 1998 14:21:17 +0000 Subject: Revised documentation files. git-svn-id: file:///fltk/svn/fltk/trunk@177 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- documentation/FL.gif | Bin 0 -> 1140 bytes documentation/Fl_Adjuster.html | 61 ++ documentation/Fl_Box.html | 52 ++ documentation/Fl_Browser.html | 276 +++++++ documentation/Fl_Browser_.html | 171 +++++ documentation/Fl_Button.html | 176 +++++ documentation/Fl_Chart.html | 162 ++++ documentation/Fl_Check_Button.html | 53 ++ documentation/Fl_Choice.html | 110 +++ documentation/Fl_Clock.html | 78 ++ documentation/Fl_Color_Chooser.html | 103 +++ documentation/Fl_Counter.html | 66 ++ documentation/Fl_Dial.html | 65 ++ documentation/Fl_Double_Window.html | 66 ++ documentation/Fl_End.html | 51 ++ documentation/Fl_Float_Input.html | 47 ++ documentation/Fl_Free.html | 87 +++ documentation/Fl_Gl_Window.html | 265 +++++++ documentation/Fl_Group.html | 178 +++++ documentation/Fl_Hold_Browser.html | 74 ++ documentation/Fl_Input.html | 256 +++++++ documentation/Fl_Input_.html | 220 ++++++ documentation/Fl_Int_Input.html | 47 ++ documentation/Fl_Light_Button.html | 53 ++ documentation/Fl_Menu_.html | 220 ++++++ documentation/Fl_Menu_Bar.html | 85 +++ documentation/Fl_Menu_Button.html | 101 +++ documentation/Fl_Menu_Item.html | 366 +++++++++ documentation/Fl_Menu_Window.html | 59 ++ documentation/Fl_Multi_Browser.html | 73 ++ documentation/Fl_Multiline_Input.html | 53 ++ documentation/Fl_Multiline_Output.html | 46 ++ documentation/Fl_Output.html | 108 +++ documentation/Fl_Overlay_Window.html | 70 ++ documentation/Fl_Pack.html | 103 +++ documentation/Fl_Positioner.html | 97 +++ documentation/Fl_Repeat_Button.html | 45 ++ documentation/Fl_Return_Button.html | 44 ++ documentation/Fl_Roller.gif | Bin 0 -> 1142 bytes documentation/Fl_Roller.html | 46 ++ documentation/Fl_Round_Button.html | 53 ++ documentation/Fl_Scroll.gif | Bin 0 -> 5112 bytes documentation/Fl_Scroll.html | 135 ++++ documentation/Fl_Scrollbar.html | 78 ++ documentation/Fl_Secret_Input.html | 47 ++ documentation/Fl_Select_Browser.html | 72 ++ documentation/Fl_Single_Window.html | 49 ++ documentation/Fl_Slider.html | 101 +++ documentation/Fl_Tabs.html | 85 +++ documentation/Fl_Tile.gif | Bin 0 -> 4423 bytes documentation/Fl_Tile.html | 85 +++ documentation/Fl_Timer.html | 81 ++ documentation/Fl_Valuator.html | 182 +++++ documentation/Fl_Value_Input.gif | Bin 0 -> 464 bytes documentation/Fl_Value_Input.html | 89 +++ documentation/Fl_Value_Output.gif | Bin 0 -> 409 bytes documentation/Fl_Value_Output.html | 80 ++ documentation/Fl_Value_Slider.html | 67 ++ documentation/Fl_Widget.html | 380 ++++++++++ documentation/Fl_Window.html | 341 +++++++++ documentation/adjuster1.gif | Bin 0 -> 944 bytes documentation/ask.C.gif | Bin 0 -> 2778 bytes documentation/basics.html | 211 ++++++ documentation/bglogo.gif | Bin 0 -> 1503 bytes documentation/boxtypes.gif | Bin 0 -> 10886 bytes documentation/button.C.gif | Bin 0 -> 1725 bytes documentation/buttons.gif | Bin 0 -> 3012 bytes documentation/charts.gif | Bin 0 -> 12873 bytes documentation/choice.gif | Bin 0 -> 3354 bytes documentation/clock.gif | Bin 0 -> 1819 bytes documentation/common.html | 389 ++++++++++ documentation/counter.gif | Bin 0 -> 1488 bytes documentation/dial.gif | Bin 0 -> 1140 bytes documentation/drawing.html | 1295 ++++++++++++++++++++++++++++++++ documentation/editor-replace.gif | Bin 0 -> 4768 bytes documentation/editor.gif | Bin 0 -> 34026 bytes documentation/editor.html | 603 +++++++++++++++ documentation/enumerations.html | 328 ++++++++ documentation/events.html | 499 ++++++++++++ documentation/filechooser.gif | Bin 0 -> 8579 bytes documentation/fl_alert.gif | Bin 0 -> 2615 bytes documentation/fl_ask.gif | Bin 0 -> 2442 bytes documentation/fl_choice.gif | Bin 0 -> 2714 bytes documentation/fl_color_chooser.jpg | Bin 0 -> 9113 bytes documentation/fl_input.gif | Bin 0 -> 2910 bytes documentation/fl_message.gif | Bin 0 -> 2299 bytes documentation/fl_password.gif | Bin 0 -> 2800 bytes documentation/fl_show_colormap.gif | Bin 0 -> 13024 bytes documentation/fluid.gif | Bin 0 -> 5790 bytes documentation/fluid.html | 894 ++++++++++++++++++++++ documentation/fluid_main.gif | Bin 0 -> 5544 bytes documentation/fluid_widget.gif | Bin 0 -> 9938 bytes documentation/forms.html | 230 ++++++ documentation/functions.html | 768 +++++++++++++++++++ documentation/glut.html | 145 ++++ documentation/hello.C.gif | Bin 0 -> 3664 bytes documentation/intro.html | 260 +++++++ documentation/license.html | 468 ++++++++++++ documentation/menu.gif | Bin 0 -> 3079 bytes documentation/menu_button.gif | Bin 0 -> 2874 bytes documentation/menubar.gif | Bin 0 -> 4537 bytes documentation/opengl.html | 486 ++++++++++++ documentation/osissues.html | 455 +++++++++++ documentation/positioner.gif | Bin 0 -> 1467 bytes documentation/preface.html | 75 ++ documentation/resizebox1.gif | Bin 0 -> 2795 bytes documentation/resizebox2.gif | Bin 0 -> 4291 bytes documentation/round_clock.gif | Bin 0 -> 1616 bytes documentation/scrollbar.gif | Bin 0 -> 1041 bytes documentation/shape.C.gif | Bin 0 -> 4847 bytes documentation/slider.gif | Bin 0 -> 3098 bytes documentation/subclassing.html | 519 +++++++++++++ documentation/symbols.gif | Bin 0 -> 6008 bytes documentation/tabs.gif | Bin 0 -> 2779 bytes documentation/text.gif | Bin 0 -> 2189 bytes documentation/valuators.gif | Bin 0 -> 18411 bytes documentation/value_slider.gif | Bin 0 -> 3357 bytes documentation/widgets.html | 6 + 118 files changed, 13789 insertions(+) create mode 100644 documentation/FL.gif create mode 100644 documentation/Fl_Adjuster.html create mode 100644 documentation/Fl_Box.html create mode 100644 documentation/Fl_Browser.html create mode 100644 documentation/Fl_Browser_.html create mode 100644 documentation/Fl_Button.html create mode 100644 documentation/Fl_Chart.html create mode 100644 documentation/Fl_Check_Button.html create mode 100644 documentation/Fl_Choice.html create mode 100644 documentation/Fl_Clock.html create mode 100644 documentation/Fl_Color_Chooser.html create mode 100644 documentation/Fl_Counter.html create mode 100644 documentation/Fl_Dial.html create mode 100644 documentation/Fl_Double_Window.html create mode 100644 documentation/Fl_End.html create mode 100644 documentation/Fl_Float_Input.html create mode 100644 documentation/Fl_Free.html create mode 100644 documentation/Fl_Gl_Window.html create mode 100644 documentation/Fl_Group.html create mode 100644 documentation/Fl_Hold_Browser.html create mode 100644 documentation/Fl_Input.html create mode 100644 documentation/Fl_Input_.html create mode 100644 documentation/Fl_Int_Input.html create mode 100644 documentation/Fl_Light_Button.html create mode 100644 documentation/Fl_Menu_.html create mode 100644 documentation/Fl_Menu_Bar.html create mode 100644 documentation/Fl_Menu_Button.html create mode 100644 documentation/Fl_Menu_Item.html create mode 100644 documentation/Fl_Menu_Window.html create mode 100644 documentation/Fl_Multi_Browser.html create mode 100644 documentation/Fl_Multiline_Input.html create mode 100644 documentation/Fl_Multiline_Output.html create mode 100644 documentation/Fl_Output.html create mode 100644 documentation/Fl_Overlay_Window.html create mode 100644 documentation/Fl_Pack.html create mode 100644 documentation/Fl_Positioner.html create mode 100644 documentation/Fl_Repeat_Button.html create mode 100644 documentation/Fl_Return_Button.html create mode 100644 documentation/Fl_Roller.gif create mode 100644 documentation/Fl_Roller.html create mode 100644 documentation/Fl_Round_Button.html create mode 100644 documentation/Fl_Scroll.gif create mode 100644 documentation/Fl_Scroll.html create mode 100644 documentation/Fl_Scrollbar.html create mode 100644 documentation/Fl_Secret_Input.html create mode 100644 documentation/Fl_Select_Browser.html create mode 100644 documentation/Fl_Single_Window.html create mode 100644 documentation/Fl_Slider.html create mode 100644 documentation/Fl_Tabs.html create mode 100644 documentation/Fl_Tile.gif create mode 100644 documentation/Fl_Tile.html create mode 100644 documentation/Fl_Timer.html create mode 100644 documentation/Fl_Valuator.html create mode 100644 documentation/Fl_Value_Input.gif create mode 100644 documentation/Fl_Value_Input.html create mode 100644 documentation/Fl_Value_Output.gif create mode 100644 documentation/Fl_Value_Output.html create mode 100644 documentation/Fl_Value_Slider.html create mode 100644 documentation/Fl_Widget.html create mode 100644 documentation/Fl_Window.html create mode 100644 documentation/adjuster1.gif create mode 100644 documentation/ask.C.gif create mode 100644 documentation/basics.html create mode 100644 documentation/bglogo.gif create mode 100644 documentation/boxtypes.gif create mode 100644 documentation/button.C.gif create mode 100644 documentation/buttons.gif create mode 100644 documentation/charts.gif create mode 100644 documentation/choice.gif create mode 100644 documentation/clock.gif create mode 100644 documentation/common.html create mode 100644 documentation/counter.gif create mode 100644 documentation/dial.gif create mode 100644 documentation/drawing.html create mode 100644 documentation/editor-replace.gif create mode 100644 documentation/editor.gif create mode 100644 documentation/editor.html create mode 100644 documentation/enumerations.html create mode 100644 documentation/events.html create mode 100644 documentation/filechooser.gif create mode 100644 documentation/fl_alert.gif create mode 100644 documentation/fl_ask.gif create mode 100644 documentation/fl_choice.gif create mode 100644 documentation/fl_color_chooser.jpg create mode 100644 documentation/fl_input.gif create mode 100644 documentation/fl_message.gif create mode 100644 documentation/fl_password.gif create mode 100644 documentation/fl_show_colormap.gif create mode 100644 documentation/fluid.gif create mode 100644 documentation/fluid.html create mode 100644 documentation/fluid_main.gif create mode 100644 documentation/fluid_widget.gif create mode 100644 documentation/forms.html create mode 100644 documentation/functions.html create mode 100644 documentation/glut.html create mode 100644 documentation/hello.C.gif create mode 100644 documentation/intro.html create mode 100644 documentation/license.html create mode 100644 documentation/menu.gif create mode 100644 documentation/menu_button.gif create mode 100644 documentation/menubar.gif create mode 100644 documentation/opengl.html create mode 100644 documentation/osissues.html create mode 100644 documentation/positioner.gif create mode 100644 documentation/preface.html create mode 100644 documentation/resizebox1.gif create mode 100644 documentation/resizebox2.gif create mode 100644 documentation/round_clock.gif create mode 100644 documentation/scrollbar.gif create mode 100644 documentation/shape.C.gif create mode 100644 documentation/slider.gif create mode 100644 documentation/subclassing.html create mode 100644 documentation/symbols.gif create mode 100644 documentation/tabs.gif create mode 100644 documentation/text.gif create mode 100644 documentation/valuators.gif create mode 100644 documentation/value_slider.gif create mode 100644 documentation/widgets.html (limited to 'documentation') 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 @@ + + + +
+ +

class Fl_Adjuster

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ + + +

Description

+ +The Fl_Adjuster widget was stolen from Prisms, and has +proven to be very useful for values that need a large dynamic range. +When you press a button and drag to the right the value increases. When +you drag to the left it decreases. The largest button adjusts by +100 * step(), the next by 10 * step() and that +smallest button by step(). Clicking on the buttons increments +by 10 times the amount dragging by a pixel does. Shift + click +decrements by 10 times the amount. + +

Methods

+ + + +

Fl_Adjuster::Fl_Adjuster(int x, int y, int w, int h, const char *label = 0)

+ +Creates a new Fl_Adjuster widget using the given position, size, and +label string. It looks best if one of the dimensions is 3 times the other. + +

virtual Fl_Adjuster::~Fl_Adjuster()

+ +Destroys the valuator. + +

uchar Fl_Adjuster::soft() const
+void Fl_Adjuster::soft(uchar)

+ +If "soft" is turned on, the user is allowed to drag the value outside +the range. If they drag the value to one of the ends, let go, then +grab again and continue to drag, they can get to any value. Default +is one. + + + diff --git a/documentation/Fl_Box.html b/documentation/Fl_Box.html new file mode 100644 index 000000000..e702d863d --- /dev/null +++ b/documentation/Fl_Box.html @@ -0,0 +1,52 @@ + + + +
+ +

class Fl_Box

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ + + +

Description

+ +This widget simply draws its box, and possibly it's label. Putting it +before some other widgets and making it big enough to surround them +will let you draw a frame around them. + +

Methods

+ + + +

Fl_Box::Fl_Box(int x, int y, int w, int h, const char * = 0)
+Fl_Box::Fl_Box(Fl_Boxtype b, int x, int y, int w, int h, const char *)

+ +The first constructor sets box() to FL_NO_BOX, which +means it is invisible. However such widgets are useful as placeholders +or Fl_Group::resizable() +values. To change the box to something visible, use box(n). + +

The second form of the constructor sets the box to the specified box type. + +

Fl_Box::~Fl_Box(void)

+ +The destructor removes the box. + + + diff --git a/documentation/Fl_Browser.html b/documentation/Fl_Browser.html new file mode 100644 index 000000000..c0219955c --- /dev/null +++ b/documentation/Fl_Browser.html @@ -0,0 +1,276 @@ + + + +
+ +

class Fl_Browser

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ + + +

Description

+ +The Fl_Browser widget displays a scrolling list of text lines, +and manages all the storage for the text. This is not a text editor or +spreadsheet! But it is useful for showing a vertical list of named +objects to the user. + +

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_. + +

Methods

+ +
+ + + + + + + + +
+ + + + + + + + + +
+
+ +

Fl_Browser::Fl_Browser(int, int, int, int, const char * = 0)

+ +The constructor makes an empty browser. + +

Fl_Browser::~Fl_Browser(void)

+ +The destructor deletes all list items and destroys the browser. + +

void Fl_Browser::add(const char *, void * = 0)

+ +Add a new line to the end of the browser. The text is copied using the +strdup() function. It may also be NULL to make a +blank line. The void * argument is returned as the +data() of the new item. + +

void Fl_Browser::clear()

+ +Remove all the lines in the browser. + +

uchar Fl_Browser::column_char() const
+void Fl_Browser::column_char(char c)

+ +The first form gets the current column separator character. By default this is +'\t' (tab). + +

The second form sets the column separator to c. This will only +have an effect if you also set column_widths(). + +

const int *Fl_Browser::column_widths() const
+void Fl_Browser::column_widths(const int *w)

+ +The first form gets the current column width array. This array is +zero-terminated and specifies the widths in pixels of each column. The +text is split at each column_char() and each part is formatted +into it's own column. After the last column any remaining text is +formatted into the space between the last column and the right edge of +the browser, even if the text contains instances of +column_char(). The default value is a one-element array of +just a zero, which makes there are no columns. + +

The second form sets the current array to w. Make sure the last +entry is zero. + +

void *Fl_Browser::data(int n) const
+void Fl_Browser::data(int n, void *)

+ +The first form returns the data for line n. If n is +out of range this returns NULL. + +

The second form sets the data for line n. + +

uchar Fl_Browser::format_char() const
+void Fl_Browser::format_char(char c)

+ +The first form gets the current format code prefix character, which by +default is @. A string of formatting codes at the start of +each column are stripped off and used to modify how the rest of the +line is printed: + + + +Notice that the @. 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. + +

void Fl_Browser::hide(int n)

+ +Makes line n invisible, preventing selection by the user. The line +can still be selected under program control. + +

void Fl_Browser::insert(int n, const char *, void * = 0)

+ +Insert a new line before line n. If n > +size() then the line is added to the end. + +

int Fl_Browser::load(const char *filename)

+ +Clears the browser and reads the file, adding each line from the file +to the browser. If the filename is NULL or a zero-length +string then this just clears the browser. This returns zero if there +was any error in opening or reading the file, in which case +errno is set to the system error. The data() of each +line is set to NULL. + +

void Fl_Browser::move(int to, int from)

+ +Line from is removed and reinserted at to; to +is calculated after the line is removed. + +

int Fl_Browser::position() const
+void Fl_Browser::position(int p)

+ +The first form returns the current vertical scrollbar position, where 0 +corresponds to the top. If there is not vertical scrollbar then this +will always return 0. + +

void Fl_Browser::remove(int n)

+ +Remove line n and make the browser one line shorter. + +

void Fl_Browser::show(int n)

+ +Makes line n visible for selection. + +

int Fl_Browser::size() const

+ +Returns how many lines are in the browser. The last line number is +equal to this. + +

const char *Fl_Browser::text(int n) const
+void Fl_Browser::text(int n, const char *)

+ +The first form returns the text for line n. If n is +out of range it returns NULL. + +

The second form sets the text for line n. + +

int Fl_Browser::topline() const
+void Fl_Browser::topline(int n)

+ +The first form returns the current top line in the browser. If there is no +vertical scrollbar then this will always return 1. + +

The second form sets the top line in the browser to n. + +

The second form sets the vertical scrollbar position to p. + +

int Fl_Browser::visible(int n) const

+ +Returns a non-zero value if line n is visible. + + + diff --git a/documentation/Fl_Browser_.html b/documentation/Fl_Browser_.html new file mode 100644 index 000000000..fc8456f51 --- /dev/null +++ b/documentation/Fl_Browser_.html @@ -0,0 +1,171 @@ + + + +
+ +

class Fl_Browser_

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ + + +

Description

+ +This is the base class for browsers. To be useful it must be +subclassed and several virtual functions defined. The Forms-compatable +browser and the file chooser's browser are subclassed off of this. + +

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. + +

Methods

+ +
+ + + + + + + + +
+ + + + + + + + + +
+
+ +

Fl_Browser::Fl_Browser(int, int, int, int, const char * = 0)

+ +The constructor makes an empty browser. + +

Fl_Browser::~Fl_Browser(void)

+ +The destructor deletes all list items and destroys the browser. + +

void Fl_Browser_::has_scrollbar(int h)

+ +By default you can scroll in both directions, and the scrollbars +disappear if the data will fit in the widget. has_scrollbar() +changes this based on the value of h: + + + +

Fl_Color Fl_Browser_::textcolor() const
+void Fl_Browser_::textcolor(Fl_Color color)

+ +The first form gets the default text color for the lines in the +browser. + +

The second form sets the default text color to color + +

Fl_Font Fl_Browser_::textfont() const
+void Fl_Browser_::textfont(Fl_Font font)

+ +The first form gets the default text font for the lines in the +browser. + +

The second form sets the default text font to font + +

uchar Fl_Browser_::textsize() const
+void Fl_Browser_::textsize(uchar size)

+ +The first form gets the default text size for the lines in the +browser. + +

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 @@ + + + +


+ +

class Fl_Button

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ + + +

Description

+ +

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. + +

Methods

+ +
+ + + + + + + + +
+ + + + + + + + + +
+
+ +

Fl_Button::Fl_Button(int x, int y, int w, int h, const char *label = 0)

+ +The constructor creates the button using the position, size, and label. + +

Fl_Button::~Fl_Button(void)

+ +The destructor removed the button. + +

int Fl_Button::clear()

+ +Same as value(0). + +

Fl_Boxtype Fl_Button::down_box() const
+void Fl_Button::down_box(Fl_Boxtype bt)

+ +The first form returns the current down box type, which is drawn when +value() is non-zero. + +

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(). + +

int Fl_Button::set()

+ +Same as value(1). + +

void Fl_Button::setonly()

+ +Turns on this button and turns off all other radio buttons in the +group (calling value(1) or set() does not do this). + +

ulong Fl_Button::shortcut() const
+void Fl_Button::shortcut(ulong key)

+ +The first form returns the current shortcut key for the button. + +

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). + +

uchar Fl_Button::type() const
+void Fl_Button::type(uchar t)

+ +The first form of type() returns the current button type, +which can be one of: + + + +The second form sets the button type to t. + +

char Fl_Button::value() const
+int Fl_Button::value(int)

+ +The first form returns the current value (0 or 1). The second form sets +the current value. + +

Fl_When Fl_Widget::when() const
+void Fl_Widget::when(Fl_When w)

+ +Controls when callbacks are done. The following values are useful, +the default value is FL_WHEN_RELEASE: + + + + + diff --git a/documentation/Fl_Chart.html b/documentation/Fl_Chart.html new file mode 100644 index 000000000..5a9d527ab --- /dev/null +++ b/documentation/Fl_Chart.html @@ -0,0 +1,162 @@ + + + +
+ +

class Fl_Chart

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ + + +

Description

+ +This widget displays simple charts and is provided for forms compatibility. + +

Methods

+ +
+ + + + + + + + +
+ + + + + + + + + +
+
+ +

Fl_Chart::Fl_Chart(int x, int y, int w, int h, const char *label = 0)

+ +Creates a new Fl_Chart widget using the given position, size, and +label string. The default boxtype is FL_NO_BOX. + +

virtual Fl_Chart::~Fl_Chart()

+ +Destroys the Fl_Chart widget and all of its data. + +

void add(double value, const char *label = NULL, uchar color = 0)

+ +The add method adds the value and optionally label +and color to the chart. + +

uchar autosize(void) const
+void autosize(uchar onoff)

+ +The autosize method controls whether or not the chart will +automatically adjust the bounds of the chart. The first form returns a +boolean value that is non-zero if auto-sizing is enabled and zero is auto-sizing +is disabled. + +

The second form of autosize sets the auto-sizing property to +onoff. + +

void bounds(double *a, double *b)
+void bounds(double a, double b)

+ +The bounds method gets or sets the lower and upper bounds of the chart +values to a and b respectively. + +

void clear(void)

+ +The clear method removes all values from the chart. + +

void insert(int pos, double value, const char *label = NULL, uchar color = 0)

+ +The insert method inserts a data value at the given position +pos. Position 0 is the first data value. + +

int maxsize(void) const
+void maxsize(int n)

+ +The maxsize method gets or sets the maximum number of data values for +a chart. + +

void replace(int pos, double value, const char *label = NULL, uchar color = 0)

+ +The replace method replaces data value pos with +value, label, and color. Position 0 is +the first data value. + +

int size(void) const

+ +The size method returns the number of data values in the chart. + +

uchar type() const
+void type(uchar t)

+ +The first form of type() returns the current chart type. +The chart type can be one of the following: + +
+
FL_BAR_CHART
+
Each sample value is drawn as a vertical bar.
+ +
FL_FILLED_CHART
+
The chart is filled from the bottom of the graph to the + sample values.
+ +
FL_HORBAR_CHART
+
Each sample value is drawn as a horizontal bar.
+ +
FL_LINE_CHART
+
The chart is drawn as a polyline with vertices at each + sample value.
+ +
FL_PIE_CHART
+
A pie chart is drawn with each sample value being drawn + as a proportionate slice in the circle.
+ +
FL_SPECIALPIE_CHART
+
Like FL_PIE_CHART, but the first slice is separated from + the pie.
+ +
FL_SPIKE_CHART
+
Each sample value is drawn as a vertical line.
+
+ +The second form of type() sets the chart type to t. + +
+ + + diff --git a/documentation/Fl_Check_Button.html b/documentation/Fl_Check_Button.html new file mode 100644 index 000000000..14ac7f0eb --- /dev/null +++ b/documentation/Fl_Check_Button.html @@ -0,0 +1,53 @@ + + + +
+ +

class Fl_Check_Button

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ + + +

Description

+ +Buttons generate callbacks when they are clicked by the user. You +control exactly when and how by changing the values for type() and +when(). + +

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

+ + + +

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. + +

Methods

+ + + +

Fl_Choice::Fl_Choice(int x, int y, int w, int h, const char *label = 0)

+ +Creates a new Fl_Choice widget using the given position, size, and +label string. The default boxtype is FL_UP_BOX. + +

The constructor sets menu() to NULL. See Fl_Menu_ for the methods to set or change +the menu. + +

virtual Fl_Choice::~Fl_Choice()

+ +The destructor removes the Fl_Choice widget and all of its menu items. + +

int Fl_Choice::value() const
+int Fl_Choice::value(int)
+int Fl_Choice::value(const Fl_Menu *)

+ +The value is the index into the Fl_Menu array of the last item chosen +by the user. It is zero initially. You can set it as an integer, or +set it with a pointer to a menu item. The set routines return +non-zero if the new value is different than the old one. Changing it +causes a redraw(). + +

int Fl_Widget::changed() const

+ +This value is true if the user picks a different value. It is +turned off by value() and just before doing a callback (the +callback can turn it back on if desired). + +

void Fl_Widget::set_changed()

+ +This method sets the changed() flag. + +

void Fl_Widget::clear_changed()

+ +This method clears the changed() flag. + +

Fl_Boxtype Fl_Choice::down_box() const
+void Fl_Choice::down_box(Fl_Boxtype b)

+ +The first form gets the current down box, which is used when the menu +is popped up. The default down box type is FL_DOWN_BOX + +The second form sets the current down box type to b. + + + diff --git a/documentation/Fl_Clock.html b/documentation/Fl_Clock.html new file mode 100644 index 000000000..e1da8a9e9 --- /dev/null +++ b/documentation/Fl_Clock.html @@ -0,0 +1,78 @@ + + + +
+ +

class Fl_Clock

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ +
    +#include <FL/Fl_Clock.H>
    +
+ +

Description

+ +This widget provides a round analog clock display and is provided for +Forms compatibility. It installs a 1-second timeout callback using +Fl::add_timeout(). + +

Methods

+ + + +

Fl_Clock::Fl_Clock(int x, int y, int w, int h, const char *label = 0)

+ +Creates a new Fl_Clock widget using the given position, size, and +label string. The default boxtype is FL_NO_BOX. + +

virtual Fl_Clock::~Fl_Clock()

+ +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_Clock and all of it's children can be automatic (local) +variables, but you must declare the Fl_Clock first, so +that it is destroyed last. + +

int Fl_Clock::hour() const

+ +Returns the current hour (0 to 23). + +

int Fl_Clock::minute() const

+ +Returns the current minute (0 to 59). + +

int Fl_Clock::second() const

+ +Returns the current second (0 to 60, 60 = leap second). + +

void Fl_Clock::value(ulong v)
+void Fl_Clock::value(int h, int m, int s)
+ulong Fl_Clock::value(void)

+ +The first two forms of value set the displayed time to the given +UNIX time value or specific hours, minutes, and seconds. + +

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 @@ + + + +


+ +

class Fl_Color_Chooser

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ +
    +#include <FL/Fl_Color_Chooser.H>
    +
+ +

Description

+ +The Fl_Color_Chooser widget provides a standard RGB color +chooser. You can place any number of these into a panel of your own +design. This widget contains the hue box, value slider, and rgb input +fields from the above diagram (it does not have the color chips or the +Cancel or OK buttons). The callback is done every time the user +changes the rgb value. It is not done if they move the hue control in +a way that produces the same rgb value, such as when saturation +or value is zero. + +

Methods

+ + + +

Fl_Color_Chooser::Fl_Color_Chooser(int x, int y, int w, int h, const char *label = 0)

+ +Creates a new Fl_Color_Chooser widget using the given +position, size, and label string. The recommended dimensions are +200x95. The color is initialized to black. + +

virtual Fl_Color_Chooser::~Fl_Color_Chooser()

+ +The destructor removes the color chooser and all of its controls. + +

double Fl_Color_Chooser::hue() const

+ +Return the current hue. 0 <= hue < 6. Zero is red, one is +yellow, two is green, etc. This value is convienent for the internal +calculations - some other systems consider hue to run from zero to +one, or from 0 to 360. + +

double Fl_Color_Chooser::saturation() const

+ +Returns the saturation. 0 <= saturation <= 1. + +

double Fl_Color_Chooser::value() const

+ +Returns the value/brightness. 0 <= value <= 1. + +

double Fl_Color_Chooser::r() const

+ +Returns the current red value. 0 <= r <= 1. + +

double Fl_Color_Chooser::g() const

+ +Returns the current green value. 0 <= g <= 1. + +

double Fl_Color_Chooser::b() const

+ +Returns the current blue value. 0 <= b <= 1. + +

int Fl_Color_Chooser::rgb(double, double, +double)

+ +Sets the current rgb color values. Does not do the callback. Does +not clamp (but out of range values will produce psychedelic effects in +the hue selector). + +

int Fl_Color_Chooser::hsv(double,double,double)

+ +Set the hsv values. The passed values are clamped (or for hue, +modulus 6 is used) to get legal values. Does not do the callback. + +

static void Fl_Color_Chooser::hsv2rgb(double, double, +double, double&, double&, double&)

+ +This static method converts HSV colors to RGB colorspace. + +

static void Fl_Color_Chooser::rgb2hsv(double, double, double, double&, +double&, double&)

+ +This static method converts RGB colors to HSV colorspace. + + + diff --git a/documentation/Fl_Counter.html b/documentation/Fl_Counter.html new file mode 100644 index 000000000..42551fefa --- /dev/null +++ b/documentation/Fl_Counter.html @@ -0,0 +1,66 @@ + + + +
+ +

class Fl_Counter

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ +
    +#include <FL/Fl_Counter.H>
    +
+ +

Description

+ +The Fl_Counter widget is provided for forms compatibility. It +controls a single floating point value. + +

Methods

+ + + +

Fl_Counter::Fl_Counter(int x, int y, int w, int h, const char *label = 0)

+ +Creates a new Fl_Counter widget using the given position, size, and +label string. The default type is FL_NORMAL_COUNTER. + +

virtual Fl_Counter::~Fl_Counter()

+ +Destroys the valuator. + +

double Fl_Counter::lstep() const
+void Fl_Counter::lstep(double)

+ +Get or set the increment for the double-arrow buttons. The default +value is 1.0. + +

type(uchar)

+ +Sets the type of counter: + +
    +
  • FL_NORMAL_COUNTER - Displays a counter with 4 arrow + buttons. + +
  • FL_SIMPLE_COUNTER - Displays a counter with only 2 + arrow buttons. +
+ + + diff --git a/documentation/Fl_Dial.html b/documentation/Fl_Dial.html new file mode 100644 index 000000000..2e732440a --- /dev/null +++ b/documentation/Fl_Dial.html @@ -0,0 +1,65 @@ + + + +
+ +

class Fl_Dial

+ +
+ +

Class Hierarchy

+ + + +

Include Files

+ +
    +#include <FL/Fl_Dial.H>
    +
+ +

Description

+ +The Fl_Dial widget provides a circular dial to control a +single floating point value. + +

Methods

+ + + +

Fl_Dial::Fl_Dial(int x, int y, int w, int h, const char *label = 0)

+ +Creates a new Fl_Dial widget using the given position, size, and +label string. The default type is FL_NORMAL_DIAL. + +

virtual Fl_Dial::~Fl_Dial()

+ +Destroys the valuator. + +

void Fl_Dial::angles(short a, short b)

+ +Sets the angles used for the minimum and maximum values. By default these +are 0 and 360, respectively. + +

type(uchar)

+ +Sets the type of the dial to: + +

FLTK Drawing functions
#include <FL/fl_draw.H>

+ + + +

Clipping

+ +

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);

    + +Intesect the current clip region with a rectangle and push this new +region onto the stack. + +

void fl_pop_clip();

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

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

    + +Returns true if any of the rectangle intersects the current clip +region. If this returns false you don't have to draw the object. +On X this returns 2 if the rectangle is partially clipped, and 1 if +it is entirely inside the clip region. + +

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

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

Colors

+ +

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();

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

void Fl::set_color(Fl_Color, uchar r, uchar g, uchar b); +
void Fl::get_color(Fl_Color, uchar &, uchar &, uchar &);

    + +Set or get an entry in the fl_color index table. You can set it to +any 8-bit rgb color. On X, if the index has been requested before, +the pixel is free'd. No pixel is allocated until fl_color(i) is used +again, and there is no guarantee that the same pixel will be used next +time. + +

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! + +


Fast Shapes

+ +These are used to draw almost all the FLTK widgets. They draw on +exact pixel boundaries and are as fast as possible, and their behavior +will be duplicated exactly on any platform FLTK is ported to. It is +undefined whether these are affected by the transformation matrix, so you should only call these +while it is the identity. + +

All arguments are integers. + +

void fl_rectf(x, y, w, h);

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

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

    + +Color a rectangle with "exactly" the passed r,g,b color. On screens +with less than 24 bits of color this is done by drawing a +solid-colored block using fl_draw_image() so that dithering +is produced. If you have 24 bit color, this fills the rectangle with a +single pixel value and is about 1 zillion times faster. + +

void fl_rect(x, y, w, h);

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

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

    + +Draw one or two 1-pixel thick lines between the given points. + +

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

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

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

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

void fl_xyline(x, y, x1, y1); +
void fl_xyline(x, y, x1, y1, x2); +
void fl_xyline(x, y, x1, y1, x2, y3); +

    + +Draw 1-pixel wide horizontal and vertical lines. A horizontal line is +drawn first, then a vertical, then a horizontal. + +

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

    + +Draw 1-pixel wide vertical and horizontal lines. A vertical line is +drawn first, then a horizontal, then a vertical. + +

+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);

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

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

    fl_arc draws a 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. + +


Complex Shapes

+ +These functions let you draw arbitrary shapes with 2-D linear +transformations. The functionality matches PostScript. The exact +pixels filled in is less defined than for the above calls, so that FLTK +can take advantage of drawing hardware. (Both Xlib and MSWindows round +all the transformed verticies to integers before drawing the line +segments. This severely limits the accuracy of these functions for +complex graphics. Try using OpenGL instead) + +

All arguments are float. + +

void fl_push_matrix(); +
void fl_pop_matrix();

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

void fl_scale(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);

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

void fl_begin_line(); +
void fl_end_line();

    + +Start and end drawing 1-pixel thick lines. + +

void fl_begin_loop(); +
void fl_end_loop();

    + +Start and end drawing a closed sequence of 1-pixel thick lines. + +

void fl_begin_polygon(); +
void fl_end_polygon();

    + +Start and end drawing a convex filled polygon. + +

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

    + +Start and end drawing a complex filled polygon. This polygon may be +concave, may have holes in it, or may be several disconnected pieces. +Call fl_gap() to seperate loops of the path (it is unnecessary but +harmless to call fl_gap() before the first vertex, after the last one, +or several times in a row). For portability, you should only draw +polygons that appear the same whether "even/odd" or "non-zero" +"winding rules" are used to fill them. This mostly means that holes +should be drawn in the opposite direction of the outside. + +

    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);

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

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

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

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

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

void fl_circle(x, y, r);

    + +fl_circle() is equivalent to fl_arc(...,0,360) but may be faster. It +must be the only thing in the path: if you want a circle as +part of a complex polygon you must use fl_arc(). Under Xlib and +MSWindows this draws incorrectly if the transformation is both rotated +and non-square scaled. + +

Text

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

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

    + +Draw a null terminated string or an array of n characters +starting at the given location. + +

void fl_draw(const char*, int x,int y,int w,int h, Fl_Align);

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

void fl_measure(const char*, int& w, int& h);

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

int fl_height();

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

int fl_descent();

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

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

    + +Return the width of a null-terminated string, a sequence of n +characters, and a single character. + +

const char* fl_shortcut_label(ulong);

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

Fonts

+ +

void fl_font(int face, int size);

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

    The font is identified by a face and a size. The +size of the font is measured in pixels (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();

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

const char* Fl::get_font(int face);

    + +Get the string for this face. This string is different for each face. +Under X this value is passed to XListFonts to get all the sizes of +this face. + +

const char* Fl::get_font_name(int face, int* attributes=0);

    + +Get a human-readable string describing the family of this face. This +is useful if you are presenting a choice to the user. There is no +guarantee that each face has a different name. The return value +points to a static buffer that is overwritten each call. + +

    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);

    + +Return an array of sizes in sizep. The return value is the +length of this array. The sizes are sorted from smallest to largest +and indicate what sizes can be given to fl_font() that will be matched +exactly (fl_font() will pick the closest size for other sizes). A +zero in the first location of the array indicates a scalable font, +where any size works, although the array may list sizes that work +"better" than others. Warning: the returned array points at a static +buffer that is overwritten each call. Under X this will open the +display. + +

int Fl::set_font(int face, const char*);

    + +Change a face. The string pointer is simply stored, the string is not +copied, so the string must be in static memory. + +

int Fl::set_font(int face, int from);

    + +Copy one face to another. + +

int Fl::set_fonts(const char* = 0);

    + +FLTK will open the display, and add every font on the server to the +face table. It will attempt to put "families" of faces together, so +that the normal one is first, followed by bold, italic, and bold +italic. + +

    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. + +


Bitmaps, Pixmaps and Images

+ +Click here for information on drawing images + +

Cursor

+ +

void fl_cursor(Fl_Cursor, Fl_Color=FL_WHITE, Fl_Color=FL_BLACK);

    + +Change the cursor. Depending on the system this may affect the cursor +everywhere, or only when it is pointing at the window that is current +when you call this. For portability you should change the cursor back +to the default in response to FL_LEAVE events. + +

    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 +
    + +

Overlay rectangle

+ +

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) + + +Drawing Images in FLTK +

Drawing Images in FLTK

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


Direct Image Drawing
+#include <FL/fl_draw.H>

+ +

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); +

+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); +

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

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

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


class Fl_Bitmap +
#include <FL/Fl_Bitmap.H>

+ +This object encapsulates the width, height, and bits of an Xbitmap +(XBM), and allows you to make an Fl_Widget use a bitmap as a label, or +to just draw the bitmap directly. Under X it will create an +offscreen pixmap the first time it is drawn, and copy this each +subsequent time it is drawn. + +

Fl_Bitmap(const char *bits, int W, int H); +
Fl_Bitmap(const uchar *bits, int W, int H);

+ +Construct from an Xbitmap. The bits pointer is simply copied to the +object, so it must point at persistent storage. I provide two +constructors because various X implementations disagree about the type +of bitmap data. To use an XBM file, +#include "foo.xbm", and then do "new +Fl_Bitmap(foo_bits,foo_width,foo_height)" + +

~Fl_Bitmap()

+ +The destructor will destroy any X pixmap created. It does not do +anything to the bits data. + +

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

+ +x,y,w,h indicates a destination rectangle. ox,oy,w,h is +a source rectangle. This source rectangle from the bitmap is drawn in +the destination. 1 bits are drawn with the current color, 0 bits are +unchanged. The source rectangle may extend outside the bitmap (i.e. ox +and oy may be negative and w and h may be bigger than the bitmap) and +this area is left unchanged. + +

void draw(int x, int y);

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

void label(Fl_Widget *);

+ +Change the label() and the labeltype() of the widget to draw the +bitmap. 1 bits will be drawn with the labelcolor(), zero bits will be +unchanged. You can use the same bitmap for many widgets. + +
+


class Fl_Pixmap +
#include <FL/Fl_Pixmap.H>

+ +This object encapsulates the data from an XPM image, and allows you to +make an Fl_Widget use a pixmap as a label, or to just draw the pixmap +directly. Under X it will create an offscreen pixmap the first +time it is drawn, and copy this each subsequent time it is drawn. + +

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);

+ +Construct from XPM data. The data pointer is simply copied to the +object, so it must point at persistent storage. To use an XPM file, +#include "foo.xpm", and then do "new +Fl_Pixmap(foo)" + +

~Fl_Pixmap()

+ +The destructor will destroy any X pixmap created. It does not do +anything to the data. + +

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

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

void draw(int x, int y);

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

void label(Fl_Widget *);

+ +Change the label() and the labeltype() of the widget to draw the +pixmap. You can use the same pixmap for many widgets. + + +


class Fl_Image +
#include <FL/Fl_Image.H>

+ +This object encapsulates a full-color RGB image, and allows you to +make an Fl_Widget use a Image as a label, or to just draw the Image +directly. Under X it will create an offscreen pixmap the first +time it is drawn, and copy this each subsequent time it is drawn. + +

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);

+ +Construct from a pointer to RGB data. W and H are the size of the +image in pixels. D is the delta between pixels (it may be more than 3 +to skip alpha or other data, or negative to flip the image +left/right). LD is the delta between lines (it may be more than D*W +to crop images, or negative to flip the image vertically). The data +pointer is simply copied to the object, so it must point at persistent +storage. + +

~Fl_Image()

+ +The destructor will destroy any X pixmap created. It does not do +anything to the data. + +

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

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

void draw(int x, int y);

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

void label(Fl_Widget *);

+ +Change the label() and the labeltype() of the widget to draw the +Image. You can use the same Image for many widgets. + +

(back to contents) +FLTK enhancements to the XPM format +

FLTK enhancements to the XPM format

+ +

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. + + + +

Chapter XXX - Drawing Things in FLTK

+ +

When can you draw things in FLTK?

+ +There are only certain places you can execute drawing code in FLTK. +Calling these functions at other places will result in undefined +behavior! + +
    + +
  • The most common is inside the virtual method Fl_Widget::draw(). To write code here, +you must subclass one of the existing Fl_Widget classes and implement +your own version of draw(). + +

    + +

  • You can also write boxtypes and labeltypes. These are small procedures that can be +called by existing Fl_Widget draw() methods. These "types" are +identified by an 8-bit index that is stored in the widget's box(), +labeltype(), and possibly other properties. + +

    + +

  • You can call Fl_Window::make_current() to do +incremental update of a widget (use Fl_Widget::window() to find the +window). Under X this only works for the base Fl_Window class, not +for double buffered, overlay, or OpenGL windows! + +
+ +

FLTK Drawing functions
#include <FL/fl_draw.H>

+ + + +

Clipping

+ +

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);

    + +Intesect the current clip region with a rectangle and push this new +region onto the stack. + +

void fl_pop_clip();

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

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

    + +Returns true if any of the rectangle intersects the current clip +region. If this returns false you don't have to draw the object. +On X this returns 2 if the rectangle is partially clipped, and 1 if +it is entirely inside the clip region. + +

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

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

Colors

+ +

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();

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

void Fl::set_color(Fl_Color, uchar r, uchar g, uchar b); +
void Fl::get_color(Fl_Color, uchar &, uchar &, uchar &);

    + +Set or get an entry in the fl_color index table. You can set it to +any 8-bit rgb color. On X, if the index has been requested before, +the pixel is free'd. No pixel is allocated until fl_color(i) is used +again, and there is no guarantee that the same pixel will be used next +time. + +

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! + +


Fast Shapes

+ +These are used to draw almost all the FLTK widgets. They draw on +exact pixel boundaries and are as fast as possible, and their behavior +will be duplicated exactly on any platform FLTK is ported to. It is +undefined whether these are affected by the transformation matrix, so you should only call these +while it is the identity. + +

All arguments are integers. + +

void fl_rectf(x, y, w, h);

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

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

    + +Color a rectangle with "exactly" the passed r,g,b color. On screens +with less than 24 bits of color this is done by drawing a +solid-colored block using fl_draw_image() so that dithering +is produced. If you have 24 bit color, this fills the rectangle with a +single pixel value and is about 1 zillion times faster. + +

void fl_rect(x, y, w, h);

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

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

    + +Draw one or two 1-pixel thick lines between the given points. + +

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

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

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

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

void fl_xyline(x, y, x1, y1); +
void fl_xyline(x, y, x1, y1, x2); +
void fl_xyline(x, y, x1, y1, x2, y3); +

    + +Draw 1-pixel wide horizontal and vertical lines. A horizontal line is +drawn first, then a vertical, then a horizontal. + +

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

    + +Draw 1-pixel wide vertical and horizontal lines. A vertical line is +drawn first, then a horizontal, then a vertical. + +

+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);

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

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

    fl_arc draws a 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. + +


Complex Shapes

+ +These functions let you draw arbitrary shapes with 2-D linear +transformations. The functionality matches PostScript. The exact +pixels filled in is less defined than for the above calls, so that FLTK +can take advantage of drawing hardware. (Both Xlib and MSWindows round +all the transformed verticies to integers before drawing the line +segments. This severely limits the accuracy of these functions for +complex graphics. Try using OpenGL instead) + +

All arguments are float. + +

void fl_push_matrix(); +
void fl_pop_matrix();

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

void fl_scale(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);

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

void fl_begin_line(); +
void fl_end_line();

    + +Start and end drawing 1-pixel thick lines. + +

void fl_begin_loop(); +
void fl_end_loop();

    + +Start and end drawing a closed sequence of 1-pixel thick lines. + +

void fl_begin_polygon(); +
void fl_end_polygon();

    + +Start and end drawing a convex filled polygon. + +

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

    + +Start and end drawing a complex filled polygon. This polygon may be +concave, may have holes in it, or may be several disconnected pieces. +Call fl_gap() to seperate loops of the path (it is unnecessary but +harmless to call fl_gap() before the first vertex, after the last one, +or several times in a row). For portability, you should only draw +polygons that appear the same whether "even/odd" or "non-zero" +"winding rules" are used to fill them. This mostly means that holes +should be drawn in the opposite direction of the outside. + +

    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);

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

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

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

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

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

void fl_circle(x, y, r);

    + +fl_circle() is equivalent to fl_arc(...,0,360) but may be faster. It +must be the only thing in the path: if you want a circle as +part of a complex polygon you must use fl_arc(). Under Xlib and +MSWindows this draws incorrectly if the transformation is both rotated +and non-square scaled. + +

Text

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

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

    + +Draw a null terminated string or an array of n characters in the +current font, starting at the given location. + +

void fl_draw(const char*, int x,int y,int w,int h, Fl_Align);

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

void fl_measure(const char*, int& w, int& h);

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

int fl_height();

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

int fl_descent();

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

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

    + +Return the width of a null-terminated string, a sequence of n +characters, and a single character. + +

const char* fl_shortcut_label(ulong);

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

Fonts

+ +

void fl_font(int face, int size);

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

    The font is identified by a face and a size. The +size of the font is measured in pixels (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();

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

const char* Fl::get_font(int face);

    + +Get the string for this face. This string is different for each face. +Under X this value is passed to XListFonts to get all the sizes of +this face. + +

const char* Fl::get_font_name(int face, int* attributes=0);

    + +Get a human-readable string describing the family of this face. This +is useful if you are presenting a choice to the user. There is no +guarantee that each face has a different name. The return value +points to a static buffer that is overwritten each call. + +

    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);

    + +Return an array of sizes in sizep. The return value is the +length of this array. The sizes are sorted from smallest to largest +and indicate what sizes can be given to fl_font() that will be matched +exactly (fl_font() will pick the closest size for other sizes). A +zero in the first location of the array indicates a scalable font, +where any size works, although the array may list sizes that work +"better" than others. Warning: the returned array points at a static +buffer that is overwritten each call. Under X this will open the +display. + +

int Fl::set_font(int face, const char*);

    + +Change a face. The string pointer is simply stored, the string is not +copied, so the string must be in static memory. + +

int Fl::set_font(int face, int from);

    + +Copy one face to another. + +

int Fl::set_fonts(const char* = 0);

    + +FLTK will open the display, and add every font on the server to the +face table. It will attempt to put "families" of faces together, so +that the normal one is first, followed by bold, italic, and bold +italic. + +

    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. + +


Bitmaps, Pixmaps and Images

+ +Click here for information on drawing images + +

Cursor

+ +

void fl_cursor(Fl_Cursor, Fl_Color=FL_WHITE, Fl_Color=FL_BLACK);

    + +Change the cursor. Depending on the system this may affect the cursor +everywhere, or only when it is pointing at the window that is current +when you call this. For portability you should change the cursor back +to the default in response to FL_LEAVE events. + +

    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 +
    + +

Overlay rectangle

+ +

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 @@ + + + +

4 - Designing a Simple Text Editor

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

Determining the Goals of the Text Editor

+ +Since this will be the first big project you'll be doing with FLTK, lets define +what we want our text editor to do: + +
    +
  1. Menu_Bar/menus for all functions. +
  2. Edit a single text file. +
  3. Load from a file. +
  4. Save to a file. +
  5. Cut/copy/delete/paste functions. +
  6. Search and replace functions. +
  7. Keep track of when the file has been changed. +
+ +

Designing the Main Window

+ +Now that we've outlined the goals for our editor, we can begin with the design +of our GUI. Obviously the first thing that we need is a window: + +
    +Fl_Window *window;
    +
    +window = new Fl_Window(640, 480, "Text Editor");
    +
+ +

Variables

+ +Our text editor will need some global variables to keep track of things: + +
    +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. + +

Menu_Bars and Menus

+ +The first goal requires us to use a menubar and menus that define +each function the editor needs to perform. The +Fl_Menu_Item structure is used to +define the menus and items in a menubar: + +
    +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. + +

Editing the Text

+ +To keep things simple our text editor will use the +Fl_Multiline_Input widget to +edit the text: + +
    +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);
    +
+ +

The Replace Dialog

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

Callbacks

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

changed_cb()

+ +This function will be called whenever the user changes any text in the +input widget: + +
    +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. + +

copy_cb()

+ +This callback function will call +input->copy() to copy the currently selected text to the +clipboard: + +
    +void copy_cb(void) {
    +  input->copy();
    +}
    +
+ +

cut_cb()

+ +This callback function will call +input->copy() to copy the currently selected text to the +clipboard and then input->cut() +to delete it: + +
    +void cut_cb(void) {
    +  input->copy();
    +  input->cut();
    +}
    +
+ +

delete_cb()

+ +This callback function will call +input->cut() to delete the selected text: + +
    +void delete_cb(void) {
    +  input->cut();
    +}
    +
+ +

find_cb()

+ +This callback function asks for a search string using the +fl_input() convenience function and +then calls the find2_cb() function to find the string: + +
    +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();
    +  }
    +}
    +
+ +

find2_cb()

+ +This function will find the next occurrence of the search string. If the +search string is blank then we want to pop up the search dialog: + +
    +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. + +

new_cb()

+ +This callback function will clear the input widget and current filename. +It also calls the check_save() function to give the user the +opportunity to save the current file first as needed: + +
    +void new_cb(void) {
    +  if (changed)
    +    if (!check_save()) return;
    +
    +  filename[0] = '\0';
    +  input->value("");
    +  set_changed(0);
    +}
    +
+ +

open_cb()

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

paste_cb()

+ +This callback function will send a FL_PASTE message to the input +widget using the Fl::paste() method: + +
    +void paste_cb(void) {
    +  Fl::paste(*input);
    +}
    +
+ +

quit_cb()

+ +The quit callback will first see if the current file has been modified, +and if so give the user a chance to save it. It then hides the main window: + +
    +void quit_cb(void) {
    +  if (changed)
    +    if (!check_save())
    +      return;
    +
    +  window->hide();
    +}
    +
+ +

replace_cb()

+ +The replace callback just shows the replace dialog: + +
    +void replace_cb(void) {
    +  replace_dlg->show();
    +}
    +
+ +

replace2_cb()

+ +This callback will replace the next occurence of the replacement string. If +nothing has been entered for the replacement string, then the replace dialog +is displayed instead: + +
    +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);
    +}
    +
+ +

replall_cb()

+ +This callback will replace all occurences of the search string in the file: + +
    +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);
    +}
    +
+ +

replcan_cb()

+ +This callback just hides the replace dialog: + +
    +void replcan_cb() {
    +  replace_dlg->hide();
    +}
    +
+ +

save_cb()

+ +This callback saves the current file. If the current filename is blank it +calls the "save as" callback: + +
    +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. + +

saveas_cb()

+ +This callback asks the user for a filename and saves the current file: + +
    +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. + +

undo_cb()

+ +The undo callback just calls the
+undo() method: + +
    +void undo_cb(void) {
    +  input->undo();
    +}
    +
+ +

Other Functions

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

check_save()

+ +This function checks to see if the current file needs to be saved. If +so, it asks the user if they want to save it: + +
    +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);
    +}
    +
+ +

load_file()

+ +This function loads the specified file into the input widget: + +
    +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. + +

save_file()

+ +This function saves the current buffer to the specified file: + +
    +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!");
    +  }
    +}
    +
+ +

set_changed()

+ +This function sets the changed variable and updates the window label +accordingly: + +
    +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);
    +  }
    +}
    +
+ +

Compiling the Editor

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

The Final Product

+ +The final editor window should look like the image below: + +
+ + + diff --git a/documentation/enumerations.html b/documentation/enumerations.html new file mode 100644 index 000000000..355437a73 --- /dev/null +++ b/documentation/enumerations.html @@ -0,0 +1,328 @@ + + +

C - FLTK Enumerations.H

+ +Here are the values of all the public-visible enumerations used by fltk: + +
+#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 @@ + + + +

4 - Handling Events

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

The FLTK Event Model

+ +

Mouse Events

+ +

FL_PUSH

+ +

FL_RELEASE

+ +

FL_DRAG

+ +

FL_MOVE

+ +

Keyboard Events

+ +

FL_KEYBOARD

+ +

FL_SHORTCUT

+ +

Widget Events

+ +

FL_ACTIVATE

+ +

FL_DEACTIVATE

+ +

FL_HIDE

+ +

FL_SHOW

+ +

FL_FOCUS

+ +

FL_UNFOCUS

+ +

FL_ENTER

+ +

FL_LEAVE

+ +

FL_PASTE

+ +

FL_SELECTIONCLEAR

+ + + +Events in Fltk + +

Events in Fltk

+ +

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 mouse button has gone down with the mouse pointing at this widget. +You can find out what button by calling Fl::event_button(). You find out the mouse +position by calling Fl::event_x() and +Fl::event_y(). + +

    A widget indicates that it "wants" the mouse click by returning +non-zero from 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)

    + +The mouse has moved with the button held down. + +

FL_RELEASE (2)

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

FL_ENTER (3)

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

FL_MOVE (10)

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

FL_LEAVE (4)

    + +The mouse has moved out of the widget. + +

FL_FOCUS (6)

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

    If a widget wants the focus, it should change itself to display the +fact that it has the focus, and return non-zero from 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)

    + +Sent to the old Fl::focus() when something else +gets the focus. + +

FL_KEYBOARD (8)

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

FL_SHORTCUT (11)

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

    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)

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

FL_ACTIVATE (14)

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

FL_HIDE (15)

    + +This widget is no longer visible, due to hide() being called, or a parent group +or window having hide() be called, or due to a parent window being +iconized. visible() may still be true after this, the widget is +visible only if visible() is true for it and all it's parents. + +

FL_SHOW (16)

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

FL_PASTE (17)

FL_SELECTIONCLEAR (18)

    + +The Fl::selection_owner() will get this +event before the selection is moved to another widget. This indicates +that some other widget or program has claimed the selection. + +
+ + +

Fl::event_*() methods

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

These are all trivial inline functions and thus very fast and +small. The data is stored in static locations and remains valid until +the next X event is handled. + + +

int Fl::event_button();

int Fl::event_x() +
int Fl::event_y()

int Fl::event_x_root() +
int Fl::event_y_root()

void Fl::get_mouse(int &,int &)

ulong Fl::event_state(); +
unsigned int Fl::event_state(int);

int Fl::event_key(); +
int Fl::event_key(int); +
int Fl::get_key(int);

char * Fl::event_text()

char * Fl::event_length()

int Fl::event_is_click()

void Fl::event_is_click(0)

int Fl::event_clicks()

void Fl::event_clicks(int)

int Fl::event_inside(const Fl_Widget *) const ; +
int Fl::event_inside(int,int,int,int);

int Fl::test_shortcut(ulong) const ;

+ + +

Event Propagation

+ +

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

Fl_Widget *Fl::focus() const; +
void Fl::focus(Fl_Widget *);

int Fl_Widget::take_focus();

Fl_Widget *Fl::belowmouse() const; +
void Fl::belowmouse(Fl_Widget *);

Fl_Widget *Fl::pushed() const; +
void Fl::pushed(Fl_Widget *);

void Fl::add_handler(int (*f)(int));

Fl_Window* Fl::modal();

void Fl::grab(Fl_Window&);
+Fl_Window* Fl::grab();

void Fl::release()

(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 @@ + + + +

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

+ + + +fluid Reference Manual + +
+ +

What is Fluid?

+ +

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). + +

+                               _________
+                              /        /
+    __________            +->/.C file /--------+
+   /         /           /  /________/         |
+  /.fl file /<==>[fluid]<     #include         |
+ /_________/             \     ___v_____       |
+                          \   /        /       |
+                           +>/.H file /        |
+                            /________/         |
+                                  ^            |
+                              #include         |
+                               ___|_____       |          __________
+                              /        /       V         /         /
+                             / main.C /--->[c++,link]-->/ program /
+                            /________/                 /_________/
+
+ +

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. + + +

Worlds shortest tutorial

+ +
    + +
  1. Type "fluid&" + +
  2. Pick "New/code/function" off the menu. + +
  3. Hit Tab, Delete to delete the function name and hit OK. This is +how you get fluid to output a "main()" function. The text "main()" +with a triangle next to it should appear highlighted in the main +window. + +
  4. Pick "New/group/Window" off the menu. + +
  5. Move the new window and resize it to the size you want. + +
  6. Pick "New/buttons/Button" off the menu. + +
  7. Hit the "OK" button to dismiss the panel that appears. + +
  8. In the window you created, try moving the button by dragging it +around. Notice that it "snaps" to fixed locations. If you want to +drag it smoothly, hold down Alt. You can also change the size of the +steps with Edit/Preferences. + +
  9. Try resizing the widget by dragging the edges and corners. + +
  10. Type Alt+c to copy the widget. + +
  11. Type Alt+v to paste a copy into the window. + +
  12. Type Alt+v several times. + +
  13. Drag the widgets and resize them so they don't overlap. Notice +that you have to click a widget to pick it first, then drag it. + +
  14. Try selecting several widgets by dragging a box around them. Check +what happens when you move them, or when you drag an edge to resize +them. + +
  15. You can also use Shift+click to toggle widgets on and off. + +
  16. You can also select widgets by clicking on them in the list in the +main window, try that. + +
  17. Double-click one of the widgets. You will get a control panel. + +
  18. Try changing the "label". Try changing other items near the top of +the panel. To see any changes to the box type clearer, type "Alt+o" +to make the red overlay disappear. + +
  19. Type "#include <stdlib.h>" into the first line of "extra code:". + +
  20. Type "exit(0);" into the "callback:". + +
  21. Hit OK. + +
  22. Pick "File/Save As" off the menu. + +
  23. Type "test.fl" into the file chooser and hit return. + +
  24. Pick "File/Write Code" off the menu, hit OK on the confirmation panel. + +
  25. Go back to your terminal window. Type "more test.C" and "more +test.H" and you can see the code it made. Also try "more test.fl" to +see how fluid saves it's data. + +
  26. Type "make test" (you may have to add libaries to your Makefile). + +
  27. Type "./test" to run your program. + +
  28. Try the buttons. The one you put the code into will exit the +program. + +
  29. Type "Alt+Q" to exit fluid. + +
  30. Ok, now try to make a real program. + +
+ +
+

Running fluid

+ +

Type + +

+	fluid <name>.fl &
+
+ +

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: + +

+	 -display host:n.n
+	 -geometry WxH+X+Y
+	 -title windowtitle
+	 -name classname
+	 -iconic
+	 -fg color
+	 -bg color
+	 -bg2 color
+
+ +

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. + + +

Compiling .fl files

+ +

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 + +

+	fluid -c <name>.fl
+
+ +

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: + +

+my_panels.H my_panels.C : my_panels.fl
+	fluid -c my_panels.fl
+
+ +

Some versions of Make will accept rules like this to allow all .fl +files found to be compiled: + +

+.SUFFIXES : .fl .C .H
+.fl.H :
+	fluid -c $<
+.fl.C :
+	fluid -c $<
+
+ +

Some versions of Make (gnumake) may prefer this syntax: + +

+%.H: %.fl
+        fluid -c $<
+
+%.C: %.fl
+        fluid -c $<
+
+ +
+

The Widget Browser

+ +

+ +

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

The widgets are stored in a hierarchy. You can open and close a +level by clicking the "triangle" at the left of a widget. 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. + + +

Menu Items

+ +

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

File/Open... (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. + +

    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! + +

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. + +

    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. + +

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. + +

    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. + +

Edit/Select All (Alt+a)

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

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

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. + +

    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. + +

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. + +

    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. + +

New/...

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

    When you create the widget you will get the widget's control panel, +described in the next chapter. + +

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": + +

+ +

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. + + +

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. + +

    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. + +

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. + +

    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). + +

Color

    + +

    The color to draw the box with. + +

Color2

    + +

    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. + +

Label

    + +String to print next to or inside the button. + +

    You can put newlines into the string to make multiple lines, the +easiest way is by typing ctrl+j. + +

Label style (pull down menu)

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. + +

    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. + +

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. + +

    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. + +

Extra code

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

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

    All other lines are "code" lines. The 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. + +

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. + +

    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. + +

user_data

    + +

    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>)". + +

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. + +

    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. + +

+ + +

Selecting & Moving Widgets

+ +

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

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

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

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

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

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

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

Type 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: + +

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

+ +

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. + +

Notes for all image types

    + +

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

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

    If you 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. + +

XBM (X bitmap files)

    + +

    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. + +

XPM (X pixmap files)

GIF files

    + +

    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 @@ + + + +

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. + +

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. + +

Problems you will encounter

+ +
    + +

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

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

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

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

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

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

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

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

  • All the following XForms calls are missing:

    + +

  • FL_VERSION, FL_REVISION, fl_library_version() +
  • FL_RETURN_DBLCLICK (use Fl::event_clicks()) +
  • fl_add_signal_callback() +
  • fl_set_form_atactivate() & fl_set_form_atdeactivate() +
  • fl_set_form_property() +
  • fl_set_app_mainform(), fl_get_app_mainform() +
  • fl_set_form_minsize(), fl_set_form_maxsize() +
  • fl_set_form_event_cmask(), fl_get_form_event_cmask() +
  • fl_set_form_dblbuffer(), fl_set_object_dblbuffer() (use an +Fl_Double_Window instead) +
  • fl_adjust_form_size() +
  • fl_register_raw_callback() +
  • fl_set_object_bw(), fl_set_border_width() +
  • fl_set_object_resize(), fl_set_object_gravity() +
  • fl_set_object_shortcutkey() +
  • fl_set_object_automatic() +
  • fl_get_object_bbox() (maybe FLTK should do this) +
  • fl_set_object_prehandler(), fl_set_object_posthandler() +
  • fl_enumerate_fonts() +
  • Most drawing functions +
  • fl_set_coordunit() (FLTK uses pixels all the time) +
  • fl_ringbell() +
  • fl_gettime() +
  • fl_win*() (all these functions) +
  • fl_initialize(argc,argv,x,y,z) ignores last 3 arguments +
  • fl_read_bitmapfile(), fl_read_pixmapfile() +
  • fl_addto_browser_chars() +
  • FL_MENU_BUTTON just draws normally +
  • fl_set_bitmapbutton_file(), fl_set_pixmapbutton_file() +
  • FL_CANVAS objects +
  • FL_DIGITAL_CLOCK (comes out analog) +
  • fl_create_bitmap_cursor(), fl_set_cursor_color() +
  • fl_set_dial_angles() +
  • fl_show_oneliner() +
  • fl_set_choice_shortcut(a,b,c) +
  • command log +
  • Only some of file selector is emulated +
  • FL_DATE_INPUT +
  • fl_pup*() (all these functions) +
  • textbox object (should be easy but I had no sample programs) +
  • xyplot object +
+ +

Additional notes for porting old Forms programs

+ +

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: + +

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

+ +

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. + +

You must use OpenGL to draw everything

+ +

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. + +

You cannot make Forms subclasses

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

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

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

You cannot use <device.h>

+ +If you have written your own "free" widgets you will probably get a +lot of errors about "getvaluator". You should substitute: + + +
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... + +

Font numbers are different

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

B - Function Reference

+ +When we created the window and box widgets + and widgets inside the window. + Here a single +Fl_Box is created. The arguments to the +constructor are a value for the box() +property (most constructors do not have this), values for x(), y(), w(), h() to define the position +and size of the box, and a value for label() to define the text printed in the +box. + +

All the widgets have several attributes and there is a method for +setting and getting the current value of each of them. +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. + +

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. + +

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! + +

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. + + + + + + +This chapter demonstrates the basics of FLTK programming with examples. + +

Compiling a FLTK Program

+ +

Include Files

+ +

Library Files

+ +

A "Hello, World" Program

+ +

Creating the Window

+ +

The Main Loop

+ + + +FLTK example: ask.C +

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
+  }
+}
+
+ +

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] +
[back to contents] +FLTK example: button.C +

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();
+}
+
+ +

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] +
[back to contents] +FLTK methods + +

#include <FL/Fl.H>

+ +

You will have to include at least this header file in your main +code so that you can call the methods described here. + +

Initialization

+ +

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. + + +

int Fl::visual(int)

int Fl::gl_visual(int)

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. + +

    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). + +

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. + +

    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. + +

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)

    + +

    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 first word that does not start with '-'. + +
    • The word '-' (used by many programs to name stdin as a file) + +
    • The first word after '--' + +
    • The first unrecognized switch (return value is 0). + +
    • argc + +
    + +

    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. + +

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)

+ +

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()

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. + +

    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. + +

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. + +

    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): + +

      +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;
      +}
      +
    + +

    This returns non-zero if any windows are displayed, and 0 if no +windows are displayed. + +

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);

void Fl::set_idle(void (*cb)());

void Fl::flush()

int Fl::damage()

Fl_Widget *Fl::readqueue();

+

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. + +

    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. + +

+ +

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(). + +

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: + +

    +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. + +

    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). + +

(back to contents) +FLTK example: hello.C +

hello.C

+ + +

[Next example] +
[back to contents] + + + diff --git a/documentation/glut.html b/documentation/glut.html new file mode 100644 index 000000000..3cbfdb50e --- /dev/null +++ b/documentation/glut.html @@ -0,0 +1,145 @@ + + + +

D - GLUT Compatibility

+ +You should be able to compile existing Glut source code by +including <FL/glut.H> instead of <GL/glut.h>. This can be done by +editing the source, by changing the -I switches to the compiler, or by +providing a symbolic link from GL/glut.h to FL/glut.H. + +

All files calling glut procedures must be compiled with C++. You may +have to alter them slightly to get them to compile without warnings, +and you may have to rename them to get make to use the C++ compiler. +I was unable to get some calls to glu to compile without adding some +casts, apparently due to errors in the glu header files. + +

You must link with -lFl. If you call any glut drawing functions +that fltk does not emulate (glutExtensionsSupported(), glutWire*(), +glutSolid*(), and glutStroke*()), you will also have to link with +-lglut, after -lFl. + +

Most of glut.H is inline functions. You should take a look at it +(and maybe at glut.C in the fltk source) if you are having trouble +porting your Glut program. + +

This has been tested with most of the demo programs that come with +the Glut 3.3 distribution. + +

Known Problems

+ +
    + +
  • The following functions and/or arguments to functions are missing, +and you will have to replace them or comment them out for your code to +compile:
      + +
    • glutLayerGet(GLUT_LAYER_IN_USE) +
    • glutLayerGet(GLUT_HAS_OVERLAY) +
    • glutSetColor(), glutGetColor(), glutCopyColormap() +
    • glutInitDisplayMode(GLUT_STEREO) +
    • glutInitDisplayMode(GLUT_LUMINANCE) +
    • glutPushWindow() +
    • glutWarpPointer() +
    • Spaceball, buttonbox, dials, tablet functions, glutDeviceGet() +
    • glutWindowStatusFunc() +
    • glutGet(GLUT_WINDOW_NUM_CHILDREN) +
    • glutGet(GLUT_SCREEN_WIDTH_MM) +
    • glutGet(GLUT_SCREEN_HEIGHT_MM) +
    • glutGet(GLUT_ELAPSED_TIME) +
    • glutVideoResize() missing. + +
    + +
  • Most of the symbols/enumerations have different values than +Glut uses. This will break code that relies on the actual values. +The only symbols guaranteed to have the same values are true/false +pairs like GLUT_DOWN and GLUT_UP, mouse +buttons GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, +GLUT_RIGHT_BUTTON, and GLUT_KEY_F1 thru +F12. + +
  • The strings passed as menu labels are not copied. + +
  • glutPostRedisplay() does not work if called from +inside a display function. You must use glutIdleFunc() +if you want your display to update continuously. + +
  • glutSwapBuffers() does not work from inside a display +function. This is on purpose, because fltk swaps the buffers for you. + +
  • glutUseLayer() does not work well, and should only be +used to initialize transformations inside a resize callback. You +should redraw overlays by using glutOverlayDisplayFunc(). + +
  • Overlays are cleared before the overlay display function is +called. glutLayerGet(GLUT_OVERLAY_DAMAGED) always +returns true, this fixed some glut overlay programs. You must rewrite +your code so that gl_color() is used to choose colors in an overlay, +or you will get random overlay colors. + +
  • glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR) just +results in a small crosshair. + +
  • The fonts used by glutBitmapCharacter() and +glutBitmapWidth() may be different. + +
  • glutInit(argc,argv) will consume different switches than glut +does. It accepts the switches recognized by Fl_Window::arg(), and will accept any +abbreviation of these switches (such as -d for -display). + +
+ +

Mixing Glut code and Fltk code

+ +You can make your Glut window a child of a Fl_Window with the +following scheme. The biggest trick is that Glut insists on +show()'ing the window at the point it is created, which means the +Fl_Window parent window must already be show()n. + +

Don't call glutInit(). + +

Create your Fl_Window, and any fltk widgets. Leave a blank area in +the window for your glut window. + +

show() the Fl_Window. Perhaps call show(argc,argv). + +

Call window->begin() so the glut window will be automatically added +to it. + +

Use glutInitWindowSize() and glutInitWindowPosition() to set the +location in the parent window to put the glut window. + +

Put your glut code next. It probably does not need many changes. +Call window->end() immediately after the glutCreateWindow()! + +

You can call either glutMainLoop() or Fl::run() or loop calling +Fl::wait() to run the program. + +

class Fl_Glut_Window : public Fl_Gl_Window

+ +Each Glut window is an instance of this class, which is a subclass of +Fl_Gl_Window. You may find it useful to +manipulate instances directly rather than use glut window id's. These +may be created without opening the display, and thus can fit better +into FL's method of creating windows. + +

The current glut window is available in Fl_Glut_Window +*glut_window. + +

new Fl_Glut_Window(...) is the same as +glutCreateWindow() except it does not show() the window +or make the window current. + +

window->make_current() is the same as +glutSetWindow(number). If the window has not had show() +called on it yet, some functions that assumme a gl context will not +work. If you do show() the window, call make_current() again to set +the context. + +

~Fl_Glut_Window() is the same as +glutDestroyWindow(). + + + diff --git a/documentation/hello.C.gif b/documentation/hello.C.gif new file mode 100644 index 000000000..c051dffc8 Binary files /dev/null and b/documentation/hello.C.gif differ diff --git a/documentation/intro.html b/documentation/intro.html new file mode 100644 index 000000000..39b73c225 --- /dev/null +++ b/documentation/intro.html @@ -0,0 +1,260 @@ + + + +

1 - Introduction to FLTK

+ +The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a LGPL'd C++ +graphical user interface toolkit for X (UNIX®), OpenGL®, and +Microsoft® Windows® NT 4.0, 95, or 98. It is currently +maintained by a small group of developers across the world with a +central repository in the US. + +

History of FLTK

+ +It has always been Bill's belief that the GUI API of all modern systems +is much too high level. Toolkits (even FL) are not what should +be provided and documented as part of an operating system. The system +only has to provide arbitrary shaped but featureless windows, a +powerful set of graphics drawing calls, and a simple unalterable +method of delivering events to the owners of the windows. NeXT (if you +ignored NextStep) provided this, but they chose to hide it and tried to +push their own baroque toolkit instead... + +

Many of the ideas in FLTK were developed on a NeXT (but not +using NextStep) in 1987 in a C toolkit Bill called "views". Here he +came up with passing events downward in the tree and having the handle +routine return a value indicating the used the event, and the +table-driven menus. In general he was trying to prove that complex UI +ideas could be entirely implemented in a user space toolkit, with no +knowledge or support by the system. + +

After going to film school for a few years, Bill worked at Sun +Microsystems on the (doomed) NeWS project. Here he found an even +better and cleaner windowing system, and he reimplemented "views" atop +that. NeWS did have an unnecessarily complex method of delivering +events which hurt it. But the designers did admit that perhaps the +user could write just as good of a button as they could, and officially +exposed the lower level interface. + +

With the death of NeWS Bill realized that he would have to live with +X. The biggest problem with X is the "window manager", which means +that the toolkit can no longer control the window borders or drag the +window around. + +

At Digital Domain Bill discovered another toolkit, "Forms". Forms was +similar to his work, but provided many more widgets, since it was used +in many real applications, rather then as theoretical work. He decided +to use Forms, except he integrated my table-driven menus into it. +Several very large programs were created using this version of Forms. + +

The need to switch to OpenGL and GLX, portability, and a desire to +use C++ subclassing required a rewrite of Forms. This produced the +first version of FLTK. The conversion to C++ required so many changes +it made it impossible to recompile any Forms objects. Since it was +incompatable anyway, Bill decided to incorporate as much as possible my +older ideas on simplifying the lower level interface and the event +passing mechanisim. + +

Bill received permission to release it for free on the Internet, +with the GNU general public license. Response from Internet users +indicated that the Linux market dwarfed the SGI and high-speed GL +market, so he rewrote it to use X for all drawing, greatly speeding it +up on these machines. That is the version you have now. + +

Digital Domain has since withdrawn support for FLTK. While Bill is +no longer able to actively develop it, he still contributes to FLTK in +his free time and is a part of the FLTK development team. + +

Features

+ +FLTK was designed to be statically linked. This was done by splitting it +into many small objects and desigining it so that functions that are not +used do not have pointers to them in the parts that are used, and thus +do not get linked in. This allows you to make an easy-to-install program, +or to modify FLTK to the exact requirements of your application, without +worrying about bloat. FLTK works fine as a shared library, though, and +has started being included on Linux distributions. + +

Here are some of the core features unique to FLTK: + +

    +
  • sizeof(Fl_Widget) == 48.
  • + +
  • The "core" (the "hello" program compiled & linked with a static FLTK + library using gcc on a 486 and then stripped) is 39.5K.
  • + +
  • A program including every widget is less than 108K. Does not use + macros, templates, multiple inheritance, or exceptions.
  • + +
  • Written directly atop Xlib (or WIN32) for maximum speed, + and carefully optimized for code size and performance.
  • + +
  • Precise low-level compatability between the X11 and WIN32 + version (only about 10% of the code is different).
  • + +
  • Interactive user interface builder program. Output is + human-readable and editable C++ source code.
  • + +
  • Support for the X11 double buffering extension (emulation + if not available and under Windows.)
  • + +
  • Support for X11 overlay hardware (emulation if none and + under WIN32.)
  • + +
  • Very small & fast portable 2-D drawing library to hide + Xlib and WIN32.
  • + +
  • OpenGL/Mesa drawing area widget.
  • + +
  • Support for OpenGL overlay hardware on both X11 and WIN32. + Emulation if none.
  • + +
  • Text input fields with Emacs key bindings, X cut & + paste, and foreign letter compose!
  • + +
  • Compatability header file for the GLUT library.
  • + +
  • Compatability header file for the XForms library.
  • + +
  • Much too much to list here...
  • +
+ +

Licensing

+ +FLTK comes with complete free source code. FLTK is available under the +terms of the GNU Library General Public +License. Contrary to popular belief, it can be used in commercial +software! (Even Bill Gates could use it.) + +

What Does "FLTK" Mean?

+ +FLTK was originally designed to be compatable with the Forms Library written +for SGI machines. In that library all the functions and structures started +with "fl_". This naming was extended to all new methods and widgets in +the C++ library, and this prefix was taken as the name of the library. +It is almost impossible to search for "FL" on the Internet, due to the +fact that it is also the abbreviation for Florida. After much debating +and searching for a new name for the toolkit, which was already in use +by several people, Bill came up with "FLTK", and even a bogus excuse that +it stands for "The Fast Light Tool Kit". + +

Building and Installing FLTK Under UNIX

+ +In most cases you can just type "make". This will run configure with +the default of no options and then compile everything. + +

FLTK uses GNU autoconf to configure itself for your UNIX platform. The +main things that the configure script will look for are the X11, OpenGL +(or Mesa), and JPEG header and library files. Make sure that they +are in the standard include/library locations. + +

You can run configure yourself to get the exact setup you need. Type +"./configure <options>", where options are: + +

+
--enable-debug
+ +
Enable debugging code & symbols
+ +
--enable-shared
+ +
Enable generation of shared libraries
+ +
--bindir=/path
+ +
Set the location for executables [default = /usr/local/bin]
+ +
--libdir=/path
+ +
Set the location for libraries [default = /usr/local/lib]
+ +
--includedir=/path
+ +
Set the location for include files. [default = /usr/local/include]
+ +
--prefix=/dir
+ +
Set the directory prefix for files [default = /usr/local]
+
+ +When the configure script is done you can just run the "make" command. +This will build the library, FLUID tool, and all of the test programs. + +

To install the library, become root and type "make install". This +will copy the "fluid" executable to "bindir", the header files to "includedir", +and the library files to "libdir". + +

Building FLTK Under Micrsoft Windows

+ +There are two ways to build FLTK under Microsoft Windows. The first +is to use the Visual C++ 5.0 project files under the "visualc" directory. +Just open (or double-click on) the "fltk.dsw" file to get the whole shebang. + +

The second method is to use a GNU-based development tool with the files +in the "makefiles" directory. To build using one of these tools simply +copy the appropriate makeinclude and config files to the main directory +and do a make: + +

    +cp makefiles/makeinclude.<env> makeinclude
    +cp makefiles/config.<env> config.h
    +make
    +
+ +

Building FLTK Under OS/2

+ +The current OS/2 build requires XFree86 for OS/2 to work. A native +Presentation Manager version has not been implemented yet (volunteers are +welcome!). + +

To build the XFree86 version of FLTK for OS/2, copy the appropriate +makeinclude and config files to the main directory and do a make: + +

    +cp makefiles/Makefile.os2x Makefile
    +cp makefiles/makeinclude.os2x makeinclude
    +cp makefiles/config.os2x config.h
    +make
    +
+ +

Internet Resources

+ +FLTK is available on the 'net in a bunch of locations: + +
+
WWW
+ +
http://fltk.easysw.com
+ +
FTP
+ +
ftp://ftp.easysw.com/pub/fltk
+ftp://ftp.funet.fi/mirrors/ftp.easysw.com/pub/fltk
+ftp.northamerica.net/pub/ESP/fltk
+ +
EMail
+ +
fltk@easysw.com [see instructions below]
+ +
fltk-bugs@easysw.com [for reporting bugs]
+
+ +To send a message to the FLTK mailing list ("fltk@easysw.com") you must +first join the list. Non-member submissions are blocked to avoid +problems with SPAM... + +

To join the FLTK mailing list, send a message to "majordomo@easysw.com" +with "subscribe fltk" in the message body. A digest of this list is available +by subscribing to the "fltk-digest" mailing list. + +

Reporting Bugs

+ +To report a bug in FLTK, send an email to "fltk-bugs@easysw.com". Please +include the FLTK version, operating system & version, and compiler +that you are using when describing the bug or problem. + +

For general support and questions, please use the FLTK mailing list +at "fltk@easysw.com". + + + diff --git a/documentation/license.html b/documentation/license.html new file mode 100644 index 000000000..2dbaaa5e0 --- /dev/null +++ b/documentation/license.html @@ -0,0 +1,468 @@ + + + +

G - Software License

+ +

GNU LIBRARY GENERAL PUBLIC LICENSE

+ +

Version 2, June 1991
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed.
+[This is the first released version of the library GPL. It is +numbered 2 because it goes with version 2 of the ordinary GPL.] + +

Preamble

+ +The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + +

This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + +

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + +

For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + +

Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + +

Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + +

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + +

Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + +

The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + +

Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + +

However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + +

The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the libary" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + +

Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + +

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+ +0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + +

A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + +

The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + +

"Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + +

Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +

1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + +

You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +

2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +

+ +a) The modified work must itself be a software library. + +

b) You must cause the files modified to carry prominent notices +stating that you changed the files and the date of any change. + +

c) You must cause the whole of the work to be licensed at no +charge to all third parties under the terms of this License. + +

d) If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses +the facility, other than as an argument passed when the facility +is invoked, then you must make a good faith effort to ensure that, +in the event an application does not supply such function or +table, the facility still operates, and performs whatever part of +its purpose remains meaningful. + +

(For example, a function in a library to compute square roots has +a purpose that is entirely well-defined independent of the +application. Therefore, Subsection 2d requires that any +application-supplied function or table used by this function must +be optional: if the application does not supply it, the square +root function must still compute square roots.) + +

+ +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +

Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +

In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +

3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + +

Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + +

This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +

4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + +

If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +

5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + +

However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + +

When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + +

If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + +

Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +

6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + +

You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +

+ +a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + +

b) + Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + +

c) + If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + +

d) + Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. +

+ +For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + +

It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +

7. + You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +

+ +a) + Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + +

b) + Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. +

+ +8. + You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +

9. + You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +

10. + Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +

11. + If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +

If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +

It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +

This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +

12. + If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +

13. + The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +

Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +

14. + If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +

NO WARRANTY

+ +

15. + BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +

16. + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +

END OF TERMS AND CONDITIONS

+ + + diff --git a/documentation/menu.gif b/documentation/menu.gif new file mode 100644 index 000000000..6ed0f6d32 Binary files /dev/null and b/documentation/menu.gif differ diff --git a/documentation/menu_button.gif b/documentation/menu_button.gif new file mode 100644 index 000000000..5ee9b58ec Binary files /dev/null and b/documentation/menu_button.gif differ diff --git a/documentation/menubar.gif b/documentation/menubar.gif new file mode 100644 index 000000000..955b81a35 Binary files /dev/null and b/documentation/menubar.gif differ diff --git a/documentation/opengl.html b/documentation/opengl.html new file mode 100644 index 000000000..e26895a2c --- /dev/null +++ b/documentation/opengl.html @@ -0,0 +1,486 @@ + + + +

7 - Using OpenGL

+ +This chapter discusses using FLTK for your OpenGL applications. + +

The OpenGL Widget

+ +

Making a Simple OpenGL Wrapper Widget

+ +

A Simple Flight Simulator

+ +

Using FLTK with OpenGL Optimizer

+ +

Using OpenGL Optimizer for the Flight Simulator

+ + + +Using OpenGL in Fltk + +

Using OpenGL in Fltk
#include <FL/gl.h>

+ +The easiest way to make an OpenGL display is to subclass Fl_Gl_Window. +Your subclass should implement a draw() method which uses OpenGL calls +to draw the display. Your main program should call w->redraw() when +the display needs to change, and (somewhat later) fltk will call +draw(). + +

With a bit of care you can also use OpenGL to draw into normal fltk +windows. This is mostly useful because you can access Gourand shading +for drawing your widgets. To do this you use the gl_start() and gl_finish() functions around your +OpenGL code. + +

You must include fltk's <FL/gl.h> header file. It will include +the file <GL/gl.h>, plus it defines some extra drawing functions +provided by fltk, and also gets around a horrid screwup by our friends +in Seattle. + +

Sample code for subclassing Fl_Gl_Window

+ +

+  class MyWindow : public Fl_Gl_Window {
+    void draw();
+    int handle(int);
+  public:
+    MyWindow(int X, int Y, int W, int H, const char* L)
+      : Fl_Gl_Window(X,Y,W,H,L) {}
+  };
+
+  void MyWindow::draw() {
+    if (!valid()) {
+      ... set up projection, viewport, etc ...
+      ... window size is in w() and h().
+      ... valid() is turned on by fltk after draw() returns
+    }
+    ... draw ...
+  }
+
+  int MyWindow::handle(int event) {
+    switch(event) {
+    case FL_PUSH:
+      ... mouse down event ...
+      ... position in Fl::event_x() and Fl::event_y()
+      return 1;
+    case FL_DRAG:
+      ... mouse moved while down event ...
+      return 1;
+    case FL_RELEASE:    
+      ... mouse up event ...
+      return 1;
+    case FL_KEYBOARD:
+      ... keypress, key is in Fl::event_key(), ascii in Fl::event_text()
+      return 1;
+    default:
+      // tell fltk that I don't understand other events
+      return 0;
+    }
+  }
+
+ +

When handle() is called, the glx context is not set up! If your +display changes, you should call redraw() and let draw() do the work. +Don't call any gl functions from inside handle()! + +

This may mean you cannot call some OpenGl stuff like hit detection. +You can fix this by doing: + +

+    case FL_PUSH:
+      make_current(); // make glx context current
+      if (!valid()) {
+        ... set up projection exactly the same as draw ...
+        valid(1); // stop it from doing this next time
+      }
+      ... ok to call NON-DRAWING OpenGL code here, such as hit
+      detection ...
+
+ +

Your main program can now create one of your windows by doing "new +MyWindow(...)". You can also use fluid: + +

    +
  1. Put your class definition in a MyWindow.H file. +
  2. In fluid create a box object, resize & place where you want. +
  3. In the control panel, fill in the "class" field with MyWindow.H. +This will make fluid produce constructors for your new class. +
  4. In the "extra code" put "#include "MyWindow.H"", so that the fluid +output file will compile. +
+ +

You must put glwindow->show() in your main code after calling +show() on the window containing the gl window. + +


+

class Fl_Gl_Window : public Fl_Window

+ +

An Fl_Gl_Window sets things up so OpenGL works, and also keeps an +OpenGL "context" for that window, so that changes to the lighting and +projection may be reused between redraws. Fl_Gl_Window also flushes +the OpenGL streams and swaps buffers after draw() returns. + +

Fl_Gl_Window::draw() is a pure virtual method. You must subclass +Fl_Gl_Window and provide an implementation for draw(). You may also +provide an implementation of draw_overlay() if you want to draw into +the overlay planes. You can avoid reinitializing the viewport and +lights and other things by checking valid() at the start of draw() and +only doing the initialization if it is false. + +

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(). + +

Methods:

+ +

Fl_Gl_Window::Fl_Gl_Window(int W, int H, const char *l=0); +
Fl_Gl_Window::Fl_Gl_Window(int X, int Y, int W, int H, const char +*l=0)

    + +The constructors. Fl_Gl_Window::mode() defaults to +FL_RGB|FL_DOUBLE|FL_DEPTH. + + +

const int Fl_Gl_Window::mode() const; +
int Fl_Gl_Window::mode(int);

int Fl_Gl_Window::mode(const int *);

static int Fl_Gl_Window::can_do(int); +
static int Fl_Gl_Window::can_do(const int *mode); +
int Fl_Gl_Window::can_do() const;

char Fl_Gl_Window::valid() const; +
void Fl_Gl_Window::invalidate(); +
void Fl_Gl_Window::valid(char i);

void Fl_Gl_Window::ortho();

void Fl_Gl_Window::make_current(); +
void Fl_Gl_Window::make_overlay_current(); +
void Fl_Gl_Window::swap_buffers();

void Fl_Gl_Window::hide(); +
Fl_Gl_Window::~Fl_Gl_Window();

Fl_Gl_Window overlay

+ +GL 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. + +

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();

    + +Call this if what is drawn in the overlay needs to change, this will +cause 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() must 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. + +


+
+

Using OpenGL in normal Fltk windows

+ +

You can put OpenGL code into an Fl_Widget::draw() method or into the code +for a boxtype or other places, with some care. + +

Most important, before you show any windows (including those +that don't have OpenGL drawing) you must initialize fltk/X so that it +knows it is going to use OpenGL. You may use any of the symbols +described for Fl_Gl_Window::mode() to describe how +you intend to use OpenGL: + +

    Fl::gl_visual(FL_RGB);

+ +

You can then put OpenGL drawing code anywhere you can draw normally +by surrounding it with: + +

    gl_start();
    +... put your OpenGL code here ...
    +gl_finish();

+ +

gl_start() and gl_finish() set up a GL context with an orthographic +projection so that 0,0 is the lower-left corner of the window and each +pixel is one unit. The current clipping is reproduced with OpenGL +scissor commands. These also synchronize the OpenGL graphics stream +with the drawing done by other X or fltk functions. + +

The same context is reused each time. If your code changes the +projection transformation or anything else you should use glPush/glPop +to put the state back before calling gl_finish(). + +

You may want to use Fl_Window::current()->h() to get +the drawable height so you can flip the coordinate system. + +

Unfortunately there are a bunch of limitations you must adhere to for +maximum portability:

    + +
  • You must choose a default visual with Fl::gl_visual(). + +
  • You cannot pass FL_DOUBLE to Fl::gl_visual(). + +
  • You cannot use Fl_Double_Window (or Fl_Overlay_Window). + +
+ +

Do not call gl_start()/gl_finish() when drawing an +Fl_Gl_Window! + +


+ +

OpenGL drawing functions +
#include <FL/gl_draw.H>

+ +Fltk provides some useful gl drawing functions. They can be freely +mixed with any OpenGL calls, and are defined by including <FL/gl.H> +(which you should include instead of the OpenGL header <GL/gl.h>). + +

void gl_color(Fl_Color);

    + +Set the current color to a fltk color index. For color-index modes +it will use fl_xpixel(c), which is only right if this window uses the +default X colormap. + +

void gl_rect(int x,int y,int w,int h); +
void gl_rectf(int x,int y,int w,int h);

    + +Outline or fill a rectangle with the current color. If ortho() has +been called, then the rectangle will exactly fill the pixel rectangle +passed. + +

void gl_font(Fl_Font fontid, int size);

int gl_height(); +
int gl_descent(); +
float gl_width(const char *); +
float gl_width(const char *, int n); +
float gl_width(uchar);

    + +Return information about the current GL font. + +

void gl_draw(const char *); +
void gl_draw(const char *, int n);

    + +Draw a null-terminated string or an array of n characters in +the current GL font at the current glRasterPos. + +

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

    + +Draw a null-terminated string or an array of n characters in +the current GL font at the given position. + +

void gl_draw(const char *, int x, int y, int w, int h, Fl_Align);

    + +Draw a string formatted into a box, with newlines and tabs expanded, +other control characters changed to ^X, and aligned with the edges or +center. Exactly the same output as fl_draw(). + +
+

(back to contents) +Fltk example: shape.C +

shape.C

+ +

Of course GL is no fun unless you can draw your own graphics. This +is done with a subclass that you create: + +

+ +

+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Hor_Slider.H>
+#include <FL/math.h>
+#include <FL/gl.h>
+#include <FL/Fl_Gl_Window.H>
+
+class shape_window : public Fl_Gl_Window {
+  void draw();
+public:
+  int sides;
+  shape_window(int x,int y,int w,int h,const char *l=0);
+};
+
+shape_window::shape_window(int x,int y,int w,int h,const char *l) :
+Fl_Gl_Window(x,y,w,h,l) {
+  sides = 3;
+}
+
+void shape_window::draw() {
+  // the valid() property may be used to avoid reinitializing your
+  // GL transformation for each redraw:
+  if (!valid()) {
+    valid(1);
+    glLoadIdentity();
+    glViewport(0,0,w(),h());
+  }
+  // draw an amazing graphic:
+  glClear(GL_COLOR_BUFFER_BIT);
+  glColor3f(.5,.6,.7);
+  glBegin(GL_POLYGON);
+  for (int i=0; i<sides; i++) {
+    double ang = i*2*M_PI/sides;
+    glVertex3f(cos(ang),sin(ang),0);
+  }
+  glEnd();
+}
+
+// when you change the data, as in this callback, you must call redraw():
+void sides_cb(Fl_Widget *o, void *p) {
+  shape_window *sw = (shape_window *)p;
+  sw->sides = int(((Fl_Slider *)o)->value());
+  sw->redraw();
+}
+
+int main(int argc, char **argv) {
+
+  Fl_Window window(300, 330);
+
+  shape_window sw(10, 10, 280, 280);
+  window.resizable(&sw);
+
+  Fl_Hor_Slider slider(50, 295, window.w()-60, 30, "Sides:");
+  slider.align(FL_ALIGN_LEFT);
+  slider.callback(sides_cb,&sw);
+  slider.value(sw.sides);
+  slider.step(1);
+  slider.bounds(3,40);
+
+  window.show(argc,argv);
+    
+  return Fl::run();
+}
+
+ +

To do your own drawing, you must subclass Fl_Gl_Window. The virtual method draw() is called when the window should +update. You can only draw into the window inside a draw() method. +You call the method redraw() on the +window to indicate that draw() needs to be called. It won't actually +be called until Fl::wait() is called. + +

The window may be made a child of another window, as it is here. +This is done by add()ing it to a parent before you show() it. If +you don't want to make a child window, be sure to end() the previous +window! The Fl_Gl_Window constructor automatically does end() so +you don't accidentally add children to it. + +

The files <FL/math.h> and <FL/gl.h> are wrappers for the +normal header files. You should use them to port to MSWindows because +the MicroSoft header files have errors or ommisions in them. + +

[back to contents] diff --git a/documentation/osissues.html b/documentation/osissues.html new file mode 100644 index 000000000..f9cd36991 --- /dev/null +++ b/documentation/osissues.html @@ -0,0 +1,455 @@ + + + +

F - Operating System Specific Issues

+ +Fltk X-specific interface +

Fltk X-specific interface

+ +#include <FL/x.H> + +

On Unix/X you can include this file to access fltk's X-specific +functions. Be warned that some of the structures and calls in it are +subject to change in future version of fltk. Try to avoid doing this +so your code is portable. + +


+ +

Handling other X events

+ + +

void Fl::add_handler(int (*f)(int));

extern XEvent* fl_xvent;

extern ulong fl_event_time;

Window fl_xid(const Fl_Window*);

Fl_Window* fl_find(ulong xid);

int fl_handle(const XEvent&);

+


+ + +

Drawing using Xlib

+ +

+extern Display* fl_display;
+extern Window fl_window;
+extern GC fl_gc;
+extern int fl_screen;
+extern XVisualInfo* fl_visual;
+extern Colormap fl_colormap;

unsigned long fl_xpixel(Fl_Color i);

    + +Returns the X pixel number used to draw the given fltk color index. +This is the X pixel that fl_color(i) would use. + +

unsigned long fl_xpixel(uchar r, uchar g, uchar +b);

    + +Return the X pixel number used to draw the given rgb color. This is +the X pixel that fl_color(r,g,b) would use. + +

extern XFontStruct* fl_xfont;

+ +


+ + +

Changing the display, screen, or X visual

+ +

Fltk uses only a single display, screen, X visual, and X colormap. +This greatly simplifies it's internal structure and makes it much +smaller and faster. You can change which it uses by setting global +variables before the first Fl_Window::show() is called. +You may also want to call Fl::visual(int), which is a portable interface +to get a full color and/or double buffered visual. + +

int Fl::display(const char *)

    + +Set which X display to use. This actually does +setenv("DISPLAY", x) so that child programs will +display on the same screen if called with exec(). This must be done +before the display is opened. This call is provided on MSWindows, but +it just sets the environment variable and has no other effect. + +

extern Display* fl_display;

    + +The open X display. This is needed as an argument to most Xlib calls. +Don't attempt to change it! This is zero before the display is opened. + +

void fl_open_display();

    + +Open the display. Does nothing if it is already open. This will make +sure fl_display is non-zero. You should call this if you +wish to do X calls and there is a chance that your code will be called +before the first show() of a window. + +

    This may call Fl::abort() if there is an error opening the display. + +

void fl_close_display();

    + +This closes the X connection. You do not need to call this to +exit, and in fact it is faster to not do so! It may be useful to call +this if you want your program to continue without the X connection. +You cannot open the display again, and probably cannot call any fltk +functions. + +

extern int fl_screen;

    + +Which screen to use. This is set by fl_open_display() to the default +screen. You can change it by setting this to a different value +immediately afterwards. It can also be set by changing the last +number in the Fl::display() string: host:0,#. + +

extern XVisualInfo* fl_visual;
+extern Colormap fl_colormap;

    + +

    The visual and colormap that fltk will use for all windows. These +are set by fl_open_display() to the default visual and colormap. You +can change them before calling show() on the first window. Typical +code for changing the default visual: + +

      +Fl::args(argc, argv); // do this first so $DISPLAY is set
      +fl_open_display();
      +fl_visual = find_a_good_visual(fl_display, fl_screen);
      +if (!fl_visual) Fl::abort("No good visual");
      +fl_colormap = make_a_colormap(fl_display, fl_visual->visual, fl_visual->depth);
      +// it is now ok to show() windows:
      +window->show(argc, argv);
      +
    + +
+ +


+ +

Using a subclass of Fl_Window for special X stuff

+ +Fltk can manage an X window on a different screen, visual and/or +colormap, you just can't use fltk's drawing routines to draw into it. +But you can write your own draw() method that uses Xlib calls only. + +

Fltk can also manage xid's provided by other libraries or programs, +and call those libraries when the window needs to be redrawn. + +

To do this, you need to make a subclass of Fl_Window and override some of these virtual +functions: + +

virtual void Fl_Window::show()

    + +

    If the window is already shown() this must cause it to be raised, +this can usually be done by calling Fl_Window::show(). If not shown() +your implementation must call either Fl_X::set_xid() or +Fl_X::make_xid(): + +

    Fl_X* Fl_X::set_xid(Fl_Window*, Window xid);

      + +Allocate a hidden structure called an Fl_X, put the xid into it, and +set a pointer to it from the Fl_Window. This causes +Fl_Window::shown() to return true. + +

    void Fl_X::make_xid(Fl_Window*, XVisualInfo* = +fl_visual, Colormap = fl_colormap);

      + +This static method does the most onerous parts of creating an X window, +including setting the label, resize limitations, etc. It then does +set_xid with this new window and maps the window. + +
    + +

    Example: + +

    +void MyWindow::show() {
    +  if (shown()) {Fl_Window::show(); return;}  // you must do this!
    +  fl_open_display();	// necessary if this is first window
    +  // we only calcualte the necessary visual & colormap once:
    +  static XVisualInfo *visual;
    +  static Colormap colormap;
    +  if (!visual) {
    +    visual = figure_out_visual();
    +    colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
    +			        vis->visual, AllocNone);
    +  }
    +  Fl_X::make_xid(this, visual, colormap);
    +}
    +
    + +

virtual void Fl_Window::flush()

    + +This virtual function is called by Fl::flush() to update the window. +For fltk's own windows it does this by setting the global variables +fl_window and fl_gc and then calling the draw() method. For your own +windows you might just want to put all the drawing code in here. + +

    The X region that is a combination of all damage() calls done so +far is in Fl_X::i(this)->region. If null then +you should redraw the entire window. The undocumented function +fl_clip_region(XRegion) will initialize the fl clip stack +with a region or null for no clipping. You must set region to null +afterwards as fl_clip_region() now owns it and will delete it when +done. + +

    If damage()==2 then only X expose events have +happened. This may be useful if you have an undamaged image (such as +a backing buffer) around. + +

    Here is a sample where an undamaged image is kept somewhere: + +

    +void MyWindow::flush() {
    +  fl_clip_region(Fl_X::i(this)->region);
    +  Fl_X::i(this)->region = 0;
    +  if (damage() != 2) {... draw things into backing store ...}
    +  ... copy backing store to window ...
    +}
    +
    + +

virtual void Fl_Window::hide()

    + +Destroy the window server copy of the window. Usually you will +destroy contexts, pixmaps, or other resources used by the window, and +then call Fl_Window::hide() to get rid of the main window identified +by xid(). If you override this, you must also override the destructor +as shown: + +
    +void MyWindow::hide() {
    +  if (mypixmap) {
    +    XFreePixmap(fl_display,mypixmap);
    +    mypixmap = 0;
    +  }
    +  Fl_Window::hide(); // you must call this
    +}
    +
    + +

virtual void Fl_Window::~Fl_Window()

    + +Because of the way C++ works, if you override hide() you must +override the destructor as well (otherwise only the base class hide() +is called): + +
    +MyWindow::~MyWindow() {
    +  hide();
    +}
    +
    + +
+ +

(back to contents) +Fltk MSWindows-specific interface +

#include <FL/x.H>
+Fltk MSWindows-specific interface

+ +The <FL/x.H> header file defines the interface to fltk's +MSWindows-specific functions. Be warned that some of the structures +and calls in it are subject to change in future version of fltk. Try +to avoid doing this so your code is portable. + +


+ +

Handling other MSWindows messages

+ +

A single WNDCLASSEX called "FLTK" is created. All +Fl_Windows are of this class. This window class is created the first +time Fl_Window::show() is called. + +

You can probably combine fltk with other libraries that make their +own MSWindows window classes. The easiest way is to call Fl::wait(), it +will call DispatchMessage for all messages to the other windows. If +necessary you can let the other library take over (as long as it calls +DispatchMessage()), but you will have to arrange for the function +Fl::flush() to be called regularily (otherwise widgets will not +update), and timeouts and the idle function will not work. + + +

extern MSG fl_msg;

void Fl::add_handler(int (*f)(int));

HWND fl_xid(const Fl_Window*);

Fl_Window* fl_find(HWND xid)

+ +


+ +
+

Drawing things using the MSWindows GDI

+ +

When the virtual function Fl_Widget::draw() is called, fltk has +stashed in some global variables all the silly extra arguments you +need to make a proper GDI call. These are: + +

+extern HINSTANCE fl_display;
+extern HWND fl_window;
+extern HDC fl_gc;
+COLORREF fl_RGB();
+HPEN fl_pen();
+HBRUSH fl_brush();

+


+

How to not get a MSDOS console window

+ +MSWindows has a really stupid mode switch stored in the executables that +controls whether or not to make a console window (hint to Mr Gates: +why not leave it hidden until the program prints something?). + +

To not produce a "console" window when you run your program add the +following secret incantation to the Micro$oft linker: + +

        /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup
+ +

Unfortunately this seems to completely disable stdin/stdout, even +if you run the program from a console. So don't do this until you +have debugged your program! + +


+

Other hints

+ +

I use capital C as the extension for c++ source code, for instace +for Fluid output. Unfortunately there is no way to convince VC++ to +use this except to tell it to compile *everything* using C++ by +putting the switch "/TP" in the options. This makes it impossible to +combine old C code and fltk code. + +


+

Known bugs

+ +

If program is deactivated, Fl::wait() does not return until it is +activated again, even though many events are delivered to the program. +This can cause idle background processes to stop unexpectedly. This +also happens while the user is dragging or resizing windows or +otherwise holding the mouse down. I was forced to remove most of the +efficiency fltk uses for redrawing in order to get windows to update +while being moved. This is a design error in MSWindows and probably +impossible to get around. + +

Fl_Gl_Window::can_do_overlay() returns true until the first time it +attempts to draw an overlay, and then correctly returns whether or not +there is overlay hardware. + +

Cut text contains ^J rather than ^M^J to break lines. This is a +feature, not a bug. + +

I can't seem to get SetCapture (used by Fl::grab()) to work, and I +can't find a way to stop the main window title from turning gray while +menus are popped up. + +

glpuzzle program does not animate unless you resize it first. Unknown why. + +

Fl_Window::fullscreen() not implemented (should take over the screen +without a title bar). Currently does maximize instead. + +

Import .bmp files into fluid. Wonko has the specs. + +

Can't set icon of windows. + + + + diff --git a/documentation/positioner.gif b/documentation/positioner.gif new file mode 100644 index 000000000..ba9d2694d Binary files /dev/null and b/documentation/positioner.gif differ diff --git a/documentation/preface.html b/documentation/preface.html new file mode 100644 index 000000000..5be3d0f99 --- /dev/null +++ b/documentation/preface.html @@ -0,0 +1,75 @@ + + + + + + FLTK 1.0 Programming Manual + + + +

Preface

+ +This manual describes the Fast Light Tool Kit ("FLTK") version 1.0, a C++ Graphical User Interface ("GUI") toolkit for UNIX and Microsoft Windows. Each of the chapters +in this manual is designed as a tutorial for using FLTK, while the appendices provide +a convenient reference for all FLTK widgets, functions, and operating system +interfaces. + +

Organization

+ +This manual is organized into the following chapters and appendices: + + + +

Conventions

+ +The following typeface conventions are used in this manual: + +
    + +
  • Function and constant names are shown in bold courier type + +
  • Code samples and commands are shown in regular courier type + +
+ +

Abbreviations

+ +The following abbreviations are used in this manual: + +
+
X11
+
The X Window System version 11.
+ +
Xlib
+
The X Window System interface library.
+ +
WIN32
+
The Microsoft Windows 32-bit Application Programmer's Interface.
+
+ +

Copyrights and Trademarks

+ +FLTK is Copyright 1998 by Bill Spitzak and others. Use and distribution of FLTK is +governed by the GNU Library General Public License, located in +Appendix D. + +

UNIX is a registered trademark of the X Open Group, Inc. Microsoft and Windows are +registered trademarks of Microsoft Corporation. OpenGL is a registered trademark +of Silicon Graphics, Inc. + + + diff --git a/documentation/resizebox1.gif b/documentation/resizebox1.gif new file mode 100644 index 000000000..c5e8c300b Binary files /dev/null and b/documentation/resizebox1.gif differ diff --git a/documentation/resizebox2.gif b/documentation/resizebox2.gif new file mode 100644 index 000000000..2083afd0d Binary files /dev/null and b/documentation/resizebox2.gif differ diff --git a/documentation/round_clock.gif b/documentation/round_clock.gif new file mode 100644 index 000000000..982f084b6 Binary files /dev/null and b/documentation/round_clock.gif differ diff --git a/documentation/scrollbar.gif b/documentation/scrollbar.gif new file mode 100644 index 000000000..3b548a4d0 Binary files /dev/null and b/documentation/scrollbar.gif differ diff --git a/documentation/shape.C.gif b/documentation/shape.C.gif new file mode 100644 index 000000000..ebed8a6f2 Binary files /dev/null and b/documentation/shape.C.gif differ diff --git a/documentation/slider.gif b/documentation/slider.gif new file mode 100644 index 000000000..af3e09863 Binary files /dev/null and b/documentation/slider.gif differ diff --git a/documentation/subclassing.html b/documentation/subclassing.html new file mode 100644 index 000000000..414cca67b --- /dev/null +++ b/documentation/subclassing.html @@ -0,0 +1,519 @@ + + + +

5 - Adding and Extending Widgets

+ +This chapter describes how to add your own widgets or extend existing widgets in FLTK. + +

Subclassing

+ +

Adding Syntax Highlighting to the Fl_Input Widget

+ +

Drawing Functions

+ +

Lines, Rectangles, and Curves, Oh, My!

+ +

Colors

+ +

Fonts

+ +

Images

+ +

Writing a Table Widget

+ +

Methods

+ +

Cut and Paste Support

+ + + +Cut & paste +

Cut & paste

+ +Fltk provides routines to cut and paste ASCII text (in the future this +may be UTF-8) between applications. It may be possible to cut/paste +non-ascii data under X by using Fl::add_handler(). + +

void Fl::paste(Fl_Widget *receiver)

    + +

    Set things up so the receiver widget will be called with an FL_PASTE event some time in the future. +The reciever should be prepared to be called directly by this, +or for it to happen later, or possibly not at all. This +allows the window system to take as long as necessary to retrieve the +paste buffer (or even to screw up completely) without complex and +error-prone synchronization code in fltk. + +

void Fl::selection(Fl_Widget *owner, const char *stuff, int len); +

    + +

    Change the current selection. The block of text is copied to an +internal buffer by Fltk (be careful if doing this in response to an +FL_PASTE as this may be the same buffer returned by +event_text()). The selection_owner is set to the passed owner +(possibly sending FL_SELECTIONCLEAR to the previous owner). + +

const char* Fl::selection(); +
int Fl::selection_length();

    + +You can look at the buffer containing the current selection. Contents +of this buffer are undefined if this program does not own the X +selection. + +

Fl_Widget *Fl::selection_owner() const; +
void Fl::selection_owner(Fl_Widget *);

    + +

    The single-argument selection_owner(x) call can be used to move the +selection to another widget or to set the owner to NULL, without +changing the actual text of the selection. FL_SELECTIONCLEAR is sent +to the old selection owner, if any. + +

+ +

Copying the buffer every time the selection is changed is +obviously wasteful, especially for large selections. I expect an +interface will be added in a future version to allow the selection to +be made by a callback function. The current interface will be +emulated on top of this. + +Making a subclass of Fl_Widget +

Making a subclass of Fl_Widget

+ +

Your subclasses can directly descend from Fl_Widget or any +subclass of Fl_Widget. Fl_Widget has only four virtual methods, and +overriding some or all of these may be necessary. + +

Parts of this document: + +

+ + +

Constructing your Fl_Widget

+ +I recommend your constructor be of this form: + +

+    Class(int x, int y, int w, int h, const char* label = 0);
+
+ +

This will allow the class name to be typed into fluid and it will produce the correct call. + +

The constructor must call the constructor for the base class and +pass the same arguments. Fl_Widget's protected constructor sets x(), +y(), w(), h(), and label() to the passed values and initializes the +other instance variables to: + +

+    type(0);
+    box(FL_NO_BOX);
+    color(FL_GRAY);
+    selection_color(FL_GRAY);
+    labeltype(FL_NORMAL_LABEL);
+    labelstyle(FL_NORMAL_STYLE);
+    labelsize(FL_NORMAL_SIZE);
+    labelcolor(FL_BLACK);
+    align(FL_ALIGN_CENTER);
+    callback(default_callback,0);
+    flags(ACTIVE|VISIBLE);
+
+ + +

Protected methods of Fl_Widget

+ +

These methods are provided for subclasses to use. + +

uchar Fl_Widget::type() const; +
void Fl_Widget::type(uchar); +

void Fl_Widget::set_flag(SHORTCUT_LABEL);

int Fl_Widget::test_shortcut() const;
+static int Fl_Widget::test_shortcut(const char *);

void Fl_Widget::x(short); +
void Fl_Widget::y(short); +
void Fl_Widget::w(short); +
void Fl_Widget::h(short);

void Fl_Widget::damage(uchar mask);

void Fl_Widget::damage(uchar mask,int x,int y,int w,int +h);

void Fl_Widget::clear_damage(uchar value = 0);

uchar Fl_Widget::damage()

void Fl_Widget::set_visible(); +
void Fl_Widget::clear_visible();

void Fl_Widget::draw_box() const ;

void Fl_Widget::draw_box(Fl_Boxtype b,ulong c) const +;

void Fl_Widget::draw_label() const ;

void Fl_Widget::draw_label(int x,int y,int w,int h) const +;

void Fl_Widget::draw_label(int x,int y,int w,int +h,Fl_Align align) const ;

+ +

virtual int Fl_Widget::handle()

+ +The virtual method int Fl_Widget::handle(int +event) is called to handle each event passed to the widget. +It can:
+ +

Events are identified the small integer argument. Other +information about the most recent event is stored in static locations +and aquired by calling Fl::event_*(). +This other information remains valid until another event is read from +the X server. + +

Here is a sample Fl_Widget::handle(), for a widget that acts as a +pushbutton and also accepts the keystroke 'x' to cause the callback: + +

    int Fl_Pushbutton::handle(int event) {
    +  switch(event) {
    +    case FL_PUSH:
    +      highlight = 1; redraw();
    +      return 1;
    +    case FL_DRAG:
    +      {int t = Fl::event_inside(this);
    +      if (t != highlight) {highlight = t; redraw();}}
    +      return 1;
    +    case FL_RELEASE:
    +      if (highlight) {
    +	highlight = 0; redraw();
    +        do_callback();
    +	// never do anything after a callback, so that the callback
    +	// may delete the widget!
    +      }
    +      return 1;
    +    case FL_SHORTCUT:
    +      if (Fl::event_key() == 'x') {do_callback(); return 1;}
    +      return 0;
    +    default:
    +      return 0;
    +    }
    +  }
    +}
    +
+ +

You must return non-zero if your handle() method used the event. +If you return zero it indicates to the parent that it can try sending +another widget the event. + +

It looks like it is best to make the handle() method public. + + +

virtual void Fl_Widget::draw()

+ +

The virtual method Fl_Widget::draw() is called when fltk wants you +to redraw your widget. It will be called if and only if damage() is +non-zero, and damage() will be cleared to zero after it returns. +draw() should be declared protected, so that subclasses may call it +but it can't be called from non-drawing code. + +

damage() contains the bitwise-or of all the damage(n) calls to this +widget since it was last drawn. This can be used for minimal update, +by only redrawing the parts whose bits are set. Fltk will turn +all the bits on if it thinks the entire widget must be redrawn +(for instance due to an expose event). It is easiest to program to +handle this by pretending a bit (usually damage()&128) draw the +non-minimal-update parts of your widget (such as the box()). + +

Expose events (and the above damage(b,x,y,w,h)) will cause draw() +to be called with fltk's clipping +turned on. You can greatly speed up redrawing in some cases by +testing fl_clipped and fl_current_clip +and skipping invisible parts. + +

The functions you can use to draw are described in <FL/fl_draw.H> or any of the protected +Fl_Widget::draw_* methods described above. + + +

virtual void Fl_Widget::resize(int,int,int,int);

+ +This is called when the widget is being resized or moved. The +arguments are the new position, width, and height. x(), y(), w(), and +h() still return the old size. You must call resize() on your +base class with the same arguments to get the widget size to actually +change. + +

This should not call redraw(), at least if only the x() and +y() change. This is because group objects like Fl_Scroll may have a more efficient way of +drawing the new position. + +

It may be useful to refer to the size the widget was constructed +at, these are stored in Fl_Widget::ix(), iy(), iw(), and ih(). + +

Resize should be declared public. + + +

virtual Fl_Widget::~Fl_Widget();

+ +We all know why the destructor must be virtual don't we? Don't forget +to make it public. + + +

Making a Composite/Group Widget

+ +A "composite" widget contains one or more "child" widgets. To do this +you should subclass
Fl_Group (it is +possible to make a composite object that is not a subclass of +Fl_Group, but this is very difficult). + +

Instances of the child widgets may be included in the parent: + +

    class MyClass : public Fl_Group {
    +  Fl_Button the_button;
    +  Fl_Slider the_slider;
    +  ...
    +};
    +
+ +

The constructor has to initialize these instances. They are +automatically add()ed to the group, since the Fl_Group constructor +does begin(). Don't forget to call end(): + +

    MyClass::MyClass(int x,int y,int w,int h) :
    +  Fl_Group(x,y,w,h),
    +  the_button(x+5,y+5,100,20),
    +  the_slider(x,y+50,w,20)
    +{
    +  ...(you could add dynamically created child widgets here)...
    +  end(); // don't forget to do this!
    +}
    +
+ +

The child widgets need callbacks. These will be called with a +pointer to the children, but the widget itself may be found in the +parent() pointer of the child. Usually these callbacks can be static +private methods, with a matching private method: + +

    void MyClass::slider_cb(Fl_Widget* v, void *) { // static method
    +  ((MyClass*)(v->parent())->slider_cb();
    +}
    +void MyClass::slider_cb() { // normal method
    +  use(the_slider->value());
    +}
    +
+ +

If you make the handle() method, you can quickly pass all the +events to the children (notice that you don't need to override +handle() if your composite widget does nothing other than pass events +to the children): + +

    int MyClass::handle(int event) {
    +  if (Fl_Group::handle(event)) return 1;
    +  ... handle events that children don't want ...
    +}
    +
+ +

If you override draw() you need to draw all the children. If +redraw() or damage() is called on a child, damage(1) is done to the +group. Thus the 1 bit of damage() can be used to indicate that a +child needs to be drawn. It is fastest if you avoid drawing anything +else in this case: + +

    int MyClass::draw() {
    +  Fl_Widget*const* a = array();
    +  if (damage()==1) { // only redraw some children
    +    for (int i=children(); i--; a++) update_child(**a);
    +  } else { // total redraw
    +    ... draw background graphics ...
    +    // now draw all the children atop the background:
    +    for (int i=children_; i--; a++) {
    +      draw_child(**a);
    +      draw_outside_label(**a); // you may not want to do this
    +    }
    +  }
    +}
    +
+ +

Fl_Group provides some protected methods to make drawing easier: + +

void Fl_Group::draw_outside_label(Fl_Widget&) const;

    + +Draw the labels that are not drawn by draw_label(). If you want more control over the +label positions you might want to call child->draw_label(x,y,w,h,a). + +

void Fl_Group::draw_child(Fl_Widget&);

    + +This will force the child's damage() bits all to one and call draw() +on it, then clear the damage(). You should call this on all children +if a total redraw of your widget is requested, or if you draw +something (like a background box) that damages the child. Nothing is +done if the child is not visible() or if it is clipped. + +

void Fl_Group::update_child(Fl_Widget&);

    + +Draws the child only if it's damage() is non-zero. You should call +this on all the children if your own damage is equal to 1. Nothing is +done if the child is not visible() or if it is clipped. + +
+ + +

Making a subclass of Fl_Window

+ +

You may want your widget to be a subclass of Fl_Window. This can +be useful if your widget wants to occupy an entire window, and can +also be used to take advantage of system-provided clipping, or to work +with a library that expects a system window id to indicate where to +draw. + +

Subclassing Fl_Window is almost exactly like subclassing Fl_Widget, +in fact you can easily switch a subclass back and forth. Watch out +for the following differences: + +

    + +
  1. Fl_Window is a subclass of Fl_Group so make sure your constructor +calls end() (unless you actually want children added to your +window). + +
  2. When handling events and drawing, the lower-left corner is at 0,0, +not x(),y() as in other Fl_Widgets. For instance, to draw a box +around the widget, call draw_box(0,0,w(),h()), rather than +draw_box(x(),y(),w(),h()). + + +
+ +

You may also want to subclass Fl_Window in order to get access to +different X visuals or to change other X attributes of the windows, +See here for details. + +

(back to contents) diff --git a/documentation/symbols.gif b/documentation/symbols.gif new file mode 100644 index 000000000..d4c1b8560 Binary files /dev/null and b/documentation/symbols.gif differ diff --git a/documentation/tabs.gif b/documentation/tabs.gif new file mode 100644 index 000000000..c1f151644 Binary files /dev/null and b/documentation/tabs.gif differ diff --git a/documentation/text.gif b/documentation/text.gif new file mode 100644 index 000000000..c96bcbf97 Binary files /dev/null and b/documentation/text.gif differ diff --git a/documentation/valuators.gif b/documentation/valuators.gif new file mode 100644 index 000000000..7dd1fbe75 Binary files /dev/null and b/documentation/valuators.gif differ diff --git a/documentation/value_slider.gif b/documentation/value_slider.gif new file mode 100644 index 000000000..668bd79fc Binary files /dev/null and b/documentation/value_slider.gif differ diff --git a/documentation/widgets.html b/documentation/widgets.html new file mode 100644 index 000000000..c85824acd --- /dev/null +++ b/documentation/widgets.html @@ -0,0 +1,6 @@ + + +

A - Widget Reference

+ + + -- cgit v1.2.3