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/functions.html | 768 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 768 insertions(+) create mode 100644 documentation/functions.html (limited to 'documentation/functions.html') 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] + + + -- cgit v1.2.3