diff --git a/FL/Fl.H b/FL/Fl.H index a25063253..fe1eea461 100644 --- a/FL/Fl.H +++ b/FL/Fl.H @@ -49,6 +49,10 @@ typedef void (Fl_Box_Draw_F)(int,int,int,int, Fl_Color); typedef void (*Fl_Timeout_Handler)(void*); typedef void (*Fl_Awake_Handler)(void*); +/** + The Fl is the FLTK global (static) containing + state information and global methods for the current application. +*/ class FL_EXPORT Fl { Fl() {}; // no constructor! @@ -77,6 +81,9 @@ public: // should be private! static int compose_state; static int visible_focus_; static int dnd_text_ops_; + /** + If true then flush() will do something. + */ static void damage(int d) {damage_ = d;} static void (*idle)(); @@ -102,8 +109,8 @@ public: // argument parsers: static int arg(int, char**, int&); static int args(int, char**, int&, int (*)(int,char**,int&) = 0); - static const char* const help; static void args(int, char**); + static const char* const help; // things called by initialization: static void display(const char*); @@ -117,8 +124,14 @@ public: // schemes: static int scheme(const char*); + /** See void scheme(const char *name) */ static const char* scheme() {return scheme_;} - static int reload_scheme(); + /** + Called by scheme according to scheme name. + Loads or reloads the current scheme selection. + See void scheme(const char *name) + */ + static int reload_scheme(); // platform dependent static int scrollbar_size(); static void scrollbar_size(int W); @@ -136,49 +149,300 @@ public: static void add_check(Fl_Timeout_Handler, void* = 0); static int has_check(Fl_Timeout_Handler, void* = 0); static void remove_check(Fl_Timeout_Handler, void* = 0); - static void add_fd(int fd, int when, void (*cb)(int,void*),void* =0); - static void add_fd(int fd, void (*cb)(int, void*), void* = 0); - static void remove_fd(int, int when); - static void remove_fd(int); + /** + Add file descriptor fd to listen to. When the fd + becomes ready for reading Fl::wait() will call the callback + and then return. The callback is + passed the fd and the arbitrary void* argument.

+ +

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

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

Under UNIX any file descriptor can be monitored (files, + devices, pipes, sockets, etc.) Due to limitations in Microsoft Windows, + WIN32 applications can only monitor sockets. + */ + static void add_fd(int fd, int when, void (*cb)(int,void*),void* =0); // platform dependent + /** See void add_fd(int fd, int when, void (*cb)(int,void*),void* =0) */ + static void add_fd(int fd, void (*cb)(int, void*), void* = 0); // platform dependent + /** Removes a file descriptor handler. */ + static void remove_fd(int, int when); // platform dependent + /** Removes a file descriptor handler. */ + static void remove_fd(int); // platform dependent + static void add_idle(void (*cb)(void*), void* = 0); static int has_idle(void (*cb)(void*), void* = 0); static void remove_idle(void (*cb)(void*), void* = 0); + /** If true then flush() will do something. */ static int damage() {return damage_;} static void redraw(); static void flush(); + /** \fn void (*warning)(const char*, ...) + FLTK calls this to print a warning message. You can + override the behavior by setting the function pointer to your + own routine. +

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, for example. + */ static void (*warning)(const char*, ...); + /** + FLTK calls this to print a normal error message. You can + override the behavior by setting the function pointer to your + own routine. +

Fl::error means there is a recoverable error such as + the inability to read an image file. The default implementation + prints the error message to stderr and returns. + */ static void (*error)(const char*, ...); + /** + FLTK calls this to print a fatal error message. You can + override the behavior by setting the function pointer to your + own routine. +

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. The default implementation prints the error message to + stderr and exits with status 1. + */ static void (*fatal)(const char*, ...); static Fl_Window* first_window(); static void first_window(Fl_Window*); static Fl_Window* next_window(const Fl_Window*); + /** + Returns the top-most modal() window currently shown. + This is the most recently + shown() window with + modal() true, or NULL if there are no modal() + windows shown(). + The modal() window has its handle() method called + for all events, and no other windows will have handle() + called (grab() overrides this). + */ static Fl_Window* modal() {return modal_;} + /** + This is used when pop-up menu systems are active. Send all events to + the passed window no matter where the pointer or focus is (including + in other programs). The window does not have to be + shown() , this lets the handle() method of a + "dummy" window override all event handling and allows you to + map and unmap a complex set of windows (under both X and WIN32 + some window must be mapped because the system interface needs a + window id). + +

If grab() is on it will also affect show() of windows by + doing system-specific operations (on X it turns on + override-redirect). These are designed to make menus popup reliably + and faster on the system. + +

To turn off grabbing do Fl::grab(0). + +

Be careful that your program does not enter an infinite loop + while grab() is on. On X this will lock up your screen! + To avoid this potential lockup, all newer operating systems seem to + limit mouse pointer grabbing to the time during which a mouse button + is held down. Some OS's may not support grabbing at all. + */ static Fl_Window* grab() {return grab_;} - static void grab(Fl_Window*); + /** Selects the window to grab. See Fl_Window* Fl::grab() */ + static void grab(Fl_Window*); // platform dependent // event information: + /** + Returns the last event that was processed. This can be used + to determine if a callback is being done in response to a + keypress, mouse click, etc. + */ static int event() {return e_number;} + /** + Returns the mouse position of the event relative to the Fl_Window + it was passed to. + */ static int event_x() {return e_x;} + /** + Returns the mouse position of the event relative to the Fl_Window + it was passed to. + */ static int event_y() {return e_y;} + /** + Returns the mouse position on the screen of the event. To find the + absolute position of an Fl_Window on the screen, use the + difference between event_x_root(),event_y_root() and + event_x(),event_y(). + */ static int event_x_root() {return e_x_root;} + /** + Returns the mouse position on the screen of the event. To find the + absolute position of an Fl_Window on the screen, use the + difference between event_x_root(),event_y_root() and + event_x(),event_y(). + */ static int event_y_root() {return e_y_root;} + /** + Returns the current horizontal mouse scrolling associated with the + FL_MOUSEWHEEL event. Right is positive. + */ static int event_dx() {return e_dx;} + /** + Returns the current vertical mouse scrolling assoaciated with the + FL_MOUSEWHEEL event. Down is positive. + */ static int event_dy() {return e_dy;} - static void get_mouse(int &,int &); + /** + Return where the mouse is on the screen by doing a round-trip query to + the server. You should use Fl::event_x_root() and + Fl::event_y_root() if possible, but this is necessary if you are + not sure if a mouse event has been processed recently (such as to + position your first window). If the display is not open, this will + open it. + */ + static void get_mouse(int &,int &); // platform dependent + /** + The first form returns non-zero if the most recent FL_PUSH or + FL_KEYBOARD was a "double click". Returns N-1 for + N clicks. A double click is counted if the same button is pressed + again while event_is_click() is true. + +

The second form directly sets the number returned by + Fl::event_clicks(). This can be used to set it to zero so that + later code does not think an item was double-clicked. + */ static int event_clicks() {return e_clicks;} + /** + See int event_clicks() + */ static void event_clicks(int i) {e_clicks = i;} + /** + The first form returns non-zero if the mouse has not moved far enough + and not enough time has passed since the last FL_PUSH or + FL_KEYBOARD event for it to be considered a "drag" rather than a + "click". You can test this on FL_DRAG, FL_RELEASE, + and FL_MOVE events. The second form clears the value returned + by Fl::event_is_click(). Useful to prevent the next + click from being counted as a double-click or to make a popup menu + pick an item with a single click. Don't pass non-zero to this. + */ static int event_is_click() {return e_is_click;} - static void event_is_click(int i) {e_is_click = i;} // only 0 works! + /** + Only i=0 works! See int event_is_click(). + */ + static void event_is_click(int i) {e_is_click = i;} + /** + Returns which mouse button caused te current event. This returns garbage if the + most recent event was not a FL_PUSH or FL_RELEASE event. + */ static int event_button() {return e_keysym-FL_Button;} + /** + This is a bitfield of what shift states were on and what mouse buttons + were held down during the most recent event. The second version + returns non-zero if any of the passed bits are turned on. The legal + bits are: + +

+ +

X servers do not agree on shift states, and FL_NUM_LOCK, FL_META, and + FL_SCROLL_LOCK may not work. The values were selected to match the + XFree86 server on Linux. In addition there is a bug in the way X works + so that the shift state is not correctly reported until the first event + after the shift key is pressed or released. + */ static int event_state() {return e_state;} + /** See int event_state() */ static int event_state(int i) {return e_state&i;} + /** + Fl::event_key() returns which key on the keyboard was last + pushed. It returns zero if the last event was not a key press or release. + +

Fl::event_key(int) returns true if the given key was held + down (or pressed) during the last event. This is constant until + the next event is read from the server. + +

Fl::get_key(int) returns true if the given key is held down + now. Under X this requires a round-trip to the server and is + much slower than Fl::event_key(int). + +

Keys are identified by the unshifted values. FLTK defines a + set of symbols that should work on most modern machines for every key + on the keyboard: + +

+ +

On X Fl::get_key(FL_Button+n) does not work. + +

On WIN32 Fl::get_key(FL_KP_Enter) and + Fl::event_key(FL_KP_Enter) do not work. + */ static int event_key() {return e_keysym;} + /** + If NumLock is deactivated, FLTK translates events from the + numeric keypad into the corresponding arrow key events. + event_key() returns the translated key code, whereas + event_original_key() returns the keycode before + NumLock translation. + */ static int event_original_key(){return e_original_keysym;} + /** See int event_key() */ static int event_key(int); - static int get_key(int); + /** + Returns true if the given key is held down now. + Under X this requires a round-trip to the server and is + much slower than Fl::event_key(int). See event_key(). + */ + static int get_key(int); // platform dependent + /** Returns the text associated with the current FL_PASTE or FL_DND_RELEASE event. */ static const char* event_text() {return e_text;} + /** + Returns the length of the text in Fl::event_text(). There + will always be a nul at this position in the text. However there may + be a nul before that if the keystroke translates to a nul character or + you paste a nul character. + */ static int event_length() {return e_length;} static int compose(int &del); + /** + If the user moves the cursor, be sure to call Fl::compose_reset(). + The next call to Fl::compose() will start out in an initial state. In + particular it will not set "del" to non-zero. This call is very fast + so it is ok to call it many times and in many places. + */ static void compose_reset() {compose_state = 0;} static int event_inside(int,int,int,int); static int event_inside(const Fl_Widget*); @@ -186,33 +450,61 @@ public: // event destinations: static int handle(int, Fl_Window*); + /** See Fl_Widget* belowmouse(Fl_Widget*) */ static Fl_Widget* belowmouse() {return belowmouse_;} static void belowmouse(Fl_Widget*); + /** See Fl_Widget* pushed(Fl_Widget*) */ static Fl_Widget* pushed() {return pushed_;} static void pushed(Fl_Widget*); + /** See Fl_Widget* focus(Fl_Widget*) */ static Fl_Widget* focus() {return focus_;} static void focus(Fl_Widget*); static void add_handler(int (*h)(int)); static void remove_handler(int (*h)(int)); // cut/paste: - static void copy(const char* stuff, int len, int clipboard = 0); - static void paste(Fl_Widget &receiver, int clipboard /*=0*/); - static int dnd(); + /** + Copies the data pointed to by stuff to the selection + (0) or primary (1) clipboard. The selection clipboard is used + for middle-mouse pastes and for drag-and-drop selections. The + primary clipboard is used for traditional copy/cut/paste + operations. + */ + static void copy(const char* stuff, int len, int clipboard = 0); // platform dependent + /** + Pastes the data from the selection (0) or primary (1) clipboard into receiver. + The selection clipboard is used for middle-mouse pastes and for + drag-and-drop selections. The primary clipboard is used for + traditional copy/cut/paste operations. + */ + static void paste(Fl_Widget &receiver, int clipboard /*=0*/); // platform dependent + /** + Initiate a Drag And Drop operation. The clipboard should be + filled with relevant data before calling this method. FLTK will + then initiate the system wide drag and drop handling. Dropped data + will be marked as text. + */ + static int dnd(); // platform dependent // These are for back-compatability only: + /** See Fl_Widget* selection_owner(Fl_Widget*) */ static Fl_Widget* selection_owner() {return selection_owner_;} static void selection_owner(Fl_Widget*); static void selection(Fl_Widget &owner, const char*, int len); static void paste(Fl_Widget &receiver); // screen size: - static int x(); - static int y(); - static int w(); - static int h(); + /** Returns the origin of the current screen, where 0 indicates the left side of the screen. */ + static int x(); // platform dependent + /** Returns the origin of the current screen, where 0 indicates the top edge of the screen. */ + static int y(); // platform dependent + /** Returns the width of the screen in pixels. */ + static int w(); // platform dependent + /** Returns the height of the screen in pixels. */ + static int h(); // platform dependent // multi-head support: static int screen_count(); + /** See void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my) */ static void screen_xywh(int &X, int &Y, int &W, int &H) { screen_xywh(X, Y, W, H, e_x_root, e_y_root); } @@ -221,22 +513,75 @@ public: // color map: static void set_color(Fl_Color, uchar, uchar, uchar); - static void set_color(Fl_Color, unsigned); + /** + Sets an entry in the fl_color index table. You can set it to + any 8-bit RGB color. The color is not allocated until fl_color(i) + is used. + */ + static void set_color(Fl_Color, unsigned); // platorm dependent static unsigned get_color(Fl_Color); static void get_color(Fl_Color, uchar&, uchar&, uchar&); - static void free_color(Fl_Color, int overlay = 0); + /** + Frees the specified color from the colormap, if applicable. + If overlay is non-zero then the color is freed from the + overlay colormap. + */ + static void free_color(Fl_Color, int overlay = 0); // platform dependent // fonts: static const char* get_font(Fl_Font); + /** + 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 or FL_ITALIC or + FL_BOLD | FL_ITALIC. 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. + */ static const char* get_font_name(Fl_Font, int* attributes = 0); + /** + 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. + */ static int get_font_sizes(Fl_Font, int*& sizep); static void set_font(Fl_Font, const char*); static void set_font(Fl_Font, Fl_Font); - static Fl_Font set_fonts(const char* = 0); + /** + FLTK will open the display, and add every fonts 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. With WIN32 NULL + selects fonts with ISO8859-1 encoding and non-NULL selects + all fonts. + +

The return value is how many faces are in the table after this is + done. + */ + static Fl_Font set_fonts(const char* = 0); // platform dependent // labeltypes: static void set_labeltype(Fl_Labeltype,Fl_Label_Draw_F*,Fl_Label_Measure_F*); - static void set_labeltype(Fl_Labeltype, Fl_Labeltype from); + /** Sets the functions to call to draw and measure a specific labeltype. */ + static void set_labeltype(Fl_Labeltype, Fl_Labeltype from); // is it defined ? // boxtypes: static Fl_Box_Draw_F *get_boxtype(Fl_Boxtype); @@ -249,35 +594,95 @@ public: static int draw_box_active(); // back compatability: + /** for back compatibility. sets the (*fatal)() callback. */ static void set_abort(void (*f)(const char*,...)) {fatal = f;} static void (*atclose)(Fl_Window*,void*); static void default_atclose(Fl_Window*,void*); + /** for back compatibility. sets the (*atclose)() callback. */ static void set_atclose(void (*f)(Fl_Window*,void*)) {atclose = f;} + /** Returns non-zero if the Shift key is pressed. */ static int event_shift() {return e_state&FL_SHIFT;} + /** Returns non-zero if the Control key is pressed. */ static int event_ctrl() {return e_state&FL_CTRL;} + /** Returns non-zero if the Alt key is pressed. */ static int event_alt() {return e_state&FL_ALT;} + /** + Returns the button state bits; if non-zero, then at least one + button is pressed. This function returns the button state at the + time of the event. During an FL_RELEASE event, the state + of the released button will be 0. To find out, which button + caused an FL_RELEASE event, you can use + Fl::event_button() instead. + */ static int event_buttons() {return e_state&0x7f000000;} + /** + Returns non-zero if button 1 is currently held down. + For more details, see Fl::event_buttons(). + */ static int event_button1() {return e_state&FL_BUTTON1;} + /** + Returns non-zero if button 2 is currently held down. + For more details, see Fl::event_buttons(). + */ static int event_button2() {return e_state&FL_BUTTON2;} + /** + Returns non-zero if button 3 is currently held down. + For more details, see Fl::event_buttons(). + */ static int event_button3() {return e_state&FL_BUTTON3;} + /** + Sets an idle callback. +

This method is obsolete - use the add_idle() method instead. + */ static void set_idle(void (*cb)()) {idle = cb;} + /** See Fl_Window* grab() */ static void grab(Fl_Window&win) {grab(&win);} + /** Releases the current grabbed window, equals grab(0). See Fl_Window* grab() */ static void release() {grab(0);} // Visible focus methods... + /** + Gets or sets the visible keyboard focus on buttons and other + non-text widgets. The default mode is to enable keyboard focus + for all widgets. + */ static void visible_focus(int v) { visible_focus_ = v; } + /** + Gets or sets the visible keyboard focus on buttons and other + non-text widgets. The default mode is to enable keyboard focus + for all widgets. + */ static int visible_focus() { return visible_focus_; } // Drag-n-drop text operation methods... + /** + Gets or sets whether drag and drop text operations are + supported. This specifically affects whether selected text can + be dragged from text fields or dragged within a text field as a + cut/paste shortcut. + */ static void dnd_text_ops(int v) { dnd_text_ops_ = v; } + /** + Gets or sets whether drag and drop text operations are + supported. This specifically affects whether selected text can + be dragged from text fields or dragged within a text field as a + cut/paste shortcut. + */ static int dnd_text_ops() { return dnd_text_ops_; } // Multithreading support: static void lock(); static void unlock(); static void awake(void* message = 0); + /** See void awake(void* message=0). */ static int awake(Fl_Awake_Handler cb, void* message = 0); - static void* thread_message(); + /** + The thread_message() method returns the last message + that was sent from a child by the awake() method. + +

See also: multithreading + */ + static void* thread_message(); // platform dependent // Widget deletion: static void delete_widget(Fl_Widget *w); diff --git a/FL/Fl_Double_Window.H b/FL/Fl_Double_Window.H index bbb68a1e6..5aac830f4 100644 --- a/FL/Fl_Double_Window.H +++ b/FL/Fl_Double_Window.H @@ -30,6 +30,21 @@ #include "Fl_Window.H" +/** + The Fl_Double_Window provides a double-buffered window. + If possible this will use the X double buffering extension (Xdbe). If + not, it will draw the window data into an off-screen pixmap, and then + copy it to the on-screen window. +

It is highly recommended that you put the following code before the + first show() of any window in your program:

+ + This makes sure you can use Xdbe on servers where double buffering + does not exist for every visual. +*/ class FL_EXPORT Fl_Double_Window : public Fl_Window { protected: void flush(int eraseoverlay); @@ -41,8 +56,15 @@ public: void resize(int,int,int,int); void hide(); ~Fl_Double_Window(); + /** + Creates a new Fl_Double_Window widget using the given + position, size, and label (title) string. + */ Fl_Double_Window(int W, int H, const char *l = 0) : Fl_Window(W,H,l), force_doublebuffering_(0) { type(FL_DOUBLE_WINDOW); } + /** + See Fl_Double_Window::Fl_Double_Window(int w, int h, const char *label = 0) + */ Fl_Double_Window(int X, int Y, int W, int H, const char *l = 0) : Fl_Window(X,Y,W,H,l), force_doublebuffering_(0) { type(FL_DOUBLE_WINDOW); } }; diff --git a/FL/Fl_Gl_Window.H b/FL/Fl_Gl_Window.H index d13b832ca..cbe793baf 100644 --- a/FL/Fl_Gl_Window.H +++ b/FL/Fl_Gl_Window.H @@ -35,6 +35,24 @@ typedef void* GLContext; // actually a GLXContext or HGLDC class Fl_Gl_Choice; // structure to hold result of glXChooseVisual +/** + The Fl_Gl_Window widget 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. +

OpenGL hardware typically provides some overlay bit planes, which + are very useful for drawing UI controls atop your 3D graphics. If the + overlay hardware is not provided, FLTK tries to simulate the overlay, + This works pretty well if your graphics are double buffered, but not + very well for single-buffered.

+

Please note that the FLTK drawing and clipping functions + will not work inside an Fl_Gl_Window. All drawing + should be done using OpenGL calls exclusively. + Even though Fl_Gl_Window is derived from Fl_Group, + it is not useful to add other FLTK Widgets as children, + unless those Widgets are modified to draw using OpenGL calls. +*/ class FL_EXPORT Fl_Gl_Window : public Fl_Window { int mode_; @@ -61,16 +79,84 @@ public: void hide(); void resize(int,int,int,int); + /** + Is turned off when FLTK creates a new + context for this window or when the window resizes, and is turned on + after draw() is called. You can use this inside your + draw() method to avoid unneccessarily initializing the OpenGL + context. Just do this: +

+ + You can turn valid() on by calling valid(1). You + should only do this after fixing the transformation inside a draw() + or after make_current(). This is done automatically after + draw() returns. + */ char valid() const {return valid_f_ & 1;} + /** + See char Fl_Gl_Window::valid() const + */ void valid(char v) {if (v) valid_f_ |= 1; else valid_f_ &= 0xfe;} void invalidate(); + /** + Will only be set if the + OpenGL context is created or recreated. It differs from + Fl_Gl_Window::valid() which is also set whenever the context + changes size. + */ char context_valid() const {return valid_f_ & 2;} + /** + See char Fl_Gl_Window::context_valid() const + */ void context_valid(char v) {if (v) valid_f_ |= 2; else valid_f_ &= 0xfd;} static int can_do(int m) {return can_do(m,0);} static int can_do(const int *m) {return can_do(0, m);} + /** + See static int Fl_Gl_Window::can_do(int) + */ int can_do() {return can_do(mode_,alist);} + /** + Set or change the OpenGL capabilites of the window. The value can be + any of the following OR'd together: + + FL_RGB and FL_SINGLE have a value of zero, so they + are "on" unless you give FL_INDEX or FL_DOUBLE. +

If the desired combination cannot be done, FLTK will try turning off + FL_MULTISAMPLE. If this also fails the show() will call + Fl::error() and not show the window.

+

You can change the mode while the window is displayed. This is most + useful for turning double-buffering on and off. Under X this will + cause the old X window to be destroyed and a new one to be created. If + this is a top-level window this will unfortunately also cause the + window to blink, raise to the top, and be de-iconized, and the xid() + will change, possibly breaking other code. It is best to make the GL + window a child of another window if you wish to do this! + */ Fl_Mode mode() const {return (Fl_Mode)mode_;} int mode(int a) {return mode(a,0);} int mode(const int *a) {return mode(0, a);} @@ -81,12 +167,35 @@ public: void swap_buffers(); void ortho(); + /** + 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. + */ int can_do_overlay(); + /** + This method causes draw_overlay to be called at a later time. + Initially the overlay is clear, if you want the window to display + something in the overlay when it first appears, you must call this + immediately after you show() your window. + */ void redraw_overlay(); void hide_overlay(); + /** + The make_overlay_current() method selects the OpenGL context + for the widget's overlay. It is called automatically prior to the + draw_overlay() method being called and can also be used to + implement feedback and/or selection within the handle() + method. + */ void make_overlay_current(); ~Fl_Gl_Window(); + /** + Creates a new Fl_Gl_Window widget using the given position, + size, and label string. The default boxtype is FL_NO_BOX. The + default mode is FL_RGB|FL_DOUBLE|FL_DEPTH. + */ Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();} Fl_Gl_Window(int X, int Y, int W, int H, const char *l=0) : Fl_Window(X,Y,W,H,l) {init();} diff --git a/FL/Fl_Group.H b/FL/Fl_Group.H index c140b3c5c..8e8626dce 100644 --- a/FL/Fl_Group.H +++ b/FL/Fl_Group.H @@ -32,6 +32,14 @@ #include "Fl_Widget.H" #endif +/** + The Fl_Group class is the FLTK container widget. It maintains + an array of child widgets. These children can themselves be any widget + including Fl_Group. The most important subclass of Fl_Group + is Fl_Window, however + groups can also be used to control radio buttons or to enforce resize + behavior. +*/ class FL_EXPORT Fl_Group : public Fl_Widget { Fl_Widget** array_; @@ -50,7 +58,18 @@ class FL_EXPORT Fl_Group : public Fl_Widget { protected: enum { CLIP_CHILDREN = 2048 }; + /** + The first method controls whether the group widget clips the drawing of + child widgets to its bounding box. + +

The second method returns the current clipping mode. + +

The default is to not clip (0) the drawing of child widgets. + */ void clip_children(int c) { if (c) set_flag(CLIP_CHILDREN); else clear_flag(CLIP_CHILDREN); } + /** + See void Fl_Group::clip_children(int c) + */ int clip_children() { return (flags() & CLIP_CHILDREN) != 0; } void draw(); @@ -68,26 +87,75 @@ public: static Fl_Group *current(); static void current(Fl_Group *g); + /** + Returns how many child widgets the group has. + */ int children() const {return children_;} + /** + Returns array()[n]. No range checking is done! + */ Fl_Widget* child(int n) const {return array()[n];} int find(const Fl_Widget*) const; + /** + See int Fl_Group::find(const Fl_Widget *w) const + */ int find(const Fl_Widget& o) const {return find(&o);} Fl_Widget* const* array() const; void resize(int,int,int,int); + /** + Creates a new Fl_Group widget using the given position, size, + and label string. The default boxtype is FL_NO_BOX. + */ Fl_Group(int,int,int,int, const char * = 0); virtual ~Fl_Group(); void add(Fl_Widget&); + /** + See void Fl_Group::add(Fl_Widget &w) + */ void add(Fl_Widget* o) {add(*o);} void insert(Fl_Widget&, int i); + /** + This does insert(w, find(beforethis)). This will append the + widget if beforethis is not in the group. + */ void insert(Fl_Widget& o, Fl_Widget* before) {insert(o,find(before));} void remove(Fl_Widget&); void remove(Fl_Widget* o) {remove(*o);} void clear(); + /** + See void Fl_Group::resizable(Fl_Widget *box) + */ void resizable(Fl_Widget& o) {resizable_ = &o;} + /** + The resizable widget defines the resizing box for the group. When the + group is resized it calculates a new size and position for all of its + children. Widgets that are horizontally or vertically inside the + dimensions of the box are scaled to the new size. Widgets outside the + box are moved. +

In these examples the gray area is the resizable: +

+

\image html resizebox1.gif   + \image html resizebox2.gif

+

The resizable may be set to the group itself (this is the default + value for an Fl_Group, although NULL is the default + for Fl_Window and Fl_Pack), in which case all the + contents are resized. + If the resizable is NULL then all widgets remain a fixed size + and distance from the top-left corner.

+

It is possible to achieve any type of resize behavior by using an + invisible Fl_Box as the resizable and/or by using a hierarchy + of child Fl_Group's. + */ void resizable(Fl_Widget* o) {resizable_ = o;} + /** + See void Fl_Group::resizable(Fl_Widget *box) + */ Fl_Widget* resizable() const {return resizable_;} + /** + Adds a widget to the group and makes it the resizable widget. + */ void add_resizable(Fl_Widget& o) {resizable_ = &o; add(o);} void init_sizes(); diff --git a/FL/Fl_Overlay_Window.H b/FL/Fl_Overlay_Window.H index ff8677ce3..8f4c96b78 100644 --- a/FL/Fl_Overlay_Window.H +++ b/FL/Fl_Overlay_Window.H @@ -30,6 +30,17 @@ #include "Fl_Double_Window.H" +/** + This window provides double buffering and also the ability to draw the + "overlay" which is another picture placed on top of the main image. The + overlay is designed to be a rapidly-changing but simple graphic such as + a mouse selection box. Fl_Overlay_Window uses the overlay + planes provided by your graphics hardware if they are available. +

If no hardware support is found the overlay is simulated by drawing + directly into the on-screen copy of the double-buffered window, and + "erased" by copying the backbuffer over it again. This means the + overlay will blink if you change the image in the window. +*/ class FL_EXPORT Fl_Overlay_Window : public Fl_Double_Window { friend class _Fl_Overlay; virtual void draw_overlay() = 0; @@ -42,9 +53,18 @@ public: ~Fl_Overlay_Window(); int can_do_overlay(); void redraw_overlay(); + /** + Creates a new Fl_Overlay_Window widget using the given + position, size, and label (title) string. If the + positions (x,y) are not given, then the window manager + will choose them. + */ Fl_Overlay_Window(int W, int H, const char *l=0) : Fl_Double_Window(W,H,l) {overlay_ = 0; force_doublebuffering_=1; image(0); } - Fl_Overlay_Window(int X, int Y, int W, int H, const char *l=0) + /** + See Fl_Overlay_Window::Fl_Overlay_Window(int W, int H, const char *l=0) + */ + Fl_Overlay_Window(int X, int Y, int W, int H, const char *l=0) : Fl_Double_Window(X,Y,W,H,l) {overlay_ = 0; force_doublebuffering_=1; image(0); } void show(int a, char **b) {Fl_Double_Window::show(a,b);} }; diff --git a/FL/Fl_Single_Window.H b/FL/Fl_Single_Window.H index b87c54a6f..c865e8b44 100644 --- a/FL/Fl_Single_Window.H +++ b/FL/Fl_Single_Window.H @@ -30,13 +30,28 @@ #include "Fl_Window.H" +/** + This is the same as Fl_Window. However, it is possible that + some implementations will provide double-buffered windows by default. + This subcan be used to force single-buffering. This may be + useful for modifying existing programs that use incremental update, or + for some types of image data, such as a movie flipbook. +*/ class FL_EXPORT Fl_Single_Window : public Fl_Window { public: void show(); void show(int a, char **b) {Fl_Window::show(a,b);} void flush(); + /** + Creates a new Fl_Single_Window widget using the given + size, and label (title) string. + */ Fl_Single_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {} + /** + Creates a new Fl_Single_Window widget using the given + position, size, and label (title) string. + */ Fl_Single_Window(int X, int Y, int W, int H, const char *l=0) : Fl_Window(X,Y,W,H,l) {} int make_current(); diff --git a/FL/Fl_Window.H b/FL/Fl_Window.H index 2d518ac0e..53ecac5f6 100644 --- a/FL/Fl_Window.H +++ b/FL/Fl_Window.H @@ -35,6 +35,21 @@ class Fl_X; +/** + This widget produces an actual window. This can either be a main + window, with a border and title and all the window management controls, + or a "subwindow" inside a window. This is controlled by whether or not + the window has a parent(). +

Once you create a window, you usually add children Fl_Widget + 's to it by using window->add(child) for each new widget. See Fl_Group for more information + on how to add and remove children.

+

There are several subclasses of Fl_Window that provide + double-buffering, overlay, menu, and OpenGL support.

+

The window's callback is done if the user tries to close a window + using the window manager and + Fl::modal() is zero or equal to the window. Fl_Window + has a default callback that calls Fl_Window::hide(). +*/ class FL_EXPORT Fl_Window : public Fl_Group { friend class Fl_X; @@ -69,60 +84,296 @@ protected: static Fl_Window *current_; virtual void draw(); + /** Forces the window to be drawn, this window is also made current and calls draw(). */ virtual void flush(); public: - Fl_Window(int,int,int,int, const char* = 0); - Fl_Window(int,int, const char* = 0); - virtual ~Fl_Window(); + /** + Creates a window from the given size and title. + If Fl_Group::current() is not NULL, the window is created as a + subwindow of the parent window.

+ +

The first form of the constructor creates a top-level window + and asks the window manager to position the window. The second + form of the constructor either creates a subwindow or a + top-level window at the specified location (x,y) , subject to window + manager configuration. If you do not specify the position of the + window, the window manager will pick a place to show the window + or allow the user to pick a location. Use position(x,y) + or hotspot() before calling show() to request a + position on the screen. See Fl_Window::resize() + for some more details on positioning windows.

+ +

Top-level windows initially have visible() set to 0 + and parent() set to NULL. Subwindows initially + have visible() set to 1 and parent() set to + the parent window pointer.

+ +

Fl_Widget::box() defaults to FL_FLAT_BOX. If you + plan to completely fill the window with children widgets you should + change this to FL_NO_BOX. If you turn the window border off + you may want to change this to FL_UP_BOX. + */ + Fl_Window(int w, int h, const char* title= 0); + /** Creates a window from the given position, size and title. + See Fl_Window::Fl_Window(int w, int h, const char *title = 0) + */ + Fl_Window(int x, int y, int w, int h, const char* title = 0); + /** + 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_Window and all of it's children can be automatic (local) + variables, but you must declare the Fl_Window first so + that it is destroyed last. + */ + virtual ~Fl_Window(); virtual int handle(int); + /** + Changes the size and position of the window. If shown() is + true, these changes are communicated to the window server (which may + refuse that size and cause a further resize). If shown() is + false, the size and position are used when show() is called. + See Fl_Group for the effect + of resizing on the child widgets. +

You can also call the Fl_Widget methods size(x,y) + and position(w,h), which are inline wrappers for this virtual + function.

+

A top-level window can not force, but merely suggest a position and + size to the operating system. The window manager may not be willing or + able to display a window at the desired position or with the given + dimensions. It is up to the application developer to verify window + parameters after the resize request. + */ virtual void resize(int,int,int,int); + /** + Gets or sets whether or not the window manager border is around the + window. The default value is true. border(n) can be used to + turn the border on and off, and returns non-zero if the value has been + changed. Under most X window managers this does not work after + show() has been called, although SGI's 4DWM does work. + */ void border(int b); + /** + Fast inline function to turn the border + off. It only works before show() is called. + */ void clear_border() {set_flag(FL_NOBORDER);} + /** + See int Fl_Window::border(int) + */ int border() const {return !(flags() & FL_NOBORDER);} + /** Activate the flags FL_NOBORDER|FL_OVERRIDE */ void set_override() {set_flag(FL_NOBORDER|FL_OVERRIDE);} + /** Returns non zero if FL_OVERRIDE flag is set, 0 otherwise. */ int override() const { return flags()&FL_OVERRIDE; } + /** + A "modal" window, when shown(), will prevent any events from + being delivered to other windows in the same program, and will also + remain on top of the other windows (if the X window manager supports + the "transient for" property). Several modal windows may be shown at + once, in which case only the last one shown gets events. You can See + which window (if any) is modal by calling + Fl::modal(). + */ void set_modal() {set_flag(FL_MODAL);} + /** + Returns true if this window is modal. + */ int modal() const {return flags() & FL_MODAL;} + /** + A "non-modal" window (terminology borrowed from Microsoft Windows) + acts like a modal() one in that it remains on top, but it has + no effect on event delivery. There are three states for a + window: modal, non-modal, and normal. + */ void set_non_modal() {set_flag(FL_NON_MODAL);} + /** + Returns true if this window is modal or non-modal. + */ int non_modal() const {return flags() & (FL_NON_MODAL|FL_MODAL);} + /** + Position the window so that the mouse is pointing at the + given position, or at the center of the given widget, which may be the + window itself. If the optional offscreen parameter is + non-zero, then the window is allowed to extend off the screen (this + does not work with some X window managers). \see position() + */ void hotspot(int x, int y, int offscreen = 0); + /** + See void Fl_Window::hotspot(int x, int y, int offscreen = 0) + */ void hotspot(const Fl_Widget*, int offscreen = 0); + /** + See void Fl_Window::hotspot(int x, int y, int offscreen = 0) + */ void hotspot(const Fl_Widget& p, int offscreen = 0) {hotspot(&p,offscreen);} + /** + Undoes the effect of a previous resize() or show() + so that the next time show() is called the window manager is + free to position the window. + */ void free_position() {clear_flag(FL_FORCE_POSITION);} + /** + Set the allowable range the user can resize this window to. This only + works for top-level windows. +

+ If this function is not called, FLTK tries to figure out the range + from the setting of resizable(): + + It is undefined what happens if the current size does not fit in the + constraints passed to size_range(). + */ void size_range(int a, int b, int c=0, int d=0, int e=0, int f=0, int g=0) { minw=a; minh=b; maxw=c; maxh=d; dw=e; dh=f; aspect=g; size_range_();} + /** + See void Fl_Window::label(const char*) + */ const char* label() const {return Fl_Widget::label();} + /** + See void Fl_Window::iconlabel(const char*) + */ const char* iconlabel() const {return iconlabel_;} + /** + Gets or sets the window title bar label. + */ void label(const char*); + /** + Gets or sets the icon label. + */ void iconlabel(const char*); void label(const char* label, const char* iconlabel); void copy_label(const char* a); + /** + See void Fl_Window::xclass(const char*) + */ const char* xclass() const {return xclass_;} + /** + A string used to tell the system what type of window this is. Mostly + this identifies the picture to draw in the icon. Under X, this is + turned into a XA_WM_CLASS pair by truncating at the first + non-alphanumeric character and capitalizing the first character, and + the second one if the first is 'x'. Thus "foo" turns into "foo, Foo", + and "xprog.1" turns into "xprog, XProg". This only works if called + before calling show(). +

Under Microsoft Windows this string is used as the name of the + WNDCLASS structure, though it is not clear if this can have any + visible effect. The passed pointer is stored unchanged. The string + is not copied. + */ void xclass(const char* c) {xclass_ = c;} + /** Gets the current icon window target dependent data */ const void* icon() const {return icon_;} + /** Sets the current icon window target dependent data */ void icon(const void * ic) {icon_ = ic;} + /** + Returns non-zero if show() has been called (but not hide() + ). You can tell if a window is iconified with (w->shown() + &!w->visible()). + */ int shown() {return i != 0;} + /** + Put the window on the screen. Usually this has the side effect of + opening the display. The second form is used for top-level + windows and allow standard arguments to be parsed from the + command-line. +

If the window is already shown then it is restored and raised to the + top. This is really convenient because your program can call show() + at any time, even if the window is already up. It also means that + show() serves the purpose of raise() in other toolkits. + */ virtual void show(); + /** + Remove the window from the screen. If the window is already hidden or + has not been shown then this does nothing and is harmless. + */ virtual void hide(); + /** + See virtual void Fl_Window::show() + */ void show(int, char**); + /** + Makes the window completely fill the screen, without any window + manager border visible. You must use fullscreen_off() to undo + this. This may not work with all window managers. + */ void fullscreen(); + /** + Turns off any side effects of fullscreen() and does + resize(x,y,w,h). + */ void fullscreen_off(int,int,int,int); + /** + Iconifies the window. If you call this when shown() is false + it will show() it as an icon. If the window is already + iconified this does nothing. +

Call show() to restore the window.

+

When a window is iconified/restored (either by these calls or by the + user) the handle() method is called with FL_HIDE and + FL_SHOW events and visible() is turned on and off.

+

There is no way to control what is drawn in the icon except with the + string passed to Fl_Window::xclass(). You should not rely on + window managers displaying the icons. + */ void iconize(); int x_root() const ; int y_root() const ; static Fl_Window *current(); + /** + Sets things up so that the drawing functions in <FL/fl_draw.H> will go into this + window. This is useful for incremental update of windows, such as in an + idle callback, which will make your program behave much better if it + draws a slow graphic. Danger: incremental update is very hard to + debug and maintain! +

This method only works for the Fl_Window and + Fl_Gl_Window classes. + */ void make_current(); // for back-compatability only: + /** + Changes the cursor for this window. This always calls the system, if + you are changing the cursor a lot you may want to keep track of how + you set it in a static varaible and call this only if the new cursor + is different. + +

The type Fl_Cursor is an enumeration defined in <Enumerations.H>. + (Under X you can get any XC_cursor value by passing + Fl_Cursor((XC_foo/2)+1)). The colors only work on X, they are + not implemented on WIN32. + */ void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); static void default_callback(Fl_Window*, void* v); diff --git a/documentation/todo_filelist_doc.txt b/documentation/todo_filelist_doc.txt index 09ccf1bf1..8264639b7 100644 --- a/documentation/todo_filelist_doc.txt +++ b/documentation/todo_filelist_doc.txt @@ -9,8 +9,8 @@ header. Most other stuff goes into the source. In Progress Work List (add your WP and name here): - - WP1 (Fabien) - - WP2 + - WP1 (Fabien) DONE + - WP2 (Fabien) - WP3 - WP4 - WP5 @@ -154,8 +154,6 @@ widgets.html covering the mainly this file ------------------------------------------------------------------- Enumerations.H -Fl.H -Fl.cxx Fl_Adjuster.H Fl_Adjuster.cxx Fl_BMP_Image.H @@ -167,7 +165,6 @@ Fl_Box.cxx Fl_Browser.H Fl_Browser.cxx Fl_Browser_.H -Fl_Browser_.cxx Fl_Browser_load.cxx Fl_Button.H Fl_Button.cxx @@ -187,8 +184,6 @@ Fl_Counter.H Fl_Counter.cxx Fl_Dial.H Fl_Dial.cxx -Fl_Double_Window.H -Fl_Double_Window.cxx Fl_Export.H Fl_File_Browser.H Fl_File_Browser.cxx @@ -211,11 +206,6 @@ Fl_GIF_Image.H Fl_GIF_Image.cxx Fl_Gl_Choice.H Fl_Gl_Choice.cxx -Fl_Gl_Overlay.cxx -Fl_Gl_Window.H -Fl_Gl_Window.cxx -Fl_Group.H -Fl_Group.cxx Fl_Help_Dialog.H Fl_Help_Dialog.cxx Fl_Help_View.H @@ -259,8 +249,6 @@ Fl_Multiline_Output.H Fl_Nice_Slider.H Fl_Object.H Fl_Output.H -Fl_Overlay_Window.H -Fl_Overlay_Window.cxx Fl_PNG_Image.H Fl_PNG_Image.cxx Fl_PNM_Image.H @@ -297,8 +285,6 @@ Fl_Select_Browser.H Fl_Shared_Image.H Fl_Shared_Image.cxx Fl_Simple_Counter.H -Fl_Single_Window.H -Fl_Single_Window.cxx Fl_Slider.H Fl_Slider.cxx Fl_Spinner.H @@ -330,10 +316,6 @@ Fl_Value_Output.H Fl_Value_Output.cxx Fl_Value_Slider.H Fl_Value_Slider.cxx -Fl_Widget.H -Fl_Widget.cxx -Fl_Window.H -Fl_Window.cxx Fl_Window_fullscreen.cxx Fl_Window_hotspot.cxx Fl_Window_iconize.cxx @@ -345,21 +327,10 @@ Fl_XColor.H Fl_XPM_Image.H Fl_XPM_Image.cxx Fl_abort.cxx -Fl_add_idle.cxx -Fl_arg.cxx -Fl_compose.cxx -Fl_display.cxx Fl_get_key.cxx Fl_get_key_mac.cxx Fl_get_key_win32.cxx -Fl_get_system_colors.cxx Fl_grab.cxx -Fl_lock.cxx -Fl_mac.cxx -Fl_own_colormap.cxx -Fl_visual.cxx -Fl_win32.cxx -Fl_x.cxx Xutf8.h cgdebug.h cmap.cxx @@ -378,12 +349,8 @@ fl_arc.cxx fl_arci.cxx fl_ask.H fl_ask.cxx -fl_boxtype.cxx fl_call_main.c fl_cmap.h -fl_color.cxx -fl_color_mac.cxx -fl_color_win32.cxx fl_cursor.cxx fl_curve.cxx fl_diamond_box.cxx @@ -408,7 +375,6 @@ fl_font_x.cxx fl_font_xft.cxx fl_gtk.cxx fl_images_core.cxx -fl_labeltype.cxx fl_line_style.cxx fl_message.H fl_open_uri.cxx @@ -430,7 +396,6 @@ fl_set_fonts_win32.cxx fl_set_fonts_x.cxx fl_set_fonts_xft.cxx fl_shadow_box.cxx -fl_shortcut.cxx fl_show_colormap.H fl_show_colormap.cxx fl_show_input.H @@ -455,7 +420,6 @@ gl.h gl2opengl.h gl_draw.H gl_draw.cxx -gl_start.cxx glu.h glut.H glut_compatability.cxx @@ -467,7 +431,6 @@ names.h numericsort.c scandir.c scandir_win32.c -screen_xywh.cxx slowarrow.h vsnprintf.c win32.H diff --git a/src/Fl.cxx b/src/Fl.cxx index dde61972d..5d2f30e54 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -25,6 +25,7 @@ // http://www.fltk.org/str.php // + // warning: the Apple Quartz version still uses some Quickdraw calls, // mostly to get around the single active context in QD and // to implement clipping. This should be changed into pure @@ -89,22 +90,34 @@ Fl_Window *Fl::modal_; // topmost modal() window // double +/** + Returns the compiled-in value of the FL_VERSION constant. This + is useful for checking the version of a shared library. +*/ Fl::version() { return FL_VERSION; } -// -// 'Fl:event_inside()' - Return whether or not the mouse event is inside -// the given rectangle. -// - +/** + Returns whether or not the mouse event is inside the given rectangle. + Returns non-zero if the current event_x and event_y + put it inside the widget or inside an arbitrary bounding box. You + should always call this rather than doing your own comparison so you + are consistent about edge effects. +*/ int Fl::event_inside(int xx,int yy,int ww,int hh) /*const*/ { int mx = e_x - xx; int my = e_y - yy; return (mx >= 0 && mx < ww && my >= 0 && my < hh); } +/** Returns whether or not the mouse event is inside the given widget. + Returns non-zero if the current event_x and event_y + put it inside the widget or inside an arbitrary bounding box. You + should always call this rather than doing your own comparison so you + are consistent about edge effects. +*/ int Fl::event_inside(const Fl_Widget *o) /*const*/ { int mx = e_x - o->x(); int my = e_y - o->y(); @@ -173,11 +186,57 @@ static void elapse_timeouts() { // time interval: static double missed_timeout_by; +/** + Add a one-shot timeout callback. The function will be called by + Fl::wait() at t seconds after this function is called. + The optional void* argument is passed to the callback. + +

You can have multiple timeout callbacks. To remove an timeout + callback use Fl::remove_timeout(). + +

If you need more accurate, repeated timeouts, use Fl::repeat_timeout() to + reschedule the subsequent timeouts.

+ +

The following code will print "TICK" each second on + stdout with a fair degree of accuracy:

+ +
+     void callback(void*) {
+       puts("TICK");
+       Fl::repeat_timeout(1.0, callback);
+     }
+  
+     int main() {
+       Fl::add_timeout(1.0, callback);
+       return Fl::run();
+     }
+  
+*/ void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) { elapse_timeouts(); repeat_timeout(time, cb, argp); } +/** + This method repeats a timeout callback from the expiration of the + previous timeout, allowing for more accurate timing. You may only call + this method inside a timeout callback. + +

The following code will print "TICK" each second on + stdout with a fair degree of accuracy:

+ +
+     void callback(void*) {
+       puts("TICK");
+       Fl::repeat_timeout(1.0, callback);
+     }
+  
+     int main() {
+       Fl::add_timeout(1.0, callback);
+       return Fl::run();
+     }
+  
+*/ void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) { time += missed_timeout_by; if (time < -.05) time = 0; Timeout* t = free_timeout; @@ -197,12 +256,19 @@ void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) { *p = t; } +/** + Returns true if the timeout exists and has not been called yet. +*/ int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) { for (Timeout* t = first_timeout; t; t = t->next) if (t->cb == cb && t->arg == argp) return 1; return 0; } +/** + Removes a timeout callback. It is harmless to remove a timeout + callback that no longer exists. +*/ void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) { // This version removes all matching timeouts, not just the first one. // This may change in the future. @@ -235,6 +301,37 @@ struct Check { }; static Check *first_check, *next_check, *free_check; +/** + FLTK will call this callback just before it flushes the display and + waits for events. This is different than an idle callback because it + is only called once, then FLTK calls the system and tells it not to + return until an event happens. + +

This can be used by code that wants to monitor the + application's state, such as to keep a display up to date. The + advantage of using a check callback is that it is called only when no + events are pending. If events are coming in quickly, whole blocks of + them will be processed before this is called once. This can save + significant time and avoid the application falling behind the events. + +

Sample code: + +

+*/ void Fl::add_check(Fl_Timeout_Handler cb, void *argp) { Check* t = free_check; if (t) free_check = t->next; @@ -246,6 +343,10 @@ void Fl::add_check(Fl_Timeout_Handler cb, void *argp) { first_check = t; } +/** + Removes a check callback. It is harmless to remove a check + callback that no longer exists. +*/ void Fl::remove_check(Fl_Timeout_Handler cb, void *argp) { for (Check** p = &first_check; *p;) { Check* t = *p; @@ -261,9 +362,8 @@ void Fl::remove_check(Fl_Timeout_Handler cb, void *argp) { } /** - * Return 1, if a check with the same handler and data pointer - * is pending, 0 otherwise. - */ + Returns 1 if the check exists and has not been called yet, 0 otherwise. +*/ int Fl::has_check(Fl_Timeout_Handler cb, void *argp) { for (Check** p = &first_check; *p;) { Check* t = *p; @@ -302,6 +402,9 @@ void (*Fl::idle)(); // see Fl_add_idle.cxx for the add/remove functions extern int fl_ready(); // in Fl_.cxx extern int fl_wait(double time); // in Fl_.cxx +/** + See int wait() +*/ double Fl::wait(double time_to_wait) { // delete all widgets that were listed during callbacks do_widget_deletion(); @@ -376,6 +479,13 @@ double Fl::wait(double time_to_wait) { #define FOREVER 1e20 +/** + As long as any windows are displayed this calls Fl::wait() + repeatedly. When all the windows are closed it returns zero + (supposedly it would return non-zero on any errors, but FLTK calls + exit directly for these). A normal program will end main() + with return Fl::run();. +*/ int Fl::run() { while (Fl_X::first) wait(FOREVER); return 0; @@ -398,17 +508,76 @@ static Fl_Win32_At_Exit win32_at_exit; +/** + Waits until "something happens" and then returns. Call this + repeatedly to "run" your program. You can also check what happened + each time after this returns, which is quite useful for managing + program state. + +

What this really does is call all idle callbacks, all elapsed + timeouts, call Fl::flush() to get the screen to update, and + then wait some time (zero if there are idle callbacks, the shortest of + all pending timeouts, or infinity), for any events from the user or + any Fl::add_fd() callbacks. It then handles the events and + calls the callbacks and then returns. + +

The return value of the first form is non-zero if there are + any visible windows - this may change in future versions of + FLTK. + +

The second form waits a maximum of time + seconds. It can return much sooner if something happens. + +

The return value is positive if an event or fd happens before the + time elapsed. It is zero if nothing happens (on Win32 this will only + return zero if time is zero). It is negative if an error + occurs (this will happen on UNIX if a signal happens). +*/ int Fl::wait() { if (!Fl_X::first) return 0; wait(FOREVER); return Fl_X::first != 0; // return true if there is a window } +/** + Same as Fl::wait(0). Calling this during a big calculation + will keep the screen up to date and the interface responsive: + +

+ +

The returns non-zero if any windows are displayed, and 0 if no + windows are displayed (this is likely to change in future versions of + FLTK). +*/ int Fl::check() { wait(0.0); return Fl_X::first != 0; // return true if there is a window } +/** + This is similar to Fl::check() except this does not + call Fl::flush() or any callbacks, which is useful if your + program is in a state where such callbacks are illegal. This returns + true if Fl::check() would do anything (it will continue to + return true until you call Fl::check() or Fl::wait()). + +

+*/ int Fl::ready() { #if ! defined( WIN32 ) && ! defined(__APPLE__) if (first_timeout) { @@ -448,25 +617,52 @@ Fl_Window* fl_find(Window xid) { return 0; } +/** + Returns the first top-level window in the list of shown() windows. If + a modal() window is shown this is the top-most modal window, otherwise + it is the most recent window to get an event. + +

The second form sets the window that is returned by + first_window. The window is removed from wherever it is in the + list and inserted at the top. This is not done if Fl::modal() + is on or if the window is not shown(). Because the first window + is used to set the "parent" of modal windows, this is often + useful. +*/ Fl_Window* Fl::first_window() { Fl_X* i = Fl_X::first; return i ? i->w : 0; } +/** + Returns the next top-level window in the list of shown() windows. You can + use this call to iterate through all the windows that are shown(). +*/ Fl_Window* Fl::next_window(const Fl_Window* window) { Fl_X* i = Fl_X::i(window)->next; return i ? i->w : 0; } +/** + See Fl_Window* first_window() +*/ void Fl::first_window(Fl_Window* window) { if (!window || !window->shown()) return; fl_find(fl_xid(window)); } +/** + Redraws all widgets. +*/ void Fl::redraw() { for (Fl_X* i = Fl_X::first; i; i = i->next) i->w->redraw(); } +/** + Causes all the windows that need it to be redrawn and graphics forced + out through the pipes. This is what wait() does before + looking for events. +*/ void Fl::flush() { if (damage()) { damage_ = 0; @@ -505,6 +701,23 @@ struct handler_link { static handler_link *handlers = 0; +/** + Install a function to parse unrecognized events. If FLTK cannot + figure out what to do with an event, it calls each of these functions + (most recent first) until one of them returns non-zero. If none of + them returns non zero then the event is ignored. Events that cause + this to be called are: + +

+*/ void Fl::add_handler(int (*ha)(int)) { handler_link *l = new handler_link; l->handle = ha; @@ -512,6 +725,9 @@ void Fl::add_handler(int (*ha)(int)) { handlers = l; } +/** + Removes a previously added event handler. +*/ void Fl::remove_handler(int (*ha)(int)) { handler_link *l, *p; @@ -540,6 +756,16 @@ static int send_handlers(int e) { Fl_Widget* fl_oldfocus; // kludge for Fl_Group... +/** + Get or set the widget that will receive FL_KEYBOARD events. + +

If you change Fl::focus(), the previous widget and all + parents (that don't contain the new widget) are sent FL_UNFOCUS + events. Changing the focus does not send FL_FOCUS to + this or any widget, because sending FL_FOCUS is supposed to + test if the widget wants the focus (by it returning non-zero from + handle()). +*/ void Fl::focus(Fl_Widget *o) { if (o && !o->visible_focus()) return; if (grab()) return; // don't do anything while grab is on @@ -568,6 +794,20 @@ void Fl::focus(Fl_Widget *o) { static char dnd_flag = 0; // make 'belowmouse' send DND_LEAVE instead of LEAVE +/** + Get or set the widget that is below the mouse. This is for + highlighting buttons. It is not used to send FL_PUSH or + FL_MOVE directly, for several obscure reasons, but those events + typically go to this widget. This is also the first widget tried for + FL_SHORTCUT events. + +

If you change the belowmouse widget, the previous one and all + parents (that don't contain the new widget) are sent FL_LEAVE + events. Changing this does not send FL_ENTER to this + or any widget, because sending FL_ENTER is supposed to test + if the widget wants the mouse (by it returning non-zero from + handle()). +*/ void Fl::belowmouse(Fl_Widget *o) { if (grab()) return; // don't do anything while grab is on Fl_Widget *p = belowmouse_; @@ -582,7 +822,19 @@ void Fl::belowmouse(Fl_Widget *o) { } } -void Fl::pushed(Fl_Widget *o) { +/** + Get or set the widget that is being pushed. FL_DRAG or + FL_RELEASE (and any more FL_PUSH) events will be sent to + this widget. + +

If you change the pushed widget, the previous one and all parents + (that don't contain the new widget) are sent FL_RELEASE + events. Changing this does not send FL_PUSH to this + or any widget, because sending FL_PUSH is supposed to test + if the widget wants the mouse (by it returning non-zero from + handle()). +*/ + void Fl::pushed(Fl_Widget *o) { pushed_ = o; } @@ -703,6 +955,10 @@ static int send(int event, Fl_Widget* to, Fl_Window* window) { } int Fl::handle(int e, Fl_Window* window) +/** + Sends the event to a window for processing. Returns non-zero if any + widget uses the event. +*/ { e_number = e; if (fl_local_grab) return fl_local_grab(e); @@ -1073,13 +1329,42 @@ int Fl_Window::handle(int ev) //////////////////////////////////////////////////////////////// // Back compatability cut & paste functions for fltk 1.1 only: +/** + 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 previous + selection owner, if any. + +

Copying the buffer every time the selection is changed is + obviously wasteful, especially for large selections. An interface will + probably 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. +*/ void Fl::selection_owner(Fl_Widget *owner) {selection_owner_ = owner;} +/** + Changes 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() + widget is set to the passed owner. +*/ void Fl::selection(Fl_Widget &owner, const char* text, int len) { selection_owner_ = &owner; Fl::copy(text, len, 0); } +/** + Set things up so the receiver widget will be called with an FL_PASTE event some + time in the future for the specified clipboard. 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::paste(Fl_Widget &receiver) { Fl::paste(receiver, 0); } @@ -1200,7 +1485,6 @@ void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) { } Fl::damage(FL_DAMAGE_CHILD); } - void Fl_Window::flush() { make_current(); //if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this; @@ -1222,8 +1506,18 @@ void Fl_Window::flush() { static int num_dwidgets = 0, alloc_dwidgets = 0; static Fl_Widget **dwidgets = 0; -void -Fl::delete_widget(Fl_Widget *wi) { +/** + Schedules a widget for deletion at the next call to the event loop. + Use this method to delete a widget inside a callback function. + To avoid early deletion of widgets, this function + should be called toward the end of a callback and only after any call + to the event loop (Fl:wait(), Fl::flush(), + fl_ask(), etc).

+ +

When deleting groups or windows, you must only delete the group or + window widget and not the individual child widgets. +*/ +void Fl::delete_widget(Fl_Widget *wi) { if (!wi) return; if (num_dwidgets >= alloc_dwidgets) { diff --git a/src/Fl_Browser_.cxx b/src/Fl_Browser_.cxx index 8a4bc2714..9a6b8f801 100644 --- a/src/Fl_Browser_.cxx +++ b/src/Fl_Browser_.cxx @@ -71,12 +71,24 @@ static void hscrollbar_callback(Fl_Widget* s, void*) { // binary compatibility in 1.1.x - M. Sweet int Fl_Browser_::scrollbar_width_ = 16; -// Get the standard scrollbar size +/** + Gets the default scrollbar size that is used by the + Fl_Browser_, + Fl_Help_View, + Fl_Scroll, and + Fl_Text_Display widgets. +*/ int Fl::scrollbar_size() { return Fl_Browser_::scrollbar_width(); } -// Set the standard scrollbar size +/** + Sets the default scrollbar size that is used by the + Fl_Browser_, + Fl_Help_View, + Fl_Scroll, and + Fl_Text_Display widgets. +*/ void Fl::scrollbar_size(int W) { Fl_Browser_::scrollbar_width(W); } diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx index 02a9fea07..4ef7c719c 100644 --- a/src/Fl_Double_Window.cxx +++ b/src/Fl_Double_Window.cxx @@ -443,6 +443,11 @@ void Fl_Double_Window::hide() { Fl_Window::hide(); } +/** + 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. +*/ Fl_Double_Window::~Fl_Double_Window() { hide(); } diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index 61c045e12..8d1a587be 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -25,6 +25,21 @@ // http://www.fltk.org/str.php // +/** \fn virtual void Fl_Gl_Window::draw(void) + 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().

+

If double-buffering is enabled in the window, the back and front + buffers are swapped after this function is completed. +*/ + #include "flstring.h" #if HAVE_GL @@ -60,6 +75,23 @@ static char SWAP_TYPE = 0 ; // 0 = determine it from environment variable //////////////////////////////////////////////////////////////// +/** + Returns non-zero if the hardware supports the given or current OpenGL + mode. + +

void* Fl_Gl_Window::context() const; +
void Fl_Gl_Window::context(void*, int destroy_flag = false);

+ + Return or set a pointer to the GLContext that this window is + using. This is a system-dependent structure, but it is portable to copy + the context from one window to another. You can also set it to NULL, + which will force FLTK to recreate the context the next time make_current() is called, this is + useful for getting around bugs in OpenGL implementations. + +

If destroy_flag is true the context will be destroyed by + fltk when the window is destroyed, or when the mode() is changed, or the next time + context(x) is called. +*/ int Fl_Gl_Window::can_do(int a, const int *b) { return Fl_Gl_Choice::find(a,b) != 0; } @@ -91,6 +123,10 @@ void Fl_Gl_Window::show() { #endif /* __APPLE__ */ } +/** + The invalidate() method turns off valid() and is + equivalent to calling value(0). +*/ void Fl_Gl_Window::invalidate() { valid(0); context_valid(0); @@ -102,6 +138,9 @@ void Fl_Gl_Window::invalidate() { #endif } +/** + See const int Fl_Gl_Window::mode() const +*/ int Fl_Gl_Window::mode(int m, const int *a) { if (m == mode_ && a == alist) return 0; #ifndef __APPLE__ @@ -139,6 +178,12 @@ int Fl_Gl_Window::mode(int m, const int *a) { #define NON_LOCAL_CONTEXT 0x80000000 +/** + The make_current() method selects the OpenGL context for the + widget. It is called automatically prior to the draw() method + being called and can also be used to implement feedback and/or + selection within the handle() method. +*/ void Fl_Gl_Window::make_current() { // puts("Fl_Gl_Window::make_current()"); // printf("make_current: context_=%p\n", context_); @@ -185,6 +230,11 @@ void Fl_Gl_Window::make_current() { current_ = this; } +/** + Set the projection so 0,0 is in the lower left of the window and each + pixel is 1 unit wide/tall. If you are drawing 2D images, your + draw() method may want to call this if valid() is false. +*/ void Fl_Gl_Window::ortho() { // Alpha NT seems to have a broken OpenGL that does not like negative coords: #ifdef _M_ALPHA @@ -200,6 +250,10 @@ void Fl_Gl_Window::ortho() { #endif } +/** + The swap_buffers() method swaps the back and front buffers. + It is called automatically after the draw() method is called. +*/ void Fl_Gl_Window::swap_buffers() { #ifdef WIN32 # if HAVE_GL_OVERLAY @@ -397,6 +451,9 @@ void Fl_Gl_Window::context(void* v, int destroy_flag) { else mode_ |= NON_LOCAL_CONTEXT; } +/** + Hides the window and destroys the OpenGL context. +*/ void Fl_Gl_Window::hide() { context(0); #if HAVE_GL_OVERLAY && defined(WIN32) @@ -408,6 +465,10 @@ void Fl_Gl_Window::hide() { Fl_Window::hide(); } +/** + The destructor removes the widget and destroys the OpenGL context + associated with it. +*/ Fl_Gl_Window::~Fl_Gl_Window() { hide(); // delete overlay; this is done by ~Fl_Group @@ -432,6 +493,20 @@ void Fl_Gl_Window::init() { #endif // 0 } +/** + You must implement this virtual function if you want to draw into the + overlay. The overlay is cleared before this is called. You should + draw anything that is not clear using OpenGL. You must use + gl_color(i) to choose colors (it allocates them from the colormap + using system-specific calls), and remember that you are in an indexed + OpenGL mode and drawing anything other than flat-shaded will probably + not work. +

Both this function and Fl_Gl_Window::draw() should check + Fl_Gl_Window::valid() and set the same transformation. If you + don't your code may not work on other systems. Depending on the OS, + and on whether overlays are real or simulated, the OpenGL context may + be the same or different between the overlay and main window. +*/ void Fl_Gl_Window::draw_overlay() {} #endif diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx index 49e2ccb1b..4879e5c2f 100644 --- a/src/Fl_Group.cxx +++ b/src/Fl_Group.cxx @@ -41,10 +41,18 @@ Fl_Group* Fl_Group::current_; // Hack: A single child is stored in the pointer to the array, while // multiple children are stored in an allocated array: +/** + Returns a pointer to the array of children. This pointer is only + valid until the next time a child is added or removed. +*/ Fl_Widget*const* Fl_Group::array() const { return children_ <= 1 ? (Fl_Widget**)(&array_) : array_; } +/** + Searches the child array for the widget and returns the index. Returns children() if the widget is + NULL or not found. +*/ int Fl_Group::find(const Fl_Widget* o) const { Fl_Widget*const* a = array(); int i; for (i=0; i < children_; i++) if (*a++ == o) break; @@ -53,9 +61,28 @@ int Fl_Group::find(const Fl_Widget* o) const { // Metrowerks CodeWarrior and others can't export the static // class member: current_, so these methods can't be inlined... +/** + Sets the current group so you can build the widget + tree by just constructing the widgets. begin() is + automatically called by the constructor for Fl_Group (and thus for + Fl_Window as well). begin() is exactly the same as current(this). +

Don't forget to end() the group or window! +*/ void Fl_Group::begin() {current_ = this;} +/** + Exactly the same as current(this->parent()). Any new widgets + added to the widget tree will be added to the parent of the group. +*/ void Fl_Group::end() {current_ = (Fl_Group*)parent();} +/** + Returns the currently active group. The Fl_Widget + constructor automatically does current()->add(widget) if this is not null. + To prevent new widgets from being added to a group, call Fl_Group::current(0). +*/ Fl_Group *Fl_Group::current() {return current_;} +/** + See static Fl_Group *Fl_Group::current() +*/ void Fl_Group::current(Fl_Group *g) {current_ = g;} extern Fl_Widget* fl_oldfocus; // set by Fl::focus @@ -341,6 +368,13 @@ Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l) begin(); } +/** + The clear() method deletes all child widgets from + memory recursively.

+ +

This method differs from the remove() method in that it + affects all child widgets and deletes them from memory. +*/ void Fl_Group::clear() { Fl_Widget*const* old_array = array(); int old_children = children(); @@ -359,10 +393,24 @@ void Fl_Group::clear() { if (old_children > 1) free((void*)old_array); } +/** + 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_Group and all of it's children can be automatic (local) + variables, but you must declare the Fl_Group first, so + that it is destroyed last. +*/ Fl_Group::~Fl_Group() { clear(); } +/** + The widget is removed from it's current group (if any) and then + inserted into this group. It is put at index n (or at the end + if n >= children(). This can also be used to rearrange + the widgets inside a group. +*/ void Fl_Group::insert(Fl_Widget &o, int index) { if (o.parent()) { Fl_Group* g = (Fl_Group*)(o.parent()); @@ -392,8 +440,21 @@ void Fl_Group::insert(Fl_Widget &o, int index) { init_sizes(); } +/** + The widget is removed from it's current group (if any) and then added + to the end of this group. +*/ void Fl_Group::add(Fl_Widget &o) {insert(o, children_);} +/** + Removes a widget from the group but does not delete it. This + method does nothing if the widget is not a child of the + group. + +

This method differs from the clear() method in that it + only affects a single widget and does not delete it from + memory. +*/ void Fl_Group::remove(Fl_Widget &o) { if (!children_) return; int i = find(o); @@ -424,6 +485,13 @@ void Fl_Group::remove(Fl_Widget &o) { // algorithim. If you change this be sure to fix Fl_Tile which // also uses this array! +/** + The Fl_Group widget keeps track of the original widget sizes and + positions when resizing occurs so that if you resize a window back to its + original size the widgets will be in the correct places. If you rearrange + the widgets in your group, call this method to register the new arrangement + with the Fl_Group that contains them. +*/ void Fl_Group::init_sizes() { delete[] sizes_; sizes_ = 0; } diff --git a/src/Fl_Overlay_Window.cxx b/src/Fl_Overlay_Window.cxx index 06ed0b244..539503180 100644 --- a/src/Fl_Overlay_Window.cxx +++ b/src/Fl_Overlay_Window.cxx @@ -25,6 +25,13 @@ // http://www.fltk.org/str.php // +/** \fn virtual void Fl_Overlay_Window::draw_overlay() = 0 + You must subclass Fl_Overlay_Window and provide this method. + It is just like a draw() method, except it draws the overlay. + The overlay will have already been "cleared" when this is called. You + can use any of the routines described in <FL/fl_draw.H>. +*/ + // A window using double-buffering and able to draw an overlay // on top of that. Uses the hardware to draw the overlay if // possible, otherwise it just draws in the front buffer. @@ -65,6 +72,9 @@ void Fl_Overlay_Window::resize(int X, int Y, int W, int H) { if (overlay_ && overlay_!=this) overlay_->resize(0,0,w(),h()); } +/** + Destroys the window and all child widgets. +*/ Fl_Overlay_Window::~Fl_Overlay_Window() { hide(); // delete overlay; this is done by ~Fl_Group @@ -74,6 +84,12 @@ Fl_Overlay_Window::~Fl_Overlay_Window() { int Fl_Overlay_Window::can_do_overlay() {return 0;} +/** + Call this to indicate that the overlay data has changed and needs to + be redrawn. The overlay will be clear until the first time this is + called, so if you want an initial display you must call this after + calling show(). +*/ void Fl_Overlay_Window::redraw_overlay() { overlay_ = this; clear_damage((uchar)(damage()|FL_DAMAGE_OVERLAY)); diff --git a/src/Fl_Widget.cxx b/src/Fl_Widget.cxx index 4ae8d8306..f96051a0e 100644 --- a/src/Fl_Widget.cxx +++ b/src/Fl_Widget.cxx @@ -62,7 +62,11 @@ void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) { if (obj_tail >= QUEUE_SIZE) obj_tail = 0; } } - +/** + All Fl_Widgets that don't have a callback defined use a + default callback that puts a pointer to the widget in this queue, and + this method reads the oldest widget out of this queue. +*/ Fl_Widget *Fl::readqueue() { if (obj_tail==obj_head) return 0; Fl_Widget *o = obj_queue[obj_tail++]; diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx index 04d94aa5c..c4a7ca8ce 100644 --- a/src/Fl_Window.cxx +++ b/src/Fl_Window.cxx @@ -85,13 +85,13 @@ Fl_Window *Fl_Widget::window() const { if (o->type() >= FL_WINDOW) return (Fl_Window*)o; return 0; } - +/** Gets the x position of the window on the screen */ int Fl_Window::x_root() const { Fl_Window *p = window(); if (p) return p->x_root() + x(); return x(); } - +/** Gets the y position of the window on the screen */ int Fl_Window::y_root() const { Fl_Window *p = window(); if (p) return p->y_root() + y(); @@ -159,6 +159,7 @@ void Fl_Window::iconlabel(const char *iname) { // the Fl::atclose pointer is provided for back compatability. You // can now just change the callback for the window instead. +/** Default callback for window widgets. It hides the window and then calls the default widget callback. */ void Fl::default_atclose(Fl_Window* window, void* v) { window->hide(); Fl_Widget::default_callback(window, v); // put on Fl::read_queue() @@ -170,6 +171,9 @@ void Fl_Window::default_callback(Fl_Window* win, void* v) { Fl::atclose(win, v); } +/** + Returns the last window that was made current. +*/ Fl_Window *Fl_Window::current() { return current_; } diff --git a/src/Fl_add_idle.cxx b/src/Fl_add_idle.cxx index 1afc4e987..6d5e4b038 100644 --- a/src/Fl_add_idle.cxx +++ b/src/Fl_add_idle.cxx @@ -49,6 +49,23 @@ static void call_idle() { p->cb(p->data); // this may call add_idle() or remove_idle()! } +/** + Adds a callback function that is called every time by + Fl::wait() and also makes it act as though the timeout is + zero (this makes Fl::wait() return immediately, so if it is + in a loop it is called repeatedly, and thus the idle fucntion is + called repeatedly). The idle function can be used to get background + processing done. + +

You can have multiple idle callbacks. To remove an idle callback use Fl::remove_idle(). + +

Fl::wait() and Fl::check() call idle callbacks, + but Fl::ready() does not. + +

The idle callback can call any FLTK functions, including + Fl::wait(), Fl::check(), and Fl::ready(). + FLTK will not recursively call the idle callback. +*/ void Fl::add_idle(void (*cb)(void*), void* data) { idle_cb* p = freelist; if (p) freelist = p->next; @@ -66,6 +83,7 @@ void Fl::add_idle(void (*cb)(void*), void* data) { } } +/** Returns true if the specified idle callback is currently installed. */ int Fl::has_idle(void (*cb)(void*), void* data) { idle_cb* p = first; if (!p) return 0; @@ -75,6 +93,7 @@ int Fl::has_idle(void (*cb)(void*), void* data) { } } +/** Removes the specified idle callback, if it is installed. */ void Fl::remove_idle(void (*cb)(void*), void* data) { idle_cb* p = first; if (!p) return; diff --git a/src/Fl_arg.cxx b/src/Fl_arg.cxx index 49002816d..ae0d446bf 100644 --- a/src/Fl_arg.cxx +++ b/src/Fl_arg.cxx @@ -67,7 +67,13 @@ extern const char *fl_fg; extern const char *fl_bg; extern const char *fl_bg2; -// consume a switch from argv. Returns number of words eaten, 0 on error: +/** + 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. +*/ int Fl::arg(int argc, char **argv, int &i) { arg_called = 1; const char *s = argv[i]; @@ -167,11 +173,116 @@ int Fl::arg(int argc, char **argv, int &i) { return 2; } -// consume all switches from argv. Returns number of words eaten. -// Returns zero on error. 'i' will either point at first word that -// does not start with '-', at the error word, or after a '--', or at -// argc. If your program does not take any word arguments you can -// report an error if i < argc. + +/** + Consume all switches from argv. Returns number of words eaten + Returns zero on error. 'i' will either point at first word that + does not start with '-', at the error word, or after a '--', or at + argc. If your program does not take any word arguments you can + report an error if i < argc. + +

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 + 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 (this is why FLTK can use very short switches instead of + the long ones all other toolkits force you to use). + +

On return i is set to the index of the first non-switch. + This is either: + +

+ +

The return value is i unless an unrecognized switch is found, + in which case it is zero. If your program takes no arguments other + than switches you should produce an error if the return value is less + than argc. + +

All switches except -bg2 may be abbreviated one letter and case is ignored: + +

+ +

The second form of Fl::args() is useful if your program does + not have command line switches of its own. It parses all the switches, + and if any are not recognized it calls Fl::abort(Fl::help). + +

A usage string is displayed if Fl::args() detects an invalid + argument on the command-line. You can change the message by setting the + Fl::help pointer. +*/ int Fl::args(int argc, char** argv, int& i, int (*cb)(int,char**,int&)) { arg_called = 1; @@ -283,7 +394,7 @@ static const char * const helpmsg = " -to[oltips]"; const char * const Fl::help = helpmsg+13; - +/** See Fl::args(int argc, char **argv, int& i, int (*cb)(int,char**,int&)) */ void Fl::args(int argc, char **argv) { int i; if (Fl::args(argc,argv,i) < argc) Fl::error(helpmsg); } diff --git a/src/Fl_compose.cxx b/src/Fl_compose.cxx index 10cdb0602..a442ee108 100644 --- a/src/Fl_compose.cxx +++ b/src/Fl_compose.cxx @@ -87,6 +87,24 @@ static char dead_keys[] = { int Fl::compose_state = 0; +/** Any text editing widget should call this for each FL_KEYBOARD event. + Use of this function is very simple. + +

If true is returned, then it has modified the + Fl::event_text() and Fl::event_length() to a set of bytes to + insert (it may be of zero length!). In will also set the "del" + parameter to the number of bytes to the left of the cursor to + delete, this is used to delete the results of the previous call to + Fl::compose(). + +

If false is returned, the keys should be treated as function + keys, and del is set to zero. You could insert the text anyways, if + you don't know what else to do. + +

Though the current implementation returns immediately, future + versions may take quite awhile, as they may pop up a window or do + other user-interface things to allow characters to be selected. +*/ int Fl::compose(int& del) { del = 0; diff --git a/src/Fl_display.cxx b/src/Fl_display.cxx index 8afc2583e..7ce6d4293 100644 --- a/src/Fl_display.cxx +++ b/src/Fl_display.cxx @@ -32,6 +32,12 @@ #include #include "flstring.h" +/** + Sets the X display to use for all windows. Actually this just sets + the environment variable $DISPLAY to the passed string, so this only + works before you show() the first window or otherwise open the display, + and does nothing useful under WIN32. +*/ void Fl::display(const char *d) { #if defined(__APPLE__) || defined(WIN32) (void)d; diff --git a/src/Fl_get_system_colors.cxx b/src/Fl_get_system_colors.cxx index 3f2fadf0e..f929cef89 100644 --- a/src/Fl_get_system_colors.cxx +++ b/src/Fl_get_system_colors.cxx @@ -51,7 +51,12 @@ static char fl_bg_set = 0; static char fl_bg2_set = 0; static char fl_fg_set = 0; - +/** + Changes fl_color(FL_BACKGROUND_COLOR) 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::background(uchar r, uchar g, uchar b) { fl_bg_set = 1; @@ -70,13 +75,19 @@ void Fl::background(uchar r, uchar g, uchar b) { uchar(pow(gray,powb)*255+.5)); } } - +/** Changes fl_color(FL_FOREGROUND_COLOR). */ void Fl::foreground(uchar r, uchar g, uchar b) { fl_fg_set = 1; Fl::set_color(FL_FOREGROUND_COLOR,r,g,b); } +/** + Changes the alternative background color. This color is used as a + background by Fl_Input and other text widgets. +

This call may change fl_color(FL_FOREGROUND_COLOR) if it + does not provide sufficient contrast to FL_BACKGROUND2_COLOR. +*/ void Fl::background2(uchar r, uchar g, uchar b) { fl_bg2_set = 1; @@ -132,7 +143,18 @@ int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) { } else return 0; } #endif // WIN32 || __APPLE__ - +/** \fn 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. + +

On X this reads some common values from the Xdefaults database. + KDE users can set these values by running the "krdb" program, and + newer versions of KDE set this automatically if you check the "apply + style to other X programs" switch in their control panel. +*/ #if defined(WIN32) static void getsyscolor(int what, const char* arg, void (*func)(uchar,uchar,uchar)) @@ -246,6 +268,25 @@ Fl_Image *Fl::scheme_bg_ = (Fl_Image *)0; static Fl_Pixmap tile(tile_xpm); +/** + Gets or sets the current widget scheme. NULL will use + the scheme defined in the FLTK_SCHEME environment + variable or the scheme resource under X11. Otherwise, + any of the following schemes can be used:

+ + +*/ int Fl::scheme(const char *s) { if (!s) { if ((s = getenv("FLTK_SCHEME")) == NULL) { diff --git a/src/Fl_lock.cxx b/src/Fl_lock.cxx index a7be4c308..82763aeb1 100644 --- a/src/Fl_lock.cxx +++ b/src/Fl_lock.cxx @@ -78,6 +78,7 @@ static void lock_ring(); static void unlock_ring(); +/** Adds an awake handler for use in awake(). */ int Fl::add_awake_handler_(Fl_Awake_Handler func, void *data) { int ret = 0; @@ -100,7 +101,7 @@ int Fl::add_awake_handler_(Fl_Awake_Handler func, void *data) unlock_ring(); return ret; } - +/** Gets the last stored awake handler for use in awake(). */ int Fl::get_awake_handler_(Fl_Awake_Handler &func, void *&data) { int ret = 0; @@ -119,9 +120,11 @@ int Fl::get_awake_handler_(Fl_Awake_Handler &func, void *&data) } // -// 'Fl::awake()' - Let the main thread know an update is pending -// and have it cal a specific function -// +/** + Let the main thread know an update is pending + and have it call a specific function + See void awake(void* message=0). +*/ int Fl::awake(Fl_Awake_Handler func, void *data) { int ret = add_awake_handler_(func, data); Fl::awake(); @@ -130,6 +133,52 @@ int Fl::awake(Fl_Awake_Handler func, void *data) { //////////////////////////////////////////////////////////////// // Windows threading... +/** \fn void Fl::lock() + The lock() method blocks the current thread until it + can safely access FLTK widgets and data. Child threads should + call this method prior to updating any widgets or accessing + data. The main thread must call lock() to initialize + the threading support in FLTK. + +

Child threads must call unlock() when they are done + accessing FLTK. + +

When the wait() method is waiting + for input or timeouts, child threads are given access to FLTK. + Similarly, when the main thread needs to do processing, it will + wait until all child threads have called unlock() before processing + additional data. + +

See also: multithreading +*/ +/** \fn void Fl::unlock() + The unlock() method releases the lock that was set + using the lock() method. Child + threads should call this method as soon as they are finished + accessing FLTK. + +

See also: multithreading +*/ +/** \fn void Fl::awake(void* msg) + The awake() method sends a message pointer to the main thread, + causing any pending Fl::wait() call to + terminate so that the main thread can retrieve the message and any pending + redraws can be processed. + +

Multiple calls to Fl::awake() will queue multiple pointers + for the main thread to process, up to a system-defined (typically several + thousand) depth. The default message handler saves the last message which + can be accessed using the + Fl::thread_message() function. + +

The second form of awake() registers a function that will be + called by the main thread during the next message handling cycle. + awake() will return 0 if the callback function was registered, + and -1 if registration failed. Over a thousand awake callbacks can be + registered simultaneously. + +

See also: multithreading. +*/ #ifdef WIN32 # include # include @@ -174,10 +223,6 @@ static void lock_function() { EnterCriticalSection(&cs); } -// -// 'Fl::lock()' - Lock access to FLTK data structures... -// - void Fl::lock() { if (!main_thread) InitializeCriticalSection(&cs); @@ -190,21 +235,10 @@ void Fl::lock() { } } -// -// 'Fl::unlock()' - Unlock access to FLTK data structures... -// - void Fl::unlock() { unlock_function(); } - -// -// 'Fl::awake()' - Let the main thread know an update is pending. -// -// When called from a thread, it causes FLTK to awake from Fl::wait()... -// - void Fl::awake(void* msg) { PostThreadMessage( main_thread, fl_wake_msg, (WPARAM)msg, 0); } diff --git a/src/Fl_own_colormap.cxx b/src/Fl_own_colormap.cxx index 9045e5da1..d1191a811 100644 --- a/src/Fl_own_colormap.cxx +++ b/src/Fl_own_colormap.cxx @@ -37,6 +37,13 @@ #include #include +/** \fn Fl::own_colormap() + Makes FLTK use its own 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 move the cursor between windows. + +

This does nothing if the current visual is not colormapped. +*/ #ifdef WIN32 // There is probably something relevant to do on MSWindows 8-bit displays // but I don't know what it is diff --git a/src/Fl_visual.cxx b/src/Fl_visual.cxx index a0487c046..c19fa5b03 100644 --- a/src/Fl_visual.cxx +++ b/src/Fl_visual.cxx @@ -31,6 +31,40 @@ #include #include +/** \fn Fl::visual(int flags) + Selects a visual so that your graphics are drawn correctly. This is + only allowed before you call show() on any windows. This does nothing + if the default visual satisfies the capabilities, or if no visual + satisfies the capabilities, or on systems that don't have such + brain-dead notions. + +

Only the following combinations do anything useful: + +

+ +

This returns true if the system has the capabilities by default or + FLTK suceeded in turing them on. Your program will still work even if + this returns false (it just won't look as good). +*/ #ifdef WIN32 int Fl::visual(int flags) { fl_GetDC(0); diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx index e8099efab..ec7490e30 100644 --- a/src/fl_boxtype.cxx +++ b/src/fl_boxtype.cxx @@ -259,9 +259,36 @@ static struct { {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+7 }; +/** Returns the X offset for the given boxtype. See box_dy(). */ int Fl::box_dx(Fl_Boxtype t) {return fl_box_table[t].dx;} +/** + Returns the Y offset for the given boxtype. + +

These functions return the offset values necessary for a given + boxtype, useful for computing the area inside a box's borders, to + prevent overdrawing the borders. + +

For instance, in the case of a boxtype like FL_DOWN_BOX + where the border width might be 2 pixels all around, the above + functions would return 2, 2, 4, and 4 for box_dx, + box_dy, box_dw, and box_dh + respectively. + +

An example to compute the area inside a widget's box(): +

+         int X = yourwidget->x() + Fl::box_dx(yourwidget->box());
+         int Y = yourwidget->y() + Fl::box_dy(yourwidget->box());
+         int W = yourwidget->w() - Fl::box_dw(yourwidget->box());
+         int H = yourwidget->h() - Fl::box_dh(yourwidget->box());
+    
+

These functions are mainly useful in the draw() code + for deriving custom widgets, where one wants to avoid drawing + over the widget's own border box(). +*/ int Fl::box_dy(Fl_Boxtype t) {return fl_box_table[t].dy;} +/** Returns the width offset for the given boxtype. See box_dy(). */ int Fl::box_dw(Fl_Boxtype t) {return fl_box_table[t].dw;} +/** Returns the height offset for the given boxtype. See box_dy(). */ int Fl::box_dh(Fl_Boxtype t) {return fl_box_table[t].dh;} void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) { @@ -270,11 +297,11 @@ void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) { fl_box_table[t].set = 1; } } - +/** Gets the current box drawing function for the specified box type. */ Fl_Box_Draw_F *Fl::get_boxtype(Fl_Boxtype t) { return fl_box_table[t].f; } - +/** Sets the function to call to draw a specific boxtype. */ void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f, uchar a, uchar b, uchar c, uchar d) { fl_box_table[t].f = f; @@ -284,9 +311,9 @@ void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f, fl_box_table[t].dw = c; fl_box_table[t].dh = d; } - -void Fl::set_boxtype(Fl_Boxtype t, Fl_Boxtype f) { - fl_box_table[t] = fl_box_table[f]; +/** Copies the from boxtype. */ +void Fl::set_boxtype(Fl_Boxtype to, Fl_Boxtype from) { + fl_box_table[to] = fl_box_table[from]; } void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) { diff --git a/src/fl_color.cxx b/src/fl_color.cxx index cad299f4d..4b692ac50 100644 --- a/src/fl_color.cxx +++ b/src/fl_color.cxx @@ -317,17 +317,30 @@ void Fl::set_color(Fl_Color i, unsigned c) { } #endif // end of X-specific code - +/** + Returns the RGB value(s) for the given FLTK color index. The + first form returns the RGB values packed in a 32-bit unsigned + integer with the red value in the upper 8 bits, the green value + in the next 8 bits, and the blue value in bits 8-15. The lower + 8 bits will always be 0. + +

The second form returns the red, green, and blue values + separately in referenced variables. +*/ unsigned Fl::get_color(Fl_Color i) { if (i & 0xffffff00) return (i); else return fl_cmap[i]; } - +/** + Sets an entry in the fl_color index table. You can set it to + any 8-bit RGB color. The color is not allocated until fl_color(i) + is used. +*/ void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) { Fl::set_color((Fl_Color)(i & 255), ((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8)); } - +/** See unsigned get_color(Fl_Color c) */ void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) { unsigned c; diff --git a/src/fl_labeltype.cxx b/src/fl_labeltype.cxx index c73f40a9f..88e22a20b 100644 --- a/src/fl_labeltype.cxx +++ b/src/fl_labeltype.cxx @@ -74,6 +74,7 @@ static Fl_Label_Draw_F* table[MAX_LABELTYPE] = { static Fl_Label_Measure_F* measure[MAX_LABELTYPE]; +/** Sets the functions to call to draw and measure a specific labeltype. */ void Fl::set_labeltype(Fl_Labeltype t,Fl_Label_Draw_F* f,Fl_Label_Measure_F*m) { table[t] = f; measure[t] = m; diff --git a/src/fl_set_font.cxx b/src/fl_set_font.cxx index 180d3bb87..4421ee86b 100644 --- a/src/fl_set_font.cxx +++ b/src/fl_set_font.cxx @@ -36,7 +36,10 @@ #include static int table_size; - +/** + Changes a face. The string pointer is simply stored, + the string is not copied, so the string must be in static memory. +*/ void Fl::set_font(Fl_Font fnum, const char* name) { while (fnum >= table_size) { int i = table_size; @@ -78,11 +81,15 @@ void Fl::set_font(Fl_Font fnum, const char* name) { s->first = 0; fl_font(-1, 0); } - +/** Copies one face to another. */ void Fl::set_font(Fl_Font fnum, Fl_Font from) { Fl::set_font(fnum, get_font(from)); } - +/** + 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(Fl_Font fnum) {return fl_fonts[fnum].name;} // diff --git a/src/fl_shortcut.cxx b/src/fl_shortcut.cxx index 98c13ad59..38bf3857b 100644 --- a/src/fl_shortcut.cxx +++ b/src/fl_shortcut.cxx @@ -51,6 +51,13 @@ #include #endif +/** + Test the current event, which must be an FL_KEYBOARD or + FL_SHORTCUT, against a shortcut value (described in + Fl_Button). Returns non-zero if there is a match. Not to + be confused with + Fl_Widget::test_shortcut(). +*/ int Fl::test_shortcut(int shortcut) { if (!shortcut) return 0; diff --git a/src/gl_start.cxx b/src/gl_start.cxx index a47aeaca7..868a0d894 100644 --- a/src/gl_start.cxx +++ b/src/gl_start.cxx @@ -109,7 +109,19 @@ void gl_finish() { glXWaitGL(); #endif } - +/** + This does the same thing as + Fl::visual(int) but also + requires OpenGL drawing to work. This must be done if + you want to draw in normal windows with OpenGL with gl_start() and + gl_end(). It may be useful to call this so your X + windows use the same visual as an + Fl_Gl_Window, which on + some servers will reduce colormap flashing. + +

See Fl_Gl_Window + for a list of additional values for the argument. +*/ int Fl::gl_visual(int mode, int *alist) { Fl_Gl_Choice *c = Fl_Gl_Choice::find(mode,alist); if (!c) return 0; diff --git a/src/screen_xywh.cxx b/src/screen_xywh.cxx index a6c98d304..7a36e19e7 100644 --- a/src/screen_xywh.cxx +++ b/src/screen_xywh.cxx @@ -141,14 +141,23 @@ static void screen_init() { #endif // WIN32 -// Return the number of screens... +/** + Gets the number of available screens. +*/ int Fl::screen_count() { if (!num_screens) screen_init(); return num_screens; } -// Return the screen bounding rect for the given mouse position... +/** + Gets the bounding box of a screen. The first form gets the + bounding box for the screen the mouse pointer is in. The second + form gets the bounding box for the screen that contains the + specified coordinates. The last form gets the bounding box for + the numbered screen, where n is a number from 0 to the + number of screens less 1. +*/ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) { if (!num_screens) screen_init(); @@ -212,7 +221,10 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) { H = Fl::h(); } -// Return the screen bounding rect for the given screen... +/** + Returns the screen bounding rect for the given screen. + See void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my) +*/ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) { if (!num_screens) screen_init();