WP1 merged from my branch, WP2 reserved, todo list updated.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6231 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Fabien Costantini 2008-09-13 22:33:03 +00:00
parent 4159c97e42
commit 9bf19e2329
31 changed files with 1806 additions and 126 deletions

449
FL/Fl.H
View File

@ -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.</P>
<P>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.
<P>There can only be one callback of each type for a file descriptor.
Fl::remove_fd() gets rid of <I>all</I> the callbacks for a given
file descriptor.
<P>Under UNIX <I>any</I> 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.
<P>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.
<P>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.
<P>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 <I>does not have to be
shown()</I> , this lets the handle() method of a
&quot;dummy&quot; window override all event handling and allows you to
map and unmap a complex set of windows (under both X and WIN32
<I>some</I> window must be mapped because the system interface needs a
window id).
<P>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.
<P>To turn off grabbing do Fl::grab(0).
<P><I>Be careful that your program does not enter an infinite loop
while grab() is on. On X this will lock up your screen!</I>
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 &quot;double click&quot;. Returns N-1 for
N clicks. A double click is counted if the same button is pressed
again while event_is_click() is true.
<P>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 &quot;drag&quot; rather than a
&quot;click&quot;. 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 <I>next</I>
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:
<UL>
<LI>FL_SHIFT</LI>
<LI>FL_CAPS_LOCK</LI>
<LI>FL_CTRL</LI>
<LI>FL_ALT</LI>
<LI>FL_NUM_LOCK</LI>
<LI>FL_META</LI>
<LI>FL_SCROLL_LOCK</LI>
<LI>FL_BUTTON1</LI>
<LI>FL_BUTTON2</LI>
<LI>FL_BUTTON3</LI>
</UL>
<P>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 <I>
after</I> 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.
<P>Fl::event_key(int) returns true if the given key was held
down (or pressed) <I>during</I> the last event. This is constant until
the next event is read from the server.
<P>Fl::get_key(int) returns true if the given key is held down <I>
now</I>. Under X this requires a round-trip to the server and is <I>
much</I> slower than Fl::event_key(int).
<P>Keys are identified by the <I>unshifted</I> values. FLTK defines a
set of symbols that should work on most modern machines for every key
on the keyboard:
<UL>
<LI>All keys on the main keyboard producing a printable ASCII
character use the value of that ASCII character (as though shift,
ctrl, and caps lock were not on). The space bar is 32. </LI>
<LI>All keys on the numeric keypad producing a printable ASCII
character use the value of that ASCII character plus FL_KP.
The highest possible value is FL_KP_Last so you can
range-check to see if something is on the keypad. </LI>
<LI>All numbered function keys use the number on the function key plus
FL_F. The highest possible number is FL_F_Last, so you
can range-check a value. </LI>
<LI>Buttons on the mouse are considered keys, and use the button
number (where the left button is 1) plus FL_Button. </LI>
<LI>All other keys on the keypad have a symbol: FL_Escape,
FL_BackSpace, FL_Tab, FL_Enter, FL_Print, FL_Scroll_Lock, FL_Pause,
FL_Insert, FL_Home, FL_Page_Up, FL_Delete, FL_End, FL_Page_Down,
FL_Left, FL_Up, FL_Right, FL_Down, FL_Shift_L, FL_Shift_R,
FL_Control_L, FL_Control_R, FL_Caps_Lock, FL_Alt_L, FL_Alt_R,
FL_Meta_L, FL_Meta_R, FL_Menu, FL_Num_Lock, FL_KP_Enter. Be
careful not to confuse these with the very similar, but all-caps,
symbols used by Fl::event_state()
. </LI>
</UL>
<P>On X Fl::get_key(FL_Button+n) does not work.
<P>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 <I>now</I>.
Under X this requires a round-trip to the server and is <I>
much</I> 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 <i>text</i>.
*/
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.
<P>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 &quot;family&quot; 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 &quot;better&quot; 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 &quot;families&quot; of faces together, so
that the normal one is first, followed by bold, italic, and bold
italic.
<P>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
&quot;-*&quot; will select all fonts with any encoding as long as they have
normal X font names with dashes in them. Passing &quot;*&quot; 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.
<P>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.
<P>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.
<P>See also: multithreading
*/
static void* thread_message(); // platform dependent
// Widget deletion:
static void delete_widget(Fl_Widget *w);

View File

@ -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.
<P>It is highly recommended that you put the following code before the
first show() of <I>any</I> window in your program: </P>
<UL>
<PRE>
Fl::visual(FL_DOUBLE|FL_INDEX)
</PRE>
</UL>
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); }
};

View File

@ -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 &quot;context&quot; 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.
<P>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. </P>
<P>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 <I>
after</I> draw() is called. You can use this inside your
draw() method to avoid unneccessarily initializing the OpenGL
context. Just do this:
<UL><PRE>
void mywindow::draw() {
if (!valid()) {
glViewport(0,0,w(),h());
glFrustum(...);
...other initialization...
}
if (!context_valid()) {
...load textures, etc. ...
}
... draw your geometry here ...
}
</PRE></UL>
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:
<UL>
<LI>FL_RGB - RGB color (not indexed) </LI>
<LI>FL_RGB8 - RGB color with at least 8 bits of each color </LI>
<LI>FL_INDEX - Indexed mode </LI>
<LI>FL_SINGLE - not double buffered </LI>
<LI>FL_DOUBLE - double buffered </LI>
<LI>FL_ACCUM - accumulation buffer </LI>
<LI>FL_ALPHA - alpha channel in color </LI>
<LI>FL_DEPTH - depth buffer </LI>
<LI>FL_STENCIL - stencil buffer </LI>
<LI>FL_MULTISAMPLE - multisample antialiasing </LI>
</UL>
FL_RGB and FL_SINGLE have a value of zero, so they
are &quot;on&quot; unless you give FL_INDEX or FL_DOUBLE.
<P>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. </P>
<P>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();}

View File

@ -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.
<p>The second method returns the current clipping mode.
<p>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]. <i>No range checking is done!</i>
*/
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.
<P>In these examples the gray area is the resizable:
<BR></P>
<P align=center>\image html resizebox1.gif&nbsp;&nbsp;
\image html resizebox2.gif</P>
<P>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. </P>
<P>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();

View File

@ -30,6 +30,17 @@
#include "Fl_Double_Window.H"
/**
This window provides double buffering and also the ability to draw the
&quot;overlay&quot; 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.
<P>If no hardware support is found the overlay is simulated by drawing
directly into the on-screen copy of the double-buffered window, and
&quot;erased&quot; 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);}
};

View File

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

View File

@ -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 &quot;subwindow&quot; inside a window. This is controlled by whether or not
the window has a parent().
<P>Once you create a window, you usually add children Fl_Widget
's to it by using window-&gt;add(child) for each new widget. See Fl_Group for more information
on how to add and remove children. </P>
<P>There are several subclasses of Fl_Window that provide
double-buffering, overlay, menu, and OpenGL support. </P>
<P>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.</p>
<p>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.</p>
<p>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.</p>
<P>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 <I>also deletes all the children</I>. 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 <I>first</I> 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.
<P>You can also call the Fl_Widget methods size(x,y)
and position(w,h), which are inline wrappers for this virtual
function. </P>
<P>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. <I>Under most X window managers this does not work after
show() has been called, although SGI's 4DWM does work.</I>
*/
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 &quot;modal&quot; 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 &quot;transient for&quot; 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 &quot;non-modal&quot; 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 <I>three</I> 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.
<UL>
<LI>minw and minh are the smallest the window can
be. Either value must be greater than 0.</LI>
<LI>maxw and maxh are the largest the window can be.
If either is <I>equal</I> to the minimum then you cannot resize in
that direction. If either is zero then FLTK picks a maximum size in
that direction such that the window will fill the screen. </LI>
<LI>dw and dh are size increments. The window will
be constrained to widths of minw + N * dw, where N
is any non-negative integer. If these are less or equal to 1 they
are ignored. (this is ignored on WIN32)</LI>
<LI>aspect is a flag that indicates that the window should
preserve it's aspect ratio. This only works if both the maximum and
minimum have the same aspect ratio. (ignored on WIN32 and by many X
window managers)</LI>
</UL>
If this function is not called, FLTK tries to figure out the range
from the setting of resizable():
<UL>
<LI>If resizable() is NULL (this is the default)
then the window cannot be resized and the resize border and max-size
control will not be displayed for the window. </LI>
<LI>If either dimension of resizable() is less than 100,
then that is considered the minimum size. Otherwise the
resizable() has a minimum size of 100. </LI>
<LI>If either dimension of resizable() is zero, then that is
also the maximum size (so the window cannot resize in that direction). </LI>
</UL>
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. <I>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 &quot;foo&quot; turns into &quot;foo, Foo&quot;,
and &quot;xprog.1&quot; turns into &quot;xprog, XProg&quot;.</I> This only works if called <I>
before</I> calling show().
<P>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-&gt;shown()
&!w-&gt;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.
<P>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.
<P>Call show() to restore the window. </P>
<P>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. </P>
<P>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 &lt;FL/fl_draw.H&gt; 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. <B>Danger: incremental update is very hard to
debug and maintain!</B>
<P>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.
<P>The type Fl_Cursor is an enumeration defined in &lt;Enumerations.H&gt;.
(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);

View File

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

View File

@ -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 <i>t</i> seconds after this function is called.
The optional void* argument is passed to the callback.
<P>You can have multiple timeout callbacks. To remove an timeout
callback use Fl::remove_timeout().
<p>If you need more accurate, repeated timeouts, use Fl::repeat_timeout() to
reschedule the subsequent timeouts.</p>
<p>The following code will print &quot;TICK&quot; each second on
stdout with a fair degree of accuracy:</p>
<PRE>
void callback(void*) {
puts("TICK");
Fl::repeat_timeout(1.0, callback);
}
int main() {
Fl::add_timeout(1.0, callback);
return Fl::run();
}
</PRE>
*/
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.
<p>The following code will print &quot;TICK&quot; each second on
stdout with a fair degree of accuracy:</p>
<PRE>
void callback(void*) {
puts("TICK");
Fl::repeat_timeout(1.0, callback);
}
int main() {
Fl::add_timeout(1.0, callback);
return Fl::run();
}
</PRE>
*/
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.
<p>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.
<p>Sample code:
<UL><PRE>
bool state_changed; // anything that changes the display turns this on
void callback(void*) {
if (!state_changed) return;
state_changed = false;
do_expensive_calculation();
widget-&gt;redraw();
}
main() {
Fl::add_check(callback);
return Fl::run();
}
</PRE></UL>
*/
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_<platform>.cxx
extern int fl_wait(double time); // in Fl_<platform>.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.
<P>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.
<P>The return value of the first form is non-zero if there are
any visible windows - this may change in future versions of
FLTK.
<P>The second form waits a maximum of <i>time</i>
seconds. <i>It can return much sooner if something happens.</i>
<P>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 <i>time</i> 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:
<UL><PRE>
while (!calculation_done()) {
calculate();
Fl::check();
if (user_hit_abort_button()) break;
}
</PRE></UL>
<P>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 <I>not</I>
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()).
<UL><PRE>
while (!calculation_done()) {
calculate();
if (Fl::ready()) {
do_expensive_cleanup();
Fl::check();
if (user_hit_abort_button()) break;
}
}
</PRE></UL>
*/
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.
<P>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:
<UL>
<LI>FL_SHORTCUT events that are not recognized by any widget.
This lets you provide global shortcut keys. </LI>
<LI>System events that FLTK does not recognize. See
fl_xevent. </LI>
<LI><I>Some</I> other events when the widget FLTK selected returns
zero from its handle() method. Exactly which ones may change
in future versions, however. </LI>
</UL>
*/
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.
<P>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 <I>not</I> send FL_FOCUS to
this or any widget, because sending FL_FOCUS is supposed to <I>
test</I> 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.
<P>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 <I>not</I> send FL_ENTER to this
or any widget, because sending FL_ENTER is supposed to <I>test</I>
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.
<P>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 <I>not</I> send FL_PUSH to this
or any widget, because sending FL_PUSH is supposed to <I>test</I>
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.
<P><I>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.</I>
*/
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 <I>may</I> 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 <I>directly</I> by this, or for
it to happen <I>later</I>, or possibly <I>not at all</I>. 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).</p>
<p>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) {

View File

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

View File

@ -443,6 +443,11 @@ void Fl_Double_Window::hide() {
Fl_Window::hide();
}
/**
The destructor <I>also deletes all the children</I>. 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();
}

View File

@ -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.
<P>The draw() method can <I>only</I> use OpenGL calls. Do not
attempt to call X, any of the functions in &lt;FL/fl_draw.H&gt;, or glX
directly. Do not call gl_start() or gl_finish(). </P>
<P>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.
<h4>void* Fl_Gl_Window::context() const;
<br>void Fl_Gl_Window::context(void*, int destroy_flag = false);</h4>
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.
<p>If <i>destroy_flag</i> 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.
<P>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

View File

@ -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. <I>This pointer is only
valid until the next time a child is added or removed.</I>
*/
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() <i>is exactly the same as</i> current(this).
<P><I>Don't forget to end() the group or window!</I>
*/
void Fl_Group::begin() {current_ = this;}
/**
<i>Exactly the same as</i> current(this-&gt;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()-&gt;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.</p>
<p>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 <I>also deletes all the children</I>. 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 <I>first</I>, 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 &gt;= 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.
<p>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;
}

View File

@ -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 &quot;cleared&quot; when this is called. You
can use any of the routines described in &lt;FL/fl_draw.H&gt;.
*/
// 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));

View File

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

View File

@ -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_;
}

View File

@ -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.
<P>You can have multiple idle callbacks. To remove an idle callback use Fl::remove_idle().
<P>Fl::wait() and Fl::check() call idle callbacks,
but Fl::ready() does not.
<P>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;

View File

@ -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.
<P>FLTK provides an <I>entirely optional</I> 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.
<P>To use the switch parser, call Fl::args(...) near the start
of your program. This does <I>not</I> open the display, instead
switches that need the display open are stashed into static variables.
Then you <I>must</I> display your first window by calling
window-&gt;show(argc,argv), which will do anything stored in the
static variables.
<P>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
<i>before</i> any other tests, so <i>you can override any FLTK
switch</i> (this is why FLTK can use very short switches instead of
the long ones all other toolkits force you to use).
<P>On return i is set to the index of the first non-switch.
This is either:
<UL>
<LI>The first word that does not start with '-'. </LI>
<LI>The word '-' (used by many programs to name stdin as a file) </LI>
<LI>The first unrecognized switch (return value is 0). </LI>
<LI>argc</LI>
</UL>
<P>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.
<P>All switches except -bg2 may be abbreviated one letter and case is ignored:
<UL>
<LI>-bg color or -background color
<P>Sets the background color using Fl::background().</LI>
<LI>-bg2 color or -background2 color
<P>Sets the secondary background color using Fl::background2().</LI>
<LI>-display host:n.n
<P>Sets the X display to use; this option is silently
ignored under WIN32 and MacOS.</LI>
<LI>-dnd and -nodnd
<P>Enables or disables drag and drop text operations
using Fl::dnd_text_ops().</LI>
<LI>-fg color or -foreground color
<P>Sets the foreground color using Fl::foreground().</LI>
<LI>-geometry WxH+X+Y
<P>Sets the initial window position and size according
the the standard X geometry string.</LI>
<LI>-iconic
<P>Iconifies the window using Fl_Window::iconize().</LI>
<LI>-kbd and -nokbd
<P>Enables or disables visible keyboard focus for
non-text widgets using Fl::visible_focus().</LI>
<LI>-name string
<P>Sets the window class using Fl_Window::xclass().</LI>
<LI>-scheme string
<P>Sets the widget scheme using Fl::scheme().</LI>
<LI>-title string
<P>Sets the window title using Fl_Window::label().</LI>
<LI>-tooltips and -notooltips
<P>Enables or disables tooltips using Fl_Tooltip::enable().</LI>
</UL>
<P>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).
<P>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);
}

View File

@ -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.
<p>If <i>true</i> is returned, then it has modified the
Fl::event_text() and Fl::event_length() to a set of <i>bytes</i> to
insert (it may be of zero length!). In will also set the "del"
parameter to the number of <i>bytes</i> to the left of the cursor to
delete, this is used to delete the results of the previous call to
Fl::compose().
<p>If <i>false</i> 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.
<p>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;

View File

@ -32,6 +32,12 @@
#include <stdlib.h>
#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;

View File

@ -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.
<P>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.
<P>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:</P>
<ul>
<li>"none" - This is the default look-n-feel which resembles old
Windows (95/98/Me/NT/2000) and old GTK/KDE</li>
<li>"plastic" - This scheme is inspired by the Aqua user interface
on Mac OS X</li>
<li>"gtk+" - This scheme is inspired by the Red Hat Bluecurve
theme</li>
</ul>
*/
int Fl::scheme(const char *s) {
if (!s) {
if ((s = getenv("FLTK_SCHEME")) == NULL) {

View File

@ -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.
<P>Child threads must call unlock() when they are done
accessing FLTK.
<P>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.
<P>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.
<P>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.
<P>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.
<P>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.
<P>See also: multithreading.
*/
#ifdef WIN32
# include <windows.h>
# include <process.h>
@ -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);
}

View File

@ -37,6 +37,13 @@
#include <FL/Fl.H>
#include <FL/x.H>
/** \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.
<P>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

View File

@ -31,6 +31,40 @@
#include <FL/Fl.H>
#include <FL/x.H>
/** \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.
<P>Only the following combinations do anything useful:
<UL>
<LI>Fl::visual(FL_RGB)
<BR>Full/true color (if there are several depths FLTK chooses the
largest). Do this if you use fl_draw_image
for much better (non-dithered) output.
<BR>&nbsp; </LI>
<LI>Fl::visual(FL_RGB8)
<BR>Full color with at least 24 bits of color. FL_RGB will
always pick this if available, but if not it will happily return a
less-than-24 bit deep visual. This call fails if 24 bits are not
available.
<BR>&nbsp; </LI>
<LI>Fl::visual(FL_DOUBLE|FL_INDEX)
<BR>Hardware double buffering. Call this if you are going to use
Fl_Double_Window.
<BR>&nbsp; </LI>
<LI>Fl::visual(FL_DOUBLE|FL_RGB)</LI>
<LI>Fl::visual(FL_DOUBLE|FL_RGB8)
<BR>Hardware double buffering and full color.
</UL>
<P>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);

View File

@ -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.
<P>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.
<P>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.
<P>An example to compute the area inside a widget's box():
<pre>
int X = yourwidget-&gt;x() + Fl::box_dx(yourwidget-&gt;box());
int Y = yourwidget-&gt;y() + Fl::box_dy(yourwidget-&gt;box());
int W = yourwidget-&gt;w() - Fl::box_dw(yourwidget-&gt;box());
int H = yourwidget-&gt;h() - Fl::box_dh(yourwidget-&gt;box());
</pre>
<P>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) {

View File

@ -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.
<P>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;

View File

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

View File

@ -36,7 +36,10 @@
#include <stdlib.h>
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;}
//

View File

@ -51,6 +51,13 @@
#include <FL/x.H>
#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;

View File

@ -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 <I>must</I> 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.
<P>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;

View File

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