"Final" changes for first draft of 1.0 documentation.
git-svn-id: file:///fltk/svn/fltk/trunk@187 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
85e6f44959
commit
367f908d8e
@ -53,11 +53,11 @@ after these.
|
||||
<li><a href="#Fl_Widget.argument">argument</a>
|
||||
<li><a href="#Fl_Widget.box">box</a>
|
||||
<li><a href="#Fl_Widget.callback">callback</a>
|
||||
<li><a href="#Fl_Widget.changed">changed</a>
|
||||
</ul>
|
||||
</td>
|
||||
<td align=left valign=top>
|
||||
<ul>
|
||||
<li><a href="#Fl_Widget.changed">changed</a>
|
||||
<li><a href="#Fl_Widget.clear_changed">clear_changed</a>
|
||||
<li><a href="#Fl_Widget.color">color</a>
|
||||
<li><a href="#Fl_Widget.contains">contains</a>
|
||||
@ -66,27 +66,22 @@ after these.
|
||||
<li><a href="#Fl_Widget.default_callback">default_callback</a>
|
||||
<li><a href="#Fl_Widget.do_callback">do_callback</a>
|
||||
<li><a href="#Fl_Widget.h">h</a>
|
||||
<li><a href="#Fl_Widget.hide">hide</a>
|
||||
<li><a href="#Fl_Widget.ih">ih</a>
|
||||
</ul>
|
||||
</td>
|
||||
<td align=left valign=top>
|
||||
<ul>
|
||||
<li><a href="#Fl_Widget.init_size">init_size</a>
|
||||
<li><a href="#Fl_Widget.hide">hide</a>
|
||||
<li><a href="#Fl_Widget.inside">inside</a>
|
||||
<li><a href="#Fl_Widget.iw">iw</a>
|
||||
<li><a href="#Fl_Widget.ix">ix</a>
|
||||
<li><a href="#Fl_Widget.iy">iy</a>
|
||||
<li><a href="#Fl_Widget.label">label</a>
|
||||
<li><a href="#Fl_Widget.labelcolor">labelcolor</a>
|
||||
<li><a href="#Fl_Widget.labelfont">labelfont</a>
|
||||
<li><a href="#Fl_Widget.labelsize">labelsize</a>
|
||||
<li><a href="#Fl_Widget.labeltype">labeltype</a>
|
||||
<li><a href="#Fl_Widget.parent">parent</a>
|
||||
</ul>
|
||||
</td>
|
||||
<td align=left valign=top>
|
||||
<ul>
|
||||
<li><a href="#Fl_Widget.parent">parent</a>
|
||||
<li><a href="#Fl_Widget.position">position</a>
|
||||
<li><a href="#Fl_Widget.redraw">redraw</a>
|
||||
<li><a href="#Fl_Widget.resize">resize</a>
|
||||
@ -94,12 +89,13 @@ after these.
|
||||
<li><a href="#Fl_Widget.set_changed">set_changed</a>
|
||||
<li><a href="#Fl_Widget.show">show</a>
|
||||
<li><a href="#Fl_Widget.size">size</a>
|
||||
<li><a href="#Fl_Widget.type">type</a>
|
||||
<li><a href="#Fl_Widget.user_data">user_data</a>
|
||||
<li><a href="#Fl_Widget.take_focus">take_focus</a>
|
||||
</ul>
|
||||
</td>
|
||||
<td align=left valign=top>
|
||||
<ul>
|
||||
<li><a href="#Fl_Widget.type">type</a>
|
||||
<li><a href="#Fl_Widget.user_data">user_data</a>
|
||||
<li><a href="#Fl_Widget.visible">visible</a>
|
||||
<li><a href="#Fl_Widget.w">w</a>
|
||||
<li><a href="#Fl_Widget.when">when</a>
|
||||
@ -150,27 +146,11 @@ way to update the display, such as scrolling from the old position).
|
||||
<p><tt>position(x,y)</tt> is a shortcut for <tt>resize(x,y,w(),h())</tt>,
|
||||
and <tt>size(w,h)</tt> is a shortcut for <tt>resize(x(),y(),w,h)</tt>.
|
||||
|
||||
<h4><a name="Fl_Widget.ix">short Fl_Widget::ix() const</a><br>
|
||||
<a name="Fl_Widget.iy">short Fl_Widget::iy() const</a><br>
|
||||
<a name="Fl_Widget.iw">short Fl_Widget::iw() const</a><br>
|
||||
<a name="Fl_Widget.ih">short Fl_Widget::ih() const</a><br>
|
||||
<a name="Fl_Widget.init_size">void Fl_Widget::init_size(int,int,int,int)</a></h4>
|
||||
|
||||
The initial size and position of the widget. This is a copy of the
|
||||
arguments that the constructor was called with. This information is
|
||||
used by <a href="#Fl_Group"><tt>Fl_Group</tt></a> to calculate new sizes of
|
||||
the children when they are resized.
|
||||
|
||||
<p><tt>init_size()</tt> calls <tt>resize()</tt> with the passed sizes,
|
||||
and then replaces the initial size with the new values. If this widget
|
||||
is a group you will have to init_size all the children as well or
|
||||
unpredictable results will occur.
|
||||
|
||||
<h4><a name="Fl_Widget.window">Fl_Window* Fl_Widget::window() const;</a></h4>
|
||||
|
||||
Return a pointer to the <a href="#Fl_Window"><tt>Fl_Window</tt></a>
|
||||
that this widget is in (it will skip any and all parent widgets between
|
||||
this and the window). Returns NULL if none. Note: for an
|
||||
this and the window). Returns <tt>NULL</tt> if none. Note: for an
|
||||
<tt>Fl_Window</tt>, this returns it's <i>parent</i> window (if any),
|
||||
not <i>this</i> window.
|
||||
|
||||
@ -376,5 +356,13 @@ this widget. Returns false if <tt>b</tt> is <tt>NULL</tt>.
|
||||
Returns true if this is a child of <tt>a</tt>, or is equal to <tt>a</tt>.
|
||||
Returns false if <tt>a</tt> is <tt>NULL</tt>.
|
||||
|
||||
<h4><a name="Fl_Widget.take_focus">int Fl_Widget::take_focus()</a></h4>
|
||||
|
||||
Tries to make this widget be the <tt>Fl::focus()</tt> widget, by first
|
||||
sending it an <tt>FL_FOCUS</tt> event, and if it returns non-zero,
|
||||
setting <tt>Fl::focus()</tt> to this widget. You should use this
|
||||
method to assign the focus to an widget. Returns true if the widget
|
||||
accepted the focus.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# "$Id: Makefile,v 1.2 1998/12/29 14:58:59 mike Exp $"
|
||||
# "$Id: Makefile,v 1.3 1999/01/07 16:36:05 mike Exp $"
|
||||
#
|
||||
# Documentation makefile for the Fast Light Tool Kit (FLTK).
|
||||
#
|
||||
@ -29,6 +29,8 @@ HTMLFILES = \
|
||||
src/basics.html \
|
||||
src/common.html \
|
||||
src/editor.html \
|
||||
src/drawing.html \
|
||||
src/events.html \
|
||||
src/subclassing.html \
|
||||
src/fluid.html \
|
||||
src/opengl.html \
|
||||
@ -113,14 +115,14 @@ index.html: $(HTMLFILES)
|
||||
fltk.ps.gz: $(HTMLFILES)
|
||||
@echo "Generating PostScript documentation..."
|
||||
@rm -f fltk.ps fltk.ps.gz
|
||||
@htmldoc -f fltk.ps --no-compression --jpeg=90 --duplex --verbose --toclevels 2 --title src/FL.gif $(HTMLFILES)
|
||||
@htmldoc -f fltk.ps --jpeg=90 --duplex --verbose --toclevels 2 --title src/FL.gif $(HTMLFILES)
|
||||
@gzip -9 fltk.ps
|
||||
|
||||
fltk.pdf: $(HTMLFILES)
|
||||
@echo "Generating PDF documentation..."
|
||||
@rm -f fltk.pdf
|
||||
@htmldoc -f fltk.pdf --no-compression --jpeg=90 --duplex --verbose --toclevels 2 --title src/FL.gif $(HTMLFILES)
|
||||
@htmldoc -f fltk.pdf --compression=9 --jpeg=90 --duplex --verbose --toclevels 2 --title src/FL.gif $(HTMLFILES)
|
||||
|
||||
#
|
||||
# End of "$Id: Makefile,v 1.2 1998/12/29 14:58:59 mike Exp $".
|
||||
# End of "$Id: Makefile,v 1.3 1999/01/07 16:36:05 mike Exp $".
|
||||
#
|
||||
|
@ -31,7 +31,7 @@ The proper way to include FLTK header files is:
|
||||
#include <FL/Fl_xyz.H>
|
||||
</pre></ul>
|
||||
|
||||
Microsoft Windows developers please note: case *is* significant
|
||||
<b>Microsoft Windows developers please note:</b> case *is* significant
|
||||
under other operating systems, and the C standard uses the forward
|
||||
slash (/) to separate directories. The following <tt>#include</tt>
|
||||
directives are *not* recommended for portability reasons:
|
||||
@ -71,9 +71,8 @@ header files. This can be done by selecting "Settings" from the
|
||||
|
||||
<p>You can build your Microsoft Windows applications as Console or
|
||||
WIN32 applications. If you want to use the standard C <tt>main()</tt>
|
||||
function as the entry point, enter the name <tt>mainCRTStartup</tt> in
|
||||
the "Entry-point symbol" field in the "Output" settings under the
|
||||
"Link" tab.
|
||||
function as the entry point, FLTK includes a <tt>WinMain()</tt> function
|
||||
that will call your <tt>main()</tt> function for you.
|
||||
|
||||
<p><i>Note: The Visual C++ optimizer is known to cause problems with
|
||||
many programs. We only recommend using the "Favor Small Code"
|
||||
@ -155,7 +154,7 @@ The <tt>boxtype</tt> value is the style of the box that is drawn around
|
||||
the widget. Usually this is <tt>FL_NO_BOX</tt>, which means that no
|
||||
box is drawn. In our "Hello, World!" example we use <tt>FL_UP_BOX</tt>,
|
||||
which means that a raised button border will be drawn around the
|
||||
widget. You can learn more about boxtypes in <a href="#common">Chapter
|
||||
widget. You can learn more about boxtypes in <a href="#boytypes">Chapter
|
||||
3</a>.
|
||||
|
||||
<p>The <tt>x</tt> and <tt>y</tt> parameters determine where the widget
|
||||
@ -170,7 +169,7 @@ governed by the underlying window system or hardware.
|
||||
<H3>Labels</H3>
|
||||
|
||||
All widgets support labels. In the case of window widgets, the label
|
||||
is used for the label in the title bar. Our example program calls the
|
||||
is used for the label in the title bar. Our example program calls the
|
||||
<a href="#Fl_Widget.labelfont"><tt>labelfont</tt></a>,
|
||||
<a href="#Fl_Widget.labelsize"><tt>labelsize</tt></a>, and
|
||||
<a href="#Fl_Widget.labeltype"><tt>labeltype</tt></a> methods.
|
||||
@ -185,7 +184,7 @@ directly.
|
||||
<p>The <tt>labeltype</tt> method sets the type of label. FLTK supports
|
||||
normal, embossed, shadowed, symbol, and image labels.
|
||||
|
||||
<p>A complete list of all label options can be found in <a href="#common">
|
||||
<p>A complete list of all label options can be found in <a href="#labels">
|
||||
Chapter 3</a>.
|
||||
|
||||
<H3>Showing the Window</H3>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<H1 ALIGN=RIGHT>3 - Common Widgets and Attributes</H1>
|
||||
<H1 ALIGN=RIGHT><A NAME="common">3 - Common Widgets and Attributes</A></H1>
|
||||
|
||||
This chapter describes many of the widgets that are provided with FLTK and covers how
|
||||
to query and set the standard attributes.
|
||||
@ -119,7 +119,7 @@ window->size(width, height);
|
||||
Changing the size or position of a widget will cause a redraw of that widget
|
||||
and its children.
|
||||
|
||||
<H2>Colors</H2>
|
||||
<H2><A NAME="colors">Colors</A></H2>
|
||||
|
||||
FLTK manages a virtual color palette of "standard" colors. The
|
||||
standard colors are:
|
||||
@ -148,7 +148,7 @@ Similarly, the label color can be set using the <tt>labelcolor()</tt> method:
|
||||
button->labelcolor(FL_WHITE);
|
||||
</pre></ul>
|
||||
|
||||
<H2>Box Types</H2>
|
||||
<H2><A NAME="boxtypes">Box Types</A></H2>
|
||||
|
||||
<p>The type <tt>Fl_Boxtype</tt> stored and returned in <a href="#Fl_Widget.box">
|
||||
<tt>Fl_Widget::box()</tt></a> is an enumeration defined in
|
||||
@ -204,9 +204,9 @@ The last 4 arguments to <tt>Fl::set_boxtype()</tt> are the offsets
|
||||
for the bounding box that should be subtracted when drawing the label
|
||||
inside the box.
|
||||
|
||||
<H2>Labels and Label Types</H2>
|
||||
<H2><A NAME="labels">Labels and Label Types</A></H2>
|
||||
|
||||
The <tt>label()</tt>, <tt>align</tt>, <tt>labelfont()</tt>, <tt>labelsize()<tt>,
|
||||
The <tt>label()</tt>, <tt>align</tt>, <tt>labelfont()</tt>, <tt>labelsize()</tt>,
|
||||
and <tt>labeltype()</tt> methods control the labeling of widgets.
|
||||
|
||||
<H3>label()</H3>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<H1 ALIGN=RIGHT>4 - Designing a Simple Text Editor</H1>
|
||||
<H1 ALIGN=RIGHT><A NAME="editor">4 - Designing a Simple Text Editor</A></H1>
|
||||
|
||||
This chapter takes you through the design of a simple FLTK-based text editor.
|
||||
|
||||
@ -295,7 +295,7 @@ We call the <tt>load_file()</tt> function to actually load the file.
|
||||
<H3>paste_cb()</H3>
|
||||
|
||||
This callback function will send a FL_PASTE message to the <tt>input</tt>
|
||||
widget using the <a href="#paste"><tt>Fl::paste()</tt> method:
|
||||
widget using the <a href="#paste"><tt>Fl::paste()</tt></a> method:
|
||||
|
||||
<ul><pre>
|
||||
void paste_cb(void) {
|
||||
@ -514,7 +514,7 @@ void load_file(char *newfile) {
|
||||
</pre></ul>
|
||||
|
||||
When loading the file we use the <a href="#Fl_Input_.replace">
|
||||
<tt>input->replace()</tt> method to "replace" the text at the end of
|
||||
<tt>input->replace()</tt></a> method to "replace" the text at the end of
|
||||
the buffer. The <tt>pos</tt> variable keeps track of the end of the
|
||||
buffer.
|
||||
|
||||
|
@ -1,328 +1,373 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
<H1><A NAME="enumerations">C - FLTK Enumerations.H</A></H1>
|
||||
<H1 ALIGN=RIGHT><A NAME="enumerations">C - FLTK Enumerations.H</A></H1>
|
||||
|
||||
Here are the values of all the public-visible enumerations used by fltk:
|
||||
This appendix lists the enumerations provided in the
|
||||
<tt><FL/Enumerations.H></tt> header file, organized by section.
|
||||
|
||||
<pre>
|
||||
#include <FL/Enumerations.H>
|
||||
<H2>Version Numbers</H2>
|
||||
|
||||
//
|
||||
// The FLTK version number; this is changed slightly from the beta versions
|
||||
// because the old "const double" definition would not allow for conditional
|
||||
// compilation...
|
||||
//
|
||||
// FL_VERSION is a double that describes the major and minor version numbers.
|
||||
// Version 1.1 is actually stored as 1.01 to allow for more than 9 minor
|
||||
// releases.
|
||||
//
|
||||
// The FL_MAJOR_VERSION, FL_MINOR_VERSION, and FL_PATCH_VERSION constants
|
||||
// give the integral values for the major, minor, and patch releases
|
||||
// respectively.
|
||||
//
|
||||
The FLTK version number is stored in a number of compile-time constants:
|
||||
|
||||
#define FL_MAJOR_VERSION 1
|
||||
#define FL_MINOR_VERSION 0
|
||||
#define FL_PATCH_VERSION 0
|
||||
#define FL_VERSION ((double)FL_MAJOR_VERSION + \
|
||||
(double)FL_MINOR_VERSION * 0.01)
|
||||
<ul>
|
||||
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned int u32; // you must fix if not 32 bits on your machine!
|
||||
<li><tt>FL_MAJOR_VERSION</tt> - The major release number, currently
|
||||
1.
|
||||
|
||||
enum Fl_Event { // events
|
||||
FL_NO_EVENT = 0,
|
||||
FL_PUSH = 1,
|
||||
FL_RELEASE = 2,
|
||||
FL_ENTER = 3,
|
||||
FL_LEAVE = 4,
|
||||
FL_DRAG = 5,
|
||||
FL_FOCUS = 6,
|
||||
FL_UNFOCUS = 7,
|
||||
FL_KEYBOARD = 8,
|
||||
FL_CLOSE = 9,
|
||||
FL_MOVE = 10,
|
||||
FL_SHORTCUT = 11,
|
||||
FL_DEACTIVATE = 13,
|
||||
FL_ACTIVATE = 14,
|
||||
FL_HIDE = 15,
|
||||
FL_SHOW = 16,
|
||||
FL_PASTE = 17,
|
||||
FL_SELECTIONCLEAR = 18
|
||||
};
|
||||
<li><tt>FL_MINOR_VERSION</tt> - The minor release number, currently
|
||||
0.
|
||||
|
||||
enum Fl_When { // Fl_Widget::when():
|
||||
FL_WHEN_NEVER = 0,
|
||||
FL_WHEN_CHANGED = 1,
|
||||
FL_WHEN_RELEASE = 4,
|
||||
FL_WHEN_RELEASE_ALWAYS= 6,
|
||||
FL_WHEN_ENTER_KEY = 8,
|
||||
FL_WHEN_ENTER_KEY_ALWAYS=10,
|
||||
FL_WHEN_NOT_CHANGED = 2 // modifier bit to disable changed() test
|
||||
};
|
||||
<li><tt>FL_PATCH_VERSION</tt> - The patch release number, currently
|
||||
0.
|
||||
|
||||
// Fl::event_key() and Fl::get_key(n) (use ascii letters for all other keys):
|
||||
#define FL_Button 0xfee8 // use Fl_Button+n for mouse button n
|
||||
#define FL_BackSpace 0xff08
|
||||
#define FL_Tab 0xff09
|
||||
#define FL_Enter 0xff0d
|
||||
#define FL_Pause 0xff13
|
||||
#define FL_Scroll_Lock 0xff14
|
||||
#define FL_Escape 0xff1b
|
||||
#define FL_Home 0xff50
|
||||
#define FL_Left 0xff51
|
||||
#define FL_Up 0xff52
|
||||
#define FL_Right 0xff53
|
||||
#define FL_Down 0xff54
|
||||
#define FL_Page_Up 0xff55
|
||||
#define FL_Page_Down 0xff56
|
||||
#define FL_End 0xff57
|
||||
#define FL_Print 0xff61
|
||||
#define FL_Insert 0xff63
|
||||
#define FL_Menu 0xff67 // the "menu/apps" key on XFree86
|
||||
#define FL_Num_Lock 0xff7f
|
||||
#define FL_KP 0xff80 // use FL_KP+'x' for 'x' on numeric keypad
|
||||
#define FL_KP_Enter 0xff8d // same as Fl_KP+'\r'
|
||||
#define FL_KP_Last 0xffbd // use to range-check keypad
|
||||
#define FL_F 0xffbd // use FL_F+n for function key n
|
||||
#define FL_F_Last 0xffe0 // use to range-check function keys
|
||||
#define FL_Shift_L 0xffe1
|
||||
#define FL_Shift_R 0xffe2
|
||||
#define FL_Control_L 0xffe3
|
||||
#define FL_Control_R 0xffe4
|
||||
#define FL_Caps_Lock 0xffe5
|
||||
#define FL_Meta_L 0xffe7 // the left MSWindows key on XFree86
|
||||
#define FL_Meta_R 0xffe8 // the right MSWindows key on XFree86
|
||||
#define FL_Alt_L 0xffe9
|
||||
#define FL_Alt_R 0xffea
|
||||
#define FL_Delete 0xffff
|
||||
<li><tt>FL_VERSION</tt> - A combined floating-point version
|
||||
number for the major and minor release numbers, currently 1.0.
|
||||
|
||||
// Fl::event_state():
|
||||
#define FL_SHIFT 0x00010000
|
||||
#define FL_CAPS_LOCK 0x00020000
|
||||
#define FL_CTRL 0x00040000
|
||||
#define FL_ALT 0x00080000
|
||||
#define FL_NUM_LOCK 0x00100000 // most X servers do this?
|
||||
#define FL_META 0x00400000 // correct for XFree86
|
||||
#define FL_SCROLL_LOCK 0x00800000 // correct for XFree86
|
||||
#define FL_BUTTON1 0x01000000
|
||||
#define FL_BUTTON2 0x02000000
|
||||
#define FL_BUTTON3 0x04000000
|
||||
</ul>
|
||||
|
||||
enum Fl_Boxtype { // boxtypes (if you change these you must fix fl_boxtype.C):
|
||||
FL_NO_BOX = 0, FL_FLAT_BOX,
|
||||
<H2>Events</H2>
|
||||
|
||||
FL_UP_BOX, FL_DOWN_BOX,
|
||||
FL_UP_FRAME, FL_DOWN_FRAME,
|
||||
FL_THIN_UP_BOX, FL_THIN_DOWN_BOX,
|
||||
FL_THIN_UP_FRAME, FL_THIN_DOWN_FRAME,
|
||||
FL_ENGRAVED_BOX, FL_EMBOSSED_BOX,
|
||||
FL_ENGRAVED_FRAME, FL_EMBOSSED_FRAME,
|
||||
FL_BORDER_BOX, _FL_SHADOW_BOX,
|
||||
FL_BORDER_FRAME, _FL_SHADOW_FRAME,
|
||||
_FL_ROUNDED_BOX, _FL_RSHADOW_BOX,
|
||||
_FL_ROUNDED_FRAME, _FL_RFLAT_BOX,
|
||||
_FL_ROUND_UP_BOX, _FL_ROUND_DOWN_BOX,
|
||||
_FL_DIAMOND_UP_BOX, _FL_DIAMOND_DOWN_BOX,
|
||||
_FL_OVAL_BOX, _FL_OSHADOW_BOX,
|
||||
_FL_OVAL_FRAME, _FL_OFLAT_BOX
|
||||
};
|
||||
extern Fl_Boxtype define_FL_ROUND_UP_BOX();
|
||||
#define FL_ROUND_UP_BOX define_FL_ROUND_UP_BOX()
|
||||
#define FL_ROUND_DOWN_BOX (Fl_Boxtype)(define_FL_ROUND_UP_BOX()+1)
|
||||
extern Fl_Boxtype define_FL_SHADOW_BOX();
|
||||
#define FL_SHADOW_BOX define_FL_SHADOW_BOX()
|
||||
#define FL_SHADOW_FRAME (Fl_Boxtype)(define_FL_SHADOW_BOX()+2)
|
||||
extern Fl_Boxtype define_FL_ROUNDED_BOX();
|
||||
#define FL_ROUNDED_BOX define_FL_ROUNDED_BOX()
|
||||
#define FL_ROUNDED_FRAME (Fl_Boxtype)(define_FL_ROUNDED_BOX()+2)
|
||||
extern Fl_Boxtype define_FL_RFLAT_BOX();
|
||||
#define FL_RFLAT_BOX define_FL_RFLAT_BOX()
|
||||
extern Fl_Boxtype define_FL_RSHADOW_BOX();
|
||||
#define FL_RSHADOW_BOX define_FL_RSHADOW_BOX()
|
||||
extern Fl_Boxtype define_FL_DIAMOND_BOX();
|
||||
#define FL_DIAMOND_UP_BOX define_FL_DIAMOND_BOX()
|
||||
#define FL_DIAMOND_DOWN_BOX (Fl_Boxtype)(define_FL_DIAMOND_BOX()+1)
|
||||
extern Fl_Boxtype define_FL_OVAL_BOX();
|
||||
#define FL_OVAL_BOX define_FL_OVAL_BOX()
|
||||
#define FL_OSHADOW_BOX (Fl_Boxtype)(define_FL_OVAL_BOX()+1)
|
||||
#define FL_OVAL_FRAME (Fl_Boxtype)(define_FL_OVAL_BOX()+2)
|
||||
#define FL_OFLAT_BOX (Fl_Boxtype)(define_FL_OVAL_BOX()+3)
|
||||
Events are identified by an <tt>Fl_Event</tt> enumeration value. The
|
||||
following events are currently defined:
|
||||
|
||||
// conversions of box types to other boxtypes:
|
||||
inline Fl_Boxtype down(Fl_Boxtype b) {return (Fl_Boxtype)(b|1);}
|
||||
inline Fl_Boxtype frame(Fl_Boxtype b) {return (Fl_Boxtype)(b|2);}
|
||||
<ul>
|
||||
|
||||
// back-compatability box types:
|
||||
#define FL_FRAME FL_ENGRAVED_FRAME
|
||||
#define FL_FRAME_BOX FL_ENGRAVED_BOX
|
||||
#define FL_CIRCLE_BOX FL_ROUND_DOWN_BOX
|
||||
#define FL_DIAMOND_BOX FL_DIAMOND_DOWN_BOX
|
||||
<li><tt>FL_NO_EVENT</tt> - No event occurred.
|
||||
|
||||
enum Fl_Labeltype { // labeltypes:
|
||||
FL_NORMAL_LABEL = 0,
|
||||
FL_NO_LABEL,
|
||||
_FL_SYMBOL_LABEL,
|
||||
_FL_SHADOW_LABEL,
|
||||
_FL_ENGRAVED_LABEL,
|
||||
_FL_EMBOSSED_LABEL,
|
||||
_FL_BITMAP_LABEL,
|
||||
_FL_PIXMAP_LABEL,
|
||||
_FL_IMAGE_LABEL,
|
||||
_FL_MULTI_LABEL,
|
||||
FL_FREE_LABELTYPE
|
||||
};
|
||||
extern Fl_Labeltype define_FL_SYMBOL_LABEL();
|
||||
#define FL_SYMBOL_LABEL define_FL_SYMBOL_LABEL()
|
||||
extern Fl_Labeltype define_FL_SHADOW_LABEL();
|
||||
#define FL_SHADOW_LABEL define_FL_SHADOW_LABEL()
|
||||
extern Fl_Labeltype define_FL_ENGRAVED_LABEL();
|
||||
#define FL_ENGRAVED_LABEL define_FL_ENGRAVED_LABEL()
|
||||
extern Fl_Labeltype define_FL_EMBOSSED_LABEL();
|
||||
#define FL_EMBOSSED_LABEL define_FL_EMBOSSED_LABEL()
|
||||
<li><tt>FL_PUSH</tt> - A mouse button was pushed.
|
||||
|
||||
enum Fl_Align { // align() values
|
||||
FL_ALIGN_CENTER = 0,
|
||||
FL_ALIGN_TOP = 1,
|
||||
FL_ALIGN_BOTTOM = 2,
|
||||
FL_ALIGN_LEFT = 4,
|
||||
FL_ALIGN_RIGHT = 8,
|
||||
FL_ALIGN_INSIDE = 16,
|
||||
FL_ALIGN_CLIP = 64,
|
||||
FL_ALIGN_WRAP = 128,
|
||||
FL_ALIGN_TOP_LEFT = FL_ALIGN_TOP | FL_ALIGN_LEFT,
|
||||
FL_ALIGN_TOP_RIGHT = FL_ALIGN_TOP | FL_ALIGN_RIGHT,
|
||||
FL_ALIGN_BOTTOM_LEFT = FL_ALIGN_BOTTOM | FL_ALIGN_LEFT,
|
||||
FL_ALIGN_BOTTOM_RIGHT = FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT,
|
||||
FL_ALIGN_LEFT_TOP = FL_ALIGN_TOP_LEFT,
|
||||
FL_ALIGN_RIGHT_TOP = FL_ALIGN_TOP_RIGHT,
|
||||
FL_ALIGN_LEFT_BOTTOM = FL_ALIGN_BOTTOM_LEFT,
|
||||
FL_ALIGN_RIGHT_BOTTOM = FL_ALIGN_BOTTOM_RIGHT,
|
||||
FL_ALIGN_NOWRAP = 0 // for back compatability
|
||||
};
|
||||
<li><tt>FL_RELEASE</tt> - A mouse button was released.
|
||||
|
||||
enum Fl_Font { // standard fonts
|
||||
FL_HELVETICA = 0,
|
||||
FL_HELVETICA_BOLD,
|
||||
FL_HELVETICA_ITALIC,
|
||||
FL_HELVETICA_BOLD_ITALIC,
|
||||
FL_COURIER,
|
||||
FL_COURIER_BOLD,
|
||||
FL_COURIER_ITALIC,
|
||||
FL_COURIER_BOLD_ITALIC,
|
||||
FL_TIMES,
|
||||
FL_TIMES_BOLD,
|
||||
FL_TIMES_ITALIC,
|
||||
FL_TIMES_BOLD_ITALIC,
|
||||
FL_SYMBOL,
|
||||
FL_SCREEN,
|
||||
FL_SCREEN_BOLD,
|
||||
FL_ZAPF_DINGBATS,
|
||||
<li><tt>FL_ENTER</tt> - The mouse pointer entered a widget.
|
||||
|
||||
FL_FREE_FONT = 16, // first one to allocate
|
||||
FL_BOLD = 1, // add this to helvetica, courier, or times
|
||||
FL_ITALIC = 2 // add this to helvetica, courier, or times
|
||||
};
|
||||
<li><tt>FL_LEAVE</tt> - The mouse pointer left a widget.
|
||||
|
||||
#define FL_NORMAL_SIZE 14 // default size of all labels & text
|
||||
<li><tt>FL_DRAG</tt> - The mouse pointer was moved with a button
|
||||
pressed.
|
||||
|
||||
enum Fl_Color { // standard colors
|
||||
FL_BLACK = 0,
|
||||
FL_RED = 1,
|
||||
FL_GREEN = 2,
|
||||
FL_YELLOW = 3,
|
||||
FL_BLUE = 4,
|
||||
FL_MAGENTA = 5,
|
||||
FL_CYAN = 6,
|
||||
FL_WHITE = 7,
|
||||
FL_INACTIVE_COLOR = 8,
|
||||
FL_SELECTION_COLOR = 15,
|
||||
<li><tt>FL_FOCUS</tt> - A widget should receive keyboard focus.
|
||||
|
||||
FL_FREE_COLOR = 16,
|
||||
FL_NUM_FREE_COLOR = 16,
|
||||
<li><tt>FL_UNFOCUS</tt> - A widget loses keyboard focus.
|
||||
|
||||
FL_GRAY_RAMP = 32,
|
||||
<li><tt>FL_KEYBOARD</tt> - A key was pressed.
|
||||
|
||||
// boxtypes limit themselves to these colors so whole ramp is not allocated:
|
||||
FL_GRAY0 = 32, // 'A'
|
||||
FL_DARK3 = 39, // 'H'
|
||||
FL_DARK2 = 45, // 'N'
|
||||
FL_DARK1 = 47, // 'P'
|
||||
FL_GRAY = 49, // 'R' default color
|
||||
FL_LIGHT1 = 50, // 'S'
|
||||
FL_LIGHT2 = 52, // 'U'
|
||||
FL_LIGHT3 = 54, // 'W'
|
||||
<li><tt>FL_CLOSE</tt> - A window was closed.
|
||||
|
||||
FL_COLOR_CUBE = 56
|
||||
};
|
||||
<li><tt>FL_MOVE</tt> - The mouse pointer was moved with no buttons
|
||||
pressed.
|
||||
|
||||
inline Fl_Color inactive(Fl_Color c) {return (Fl_Color)(c|8);}
|
||||
Fl_Color contrast(Fl_Color fg, Fl_Color bg);
|
||||
#define FL_NUM_GRAY 24
|
||||
inline Fl_Color fl_gray_ramp(int i) {return (Fl_Color)(i+FL_GRAY_RAMP);}
|
||||
#define FL_NUM_RED 5
|
||||
#define FL_NUM_GREEN 8
|
||||
#define FL_NUM_BLUE 5
|
||||
inline Fl_Color fl_color_cube(int r, int g, int b) {
|
||||
return (Fl_Color)((b*FL_NUM_RED + r) * FL_NUM_GREEN + g + FL_COLOR_CUBE);}
|
||||
<li><tt>FL_SHORTCUT</tt> - The user pressed a shortcut key.
|
||||
|
||||
enum Fl_Cursor { // standard cursors
|
||||
FL_CURSOR_DEFAULT = 0,
|
||||
FL_CURSOR_ARROW = 35,
|
||||
FL_CURSOR_CROSS = 66,
|
||||
FL_CURSOR_WAIT = 76,
|
||||
FL_CURSOR_INSERT = 77,
|
||||
FL_CURSOR_HAND = 31,
|
||||
FL_CURSOR_HELP = 47,
|
||||
FL_CURSOR_MOVE = 27,
|
||||
// fltk provides bitmaps for these:
|
||||
FL_CURSOR_NS = 78,
|
||||
FL_CURSOR_WE = 79,
|
||||
FL_CURSOR_NWSE = 80,
|
||||
FL_CURSOR_NESW = 81,
|
||||
FL_CURSOR_NONE = 255,
|
||||
// for back compatability (non MSWindows ones):
|
||||
FL_CURSOR_N = 70,
|
||||
FL_CURSOR_NE = 69,
|
||||
FL_CURSOR_E = 49,
|
||||
FL_CURSOR_SE = 8,
|
||||
FL_CURSOR_S = 9,
|
||||
FL_CURSOR_SW = 7,
|
||||
FL_CURSOR_W = 36,
|
||||
FL_CURSOR_NW = 68
|
||||
//FL_CURSOR_NS = 22,
|
||||
//FL_CURSOR_WE = 55,
|
||||
};
|
||||
<li><tt>FL_DEACTIVATE</tt> - The widget has been deactivated.
|
||||
|
||||
enum { // values for "when" passed to Fl::add_fd()
|
||||
FL_READ = 1,
|
||||
FL_WRITE = 4,
|
||||
FL_EXCEPT = 8
|
||||
};
|
||||
<li><tt>FL_ACTIVATE</tt> - The widget has been activated.
|
||||
|
||||
enum Fl_Mode { // visual types and Fl_Gl_Window::mode() (values match Glut)
|
||||
FL_RGB = 0,
|
||||
FL_INDEX = 1,
|
||||
FL_SINGLE = 0,
|
||||
FL_DOUBLE = 2,
|
||||
FL_ACCUM = 4,
|
||||
FL_ALPHA = 8,
|
||||
FL_DEPTH = 16,
|
||||
FL_STENCIL = 32,
|
||||
FL_RGB8 = 64,
|
||||
FL_MULTISAMPLE= 128
|
||||
};
|
||||
<li><tt>FL_HIDE</tt> - The widget has been hidden.
|
||||
|
||||
// damage masks
|
||||
<li><tt>FL_SHOW</tt> - The widget has been shown.
|
||||
|
||||
<li><tt>FL_PASTE</tt> - The widget should paste the contents of the
|
||||
clipboard.
|
||||
|
||||
<li><tt>FL_SELECTIONCLEAR</tt> - The widget should clear any selections
|
||||
made for the clipboard.
|
||||
|
||||
</ul>
|
||||
|
||||
<H2>Callback "When" Conditions</H2>
|
||||
|
||||
The following constants determine when a callback is performed:
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>FL_WHEN_NEVER</tt> - Never call the callback.
|
||||
|
||||
<li><tt>FL_WHEN_CHANGED</tt> - Do the callback only when the
|
||||
widget value changes.
|
||||
|
||||
<li><tt>FL_WHEN_NOT_CHANGED</tt> - Do the callback whenever the
|
||||
user interacts with the widget.
|
||||
|
||||
<li><tt>FL_WHEN_RELEASE</tt> - Do the callback when the button or
|
||||
key is released and the value changes.
|
||||
|
||||
<li><tt>FL_WHEN_ENTER_KEY</tt> - Do the callback when the user presses
|
||||
the ENTER key and the value changes.
|
||||
|
||||
<li><tt>FL_WHEN_RELEASE_ALWAYS</tt> - Do the callback when the button
|
||||
or key is released, even if the value doesn't change.
|
||||
|
||||
<li><tt>FL_WHEN_ENTER_KEY_ALWAYS</tt> - Do the callback when the user
|
||||
presses the ENTER key, even if the value doesn't change.
|
||||
|
||||
</ul>
|
||||
|
||||
<H2>Fl::event_key() Values</H2>
|
||||
|
||||
The following constants define the non-ASCII keys on the keyboard for
|
||||
<tt>FL_KEYBOARD</tt> and <tt>FL_SHORTCUT</tt> events:
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>FL_Button</tt> - A mouse button; use <tt>Fl_Button +
|
||||
n</tt> for mouse button <tt>n</tt>.
|
||||
|
||||
<li><tt>FL_BackSpace</tt> - The backspace key.
|
||||
|
||||
<li><tt>FL_Tab</tt> - The tab key.
|
||||
|
||||
<li><tt>FL_Enter</tt> - The enter key.
|
||||
|
||||
<li><tt>FL_Pause</tt> - The pause key.
|
||||
|
||||
<li><tt>FL_Scroll_Lock</tt> - The scroll lock key.
|
||||
|
||||
<li><tt>FL_Escape</tt> - The escape key.
|
||||
|
||||
<li><tt>FL_Home</tt> - The home key.
|
||||
|
||||
<li><tt>FL_Left</tt> - The left arrow key.
|
||||
|
||||
<li><tt>FL_Up</tt> - The up arrow key.
|
||||
|
||||
<li><tt>FL_Right</tt> - The right arrow key.
|
||||
|
||||
<li><tt>FL_Down</tt> - The down arrow key.
|
||||
|
||||
<li><tt>FL_Page_Up</tt> - The page-up key.
|
||||
|
||||
<li><tt>FL_Page_Down</tt> - The page-down key.
|
||||
|
||||
<li><tt>FL_End</tt> - The end key.
|
||||
|
||||
<li><tt>FL_Print</tt> - The print (or print-screen) key.
|
||||
|
||||
<li><tt>FL_Insert</tt> - The insert key.
|
||||
|
||||
<li><tt>FL_Menu</tt> - The menu key.
|
||||
|
||||
<li><tt>FL_Num_Lock</tt> - The num lock key.
|
||||
|
||||
<li><tt>FL_KP</tt> - One of the keypad numbers; use <tt>FL_KP +
|
||||
n</tt> for number <tt>n</tt>.
|
||||
|
||||
<li><tt>FL_KP_Enter</tt> - The enter key on the keypad.
|
||||
|
||||
<li><tt>FL_F</tt> - One of the function keys; use <tt>FL_F +
|
||||
n</tt> for function key <tt>n</tt>.
|
||||
|
||||
<li><tt>FL_Shift_L</tt> - The lefthand shift key.
|
||||
|
||||
<li><tt>FL_Shift_R</tt> - The righthand shift key.
|
||||
|
||||
<li><tt>FL_Control_L</tt> - The lefthand control key.
|
||||
|
||||
<li><tt>FL_Control_R</tt> - The righthand control key.
|
||||
|
||||
<li><tt>FL_Caps_Lock</tt> - The caps lock key.
|
||||
|
||||
<li><tt>FL_Meta_L</tt> - The left meta/Windows key.
|
||||
|
||||
<li><tt>FL_Meta_R</tt> - The right meta/Windows key.
|
||||
|
||||
<li><tt>FL_Alt_L</tt> - The left alt key.
|
||||
|
||||
<li><tt>FL_Alt_R</tt> - The right alt key.
|
||||
|
||||
<li><tt>FL_Delete</tt> - The delete key.
|
||||
|
||||
</ul>
|
||||
|
||||
<H2>Fl::event_state() Values</H2>
|
||||
|
||||
The following constants define bits in the <tt>Fl::event_state()</tt>
|
||||
value:
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>FL_SHIFT</tt> - One of the shift keys is down.
|
||||
|
||||
<li><tt>FL_CAPS_LOCK</tt> - The caps lock is on.
|
||||
|
||||
<li><tt>FL_CTRL</tt> - One of the ctrl keys is down.
|
||||
|
||||
<li><tt>FL_ALT</tt> - One of the alt keys is down.
|
||||
|
||||
<li><tt>FL_NUM_LOCK</tt> - The num lock is on.
|
||||
|
||||
<li><tt>FL_META</tt> - One of the meta/Windows keys is down.
|
||||
|
||||
<li><tt>FL_SCROLL_LOCK</tt> - The scroll lock is on.
|
||||
|
||||
<li><tt>FL_BUTTON1</tt> - Mouse button 1 is pushed.
|
||||
|
||||
<li><tt>FL_BUTTON2</tt> - Mouse button 2 is pushed.
|
||||
|
||||
<li><tt>FL_BUTTON3</tt> - Mouse button 3 is pushed.
|
||||
|
||||
</ul>
|
||||
|
||||
<H2>Alignment Values</H2>
|
||||
|
||||
The following constants define bits that can be used with <a
|
||||
href="#Fl_Widget.align"><tt>Fl_Widget::align()</tt></a> to control the
|
||||
positioning of the label:
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>FL_ALIGN_CENTER</tt> - The label is centered.
|
||||
|
||||
<li><tt>FL_ALIGN_TOP</tt> - The label is top-aligned.
|
||||
|
||||
<li><tt>FL_ALIGN_BOTTOM</tt> - The label is bottom-aligned.
|
||||
|
||||
<li><tt>FL_ALIGN_LEFT</tt> - The label is left-aligned.
|
||||
|
||||
<li><tt>FL_ALIGN_RIGHT</tt> - The label is right-aligned.
|
||||
|
||||
<li><tt>FL_ALIGN_INSIDE</tt> - The label is put inside the widget.
|
||||
|
||||
<li><tt>FL_ALIGN_CLIP</tt> - The label is clipped to the widget.
|
||||
|
||||
<li><tt>FL_ALIGN_WRAP</tt> - The label text is wrapped as needed.
|
||||
|
||||
</ul>
|
||||
|
||||
<H2>Fonts</H2>
|
||||
|
||||
The following constants define the standard FLTK fonts:
|
||||
|
||||
</ul>
|
||||
|
||||
<li><tt>FL_HELVETICA</tt> - Helvetica (or Arial) normal.
|
||||
|
||||
<li><tt>FL_HELVETICA_BOLD</tt> - Helvetica (or Arial) bold.
|
||||
|
||||
<li><tt>FL_HELVETICA_ITALIC</tt> - Helvetica (or Arial) oblique.
|
||||
|
||||
<li><tt>FL_HELVETICA_BOLD_ITALIC</tt> - Helvetica (or Arial) bold-oblique.
|
||||
|
||||
<li><tt>FL_COURIER</tt> - Courier normal.
|
||||
|
||||
<li><tt>FL_COURIER_BOLD</tt> - Courier bold.
|
||||
|
||||
<li><tt>FL_COURIER_ITALIC</tt> - Courier italic.
|
||||
|
||||
<li><tt>FL_COURIER_BOLD_ITALIC</tt> - Courier bold-italic.
|
||||
|
||||
<li><tt>FL_TIMES</tt> - Times roman.
|
||||
|
||||
<li><tt>FL_TIMES_BOLD</tt> - Times bold.
|
||||
|
||||
<li><tt>FL_TIMES_ITALIC</tt> - Times italic.
|
||||
|
||||
<li><tt>FL_TIMES_BOLD_ITALIC</tt> - Times bold-italic.
|
||||
|
||||
<li><tt>FL_SYMBOL</tt> - Standard symbol font.
|
||||
|
||||
<li><tt>FL_SCREEN</tt> - Default monospaced screen font.
|
||||
|
||||
<li><tt>FL_SCREEN_BOLD</tt> - Default monospaced bold screen font.
|
||||
|
||||
<li><tt>FL_ZAPF_DINGBATS</tt> - Zapf-dingbats font.
|
||||
|
||||
</ul>
|
||||
|
||||
<H2>Colors</H2>
|
||||
|
||||
The following color constants can be used to access the colors in the FLTK
|
||||
standard color palette:
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>FL_BLACK</tt>
|
||||
|
||||
<li><tt>FL_RED</tt>
|
||||
|
||||
<li><tt>FL_GREEN</tt>
|
||||
|
||||
<li><tt>FL_YELLOW</tt>
|
||||
|
||||
<li><tt>FL_BLUE</tt>
|
||||
|
||||
<li><tt>FL_MAGENTA</tt>
|
||||
|
||||
<li><tt>FL_CYAN</tt>
|
||||
|
||||
<li><tt>FL_WHITE</tt>
|
||||
|
||||
<li><tt>FL_GRAY0</tt>
|
||||
|
||||
<li><tt>FL_DARK3</tt>
|
||||
|
||||
<li><tt>FL_DARK2</tt>
|
||||
|
||||
<li><tt>FL_DARK1</tt>
|
||||
|
||||
<li><tt>FL_GRAY</tt>
|
||||
|
||||
<li><tt>FL_LIGHT1</tt>
|
||||
|
||||
<li><tt>FL_LIGHT2</tt>
|
||||
|
||||
<li><tt>FL_LIGHT3</tt>
|
||||
|
||||
</ul>
|
||||
|
||||
<H2>Cursors</H2>
|
||||
|
||||
The following constants define the mouse cursors that are available in
|
||||
FLTK:
|
||||
|
||||
<ul>
|
||||
<li><tt>FL_CURSOR_DEFAULT</tt> - the default cursor, usually an arrow
|
||||
<li><tt>FL_CURSOR_ARROW</tt> - an arrow pointer
|
||||
<li><tt>FL_CURSOR_CROSS</tt> - crosshair
|
||||
<li><tt>FL_CURSOR_WAIT</tt> - watch or hourglass
|
||||
<li><tt>FL_CURSOR_INSERT</tt> - I-beam
|
||||
<li><tt>FL_CURSOR_HAND</tt> - hand (uparrow on MSWindows)
|
||||
<li><tt>FL_CURSOR_HELP</tt> - question mark
|
||||
<li><tt>FL_CURSOR_MOVE</tt> - 4-pointed arrow
|
||||
<li><tt>FL_CURSOR_NS</tt> - up/down arrow
|
||||
<li><tt>FL_CURSOR_WE</tt> - left/right arrow
|
||||
<li><tt>FL_CURSOR_NWSE</tt> - diagonal arrow
|
||||
<li><tt>FL_CURSOR_NESW</tt> - diagonal arrow
|
||||
<li><tt>FL_CURSOR_NONE</tt> - invisible
|
||||
</ul>
|
||||
|
||||
<H2>FD "When" Conditions</H2>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>FL_READ</tt> - Call the callback when there is data to be
|
||||
read.
|
||||
|
||||
<li><tt>FL_WRITE</tt> - Call the callback when data can be written
|
||||
without blocking.
|
||||
|
||||
<li><tt>FL_EXCEPT</tt> - Call the callback if an exception occurs on
|
||||
the file.
|
||||
|
||||
</ul>
|
||||
|
||||
<H2>Damage Masks</H2>
|
||||
|
||||
The following damage mask bits are used by the standard FLTK widgets:
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>FL_DAMAGE_CHILD</tt> - A child needs to be redrawn.
|
||||
|
||||
<li><tt>FL_DAMAGE_EXPOSE</tt> - The window was exposed.
|
||||
|
||||
<li><tt>FL_DAMAGE_SCROLL</tt> - The <tt>Fl_Scroll</tt> widget was
|
||||
scrolled.
|
||||
|
||||
<li><tt>FL_DAMAGE_OVERLAY</tt> - The overlay planes need to be redrawn.
|
||||
|
||||
<li><tt>FL_DAMAGE_ALL</tt> - Everything needs to be redrawn.
|
||||
|
||||
</ul>
|
||||
|
||||
enum Fl_Damage {
|
||||
FL_DAMAGE_CHILD = 0x01,
|
||||
FL_DAMAGE_EXPOSE = 0x02,
|
||||
FL_DAMAGE_SCROLL = 0x04,
|
||||
FL_DAMAGE_OVERLAY = 0x08,
|
||||
FL_DAMAGE_ALL = 0x80
|
||||
};
|
||||
</pre>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
@ -1,499 +1,225 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<H1 ALIGN=RIGHT>4 - Handling Events</H1>
|
||||
<H1 ALIGN=RIGHT><A NAME="events">6 - Handling Events</A></H1>
|
||||
|
||||
This chapter discusses the FLTK event model and how to handle events in your program or
|
||||
widget.
|
||||
|
||||
<H2>The FLTK Event Model</H2>
|
||||
|
||||
Events are identified the small integer argument passed to the <a
|
||||
href="#handle"><tt>Fl_Widget::handle()</tt></a> virtual method. Other
|
||||
information about the most recent event is stored in static locations
|
||||
and acquired by calling the <a
|
||||
href="#event_xxx"><tt>Fl::event_*()</tt></a> methods. This static
|
||||
information remains valid until the next event is read from window
|
||||
system (i.e. it is ok to look at it outside of the <tt>handle()</tt> method).
|
||||
|
||||
<H2>Mouse Events</H2>
|
||||
|
||||
<H3><TT>FL_PUSH</TT></H3>
|
||||
|
||||
<H3><TT>FL_RELEASE</TT></H3>
|
||||
|
||||
<H3><TT>FL_DRAG</TT></H3>
|
||||
|
||||
<H3><TT>FL_MOVE</TT></H3>
|
||||
|
||||
<H2>Keyboard Events</H2>
|
||||
|
||||
<H3><TT>FL_KEYBOARD</TT></H3>
|
||||
|
||||
<H3><TT>FL_SHORTCUT</TT></H3>
|
||||
|
||||
<H2>Widget Events</H2>
|
||||
|
||||
<H3><TT>FL_ACTIVATE</TT></H3>
|
||||
|
||||
<H3><TT>FL_DEACTIVATE</TT></H3>
|
||||
|
||||
<H3><TT>FL_HIDE</TT></H3>
|
||||
|
||||
<H3><TT>FL_SHOW</TT></H3>
|
||||
|
||||
<H3><TT>FL_FOCUS</TT></H3>
|
||||
|
||||
<H3><TT>FL_UNFOCUS</TT></H3>
|
||||
|
||||
<H3><TT>FL_ENTER</TT></H3>
|
||||
|
||||
<H3><TT>FL_LEAVE</TT></H3>
|
||||
|
||||
<H3><TT>FL_PASTE</TT></H3>
|
||||
|
||||
<H3><TT>FL_SELECTIONCLEAR</TT></H3>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
<title>Events in Fltk</title>
|
||||
<a name=types>
|
||||
<h2>Events in Fltk</h2>
|
||||
|
||||
<p>Events are identified the small integer argument passed to the <a
|
||||
href=subclass.html#handle>Fl_Widget::handle()</a> virtual method.
|
||||
Other information about the most recent event is stored in static
|
||||
locations and aquired by calling <a
|
||||
href=#information><code>Fl::event_*()</code></a>. This static
|
||||
information remains valid until the next event is read from the X
|
||||
server (that is, it is ok to look at it outside the handle() method).
|
||||
|
||||
</ul><h4><code>FL_PUSH (1)</code></h4><ul>
|
||||
<h3>FL_PUSH</h3>
|
||||
|
||||
A mouse button has gone down with the mouse pointing at this widget.
|
||||
You can find out what button by calling <a
|
||||
href=#event_button>Fl::event_button()</a>. You find out the mouse
|
||||
position by calling <a href=#event_x>Fl::event_x() and
|
||||
Fl::event_y()</a>.
|
||||
href="#event_button"><tt>Fl::event_button()</tt></a>. You find out the
|
||||
mouse position by calling <a href="#event_x"><tt>Fl::event_x()</tt></a>
|
||||
and <a href="#event_y"><tt>Fl::event_y()</tt></a>.
|
||||
|
||||
<p>A widget indicates that it "wants" the mouse click by returning
|
||||
non-zero from it's <a href=subclass.html#handle>handle()</a> method.
|
||||
It will then become the <a href=#pushed>Fl::pushed()</a> widget and
|
||||
will get FL_DRAG and the matching FL_RELEASE events. If handle()
|
||||
returns zero then fltk will try sending the FL_PUSH to another widget.
|
||||
non-zero from its <a href="#handle"><tt>handle()</tt></a> method. It
|
||||
will then become the <a href="#pushed"><tt>Fl::pushed()</tt></a> widget
|
||||
and will get <tt>FL_DRAG</tt> and the matching <tt>FL_RELEASE</tt>
|
||||
events. If <tt>handle()</tt> returns zero then FLTK will try sending
|
||||
the <tt>FL_PUSH</tt> to another widget.
|
||||
|
||||
</ul><h4><code>FL_DRAG (5)</code></h4><ul>
|
||||
<h3>FL_DRAG</h3>
|
||||
|
||||
The mouse has moved with the button held down.
|
||||
The mouse has moved with a button held down.
|
||||
|
||||
</ul><h4><code>FL_RELEASE (2)</code></h4><ul>
|
||||
<h3>FL_RELEASE</h3>
|
||||
|
||||
A mouse button has been released. You can find out what button by
|
||||
calling <a href=#event_button>Fl::event_button()</a>.
|
||||
calling <a href="#event_button"><tt>Fl::event_button()</tt></a>.
|
||||
|
||||
</ul><h4><code>FL_ENTER (3)</code></h4><ul>
|
||||
|
||||
The mouse has been moved to point at this widget. This can be used
|
||||
for highlighting feedback. If a widget wants to highlight or
|
||||
otherwise track the mouse, it indicates this by returning
|
||||
non-zero from it's <a href=subclass.html#handle>handle()</a> method.
|
||||
It then becomes the <a href=#belowmouse>Fl::belowmouse()</a> widget
|
||||
and will receive FL_MOVE and FL_EXIT events.
|
||||
|
||||
</ul><h4><code>FL_MOVE (10)</code></h4><ul>
|
||||
<h3>FL_MOVE</h3>
|
||||
|
||||
The mouse has moved without any mouse buttons held down. This event
|
||||
is sent (sort of) to the belowmouse() widget.
|
||||
is sent to the <tt>belowmouse()</tt> widget.
|
||||
|
||||
</ul><h4><code>FL_LEAVE (4)</code></h4><ul>
|
||||
<H2>Focus Events</H2>
|
||||
|
||||
<h3>FL_ENTER</h3>
|
||||
|
||||
The mouse has been moved to point at this widget. This can be used for
|
||||
highlighting feedback. If a widget wants to highlight or otherwise
|
||||
track the mouse, it indicates this by returning non-zero from its <a
|
||||
href="#handle"><tt>handle()</tt></a> method. It then becomes the <a
|
||||
href="#belowmouse"><tt>Fl::belowmouse()</tt></a> widget and will
|
||||
receive <tt>FL_MOVE</tt> and <tt>FL_LEAVE</tt> events.
|
||||
|
||||
<h3>FL_LEAVE</h3>
|
||||
|
||||
The mouse has moved out of the widget.
|
||||
|
||||
</ul><h4><code>FL_FOCUS (6)</code></h4><ul>
|
||||
<h3>FL_FOCUS</h3>
|
||||
|
||||
This indicates an <i>attempt</i> to give a widget the keyboard
|
||||
focus.
|
||||
|
||||
<p>If a widget wants the focus, it should change itself to display the
|
||||
fact that it has the focus, and return non-zero from it's <a
|
||||
href=subclass.html#handle>handle()</a> method. It then becomes the <a
|
||||
href=#focus>Fl::focus()</a> widget and gets FL_KEYBOARD and FL_UNFOCUS
|
||||
events.
|
||||
fact that it has the focus, and return non-zero from its <a
|
||||
href="#handle"><tt>handle()</tt></a> method. It then becomes the <a
|
||||
href="#focus"><tt>Fl::focus()</tt></a> widget and gets <tt>FL_KEYBOARD</tt>
|
||||
and <tt>FL_UNFOCUS</tt> events.
|
||||
|
||||
<p>The focus will change either because the window manager changed
|
||||
which window gets the focus, or because the user tried to navigate
|
||||
using tab, arrows, or other keys. You can check <a
|
||||
href=#event_key>Fl::event_key()</a> to figure out why it moved. For
|
||||
navigation it will be the key pressed, for instructions from the
|
||||
href="#event_key"><tt>Fl::event_key()</tt></a> to figure out why it moved. For
|
||||
navigation it will be the key pressed and for instructions from the
|
||||
window manager it will be zero.
|
||||
|
||||
</ul><h4><code>FL_UNFOCUS (7)</code></h4><ul>
|
||||
<h3>FL_UNFOCUS</h3>
|
||||
|
||||
Sent to the old <a href=#focus>Fl::focus()</a> when something else
|
||||
gets the focus.
|
||||
Sent to the previous <a href="#focus"><tt>Fl::focus()</tt></a> when
|
||||
another widget gets the focus.
|
||||
|
||||
</ul><h4><code>FL_KEYBOARD (8)</code></h4><ul>
|
||||
<H2>Keyboard Events</H2>
|
||||
|
||||
<h3>FL_KEYBOARD</h3>
|
||||
|
||||
A key press. The key pressed can be found in <a
|
||||
href=#event_key>Fl::event_key()</a>, or, more usefully, the text that
|
||||
the key should insert can be found with <a
|
||||
href=#event_text>Fl::event_text()</a> and it's length is in <a
|
||||
href=#event_length>Fl::event_length()</a>. If you use the key
|
||||
handle() should return 1. If you return zero then fltk assummes you
|
||||
ignored the key. It will then attempt to send it to a parent widget.
|
||||
If none of them want it, it will change the event into a FL_SHORTCUT
|
||||
event.
|
||||
href="#event_key"><tt>Fl::event_key()</tt></a>. The text that the key
|
||||
should insert can be found with <a
|
||||
href="#event_text"><tt>Fl::event_text()</tt></a> and its length is in
|
||||
<a href="#event_length"><tt>Fl::event_length()</tt></a>. If you use
|
||||
the key <tt>handle()</tt> should return 1. If you return zero then
|
||||
FLTK assummes you ignored the key. It will then attempt to send it to
|
||||
a parent widget. If none of them want it, it will change the event into
|
||||
a <tt>FL_SHORTCUT</tt> event.
|
||||
|
||||
</ul><h4><code>FL_SHORTCUT (11)</code></h4><ul>
|
||||
<h3>FL_SHORTCUT</h3>
|
||||
|
||||
If the <a href=#focus>Fl::focus()</a> is zero or ignores an
|
||||
FL_KEYBOARD event then fltk tries sending this event to every widget
|
||||
it can, until one of them returns non-zero. FL_SHORTCUT is first sent
|
||||
to the belowmouse widget, then it's parents and siblings, and
|
||||
eventually to every widget in the window, trying to find an object
|
||||
that returns non-zero. Fltk tries real hard to not let any keystrokes
|
||||
be ignored!
|
||||
|
||||
<p>If the <a href=#event_text>Fl::event_text()</a> is a lower or
|
||||
upper-case letter, and nothing wants the shortcut
|
||||
If the <a href="#focus"><tt>Fl::focus()</tt></a> is zero or ignores an
|
||||
<tt>FL_KEYBOARD</tt> event then FLTK tries sending this event to every
|
||||
widget it can, until one of them returns non-zero.
|
||||
<tt>FL_SHORTCUT</tt> is first sent to the <tt>belowmouse()</tt> widget,
|
||||
then its parents and siblings, and eventually to every widget in the
|
||||
window, trying to find an object that returns non-zero. FLTK tries
|
||||
really hard to not to ignore any keystrokes!
|
||||
|
||||
<p>You can also make "global" shortcuts by using <a
|
||||
href=#add_handler>Fl::add_handler()</a>. A global shortcut will work
|
||||
no matter what windows are displayed or which one has the focus.
|
||||
href="#add_handler"><tt>Fl::add_handler()</tt></a>. A global shortcut
|
||||
will work no matter what windows are displayed or which one has the
|
||||
focus.
|
||||
|
||||
</ul><h4><code>FL_DEACTIVATE (13)</code></h4><ul>
|
||||
<H2>Widget Events</H2>
|
||||
|
||||
<h3>FL_DEACTIVATE</h3>
|
||||
|
||||
This widget is no longer active, due to <a
|
||||
href=Fl_Widget.html#active>deactivate()</a> being called on it or one
|
||||
of it's parents. active() may still be true after this, the widget is
|
||||
only active if active() is true on it and all it's parents.
|
||||
href="#Fl_Widget.deactivate"><tt>deactivate()</tt></a> being called on
|
||||
it or one of its parents. <tt>active()</tt> may still be true after this, the
|
||||
widget is only active if <tt>active()</tt> is true on it and all its parents
|
||||
(use <tt>active_r()</tt> to check this).
|
||||
|
||||
</ul><h4><code>FL_ACTIVATE (14)</code></h4><ul>
|
||||
<h3>FL_ACTIVATE</h3>
|
||||
|
||||
This widget is now active, due to <a
|
||||
href=Fl_Widget.html#activate>active()</a> being called on it or one
|
||||
of it's parents.
|
||||
href="#Fl_Widget.activate"><tt>activate()</tt></a> being called on it
|
||||
or one of its parents.
|
||||
|
||||
</ul><h4><code>FL_HIDE (15)</code></h4><ul>
|
||||
<h3>FL_HIDE</h3>
|
||||
|
||||
This widget is no longer visible, due to <a
|
||||
href=Fl_Widget.html#visible>hide()</a> being called, or a parent group
|
||||
or window having hide() be called, or due to a parent window being
|
||||
iconized. visible() may still be true after this, the widget is
|
||||
visible only if visible() is true for it and all it's parents.
|
||||
href="#Fl_Widget.hide><tt>hide()</a> being called on it or one of its
|
||||
parents, or due to a parent window being minimized. <tt>visible()</tt>
|
||||
may still be true after this, but the widget is visible only if
|
||||
<tt>visible()</tt> is true for it and all its parents (use
|
||||
<tt>visible_r()</tt> to check this).
|
||||
|
||||
</ul><h4><code>FL_SHOW (16)</code></h4><ul>
|
||||
<h3>FL_SHOW</h3>
|
||||
|
||||
This widget is visible again, due to <a
|
||||
href=Fl_Widget.html#visible>show()</a> being called on it or one of
|
||||
it's parents, or due to a parent window being deiconized. <i>Child
|
||||
Fl_Windows respond to this by actually creating the X window if not
|
||||
done already, so if you subclass a window, be sure to pass FL_SHOW to
|
||||
the base class handle() method!</i>
|
||||
href="#Fl_Widget.show"><tt>show()</tt></a> being called on it or one of
|
||||
its parents, or due to a parent window being restored. <i>Child
|
||||
<tt>Fl_Window</tt>s respond to this by actually creating the window if not
|
||||
done already, so if you subclass a window, be sure to pass <tt>FL_SHOW</tt> to
|
||||
the base class <tt>handle()</tt> method!</i>
|
||||
|
||||
<a name=paste>
|
||||
</ul><h4><code>FL_PASTE (17)</code></h4><ul>
|
||||
<H2>Clipboard Events</H2>
|
||||
|
||||
<h3>FL_PASTE</h3>
|
||||
|
||||
You should get this event some time after you call <a
|
||||
href=cutpaste.html>Fl::paste()</a>. The contents of <a
|
||||
href=#event_text>Fl::event_text()</a> is the text to insert and the
|
||||
number of characters is in <a href=#event_length>Fl::event_length()</a>.
|
||||
href="#paste"><tt>Fl::paste()</tt></a>. The contents of <a
|
||||
href="#event_text"><tt>Fl::event_text()</tt></a> is the text to insert
|
||||
and the number of characters is in <a
|
||||
href="#event_length"><tt>Fl::event_length()</tt></a>.
|
||||
|
||||
</ul><h4><code>FL_SELECTIONCLEAR (18)</code></h4><ul>
|
||||
<h3>FL_SELECTIONCLEAR</h3>
|
||||
|
||||
The <a href=cutpaste.html>Fl::selection_owner()</a> will get this
|
||||
The <a href="#selection_owner">Fl::selection_owner()</a> will get this
|
||||
event before the selection is moved to another widget. This indicates
|
||||
that some other widget or program has claimed the selection.
|
||||
|
||||
</ul>
|
||||
<h2><a name="event_xxx">Fl::event_*() methods</a></h2>
|
||||
|
||||
<a name=information>
|
||||
<h2>Fl::event_*() methods</h2>
|
||||
|
||||
Fltk keeps the information about the most recent event in static
|
||||
FLTK keeps the information about the most recent event in static
|
||||
storage. This information is good until the next event is processed.
|
||||
Thus it is valid inside handle() and callback() methods.
|
||||
Thus it is valid inside <tt>handle()</tt> and <tt>callback()</tt> methods.
|
||||
|
||||
<p>These are all trivial inline functions and thus very fast and
|
||||
small. The data is stored in static locations and remains valid until
|
||||
the next X event is handled.
|
||||
|
||||
<a name=event_button>
|
||||
</ul><h4><code>int Fl::event_button();</code></h4><ul>
|
||||
|
||||
Returns which mouse button was pressed. This returns garbage if the
|
||||
most recent event was not a FL_PUSH or FL_RELEASE.
|
||||
|
||||
<a name=event_x>
|
||||
</ul><h4><code>int Fl::event_x()</code>
|
||||
<br><code>int Fl::event_y()</code></h4><ul>
|
||||
|
||||
Returns the mouse position of the event (relative to the Fl_Window it
|
||||
was passed to).
|
||||
|
||||
</ul><h4><code>int Fl::event_x_root()</code>
|
||||
<br><code>int Fl::event_y_root()</code></h4><ul>
|
||||
|
||||
Returns the mouse position on the screen of the event. To find the
|
||||
absolute position of an Fl_Window on the screen, use the difference
|
||||
between event_x_root and event_x.
|
||||
|
||||
<a name=get_mouse>
|
||||
</ul><h4><code>void Fl::get_mouse(int &,int &)</code></h4><ul>
|
||||
|
||||
<p>Return where the mouse is on the screen by doing a round-trip query
|
||||
to the server. You should use <a
|
||||
href=#event_x>Fl::event_x/y_root()</a> 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.
|
||||
|
||||
<a name=event_state>
|
||||
</ul><h4><code>ulong Fl::event_state();
|
||||
<br>unsigned int Fl::event_state(int);</code></h4><ul>
|
||||
|
||||
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 <code>FL_SHIFT, FL_CAPS_LOCK, FL_CTRL, FL_ALT, FL_NUM_LOCK,
|
||||
FL_META, FL_SCROLL_LOCK, FL_BUTTON1, FL_BUTTON2, FL_BUTTON3</code>.
|
||||
|
||||
<i><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
|
||||
Xlib works so that the shift state is not correctly reported until the
|
||||
first event <b>after</b> the shift key is pressed or released.</i>
|
||||
|
||||
<a name=event_key>
|
||||
</ul><h4><code>int Fl::event_key();
|
||||
<br>int Fl::event_key(int);
|
||||
<br>int Fl::get_key(int);</code></h4><ul>
|
||||
|
||||
Fl::event_key() returns which key on the keyboard was last pushed.
|
||||
|
||||
<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> X keysym values.
|
||||
However fltk defines a set of symbols that should work on most modern
|
||||
machines for every key on the generic PC keyboard:
|
||||
|
||||
<p><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>All keys on the numeric keypad producing a printable ASCII
|
||||
character use the value of that ASCII character plus
|
||||
<code>FL_KP</code>. The highest possible value is
|
||||
<code>FL_KP_Last</code> so you can range-check to see if something is
|
||||
on the keypad.
|
||||
|
||||
<li>All numbered function keys use the number on the function key plus
|
||||
<code>FL_F</code>. The highest possible number is
|
||||
<code>FL_F_Last</code>, so you can range-check a value.
|
||||
|
||||
<li>Buttons on the mouse are considered keys, and use the button
|
||||
number (where the left button is 1) plus <code>FL_Button</code>.
|
||||
|
||||
<li>All other keys on the keypad have a symbol: <code>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</code>. Be
|
||||
careful not to confuse these with the very similar, but all-caps,
|
||||
symbols used by <a href=#event_state>Fl::event_state()</a>.
|
||||
small:
|
||||
|
||||
<ul>
|
||||
<li><a name="event_button">Fl::event_button</a>
|
||||
<li><a name="event_clicks">Fl::event_clicks</a>
|
||||
<li><a name="event_inside">Fl::event_inside</a>
|
||||
<li><a name="event_is_click">Fl::event_is_click</a>
|
||||
<li><a name="event_key">Fl::event_key</a>
|
||||
<li><a name="event_length">Fl::event_length</a>
|
||||
<li><a name="event_state">Fl::event_state</a>
|
||||
<li><a name="event_text">Fl::event_text</a>
|
||||
<li><a name="event_x">Fl::event_x</a>
|
||||
<li><a name="event_x_root">Fl::event_x_root</a>
|
||||
<li><a name="event_y">Fl::event_y</a>
|
||||
<li><a name="event_y_root">Fl::event_y_root</a>
|
||||
<li><a name="get_key">Fl::get_key</a>
|
||||
<li><a name="get_mouse">Fl::get_mouse</a>
|
||||
<li><a name="test_shortcut">Fl::test_shortcut</a>
|
||||
</ul>
|
||||
|
||||
<p>Known bugs: on X <code>Fl::get_key(FL_Button+n)</code> does not
|
||||
work. On MSWindows <code>Fl::get_key(FL_KP_Enter)</code> and
|
||||
<code>Fl::event_key(FL_KP_Enter)</code> do not work.
|
||||
<h2><a name="propagation">Event Propagation</a></h2>
|
||||
|
||||
<a name=event_text>
|
||||
</ul><h4><code>char * Fl::event_text()</code></h4><ul>
|
||||
|
||||
<p>ASCII text (in the future this may be UTF-8) produced by the last
|
||||
FL_KEYBOARD or FL_PASTE or possibly other event. A zero-length string
|
||||
is returned for any keyboard function keys that do not produce text.
|
||||
This pointer points at a static buffer and is only valid until the
|
||||
next event is processed.
|
||||
|
||||
<p>Under X this is the result of XLookupString.
|
||||
|
||||
<a name=event_length>
|
||||
</ul><h4><code>char * Fl::event_length()</code></h4><ul>
|
||||
|
||||
<p>Length of the text in Fl::event_text(). There will always be a
|
||||
null at this position in the text. However there may be a nul before
|
||||
that if the keystroke translates to a nul character or you paste a nul
|
||||
character.
|
||||
|
||||
</ul><h4><code>int Fl::event_is_click()</code></h4><ul>
|
||||
|
||||
Returns non-zero if the mouse has not moved far enough and not enough
|
||||
time has passed since the last FL_PUSH or FL_KEYBOARD event for it
|
||||
to be considered a "drag" rather than a "click". You can test this on
|
||||
FL_DRAG, FL_RELEASE, and FL_MOVE events.
|
||||
|
||||
</ul><h4><code>void Fl::event_is_click(0)</code></h4><ul>
|
||||
|
||||
Clear 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.
|
||||
|
||||
</ul><h4><code>int Fl::event_clicks()</code></h4><ul>
|
||||
|
||||
Returns non-zero if the most recent FL_PUSH or FL_KEYBOARD was a
|
||||
"double click". Returns N-1 for N clicks. A double click is counted
|
||||
if the same button is pressed again while event_is_click() is true.
|
||||
|
||||
</ul><h4><code>void Fl::event_clicks(int)</code></h4><ul>
|
||||
|
||||
Directly set the number returned by Fl::event_clicks(). This can be
|
||||
used to set it to zero so that later code does not think an item was
|
||||
double-clicked.
|
||||
|
||||
</ul><h4><code>int Fl::event_inside(const Fl_Widget *) const ;
|
||||
<br>int Fl::event_inside(int,int,int,int);</code></h4><ul>
|
||||
|
||||
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.
|
||||
|
||||
</ul><h4><code>int Fl::test_shortcut(ulong) const ;</code></h4><ul>
|
||||
|
||||
Test the current event, which must be an FL_KEYBOARD or FL_SHORTCUT,
|
||||
against a shortcut value (described in <a
|
||||
href=Fl_Button.html#shortcut>Fl_Button</a>). Returns non-zero if
|
||||
there is a match. Not to be confused with <a
|
||||
href=subclass.html#test_shortcut>Fl_Widget::test_shortcut()</a>.
|
||||
|
||||
</ul>
|
||||
|
||||
<a name=propagation>
|
||||
<h2>Event Propagation</h2>
|
||||
|
||||
<p>Fltk follows very simple and unchangeable rules for sending events.
|
||||
The major innovation is that widgets can indicate (by returning 0 from
|
||||
the handle() method) that they are not interested in an event, and fltk
|
||||
can then send that event elsewhere. This eliminates the need for
|
||||
FLTK follows very simple and unchangeable rules for sending events. The
|
||||
major innovation is that widgets can indicate (by returning 0 from the
|
||||
<tt>handle()</tt> method) that they are not interested in an event, and
|
||||
FLTK can then send that event elsewhere. This eliminates the need for
|
||||
"interests" (event masks or tables), and this is probably the main
|
||||
reason fltk is much smaller than other X toolkits.
|
||||
reason FLTK is much smaller than other toolkits.
|
||||
|
||||
<p>Most events are sent directly to the handle() method of the
|
||||
Fl_Window that X says they belong to. The window (actually the
|
||||
Fl_Group that Fl_Window is a subclass of) is responsible for sending
|
||||
the events on to any child widgets. To make the Fl_Group code
|
||||
somewhat easier, fltk sends some events (FL_DRAG, FL_RELEASE,
|
||||
FL_KEYBOARD, FL_SHORTCUT, FL_UNFOCUS, FL_LEAVE) directly to leaf
|
||||
widgets. These procedures control those leaf widgets:
|
||||
<p>Most events are sent directly to the <tt>handle()</tt> method of the
|
||||
<tt>Fl_Window</tt> that the window system says they belong to. The
|
||||
window (actually the <tt>Fl_Group</tt> that <tt>Fl_Window</tt> is a
|
||||
subclass of) is responsible for sending the events on to any child
|
||||
widgets. To make the <tt>Fl_Group</tt> code somewhat easier, FLTK
|
||||
sends some events (<tt>FL_DRAG</tt>, <tt>FL_RELEASE</tt>,
|
||||
<tt>FL_KEYBOARD</tt>, <tt>FL_SHORTCUT</tt>, <tt>FL_UNFOCUS</tt>, and
|
||||
<tt>FL_LEAVE</tt>) directly to leaf widgets. These procedures control
|
||||
those leaf widgets:
|
||||
|
||||
<a name=focus>
|
||||
</ul><h4><code>Fl_Widget *Fl::focus() const;
|
||||
<br>void Fl::focus(Fl_Widget *);</code></h4><ul>
|
||||
|
||||
Get or set the widget that will receive FL_KEYBOARD events.
|
||||
|
||||
<p>If you change Fl::focus(), the old one and all parents (that don't
|
||||
contain the new widget) are sent FL_UNFOCUS events. Changing the
|
||||
focus does <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()).
|
||||
|
||||
</ul><h4><code>int Fl_Widget::take_focus();</code></h4><ul>
|
||||
|
||||
<p>Try to make this widget be the Fl::focus(), by first sending it an
|
||||
FL_FOCUS event, and if it returns non-zero, setting Fl::focus() to
|
||||
this widget. You should use this method to assign the focus to an
|
||||
widget. Returns true if the widget accepted the focus.
|
||||
|
||||
<a name=belowmouse>
|
||||
</ul><h4><code>Fl_Widget *Fl::belowmouse() const;
|
||||
<br>void Fl::belowmouse(Fl_Widget *);</code></h4><ul>
|
||||
|
||||
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 old 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()).
|
||||
|
||||
<a name=pushed>
|
||||
</ul><h4><code>Fl_Widget *Fl::pushed() const;
|
||||
<br>void Fl::pushed(Fl_Widget *);</code></h4><ul>
|
||||
|
||||
<p>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 old 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()).
|
||||
|
||||
<a name=add_handler>
|
||||
</ul><h4><code>void Fl::add_handler(int (*f)(int));</code></h4><ul>
|
||||
|
||||
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:
|
||||
|
||||
<p><ul>
|
||||
<li>FL_SHORTCUT events that are not recognized by any widget. This
|
||||
lets you provide global shortcut keys.
|
||||
|
||||
<li>System events that fltk does not recognize. See <a
|
||||
href=x.html#fl_xevent>fl_xevent</a>.
|
||||
|
||||
<li><i>Some</i> other events when the widget fltk selected returns zero
|
||||
from it's handle() method. Exactly which ones may change in future
|
||||
versions, however.
|
||||
<ul>
|
||||
<li><a href="#add_handler">Fl::add_handler</a>
|
||||
<li><a href="#belowmouse">Fl::belowmouse</a>
|
||||
<li><a href="#focus">Fl::focus</a>
|
||||
<li><a href="#grab">Fl::grab</a>
|
||||
<li><a href="#modal">Fl::modal</a>
|
||||
<li><a href="#pushed">Fl::pushed</a>
|
||||
<li><a href="#release">Fl::release</a>
|
||||
<li><a href="#Fl_Widget.take_focus">Fl_Widget::take_focus</a>
|
||||
</ul>
|
||||
|
||||
<a name=modal>
|
||||
</ul><h4><code>Fl_Window* Fl::modal();</code></h4><ul>
|
||||
|
||||
The modal() window has it's handle() method called for all events, and
|
||||
no other windows will have handle() called. If <a
|
||||
href=#grab>grab()</a> has been done then this is equal to grab().
|
||||
Otherwise this is the most recently shown() window with <a
|
||||
href=Fl_Window.html#modal>modal()</a> true, or null if there are no
|
||||
modal() windows shown().
|
||||
|
||||
<a name=grab>
|
||||
</ul><h4><code>void Fl::grab(Fl_Window&);<br>
|
||||
Fl_Window* Fl::grab();</code></h4><ul>
|
||||
|
||||
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 "dummy" window override all event
|
||||
handling and allows you to map and unmap a complex set of windows
|
||||
(under both X and NT <i>some</i> window must be mapped because the
|
||||
system interface needs a window id).
|
||||
|
||||
<p>Fl::event_x() and y() are undefiend if the passed widget is not a
|
||||
mapped Fl_Window. Use Fl::event_x_root() and Fl::event_y_root()
|
||||
instead.
|
||||
|
||||
<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>
|
||||
|
||||
<p>The second function returns the current grab window, or null if
|
||||
none.
|
||||
|
||||
<a name=release>
|
||||
</ul><h4><code>void Fl::release()</code></h4><ul>
|
||||
|
||||
Turn off the grab() behavior.
|
||||
|
||||
</ul><p><a href = index.html>(back to contents)</a>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,182 +3,193 @@
|
||||
|
||||
<H1 ALIGN=RIGHT><A NAME="forms">E - Forms Compatibility</A></H1>
|
||||
|
||||
<a href="#fluid">Fluid</a> (the Fast Light User Interface Designer)
|
||||
can read the .fd files put out by all versions of Forms and XForms
|
||||
fdesign. However, it will mangle them a bit, but it prints a warning
|
||||
message about anything it does not understand. Fluid cannot write
|
||||
fdesign files, so you should save to a new name so you don't write
|
||||
over the old one.
|
||||
This appendix describes the Forms compatibility included with FLTK.
|
||||
|
||||
<H2>Importing Forms Layout Files</H2>
|
||||
|
||||
<a href="#FLUID">FLUID</a> can read the .fd files put out by all
|
||||
versions of Forms and XForms fdesign. However, it will mangle them a
|
||||
bit, but it prints a warning message about anything it does not
|
||||
understand. FLUID cannot write fdesign files, so you should save to a
|
||||
new name so you don't write over the old one.
|
||||
|
||||
<p>You will need to edit your main code considerably to get it to link
|
||||
with the output from fluid. If you are not interested in this you may
|
||||
have more immediate luck with the forms compatability header,
|
||||
with the output from FLUID. If you are not interested in this you may
|
||||
have more immediate luck with the forms compatibility header,
|
||||
<tt><FL/forms.H></tt>.
|
||||
|
||||
<p>You should be able to compile existing Forms or XForms source code
|
||||
by changing the -I switch to your compiler so that the forms.h file
|
||||
supplied with FLTK is included. Take a look at forms.h to see how it
|
||||
works, but the basic trick is lots of inline functions.
|
||||
Most of the XForms demo programs work without changes.
|
||||
<H2>Using the Compatibility Header File</H2>
|
||||
|
||||
You should be able to compile existing Forms or XForms source code
|
||||
by changing the include directory switch to your compiler so that the
|
||||
<tt>forms.h</tt> file supplied with FLTK is included. Take a look at
|
||||
<tt>forms.h</tt> to see how it works, but the basic trick is lots of
|
||||
inline functions. Most of the XForms demo programs work without
|
||||
changes.
|
||||
|
||||
<p>You will also have to compile your Forms or XForms program using a
|
||||
C++ compiler. The FLTK library does not provide C bindings or header
|
||||
files.
|
||||
|
||||
<p>Although FLTK was designed to be compatable with the GL Forms library
|
||||
(version 0.3 or so), XForms has bloated severely and it's interface is
|
||||
X specific. Therefore, XForms compatability is no longer a goal of
|
||||
FLTK. Compatability was limited to things that were free, or that
|
||||
would add code that would not be linked in if the feature is unused.
|
||||
I did not add anything that would make the FLTK widgets bigger, or that
|
||||
used X types as arguments.
|
||||
X-specific. Therefore, XForms compatibility is no longer a goal of
|
||||
FLTK. Compatibility was limited to things that were free, or that
|
||||
would add code that would not be linked in if the feature is unused,
|
||||
or that was not X-specific.
|
||||
|
||||
<p>To use any new features of FLTK, you should rewrite your code to not
|
||||
use the inline functions and instead use "pure" FLTK. This
|
||||
will make it a lot cleaner and make it easier to figure out how to
|
||||
call the FLTK functions. Unfortunately this conversion is harder than I
|
||||
expeceted and even our inhouse code still uses forms.H a lot.
|
||||
use the inline functions and instead use "pure" FLTK. This will make
|
||||
it a lot cleaner and make it easier to figure out how to call the FLTK
|
||||
functions. Unfortunately this conversion is harder than expected and
|
||||
even Digital Domain's inhouse code still uses <tt>forms.H</tt> a lot.
|
||||
|
||||
<h2>Problems you will encounter</h2>
|
||||
|
||||
<ul>
|
||||
|
||||
<p><li>Many parts of XForms use X-specific structures like XEvent in
|
||||
their interface. I did not emulate these! Unfortunately these
|
||||
<p>Many parts of XForms use X-specific structures like <tt>XEvent</tt>
|
||||
in their interface. I did not emulate these! Unfortunately these
|
||||
features (such as the "canvas" widget) are needed by most large
|
||||
programs. You will need to rewrite these to use FLTK subclasses.
|
||||
|
||||
<p><li><a href=Fl_Free.html>Fl_Free</a> widgets emulate the <i>old</i>
|
||||
Forms "free" widget. It may be useful for porting programs that
|
||||
change the handle() function on widgets, but you will still need to
|
||||
rewrite things.
|
||||
<p><a href="#Fl_Free"><tt>Fl_Free</tt></a> widgets emulate the
|
||||
<i>old</i> Forms "free" widget. It may be useful for porting programs
|
||||
that change the <tt>handle()</tt> function on widgets, but you will
|
||||
still need to rewrite things.
|
||||
|
||||
<P><li><a href=Fl_Timer.html>Fl_Timer</a> widgets are provided to
|
||||
emulate the XForms timer. These work, but are quite inefficient
|
||||
and inaccurate compared to using Fl::add_timeout().
|
||||
<p><a href="#Fl_Timer"><tt>Fl_Timer</tt></a> widgets are provided to
|
||||
emulate the XForms timer. These work, but are quite inefficient and
|
||||
inaccurate compared to using <a
|
||||
href="#add_timeout"><tt>Fl::add_timeout()</tt></a>.
|
||||
|
||||
<p><li><i>All instance variables are hidden.</i>
|
||||
<p><i>All instance variables are hidden.</i>
|
||||
If you directly refer to the x, y, w, h, label, or other fields of
|
||||
your Forms widgets you will have to add empty parenthesis after each
|
||||
reference. The easiest way to do this is to globally replace "->x"
|
||||
with "->x()", etc. Replace "boxtype" with box().
|
||||
with "->x()", etc. Replace "boxtype" with "box()".
|
||||
|
||||
<p><li>const char* arguments to most FLTK methods are simply stored, while
|
||||
Forms would strdup() the passed string. This is most noticable with the
|
||||
label of widgets. Your program must always pass static data such as a
|
||||
string constant or malloc'd buffer to label(). If you are using
|
||||
labels to display program output you may want to try the <a
|
||||
href=Fl_Output.html>Fl_Output</a> widget.
|
||||
<p><tt>const char *</tt> arguments to most FLTK methods are simply
|
||||
stored, while Forms would <tt>strdup()</tt> the passed string. This is
|
||||
most noticable with the label of widgets. Your program must always
|
||||
pass static data such as a string constant or malloc'd buffer to
|
||||
<tt>label()</tt>. If you are using labels to display program output
|
||||
you may want to try the <a href="#Fl_Output"><tt>Fl_Output</tt></a> widget.
|
||||
|
||||
<p><li>The default fonts and sizes are matched to the older GL version of
|
||||
<p>The default fonts and sizes are matched to the older GL version of
|
||||
Forms, so all labels will draw somewhat larger than an XForms program
|
||||
does.
|
||||
|
||||
<p><li>fdesign outputs a setting of a "fdui" instance variable to the main
|
||||
window. I did not emulate this because I wanted all instance
|
||||
variables to be hidden. You can store the same information in the
|
||||
user_data() field of a window. To do this,
|
||||
search through the fdesign output for all occurances
|
||||
of "->fdui" and edit to use "->user_data()" instead. This will
|
||||
require casts and is not trivial.
|
||||
<p>fdesign outputs a setting of a "fdui" instance variable to the main
|
||||
window. I did not emulate this because I wanted all instance variables
|
||||
to be hidden. You can store the same information in the
|
||||
<tt>user_data()</tt> field of a window. To do this, search through
|
||||
the fdesign output for all occurances of "->fdui" and edit to use
|
||||
"->user_data()" instead. This will require casts and is not trivial.
|
||||
|
||||
<p><li>The prototype for the functions passed to fl_add_timeout() and
|
||||
fl_set_idle_callback() callback are different.
|
||||
<p>The prototype for the functions passed to <tt>fl_add_timeout()</tt>
|
||||
and <tt>fl_set_idle_callback()</tt> callback are different.
|
||||
|
||||
<p><li><b>All the following XForms calls are missing:</b><p>
|
||||
<p><b>All the following XForms calls are missing:</b><p>
|
||||
|
||||
<li><code>FL_VERSION, FL_REVISION</code>, fl_library_version()
|
||||
<li><code>FL_RETURN_DBLCLICK</code> (use Fl::event_clicks())
|
||||
<li>fl_add_signal_callback()
|
||||
<li>fl_set_form_atactivate() & fl_set_form_atdeactivate()
|
||||
<li>fl_set_form_property()
|
||||
<li>fl_set_app_mainform(), fl_get_app_mainform()
|
||||
<li>fl_set_form_minsize(), fl_set_form_maxsize()
|
||||
<li>fl_set_form_event_cmask(), fl_get_form_event_cmask()
|
||||
<li>fl_set_form_dblbuffer(), fl_set_object_dblbuffer() (use an
|
||||
Fl_Double_Window instead)
|
||||
<li>fl_adjust_form_size()
|
||||
<li>fl_register_raw_callback()
|
||||
<li>fl_set_object_bw(), fl_set_border_width()
|
||||
<li>fl_set_object_resize(), fl_set_object_gravity()
|
||||
<li>fl_set_object_shortcutkey()
|
||||
<li>fl_set_object_automatic()
|
||||
<li>fl_get_object_bbox() (maybe FLTK should do this)
|
||||
<li>fl_set_object_prehandler(), fl_set_object_posthandler()
|
||||
<li>fl_enumerate_fonts()
|
||||
<li>Most drawing functions
|
||||
<li>fl_set_coordunit() (FLTK uses pixels all the time)
|
||||
<li>fl_ringbell()
|
||||
<li>fl_gettime()
|
||||
<li>fl_win*() (all these functions)
|
||||
<li>fl_initialize(argc,argv,x,y,z) ignores last 3 arguments
|
||||
<li>fl_read_bitmapfile(), fl_read_pixmapfile()
|
||||
<li>fl_addto_browser_chars()
|
||||
<li>FL_MENU_BUTTON just draws normally
|
||||
<li>fl_set_bitmapbutton_file(), fl_set_pixmapbutton_file()
|
||||
<li>FL_CANVAS objects
|
||||
<li>FL_DIGITAL_CLOCK (comes out analog)
|
||||
<li>fl_create_bitmap_cursor(), fl_set_cursor_color()
|
||||
<li>fl_set_dial_angles()
|
||||
<li>fl_show_oneliner()
|
||||
<li>fl_set_choice_shortcut(a,b,c)
|
||||
<li>command log
|
||||
<li>Only some of file selector is emulated
|
||||
<li>FL_DATE_INPUT
|
||||
<li>fl_pup*() (all these functions)
|
||||
<li>textbox object (should be easy but I had no sample programs)
|
||||
<li>xyplot object
|
||||
<ul>
|
||||
<li><tt>FL_REVISION</tt>, <tt>fl_library_version()</tt>
|
||||
<li><tt>FL_RETURN_DBLCLICK</tt> (use <tt>Fl::event_clicks()</tt>)
|
||||
<li><tt>fl_add_signal_callback()</tt>
|
||||
<li><tt>fl_set_form_atactivate()</tt> & <tt>fl_set_form_atdeactivate()</tt>
|
||||
<li><tt>fl_set_form_property()</tt>
|
||||
<li><tt>fl_set_app_mainform()</tt>, <tt>fl_get_app_mainform()</tt>
|
||||
<li><tt>fl_set_form_minsize()</tt>, <tt>fl_set_form_maxsize()</tt>
|
||||
<li><tt>fl_set_form_event_cmask()</tt>, <tt>fl_get_form_event_cmask()</tt>
|
||||
<li><tt>fl_set_form_dblbuffer()</tt>, <tt>fl_set_object_dblbuffer()</tt> (use an
|
||||
<tt>Fl_Double_Window</tt> instead)
|
||||
<li><tt>fl_adjust_form_size()</tt>
|
||||
<li><tt>fl_register_raw_callback()</tt>
|
||||
<li><tt>fl_set_object_bw()</tt>, <tt>fl_set_border_width()</tt>
|
||||
<li><tt>fl_set_object_resize()</tt>, <tt>fl_set_object_gravity()</tt>
|
||||
<li><tt>fl_set_object_shortcutkey()</tt>
|
||||
<li><tt>fl_set_object_automatic()</tt>
|
||||
<li><tt>fl_get_object_bbox()</tt> (maybe FLTK should do this)
|
||||
<li><tt>fl_set_object_prehandler()</tt>, <tt>fl_set_object_posthandler()</tt>
|
||||
<li><tt>fl_enumerate_fonts()</tt>
|
||||
<li>Most drawing functions
|
||||
<li><tt>fl_set_coordunit()</tt> (FLTK uses pixels all the time)
|
||||
<li><tt>fl_ringbell()</tt>
|
||||
<li><tt>fl_gettime()</tt>
|
||||
<li><tt>fl_win*()</tt> (all these functions)
|
||||
<li><tt>fl_initialize(argc,argv,x,y,z)</tt> ignores last 3 arguments
|
||||
<li><tt>fl_read_bitmapfile()</tt>, <tt>fl_read_pixmapfile()</tt>
|
||||
<li><tt>fl_addto_browser_chars()</tt>
|
||||
<li><tt>FL_MENU_BUTTON</tt> just draws normally
|
||||
<li><tt>fl_set_bitmapbutton_file()</tt>, <tt>fl_set_pixmapbutton_file()</tt>
|
||||
<li><tt>FL_CANVAS</tt> objects
|
||||
<li><tt>FL_DIGITAL_CLOCK</tt> (comes out analog)
|
||||
<li><tt>fl_create_bitmap_cursor()</tt>, <tt>fl_set_cursor_color()</tt>
|
||||
<li><tt>fl_set_dial_angles()</tt>
|
||||
<li><tt>fl_show_oneliner()</tt>
|
||||
<li><tt>fl_set_choice_shortcut(a,b,c)
|
||||
<li>command log
|
||||
<li>Only some of file selector is emulated
|
||||
<li><tt>FL_DATE_INPUT</tt>
|
||||
<li><tt>fl_pup*()</tt> (all these functions)
|
||||
<li>textbox object (should be easy but I had no sample programs)
|
||||
<li>xyplot object
|
||||
</ul>
|
||||
|
||||
<h2>Additional notes for porting old Forms programs</h2>
|
||||
<h2>Additional Notes</h2>
|
||||
|
||||
<p>These notes were written for porting programs written with the
|
||||
older GL version of Forms. Most of these problems are the same ones
|
||||
These notes were written for porting programs written with the older
|
||||
IRISGL version of Forms. Most of these problems are the same ones
|
||||
encountered when going from old Forms to XForms:
|
||||
|
||||
<h4>Does not go into background</h4>
|
||||
<h3>Does Not Run In Background</h3>
|
||||
|
||||
The GL library always forked when you created the first window, unless
|
||||
The IRISGL library always forked when you created the first window, unless
|
||||
"foreground()" was called. FLTK acts like "foreground()" is called all
|
||||
the time. If you really want the fork behavior do "if (fork())
|
||||
exit(0)" right at the start of your program.
|
||||
|
||||
<h4>You cannot use GL windows or fl_queue</h4>
|
||||
<h3>You Cannot Use IRISGL windows or fl_queue</h3>
|
||||
|
||||
<P>If a Forms (not XForms) program if you wanted your own window for
|
||||
displaying things you would create a GL window and draw in it,
|
||||
If a Forms (not XForms) program if you wanted your own window for
|
||||
displaying things you would create a IRISGL window and draw in it,
|
||||
periodically calling Forms to check if the user hit buttons on the
|
||||
panels. If the user did things to the GL window, you would find this
|
||||
out by having the value FL_EVENT returned from the call to Forms.
|
||||
panels. If the user did things to the IRISGL window, you would find
|
||||
this out by having the value FL_EVENT returned from the call to Forms.
|
||||
|
||||
<p>None of this works with FLTK. Nor will it compile, the necessary
|
||||
calls are not in the interface.
|
||||
|
||||
<p>You have to make a subclass of <a
|
||||
href=Fl_Gl_Window.html>Fl_Gl_Window</a> and write a draw() method and
|
||||
handle() method. This may require anywhere from a trivial to a major
|
||||
rewrite. See the example program <a href=shape.C.html>shape.C</a> for
|
||||
how this is structured.
|
||||
href="#Fl_Gl_Window"><tt>Fl_Gl_Window</tt></a> and write a <tt>draw()</tt>
|
||||
method and <tt>handle()</tt> method. This may require anywhere from a trivial
|
||||
to a major rewrite.
|
||||
|
||||
<p>If you draw into the overlay planes you will have to also write a
|
||||
draw_overlay() routine and call redraw_overlay() on the gl window.
|
||||
<tt>draw_overlay()</tt> method and call <tt>redraw_overlay()</tt> on the
|
||||
OpenGL window.
|
||||
|
||||
<p>One easy way to hack your program so it works is to make the draw()
|
||||
and handle() methods on your window set some static variables, storing
|
||||
what event happened. Then in the main loop of your program, call
|
||||
Fl::wait() and then check these variables, acting on them as
|
||||
though they are events read from fl_queue.
|
||||
<p>One easy way to hack your program so it works is to make the
|
||||
<tt>draw()</tt> and <tt>handle()</tt> methods on your window set some
|
||||
static variables, storing what event happened. Then in the main loop
|
||||
of your program, call <tt>Fl::wait()</tt> and then check these
|
||||
variables, acting on them as though they are events read from
|
||||
<tt>fl_queue</tt>.
|
||||
|
||||
<h4>You must use OpenGL to draw everything</h4>
|
||||
<h3>You Must Use OpenGL to Draw Everything</h3>
|
||||
|
||||
<p>The file <FL/gl.h> defines replacements for a lot of gl calls,
|
||||
translating them to OpenGL. There are much better translators
|
||||
available that you might want to investigate.
|
||||
<p>The file <tt><FL/gl.h></tt> defines replacements for a lot of
|
||||
IRISGL calls, translating them to OpenGL. There are much better
|
||||
translators available that you might want to investigate.
|
||||
|
||||
<h4>You cannot make Forms subclasses</h4>
|
||||
<h3>You Cannot Make Forms Subclasses</h3>
|
||||
|
||||
Programs that call fl_make_object or directly setting the handle
|
||||
routine will not compile. You have to rewrite them to use a subclass
|
||||
of Fl_Widget. It is important to note that the handle() method is not
|
||||
exactly the same as the handle() function of Forms. Where a Forms
|
||||
handle() returned non-zero, your handle() must call do_callback().
|
||||
And your handle() must return non-zero if it "understood" the event.
|
||||
Programs that call <tt>fl_make_object</tt> or directly setting the
|
||||
handle routine will not compile. You have to rewrite them to use a
|
||||
subclass of <tt>Fl_Widget</tt>. It is important to note that the
|
||||
<tt>handle()</tt> method is not exactly the same as the
|
||||
<tt>handle()</tt> function of Forms. Where a Forms <tt>handle()</tt>
|
||||
returned non-zero, your <tt>handle()</tt> must call
|
||||
<tt>do_callback()</tt>. And your <tt>handle()</tt> must return non-zero
|
||||
if it "understood" the event.
|
||||
|
||||
<p>An attempt has been made to emulate the "free" widget. This
|
||||
appears to work quite well. It may be quicker to modify your subclass
|
||||
@ -187,34 +198,64 @@ into a "free" widget, since the "handle" functions match.
|
||||
<p>If your subclass draws into the overlay you are in trouble and will
|
||||
have to rewrite things a lot.
|
||||
|
||||
<h4>You cannot use <device.h></h4>
|
||||
<h3>You Cannot Use <device.h></h3>
|
||||
|
||||
If you have written your own "free" widgets you will probably get a
|
||||
lot of errors about "getvaluator". You should substitute:
|
||||
|
||||
<table>
|
||||
<tr><td align=center>Forms <td align=center>FLTK
|
||||
<tr><td>MOUSE_X <td>Fl::event_x_root()
|
||||
<tr><td>MOUSE_Y<td> Fl::event_y_root()
|
||||
<tr><td>LEFTSHIFTKEY,RIGHTSHIFTKEY<td> Fl::event_shift()
|
||||
<tr><td>CAPSLOCKKEY<td> Fl::event_capslock()
|
||||
<tr><td>LEFTCTRLKEY,RIGHTCTRLKEY<td> Fl::event_ctrl()
|
||||
<tr><td>LEFTALTKEY,RIGHTALTKEY<td> Fl::event_alt()
|
||||
<tr><td>MOUSE1,RIGHTMOUSE<td> Fl::event_state()&(1<<10)
|
||||
<tr><td>MOUSE2,MIDDLEMOUSE<td> Fl::event_state()&(1<<9)
|
||||
<tr><td>MOUSE3,LEFTMOUSE<td> Fl::event_state()&(1<<8)
|
||||
<table border=1>
|
||||
<tr>
|
||||
<th align=center>Forms</th>
|
||||
<th align=center>FLTK</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MOUSE_X</td>
|
||||
<td>Fl::event_x_root()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MOUSE_Y</td>
|
||||
<td>Fl::event_y_root()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LEFTSHIFTKEY,RIGHTSHIFTKEY</td>
|
||||
<td>Fl::event_shift()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAPSLOCKKEY</td>
|
||||
<td>Fl::event_capslock()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LEFTCTRLKEY,RIGHTCTRLKEY</td>
|
||||
<td>Fl::event_ctrl()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LEFTALTKEY,RIGHTALTKEY</td>
|
||||
<td>Fl::event_alt()</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MOUSE1,RIGHTMOUSE</td>
|
||||
<td>Fl::event_state()&FL_BUTTON3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MOUSE2,MIDDLEMOUSE</td>
|
||||
<td>Fl::event_state()&FL_BUTTON2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MOUSE3,LEFTMOUSE</td>
|
||||
<td>Fl::event_state()&FL_BUTTON1</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Anything else in getvaluator and you are on your own...
|
||||
Anything else in <tt>getvaluator</tt> and you are on your own...
|
||||
|
||||
<h4>Font numbers are different</h4>
|
||||
<h3>Font Numbers Are Different</h3>
|
||||
|
||||
The "style" numbers have been changed because I wanted to insert
|
||||
bold-italic versions of the normal fonts. If you use Times, Courier,
|
||||
or Bookman to display any text you will get a different font out of
|
||||
FLTK. If you are really desperate to fix this use the following code:<ul>
|
||||
FLTK. If you are really desperate to fix this use the following code:
|
||||
|
||||
<pre>
|
||||
<ul><pre>
|
||||
fl_font_name(3,"*courier-medium-r-no*");
|
||||
fl_font_name(4,"*courier-bold-r-no*");
|
||||
fl_font_name(5,"*courier-medium-o-no*");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,143 +3,192 @@
|
||||
|
||||
<H1 ALIGN=RIGHT><A NAME="glut">D - GLUT Compatibility</A></H1>
|
||||
|
||||
You should be able to compile existing Glut source code by
|
||||
including <FL/glut.H> instead of <GL/glut.h>. This can be done by
|
||||
editing the source, by changing the -I switches to the compiler, or by
|
||||
providing a symbolic link from GL/glut.h to FL/glut.H.
|
||||
This appendix describes the GLUT compatibility header file supplied with
|
||||
FLTK.
|
||||
|
||||
<p>All files calling glut procedures must be compiled with C++. You may
|
||||
<H2>Using the GLUT Compatibility Header File</H2>
|
||||
|
||||
You should be able to compile existing GLUT source code by including
|
||||
<tt><FL/glut.H></tt> instead of <tt><GL/glut.h></tt>. This can
|
||||
be done by editing the source, by changing the <tt>-I</tt> switches to
|
||||
the compiler, or by providing a symbolic link from <tt>GL/glut.h</tt>
|
||||
to <tt>FL/glut.H</tt>.
|
||||
|
||||
<p><i>All files calling GLUT procedures must be compiled with C++</i>. You may
|
||||
have to alter them slightly to get them to compile without warnings,
|
||||
and you may have to rename them to get make to use the C++ compiler.
|
||||
I was unable to get some calls to glu to compile without adding some
|
||||
casts, apparently due to errors in the glu header files.
|
||||
|
||||
<p>You must link with -lFl. If you call any glut drawing functions
|
||||
that fltk does not emulate (<code>glutExtensionsSupported(), glutWire*(),
|
||||
glutSolid*(), and glutStroke*()</code>), you will also have to link with
|
||||
-lglut, <i>after</i> -lFl.
|
||||
<p>You must link with the FLTK library. If you call any GLUT drawing
|
||||
functions that FLTK does not emulate
|
||||
(<tt>glutExtensionsSupported()</tt>, <tt>glutWire*()</tt>,
|
||||
<tt>glutSolid*()</tt>, and <tt>glutStroke*()</tt>), you will also have
|
||||
to link with the GLUT library (<i>after</i> the FLTK library!)
|
||||
|
||||
<p>Most of glut.H is inline functions. You should take a look at it
|
||||
(and maybe at glut.C in the fltk source) if you are having trouble
|
||||
porting your Glut program.
|
||||
<p>Most of <tt>FL/glut.H</tt> is inline functions. You should take a
|
||||
look at it (and maybe at <tt>test/glut.cxx</tt> in the FLTK source) if
|
||||
you are having trouble porting your GLUT program.
|
||||
|
||||
<p>This has been tested with most of the demo programs that come with
|
||||
the Glut 3.3 distribution.
|
||||
the GLUT 3.3 distribution.
|
||||
|
||||
<h2>Known Problems</h2>
|
||||
|
||||
The following functions and/or arguments to functions are missing,
|
||||
and you will have to replace them or comment them out for your code to
|
||||
compile:
|
||||
|
||||
<ul>
|
||||
|
||||
<li>The following functions and/or arguments to functions are missing,
|
||||
and you will have to replace them or comment them out for your code to
|
||||
compile:<ul>
|
||||
|
||||
<li><code>glutLayerGet(GLUT_LAYER_IN_USE)</code>
|
||||
<li><code>glutLayerGet(GLUT_HAS_OVERLAY)</code>
|
||||
<li><code>glutSetColor(), glutGetColor(), glutCopyColormap()</code>
|
||||
<li><code>glutInitDisplayMode(GLUT_STEREO)</code>
|
||||
<li><code>glutInitDisplayMode(GLUT_LUMINANCE)</code>
|
||||
<li><code>glutPushWindow()</code>
|
||||
<li><code>glutWarpPointer()</code>
|
||||
<li>Spaceball, buttonbox, dials, tablet functions, <code>glutDeviceGet()</code>
|
||||
<li><code>glutWindowStatusFunc()</code>
|
||||
<li><code>glutGet(GLUT_WINDOW_NUM_CHILDREN)</code>
|
||||
<li><code>glutGet(GLUT_SCREEN_WIDTH_MM)</code>
|
||||
<li><code>glutGet(GLUT_SCREEN_HEIGHT_MM)</code>
|
||||
<li><code>glutGet(GLUT_ELAPSED_TIME)</code>
|
||||
<li><code>glutVideoResize()</code> missing.
|
||||
<li><tt>glutLayerGet(GLUT_LAYER_IN_USE)</tt>
|
||||
<li><tt>glutLayerGet(GLUT_HAS_OVERLAY)</tt>
|
||||
<li><tt>glutSetColor(), glutGetColor(), glutCopyColormap()</tt>
|
||||
<li><tt>glutInitDisplayMode(GLUT_STEREO)</tt>
|
||||
<li><tt>glutInitDisplayMode(GLUT_LUMINANCE)</tt>
|
||||
<li><tt>glutPushWindow()</tt>
|
||||
<li><tt>glutWarpPointer()</tt>
|
||||
<li>Spaceball, buttonbox, dials, tablet functions,
|
||||
<tt>glutDeviceGet()</tt>
|
||||
<li><tt>glutWindowStatusFunc()</tt>
|
||||
<li><tt>glutGet(GLUT_WINDOW_NUM_CHILDREN)</tt>
|
||||
<li><tt>glutGet(GLUT_SCREEN_WIDTH_MM)</tt>
|
||||
<li><tt>glutGet(GLUT_SCREEN_HEIGHT_MM)</tt>
|
||||
<li><tt>glutGet(GLUT_ELAPSED_TIME)</tt>
|
||||
<li><tt>glutVideoResize()</tt> missing.
|
||||
|
||||
</ul>
|
||||
|
||||
<li>Most of the symbols/enumerations have different values than
|
||||
Glut uses. This will break code that relies on the actual values.
|
||||
Most of the symbols/enumerations have different values than
|
||||
GLUT uses. This will break code that relies on the actual values.
|
||||
The only symbols guaranteed to have the same values are true/false
|
||||
pairs like <code>GLUT_DOWN</code> and <code>GLUT_UP</code>, mouse
|
||||
buttons <code>GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON,
|
||||
GLUT_RIGHT_BUTTON</code>, and <code>GLUT_KEY_F1</code> thru
|
||||
<code>F12</code>.
|
||||
pairs like <tt>GLUT_DOWN</tt> and <tt>GLUT_UP</tt>, mouse
|
||||
buttons <tt>GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON,
|
||||
GLUT_RIGHT_BUTTON</tt>, and <tt>GLUT_KEY_F1</tt> thru
|
||||
<tt>F12</tt>.
|
||||
|
||||
<li><i>The strings passed as menu labels are not copied</i>.
|
||||
<p>The strings passed as menu labels are not copied.
|
||||
|
||||
<li><code>glutPostRedisplay()</code> does not work if called from
|
||||
inside a display function. You must use <code>glutIdleFunc()</code>
|
||||
<p><tt>glutPostRedisplay()</tt> does not work if called from
|
||||
inside a display function. You must use <tt>glutIdleFunc()</tt>
|
||||
if you want your display to update continuously.
|
||||
|
||||
<li><code>glutSwapBuffers()</code> does not work from inside a display
|
||||
function. This is on purpose, because fltk swaps the buffers for you.
|
||||
<p><tt>glutSwapBuffers()</tt> does not work from inside a display
|
||||
function. This is on purpose, because FLTK swaps the buffers for you.
|
||||
|
||||
<li><code>glutUseLayer()</code> does not work well, and should only be
|
||||
<p><tt>glutUseLayer()</tt> does not work well, and should only be
|
||||
used to initialize transformations inside a resize callback. You
|
||||
should redraw overlays by using <code>glutOverlayDisplayFunc()</code>.
|
||||
should redraw overlays by using <tt>glutOverlayDisplayFunc()</tt>.
|
||||
|
||||
<li>Overlays are cleared before the overlay display function is
|
||||
called. <code>glutLayerGet(GLUT_OVERLAY_DAMAGED)</code> always
|
||||
returns true, this fixed some glut overlay programs. You must rewrite
|
||||
your code so that gl_color() is used to choose colors in an overlay,
|
||||
or you will get random overlay colors.
|
||||
<p>Overlays are cleared before the overlay display function is called.
|
||||
<tt>glutLayerGet(GLUT_OVERLAY_DAMAGED)</tt> always returns true for
|
||||
compatibility with some GLUT overlay programs. You must rewrite your
|
||||
code so that <tt>gl_color()</tt> is used to choose colors in an
|
||||
overlay, or you will get random overlay colors.
|
||||
|
||||
<li><code>glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR)</code> just
|
||||
<p><tt>glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR)</tt> just
|
||||
results in a small crosshair.
|
||||
|
||||
<li>The fonts used by <code>glutBitmapCharacter() and
|
||||
glutBitmapWidth()</code> may be different.
|
||||
<p>The fonts used by <tt>glutBitmapCharacter() and
|
||||
glutBitmapWidth()</tt> may be different.
|
||||
|
||||
<li><code>glutInit(argc,argv)</code> will consume different switches than glut
|
||||
<p><tt>glutInit(argc,argv)</tt> will consume different switches than GLUT
|
||||
does. It accepts the switches recognized by <a
|
||||
href=Fl.html>Fl_Window::arg()</a>, and will accept any
|
||||
abbreviation of these switches (such as -d for -display).
|
||||
href="#args"><tt>Fl::args()</tt></a>, and will accept any
|
||||
abbreviation of these switches (such as "-di" for "-display").
|
||||
|
||||
<h2>Mixing GLUT and FLTK Code</h2>
|
||||
|
||||
You can make your GLUT window a child of a <tt>Fl_Window</tt> with the
|
||||
following scheme. The biggest trick is that GLUT insists on
|
||||
<tt>show()</tt>'ing the window at the point it is created, which means the
|
||||
<tt>Fl_Window</tt> parent window must already be shown.
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Don't call <tt>glutInit()</tt>.
|
||||
|
||||
<li>Create your <tt>Fl_Window</tt>, and any FLTK widgets.
|
||||
Leave a blank area in the window for your GLUT window.
|
||||
|
||||
<li><tt>show()</tt> the <tt>Fl_Window</tt>. Perhaps call
|
||||
<tt>show(argc,argv)</tt>.
|
||||
|
||||
<li>Call <tt>window->begin()</tt> so that the GLUT window will
|
||||
be automatically added to it.
|
||||
|
||||
<li>Use <tt>glutInitWindowSize()</tt> and
|
||||
<tt>glutInitWindowPosition()</tt> to set the location in the
|
||||
parent window to put the GLUT window.
|
||||
|
||||
<li>Put your GLUT code next. It probably does not need many changes.
|
||||
Call <tt>window->end()</tt> immediately after the <tt>glutCreateWindow()</tt>!
|
||||
|
||||
<li>You can call either <tt>glutMainLoop()</tt>,
|
||||
<tt>Fl::run()</tt>, or loop calling <tt>Fl::wait()</tt> to run
|
||||
the program.
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Mixing Glut code and Fltk code</h2>
|
||||
<hr break>
|
||||
|
||||
You can make your Glut window a child of a Fl_Window with the
|
||||
following scheme. The biggest trick is that Glut insists on
|
||||
show()'ing the window at the point it is created, which means the
|
||||
Fl_Window parent window must already be show()n.
|
||||
<h2><a name="Fl_Glut_Window">class Fl_Glut_Window</a></h2>
|
||||
|
||||
<p>Don't call glutInit().
|
||||
<hr>
|
||||
|
||||
<p>Create your Fl_Window, and any fltk widgets. Leave a blank area in
|
||||
the window for your glut window.
|
||||
<h3>Class Hierarchy</h3>
|
||||
|
||||
<p>show() the Fl_Window. Perhaps call show(argc,argv).
|
||||
<ul><pre>
|
||||
<a href="#Fl_Gl_Window">Fl_Gl_Window</a>
|
||||
|
|
||||
+----<b>Fl_Glut_Window</b>
|
||||
</pre></ul>
|
||||
|
||||
<p>Call window->begin() so the glut window will be automatically added
|
||||
to it.
|
||||
<h3>Include Files</h3>
|
||||
|
||||
<p>Use glutInitWindowSize() and glutInitWindowPosition() to set the
|
||||
location in the parent window to put the glut window.
|
||||
<ul><pre>
|
||||
#include <FL/glut.H>
|
||||
</pre></ul>
|
||||
|
||||
<p>Put your glut code next. It probably does not need many changes.
|
||||
Call window->end() immediately after the glutCreateWindow()!
|
||||
<h3>Description</h3>
|
||||
|
||||
<p>You can call either glutMainLoop() or Fl::run() or loop calling
|
||||
Fl::wait() to run the program.
|
||||
|
||||
<h2>class Fl_Glut_Window : public <a href=Fl_Gl_Window.html>Fl_Gl_Window</a></h2>
|
||||
|
||||
Each Glut window is an instance of this class, which is a subclass of
|
||||
<a href=Fl_Gl_Window.html>Fl_Gl_Window</a>. You may find it useful to
|
||||
manipulate instances directly rather than use glut window id's. These
|
||||
Each GLUT window is an instance of this class. You may find it useful to
|
||||
manipulate instances directly rather than use GLUT window id's. These
|
||||
may be created without opening the display, and thus can fit better
|
||||
into FL's method of creating windows.
|
||||
into FLTK's method of creating windows.
|
||||
|
||||
<p>The current glut window is available in <code>Fl_Glut_Window
|
||||
*glut_window</code>.
|
||||
<p>The current GLUT window is available in the global variable
|
||||
<tt>glut_window</tt>.
|
||||
|
||||
<p><code>new Fl_Glut_Window(...)</code> is the same as
|
||||
<code>glutCreateWindow()</code> except it does not show() the window
|
||||
<p><tt>new Fl_Glut_Window(...)</tt> is the same as
|
||||
<tt>glutCreateWindow()</tt> except it does not <tt>show()</tt> the window
|
||||
or make the window current.
|
||||
|
||||
<p><code>window->make_current()</code> is the same as
|
||||
<code>glutSetWindow(number)</code>. If the window has not had show()
|
||||
called on it yet, some functions that assumme a gl context will not
|
||||
work. If you do show() the window, call make_current() again to set
|
||||
the context.
|
||||
<p><tt>window->make_current()</tt> is the same as
|
||||
<tt>glutSetWindow(number)</tt>. If the window has not had
|
||||
<tt>show()</tt> called on it yet, some functions that assumme an OpenGL
|
||||
context will not work. If you do <tt>show()</tt> the window, call
|
||||
<tt>make_current()</tt> again to set the context.
|
||||
|
||||
<p><code>~Fl_Glut_Window()</code> is the same as
|
||||
<code>glutDestroyWindow()</code>.
|
||||
<p><tt>~Fl_Glut_Window()</tt> is the same as
|
||||
<tt>glutDestroyWindow()</tt>.
|
||||
|
||||
<h3>Methods</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="#Fl_Glut_Window.Fl_Glut_Window">Fl_Glut_Window</a>
|
||||
<li><a href="#Fl_Glut_Window.~Fl_Glut_Window">~Fl_Glut_Window</a>
|
||||
</ul>
|
||||
|
||||
<h4><a name="Fl_Glut_Window.Fl_Glut_Window">Fl_Glut_Window::Fl_Glut_Window(int x, int y, int w, int h, const char *title = 0)<br>
|
||||
Fl_Glut_Window::Fl_Glut_Window(int w, int h, const char *title = 0)</a></h4>
|
||||
|
||||
The first constructor takes 4 int arguments to create the window with
|
||||
a preset position and size. The second constructor with 2 arguments
|
||||
will create the window with a preset size, but the window manager
|
||||
will choose the position according to it's own whims.
|
||||
|
||||
<h4><a name="Fl_Glut_Window.~Fl_Glut_Window">virtual Fl_Glut_Window::~Fl_Glut_Window()</a></h4>
|
||||
|
||||
Destroys the GLUT window.
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
@ -78,7 +78,7 @@ has started being included on Linux distributions.
|
||||
<p>Here are some of the core features unique to FLTK:
|
||||
|
||||
<ul>
|
||||
<li>sizeof(Fl_Widget) == 48.</li>
|
||||
<li>sizeof(Fl_Widget) == 40 to 48.</li>
|
||||
|
||||
<li>The "core" (the "hello" program compiled & linked with a static FLTK
|
||||
library using gcc on a 486 and then stripped) is 39.5K.</li>
|
||||
@ -112,9 +112,9 @@ has started being included on Linux distributions.
|
||||
<li>Text input fields with Emacs key bindings, X cut &
|
||||
paste, and foreign letter compose!</li>
|
||||
|
||||
<li>Compatability header file for the GLUT library.</li>
|
||||
<li>Compatibility header file for the GLUT library.</li>
|
||||
|
||||
<li>Compatability header file for the XForms library.</li>
|
||||
<li>Compatibility header file for the XForms library.</li>
|
||||
|
||||
<li>Much too much to list here...</li>
|
||||
</ul>
|
||||
@ -228,9 +228,11 @@ FLTK is available on the 'net in a bunch of locations:
|
||||
|
||||
<dt>FTP</dt>
|
||||
|
||||
<dd><a href="ftp://ftp.easysw.com/pub/fltk">ftp://ftp.easysw.com/pub/fltk</a><br>
|
||||
<a href="ftp://ftp.funet.fi/mirrors/ftp.easysw.com/pub/fltk">ftp://ftp.funet.fi/mirrors/ftp.easysw.com/pub/fltk</a><br>
|
||||
<a href="ftp://ftp.northamerica.net/pub/ESP/fltk">ftp.northamerica.net/pub/ESP/fltk</a><br></dd>
|
||||
<dd><a href="ftp://ftp.easysw.com/pub/fltk">ftp://ftp.easysw.com/pub/fltk</a></dd>
|
||||
|
||||
<dd><a href="ftp://ftp.funet.fi/mirrors/ftp.easysw.com/pub/fltk">ftp://ftp.funet.fi/mirrors/ftp.easysw.com/pub/fltk</a></dd>
|
||||
|
||||
<dd><a href="ftp://ftp.northamerica.net/pub/ESP/fltk">ftp.northamerica.net/pub/ESP/fltk</a><br></dd>
|
||||
|
||||
<dt>EMail</dt>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
<H2>GNU LIBRARY GENERAL PUBLIC LICENSE</H2>
|
||||
|
||||
<P>Version 2, June 1991<BR>
|
||||
<P ALIGN=CENTER>Version 2, June 1991<BR>
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.<BR>
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA<BR>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
@ -103,7 +103,7 @@ works together with the library.
|
||||
<P>Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
<H2>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H2>
|
||||
<H2 ALIGN=CENTER>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H2>
|
||||
|
||||
<STRONG>0.</STRONG> This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
@ -437,7 +437,7 @@ decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
<H2>NO WARRANTY</H2>
|
||||
<H2 ALIGN=CENTER>NO WARRANTY</H2>
|
||||
|
||||
<P><STRONG>15.</STRONG>
|
||||
BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
@ -462,7 +462,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
<H2>END OF TERMS AND CONDITIONS</H2>
|
||||
<H2 ALIGN=CENTER>END OF TERMS AND CONDITIONS</H2>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
@ -1,486 +1,360 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<H1 ALIGN=RIGHT><A NAME="opengl">7 - Using OpenGL</A></H1>
|
||||
<H1 ALIGN=RIGHT><A NAME="opengl">9 - Using OpenGL</A></H1>
|
||||
|
||||
This chapter discusses using FLTK for your OpenGL applications.
|
||||
|
||||
<H2>The OpenGL Widget</H2>
|
||||
<h2>Using OpenGL in FLTK</h2>
|
||||
|
||||
<H2>Making a Simple OpenGL Wrapper Widget</H2>
|
||||
The easiest way to make an OpenGL display is to subclass <a
|
||||
href="#Fl_Gl_Window"><tt>Fl_Gl_Window</tt></a>. Your subclass must
|
||||
implement a <tt>draw()</tt> method which uses OpenGL calls to draw the
|
||||
display. Your main program should call <tt>redraw()</tt> when the
|
||||
display needs to change, and (somewhat later) FLTK will call
|
||||
<tt>draw()</tt>.
|
||||
|
||||
<H2>A Simple Flight Simulator</H2>
|
||||
<p>With a bit of care you can also use OpenGL to draw into normal FLTK
|
||||
windows. This is mostly useful because you can use Gourand shading for
|
||||
drawing your widgets. To do this you use the <a
|
||||
href="#gl_start"><tt>gl_start()</tt></a> and <a
|
||||
href="#gl_finish"><tt>gl_finish()</tt></a> functions around your OpenGL
|
||||
code.
|
||||
|
||||
<H2>Using FLTK with OpenGL Optimizer</H2>
|
||||
<p>You must include FLTK's <tt><FL/gl.h></tt> header file. It will include
|
||||
the file <tt><GL/gl.h></tt>, define some extra drawing functions
|
||||
provided by FLTK, and include the <tt><windows.h></tt> header file needed
|
||||
by WIN32 applications.
|
||||
|
||||
<H2>Using OpenGL Optimizer for the Flight Simulator</H2>
|
||||
<h2>Making a Subclass of Fl_Gl_Window</h2>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
<title>Using OpenGL in Fltk</title>
|
||||
To make a subclass of Fl_Gl_Window, you must provide:
|
||||
|
||||
<h2>Using OpenGL in Fltk<br>#include <FL/gl.h></h2>
|
||||
<ul>
|
||||
|
||||
The easiest way to make an OpenGL display is to subclass Fl_Gl_Window.
|
||||
Your subclass should implement a draw() method which uses OpenGL calls
|
||||
to draw the display. Your main program should call w->redraw() when
|
||||
the display needs to change, and (somewhat later) fltk will call
|
||||
draw().
|
||||
<li>A class definition.
|
||||
<li>A <tt>draw()</tt> method.
|
||||
<li>A <tt>handle()</tt> method (if you need to recieve input from
|
||||
the user).
|
||||
</ul>
|
||||
|
||||
<p>With a bit of care you can also use OpenGL to draw into normal fltk
|
||||
windows. This is mostly useful because you can access Gourand shading
|
||||
for drawing your widgets. To do this you use the <a
|
||||
href=#gl_start>gl_start() and gl_finish()</a> functions around your
|
||||
OpenGL code.
|
||||
<h3>Defining the Subclass</h3>
|
||||
|
||||
<p>You must include fltk's <FL/gl.h> header file. It will include
|
||||
the file <GL/gl.h>, plus it defines some extra drawing functions
|
||||
provided by fltk, and also gets around a horrid screwup by our friends
|
||||
in Seattle.
|
||||
To define the subclass you just subclass <tt>Fl_Gl_Window</tt> class:
|
||||
|
||||
<h2>Sample code for subclassing Fl_Gl_Window</h2>
|
||||
<ul><pre>
|
||||
class MyWindow : public Fl_Gl_Window {
|
||||
void draw();
|
||||
int handle(int);
|
||||
|
||||
<p><pre>
|
||||
class MyWindow : public Fl_Gl_Window {
|
||||
void draw();
|
||||
int handle(int);
|
||||
public:
|
||||
MyWindow(int X, int Y, int W, int H, const char* L)
|
||||
: Fl_Gl_Window(X,Y,W,H,L) {}
|
||||
};
|
||||
public:
|
||||
MyWindow(int X, int Y, int W, int H, const char *L)
|
||||
: Fl_Gl_Window(X, Y, W, H, L) {}
|
||||
};
|
||||
</pre></ul>
|
||||
|
||||
void MyWindow::draw() {
|
||||
The <tt>draw()</tt> and <tt>handle()</tt> methods are described below. Like
|
||||
any widget, you can include additional private and public data in your class
|
||||
(such as scene graph information, etc.)
|
||||
|
||||
<h3>The draw() Method</H3>
|
||||
|
||||
The <tt>draw()</tt> method is where you actually do your OpenGL drawing:
|
||||
|
||||
<ul><pre>
|
||||
void MyWindow::draw() {
|
||||
if (!valid()) {
|
||||
... set up projection, viewport, etc ...
|
||||
... window size is in w() and h().
|
||||
... valid() is turned on by FLTK after draw() returns
|
||||
}
|
||||
... draw ...
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
<h3>The handle() Method</h3>
|
||||
|
||||
The <tt>handle()</tt> method handles mouse and keyboard events for the
|
||||
window:
|
||||
|
||||
<ul><pre>
|
||||
int MyWindow::handle(int event) {
|
||||
switch(event) {
|
||||
case FL_PUSH:
|
||||
... mouse down event ...
|
||||
... position in Fl::event_x() and Fl::event_y()
|
||||
return 1;
|
||||
case FL_DRAG:
|
||||
... mouse moved while down event ...
|
||||
return 1;
|
||||
case FL_RELEASE:
|
||||
... mouse up event ...
|
||||
return 1;
|
||||
case FL_FOCUS :
|
||||
case FL_UNFOCUS :
|
||||
... Return 1 if you want keyboard events, 0 otherwise
|
||||
return 1;
|
||||
case FL_KEYBOARD:
|
||||
... keypress, key is in Fl::event_key(), ascii in Fl::event_text()
|
||||
... Return 1 if you understand/use the keyboard event, 0 otherwise...
|
||||
return 1;
|
||||
default:
|
||||
// tell FLTK that I don't understand other events
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
When <tt>handle()</tt> is called, the OpenGL context is not set up! If your
|
||||
display changes, you should call <tt>redraw()</tt> and let <tt>draw()</tt> do the work.
|
||||
Don't call any OpenGL drawing functions from inside <tt>handle()</tt>!
|
||||
|
||||
<p>You can call some OpenGL stuff like hit detection and texture loading
|
||||
functions by doing:
|
||||
|
||||
<ul><pre>
|
||||
case FL_PUSH:
|
||||
make_current(); // make OpenGL context current
|
||||
if (!valid()) {
|
||||
... set up projection, viewport, etc ...
|
||||
... window size is in w() and h().
|
||||
... valid() is turned on by fltk after draw() returns
|
||||
... set up projection exactly the same as draw ...
|
||||
valid(1); // stop it from doing this next time
|
||||
}
|
||||
... draw ...
|
||||
}
|
||||
... ok to call NON-DRAWING OpenGL code here, such as hit
|
||||
detection, loading textures, etc...
|
||||
</pre></ul>
|
||||
|
||||
int MyWindow::handle(int event) {
|
||||
switch(event) {
|
||||
case FL_PUSH:
|
||||
... mouse down event ...
|
||||
... position in Fl::event_x() and Fl::event_y()
|
||||
return 1;
|
||||
case FL_DRAG:
|
||||
... mouse moved while down event ...
|
||||
return 1;
|
||||
case FL_RELEASE:
|
||||
... mouse up event ...
|
||||
return 1;
|
||||
case FL_KEYBOARD:
|
||||
... keypress, key is in Fl::event_key(), ascii in Fl::event_text()
|
||||
return 1;
|
||||
default:
|
||||
// tell fltk that I don't understand other events
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>When handle() is called, the glx context is not set up! If your
|
||||
display changes, you should call redraw() and let draw() do the work.
|
||||
Don't call any gl functions from inside handle()!
|
||||
|
||||
<p>This may mean you cannot call some OpenGl stuff like hit detection.
|
||||
You can fix this by doing:
|
||||
|
||||
<p><pre>
|
||||
case FL_PUSH:
|
||||
make_current(); // make glx context current
|
||||
if (!valid()) {
|
||||
... set up projection exactly the same as draw ...
|
||||
valid(1); // stop it from doing this next time
|
||||
}
|
||||
... ok to call NON-DRAWING OpenGL code here, such as hit
|
||||
detection ...
|
||||
</pre>
|
||||
|
||||
<p>Your main program can now create one of your windows by doing "new
|
||||
MyWindow(...)". You can also use <a href=fluid.html>fluid</a>:
|
||||
Your main program can now create one of your windows by doing <tt>new
|
||||
MyWindow(...)</tt>. You can also use <a href="#fluid">fluid</a> by:
|
||||
|
||||
<ol>
|
||||
<li>Put your class definition in a MyWindow.H file.
|
||||
<li>In fluid create a box object, resize & place where you want.
|
||||
<li>In the control panel, fill in the "class" field with MyWindow.H.
|
||||
This will make fluid produce constructors for your new class.
|
||||
<li>In the "extra code" put "#include "MyWindow.H"", so that the fluid
|
||||
output file will compile.
|
||||
<li>Put your class definition in a MyWindow.H file.
|
||||
|
||||
<li>In fluid create a box object, resize & place where you want.
|
||||
|
||||
<li>In the control panel, fill in the "class" field with MyWindow.H.
|
||||
This will make fluid produce constructors for your new class.
|
||||
|
||||
<li>In the "extra code" put <tt>#include "MyWindow.H"</tt>, so
|
||||
that the fluid output file will compile.
|
||||
|
||||
</ol>
|
||||
|
||||
<p>You must put glwindow->show() in your main code after calling
|
||||
show() on the window containing the gl window.
|
||||
You must put <tt>glwindow->show()</tt> in your main code after calling
|
||||
<tt>show()</tt> on the window containing the OpenGL window.
|
||||
|
||||
<p><hr>
|
||||
<h2>class Fl_Gl_Window : public <a href=Fl_Window.html>Fl_Window</a></h2>
|
||||
<h2>Using OpenGL in Normal FLTK Windows</h2>
|
||||
|
||||
<p>An Fl_Gl_Window sets things up so OpenGL works, and also keeps an
|
||||
OpenGL "context" for that window, so that changes to the lighting and
|
||||
projection may be reused between redraws. Fl_Gl_Window also flushes
|
||||
the OpenGL streams and swaps buffers after draw() returns.
|
||||
|
||||
<p>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 <FL/fl_draw.H>, or glX directly. Do
|
||||
not call gl_start() or gl_finish().
|
||||
|
||||
<h2>Methods:</h2>
|
||||
|
||||
<h4><code>Fl_Gl_Window::Fl_Gl_Window(int W, int H, const char *l=0);
|
||||
<br>Fl_Gl_Window::Fl_Gl_Window(int X, int Y, int W, int H, const char
|
||||
*l=0)</code></h4><ul>
|
||||
|
||||
The constructors. Fl_Gl_Window::mode() defaults to
|
||||
<code>FL_RGB|FL_DOUBLE|FL_DEPTH</code>.
|
||||
|
||||
<a name=mode>
|
||||
</ul><h4><code>const int Fl_Gl_Window::mode() const;
|
||||
<br>int Fl_Gl_Window::mode(int);</code></h4><ul>
|
||||
|
||||
Set or change the OpenGL capabilites of the window. The value can be
|
||||
any of the following or'd together:
|
||||
|
||||
<p><ul>
|
||||
<li><code>FL_RGB</code> - Color (not indexed)
|
||||
<li><code>FL_RGB8</code> - Color with at least 8 bits of each color
|
||||
<li><code>FL_INDEX</code> - Indexed mode
|
||||
<li><code>FL_SINGLE</code> - not double buffered
|
||||
<li><code>FL_DOUBLE</code> - double buffered
|
||||
<li><code>FL_ACCUM</code> - accumulation buffer
|
||||
<li><code>FL_ALPHA</code> - alpha channel in color
|
||||
<li><code>FL_DEPTH</code> - depth buffer
|
||||
<li><code>FL_STENCIL</code> - stencil buffer
|
||||
<li><code>FL_MULTISAMPLE</code> - multisample antialiasing
|
||||
</ul>
|
||||
|
||||
<p><code>FL_RGB</code> and <code>FL_SINGLE</code> have a
|
||||
value of zero, they are "on" <i>unless</i> you give
|
||||
<code>FL_INDEX</code> or <code>FL_DOUBLE</code>.
|
||||
|
||||
<p>If the desired combination cannot be done, fltk will try turning off
|
||||
the <code>FL_MULTISAMPLE</code>. If this also fails show() will call
|
||||
Fl::error() and not show the window.
|
||||
|
||||
<p>You can change the mode while the window is displayed. This
|
||||
is most useful for turning double-buffering on and off. <i>Under
|
||||
X this will cause the old X window to be destroyed and a new one
|
||||
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!</i>
|
||||
|
||||
</ul><h4><code>int Fl_Gl_Window::mode(const int *);</code></h4><ul>
|
||||
|
||||
<p><i>This call only works on systems using glX.</i> This value is
|
||||
passed unchanged to glXChooseVisual(), superceeding the value
|
||||
calculated from mode(int). See "man glXChooseVisual" if you wish to
|
||||
construct your own mode. Fltk assummes that the pointer is to static
|
||||
const data, and caches the pointer with the found visual.
|
||||
glXChooseVisual is not called until show() or can_do()
|
||||
is called. To restore the use of mode(int), call
|
||||
<code>mode((int*)0)</code>.
|
||||
|
||||
</ul><h4><code>static int Fl_Gl_Window::can_do(int);
|
||||
<br>static int Fl_Gl_Window::can_do(const int *mode);
|
||||
<br>int Fl_Gl_Window::can_do() const;</code></h4><ul>
|
||||
|
||||
Returns non-zero if show() will not call Fl::error() if called with
|
||||
the given or current mode.
|
||||
|
||||
</ul><h4><code>char Fl_Gl_Window::valid() const;
|
||||
<br>void Fl_Gl_Window::invalidate();
|
||||
<br>void Fl_Gl_Window::valid(char i);</code></h4><ul>
|
||||
|
||||
<code>Fl_Gl_Window::valid()</code> is turned off when fltk creates a
|
||||
new context for this window and by the window resizing, 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><code>void mywindow::draw() {
|
||||
if (!valid()) {
|
||||
glViewport(0,0,w(),h());
|
||||
glFrustum(...);
|
||||
glLight(...);
|
||||
...other initilization...
|
||||
}
|
||||
... draw your geometry here ...
|
||||
}
|
||||
</code></pre></ul>
|
||||
|
||||
<p>You can also turn valid() off yourself (for instance if you know
|
||||
the current projection has changed). To do this call
|
||||
<code>invalidate()</code>.
|
||||
|
||||
<p>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.
|
||||
|
||||
</ul><h4><code>void Fl_Gl_Window::ortho();</code></h4><ul>
|
||||
|
||||
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.
|
||||
|
||||
</ul><h4><code>void Fl_Gl_Window::make_current();
|
||||
<br>void Fl_Gl_Window::make_overlay_current();
|
||||
<br>void Fl_Gl_Window::swap_buffers();</code></h4><ul>
|
||||
|
||||
These functions can be used to set the current GL context to a window
|
||||
and draw into it incrementally, rather than using the draw() method.
|
||||
You will also need to call make_current() to do OpenGL feedback or hit
|
||||
detection in response to events. After calling make_current(), be
|
||||
sure to test valid(), and if false, initialize the transformation and
|
||||
call valid(1).
|
||||
|
||||
</ul><h4><code>void Fl_Gl_Window::hide();
|
||||
<br>Fl_Gl_Window::~Fl_Gl_Window();</code></h4><ul>
|
||||
|
||||
Hiding the window or destroying it also destroys the OpenGL context it
|
||||
uses.
|
||||
|
||||
</ul><h2>Fl_Gl_Window overlay</h2>
|
||||
|
||||
GL hardware typically provides some overlay bit planes, which are very
|
||||
useful for drawing UI controls atop your 3D graphics. If the overlay
|
||||
hardware is not provided, fltk tries to simulate the overlay, this works
|
||||
pretty well if your graphics are double buffered, but not very well
|
||||
for single-buffered.
|
||||
|
||||
</ul><h4><code>int Fl_Gl_Window::can_do_overlay();</code></h4><ul>
|
||||
|
||||
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.
|
||||
|
||||
</ul><h4><code>void Fl_Gl_Window::redraw_overlay();</code></h4><ul>
|
||||
|
||||
Call this if what is drawn in the overlay needs to change, this will
|
||||
cause draw_overlay to be called at a later time. Initially the
|
||||
overlay is clear, if you want the window to display something in the
|
||||
overlay when it first appears, you must call this immediately after
|
||||
you show() your window.
|
||||
|
||||
</ul><h4><code>virtual void Fl_Gl_Window::draw_overlay();</code></h4><ul>
|
||||
|
||||
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() must check
|
||||
Fl_Gl_Window::valid(), and set the same transformation. If you don't
|
||||
your code may not work on other systems. Depending on the OS, and on
|
||||
whether overlays are real or simulated, the OpenGL context may be the
|
||||
same or different between the overlay and main window.
|
||||
|
||||
</ul><p><hr>
|
||||
<a name=gl_start>
|
||||
<h2>Using OpenGL in normal Fltk windows</h2>
|
||||
|
||||
<p>You can put OpenGL code into an <a
|
||||
href=subclass.html#draw>Fl_Widget::draw()</a> method or into the code
|
||||
for a <a href=Boxtypes.html>boxtype</a> or other places, with some care.
|
||||
You can put OpenGL code into an <a
|
||||
href="#draw"><tt>Fl_Widget::draw()</tt></a> method or into the code for
|
||||
a <a href="#boxtypes">boxtype</a> or other places with some care.
|
||||
|
||||
<p>Most important, before you show <i>any</i> windows (including those
|
||||
that don't have OpenGL drawing) you must initialize fltk/X so that it
|
||||
that don't have OpenGL drawing) you must initialize FLTK so that it
|
||||
knows it is going to use OpenGL. You may use any of the symbols
|
||||
described for <a href=#mode>Fl_Gl_Window::mode()</a> to describe how
|
||||
you intend to use OpenGL:
|
||||
described for <a
|
||||
href="#Fl_Gl_Window.mode"><tt>Fl_Gl_Window::mode()</tt></a> to describe
|
||||
how you intend to use OpenGL:
|
||||
|
||||
<ul><p><code> Fl::gl_visual(FL_RGB);</code></ul>
|
||||
<ul><pre>
|
||||
Fl::gl_visual(FL_RGB);
|
||||
</pre></ul>
|
||||
|
||||
<p>You can then put OpenGL drawing code anywhere you can draw normally
|
||||
You can then put OpenGL drawing code anywhere you can draw normally
|
||||
by surrounding it with:
|
||||
|
||||
<ul><p><code>gl_start();</code><br>
|
||||
<i>... put your OpenGL code here ...</i><br>
|
||||
<code>gl_finish();</code></ul>
|
||||
<ul><pre>
|
||||
gl_start();
|
||||
... put your OpenGL code here ...
|
||||
gl_finish();
|
||||
</pre></ul>
|
||||
|
||||
<p>gl_start() and gl_finish() set up a GL context with an orthographic
|
||||
projection so that 0,0 is the lower-left corner of the window and each
|
||||
pixel is one unit. The current clipping is reproduced with OpenGL
|
||||
scissor commands. These also synchronize the OpenGL graphics stream
|
||||
with the drawing done by other X or fltk functions.
|
||||
<a name="gl_start"><tt>gl_start()</tt></a> and <a
|
||||
name="gl_finish"><tt>gl_finish()</tt></a> set up an OpenGL context with
|
||||
an orthographic projection so that 0,0 is the lower-left corner of the
|
||||
window and each pixel is one unit. The current clipping is reproduced
|
||||
with OpenGL <tt>glScissor()</tt> commands. These also synchronize the
|
||||
OpenGL graphics stream with the drawing done by other X, WIN32, or FLTK
|
||||
functions.
|
||||
|
||||
<p>The same context is reused each time. If your code changes the
|
||||
projection transformation or anything else you should use glPush/glPop
|
||||
to put the state back before calling gl_finish().
|
||||
projection transformation or anything else you should use
|
||||
<tt>glPushMatrix()</tt> and <tt>glPopMatrix()</tt> functions to put the
|
||||
state back before calling <tt>gl_finish()</tt>.
|
||||
|
||||
<p>You may want to use <code>Fl_Window::current()->h()</code> to get
|
||||
the drawable height so you can flip the coordinate system.
|
||||
<p>You may want to use <tt>Fl_Window::current()->h()</tt> to get
|
||||
the drawable height so you can flip the Y coordinates.
|
||||
|
||||
<p>Unfortunately there are a bunch of limitations you must adhere to for
|
||||
maximum portability:<ul>
|
||||
<p>Unfortunately, there are a bunch of limitations you must adhere to for
|
||||
maximum portability:
|
||||
|
||||
<li>You must choose a default visual with <a
|
||||
href=Fl.html#gl_visual>Fl::gl_visual()</a>.
|
||||
<ul>
|
||||
|
||||
<li>You cannot pass FL_DOUBLE to Fl::gl_visual().
|
||||
<li>You must choose a default visual with <a
|
||||
href="#gl_visual"><tt>Fl::gl_visual()</tt></a>.
|
||||
|
||||
<li>You cannot use Fl_Double_Window (or Fl_Overlay_Window).
|
||||
<li>You cannot pass <tt>FL_DOUBLE</tt> to <tt>Fl::gl_visual()</tt>.
|
||||
|
||||
<li>You cannot use <tt>Fl_Double_Window</tt> or
|
||||
<tt>Fl_Overlay_Window</tt>.
|
||||
|
||||
</ul>
|
||||
|
||||
<p>Do <i>not</i> call gl_start()/gl_finish() when drawing an
|
||||
Fl_Gl_Window!
|
||||
Do <i>not</i> call <tt>gl_start()</tt> or <tt>gl_finish()</tt> when drawing
|
||||
into an <tt>Fl_Gl_Window</tt>!
|
||||
|
||||
</ul><p><hr>
|
||||
<a name=drawing>
|
||||
<h2>OpenGL drawing functions
|
||||
<br>#include <FL/gl_draw.H></h2>
|
||||
<h2>OpenGL drawing functions</h2>
|
||||
|
||||
Fltk provides some useful gl drawing functions. They can be freely
|
||||
mixed with any OpenGL calls, and are defined by including <FL/gl.H>
|
||||
(which you should include instead of the OpenGL header <GL/gl.h>).
|
||||
FLTK provides some useful OpenGL drawing functions. They can be freely
|
||||
mixed with any OpenGL calls, and are defined by including
|
||||
<tt><FL/gl.H></tt> (which you should include instead of the OpenGL
|
||||
header <tt><GL/gl.h></tt>).
|
||||
|
||||
</ul><h4><code>void gl_color(Fl_Color);</code></h4><ul>
|
||||
<h3>void gl_color(Fl_Color)</h3>
|
||||
|
||||
Set the current color to a fltk color index. <i>For color-index modes
|
||||
it will use fl_xpixel(c), which is only right if this window uses the
|
||||
default X colormap</i>.
|
||||
Set the current color to a FLTK color index. <i>For color-index modes
|
||||
it will use <tt>fl_xpixel(c)</tt>, which is only right if this window
|
||||
uses the default colormap!</i>
|
||||
|
||||
</ul><h4><code>void gl_rect(int x,int y,int w,int h);
|
||||
<br>void gl_rectf(int x,int y,int w,int h);</code></h4><ul>
|
||||
<h3>void gl_rect(int x, int y, int w, int h)<br>
|
||||
void gl_rectf(int x, int y, int w, int h)</h3>
|
||||
|
||||
Outline or fill a rectangle with the current color. If ortho() has
|
||||
been called, then the rectangle will exactly fill the pixel rectangle
|
||||
passed.
|
||||
Outline or fill a rectangle with the current color. If
|
||||
<tt>ortho()</tt> has been called, then the rectangle will exactly fill
|
||||
the pixel rectangle passed.
|
||||
|
||||
</ul><h4><code>void gl_font(Fl_Font fontid, int size);</code></h4><ul>
|
||||
<h3>void gl_font(Fl_Font fontid, int size)</h3>
|
||||
|
||||
Set the "current GL font" to the same font you get by calling
|
||||
<a href=Draw.html#fl_font>fl_font()</a>.
|
||||
Set the "current OpenGL font" to the same font you get by calling
|
||||
<a href="#fl_font"><tt>fl_font()</tt></a>.
|
||||
|
||||
</ul><h4><code>int gl_height();
|
||||
<br>int gl_descent();
|
||||
<br>float gl_width(const char *);
|
||||
<br>float gl_width(const char *, int n);
|
||||
<br>float gl_width(uchar);</code></h4><ul>
|
||||
<h3>int gl_height()<br>
|
||||
int gl_descent()<br>
|
||||
float gl_width(const char *)<br>
|
||||
float gl_width(const char *, int n)<br>
|
||||
float gl_width(uchar)</h3>
|
||||
|
||||
Return information about the current GL font.
|
||||
Return information about the current OpenGL font.
|
||||
|
||||
</ul><h4><code>void gl_draw(const char *);
|
||||
<br>void gl_draw(const char *, int n);</code></h4><ul>
|
||||
<h3>void gl_draw(const char *)<br>
|
||||
void gl_draw(const char *, int n)</h3>
|
||||
|
||||
Draw a null-terminated string or an array of <i>n</i> characters in
|
||||
the current GL font at the current glRasterPos.
|
||||
Draw a nul-terminated string or an array of <tt>n</tt> characters in
|
||||
the current OpenGL font at the current <tt>glRasterPos</tt>.
|
||||
|
||||
</ul><h4><code>void gl_draw(const char *, int x, int y);
|
||||
<br>void gl_draw(const char *, int n, int x, int y);</code></h4><ul>
|
||||
<h3>void gl_draw(const char *, int x, int y)<br>
|
||||
void gl_draw(const char *, int n, int x, int y)<br>
|
||||
void gl_draw(const char *, float x, float y)<br>
|
||||
void gl_draw(const char *, int n, float x, float y)</h3>
|
||||
|
||||
Draw a null-terminated string or an array of <i>n</i> characters in
|
||||
the current GL font at the given position.
|
||||
Draw a nul-terminated string or an array of <tt>n</tt> characters in
|
||||
the current OpenGL font at the given position.
|
||||
|
||||
</ul><h4><code>void gl_draw(const char *, int x, int y, int w, int h, Fl_Align);</code></h4><ul>
|
||||
<h3>void gl_draw(const char *, int x, int y, int w, int h, Fl_Align)</h3>
|
||||
|
||||
Draw a string formatted into a box, with newlines and tabs expanded,
|
||||
other control characters changed to ^X, and aligned with the edges or
|
||||
center. Exactly the same output as <a href=Draw.html#fl_draw>fl_draw()</a>.
|
||||
center. Exactly the same output as <a href="#fl_draw"><tt>fl_draw()</tt></a>.
|
||||
|
||||
</ul>
|
||||
<p><a href = index.html>(back to contents)</a>
|
||||
<title>Fltk example: shape.C</title>
|
||||
<h2>shape.C</h2>
|
||||
<h2>Using OpenGL Optimizer with FLTK</h2>
|
||||
|
||||
<p>Of course GL is no fun unless you can draw your own graphics. This
|
||||
is done with a subclass that you create:
|
||||
<a href="http://www.sgi.com/software/optimizer">OpenGL Optimizer</a> is
|
||||
a scene graph toolkit for OpenGL available from Silicon Graphics for
|
||||
IRIX and Microsoft Windows. Versions are in the works for Solaris and
|
||||
HP-UX. It allows you to view large scenes without writing a lot of
|
||||
OpenGL code.
|
||||
|
||||
<p><img src = shape.C.gif align=top>
|
||||
<h3>OptimizerWindow Class Definition</h3>
|
||||
|
||||
<pre>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Hor_Slider.H>
|
||||
#include <FL/math.h>
|
||||
#include <FL/gl.h>
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
To use OpenGL Optimizer with FLTK you'll need to create a subclass of
|
||||
<tt>Fl_Gl_Widget</tt> that includes several state variables:
|
||||
|
||||
<ul><pre>
|
||||
class OptimizerWindow : public Fl_Gl_Window {
|
||||
csContext *context_; // Initialized to 0 and set by draw()...
|
||||
csDrawAction *draw_action_; // Draw action...
|
||||
csGroup *scene_; // Scene to draw...
|
||||
csCamara *camera_; // Viewport for scene...
|
||||
|
||||
class shape_window : public Fl_Gl_Window {
|
||||
void draw();
|
||||
|
||||
public:
|
||||
int sides;
|
||||
shape_window(int x,int y,int w,int h,const char *l=0);
|
||||
OptimizerWindow(int X, int Y, int W, int H, const char *L)
|
||||
: Fl_Gl_Window(X, Y, W, H, L) {
|
||||
context_ = (csContext *)0;
|
||||
draw_action_ = (csDrawAction *)0;
|
||||
scene_ = (csGroup *)0;
|
||||
camera_ = (csCamera *)0;
|
||||
}
|
||||
|
||||
void scene(csGroup *g) { scene_ = g; redraw(); }
|
||||
|
||||
void camera(csCamera *c) {
|
||||
camera_ = c;
|
||||
if (context_) {
|
||||
draw_action_->setCamera(camera_);
|
||||
camera_->draw(draw_action_);
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
};
|
||||
</ul><pre>
|
||||
|
||||
shape_window::shape_window(int x,int y,int w,int h,const char *l) :
|
||||
Fl_Gl_Window(x,y,w,h,l) {
|
||||
sides = 3;
|
||||
}
|
||||
<H3>The camera() Method</H3>
|
||||
|
||||
The <tt>camera()</tt> method sets the camera (projection and viewpoint)
|
||||
to use when drawing the scene. The scene is redrawn after this call.
|
||||
|
||||
<h3>The draw() Method</h3>
|
||||
|
||||
The <tt>draw()</tt> method performs the needed initialization
|
||||
and does the actual drawing:
|
||||
|
||||
<ul><pre>
|
||||
void OptimizerWindow::draw() {
|
||||
if (!context_) {
|
||||
// This is the first time we've been asked to draw; create the
|
||||
// Optimizer context for the scene...
|
||||
|
||||
context_ = new csContext(fl_display, fl_visual);
|
||||
context_->ref();
|
||||
context_->makeCurrent(fl_display, fl_window);
|
||||
|
||||
... perform other context setup as desired ...
|
||||
|
||||
// Then create the draw action to handle drawing things...
|
||||
|
||||
draw_action_ = new csDrawAction;
|
||||
if (camera_) {
|
||||
draw_action_->setCamera(camera_);
|
||||
camera_->draw(draw_action_);
|
||||
}
|
||||
}
|
||||
|
||||
void shape_window::draw() {
|
||||
// the valid() property may be used to avoid reinitializing your
|
||||
// GL transformation for each redraw:
|
||||
if (!valid()) {
|
||||
valid(1);
|
||||
glLoadIdentity();
|
||||
glViewport(0,0,w(),h());
|
||||
// Update the viewport for this context...
|
||||
context_->setViewport(0, 0, w(), h());
|
||||
}
|
||||
// draw an amazing graphic:
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glColor3f(.5,.6,.7);
|
||||
glBegin(GL_POLYGON);
|
||||
for (int i=0; i<sides; i++) {
|
||||
double ang = i*2*M_PI/sides;
|
||||
glVertex3f(cos(ang),sin(ang),0);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// Clear the window...
|
||||
|
||||
context_->clear(csContext::COLOR_CLEAR | csContext::DEPTH_CLEAR,
|
||||
0.0f, // Red
|
||||
0.0f, // Green
|
||||
0.0f, // Blue
|
||||
1.0f); // Alpha
|
||||
|
||||
// Then draw the scene (if any)...
|
||||
|
||||
if (scene_)
|
||||
draw_action_->apply(scene_);
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
// when you change the data, as in this callback, you must call redraw():
|
||||
void sides_cb(Fl_Widget *o, void *p) {
|
||||
shape_window *sw = (shape_window *)p;
|
||||
sw->sides = int(((Fl_Slider *)o)->value());
|
||||
sw->redraw();
|
||||
}
|
||||
<H3>The scene() Method</H3>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
The <tt>scene()</tt> method sets the scene to be drawn. The scene is
|
||||
a collection of 3D objects in a <tt>csGroup</tt>. The scene is redrawn
|
||||
after this call.
|
||||
|
||||
Fl_Window window(300, 330);
|
||||
|
||||
shape_window sw(10, 10, 280, 280);
|
||||
window.resizable(&sw);
|
||||
|
||||
Fl_Hor_Slider slider(50, 295, window.w()-60, 30, "Sides:");
|
||||
slider.align(FL_ALIGN_LEFT);
|
||||
slider.callback(sides_cb,&sw);
|
||||
slider.value(sw.sides);
|
||||
slider.step(1);
|
||||
slider.bounds(3,40);
|
||||
|
||||
window.show(argc,argv);
|
||||
|
||||
return Fl::run();
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>To do your own drawing, you must subclass <a
|
||||
href=Fl_Gl_Window.html>Fl_Gl_Window</a>. The virtual method <a
|
||||
href=subclass.html#draw>draw()</a> is called when the window should
|
||||
update. You can only draw into the window inside a draw() method.
|
||||
You call the method <a href=Fl_Widget.html#redraw>redraw()</a> on the
|
||||
window to indicate that draw() needs to be called. It won't actually
|
||||
be called until <a href=Fl.html#wait>Fl::wait()</a> is called.
|
||||
|
||||
<P>The window may be made a child of another window, as it is here.
|
||||
This is done by add()ing it to a parent before you show() it. <i>If
|
||||
you don't want to make a child window, be sure to end() the previous
|
||||
window!</i> The Fl_Gl_Window constructor automatically does end() so
|
||||
you don't accidentally add children to it.
|
||||
|
||||
<p>The files <FL/math.h> and <FL/gl.h> are wrappers for the
|
||||
normal header files. You should use them to port to MSWindows because
|
||||
the MicroSoft header files have errors or ommisions in them.
|
||||
|
||||
<p><a href = index.html>[back to contents]</a>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
@ -1,184 +1,171 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<H1 ALIGN=RIGHT>F - Operating System Specific Issues</H1
|
||||
<H1 ALIGN=RIGHT><A NAME="osissues">F - Operating System Issues</A></H1>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
<title>Fltk X-specific interface</title>
|
||||
<h2>Fltk X-specific interface</h2>
|
||||
This appendix describes the X and WIN32 specific interfaces in FLTK.
|
||||
|
||||
<b>#include <FL/x.H></b>
|
||||
<h2>X-Specific Interface</h2>
|
||||
|
||||
<p>On Unix/X you can include this file to access fltk's X-specific
|
||||
functions. Be warned that some of the structures and calls in it are
|
||||
subject to change in future version of fltk. Try to avoid doing this
|
||||
so your code is portable.
|
||||
<ul><pre>
|
||||
#include <FL/x.H>
|
||||
</pre></ul>
|
||||
|
||||
<p><hr>
|
||||
On X you can include this file to access FLTK's X-specific functions.
|
||||
Be warned that some of the structures and calls in it are subject to
|
||||
change in future version of FLTK. Try to avoid doing this so your code
|
||||
is portable.
|
||||
|
||||
<h2>Handling other X events</h2>
|
||||
<h3>Handling Other X Events</h3>
|
||||
|
||||
<a name=add_handler>
|
||||
</ul><h4><code>void Fl::add_handler(int (*f)(int));</code></h4><ul>
|
||||
<h4><a name="add_handler">void Fl::add_handler(int (*f)(int))</a></h4>
|
||||
|
||||
Install a function to parse unrecognized events. If fltk cannot figure
|
||||
Installs 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.
|
||||
returns non-zero then the event is ignored.
|
||||
|
||||
<p>Fltk calls this for any X events it does not recognize, or X events
|
||||
with a window id that fltk does not recognize. You can look at the X
|
||||
event with the <a href=#fl_xevent><code>fl_xevent</code></a>.
|
||||
<p>FLTK calls this for any X events it does not recognize, or X events
|
||||
with a window id that FLTK does not recognize. You can look at the X
|
||||
event with the <a href="#fl_xevent"><tt>fl_xevent</tt></a> variable.
|
||||
|
||||
<p>The argument is zero for unrecognized X events. These handlers are
|
||||
also called for global shortcuts and some other events that the widget
|
||||
they were passed to did not handle. In this case the argument is
|
||||
non-zero (for instance FL_SHORTCUT).
|
||||
non-zero (for example <tt>FL_SHORTCUT</tt>).
|
||||
|
||||
<a name=fl_xevent>
|
||||
</ul><h4><code>extern XEvent* fl_xvent;</code></h4><ul>
|
||||
<h4><a name="fl_xevent">extern XEvent *fl_xvent</a></h4>
|
||||
|
||||
The most current X event.
|
||||
The most recent X event.
|
||||
|
||||
<a name=fl_event_time>
|
||||
</ul><h4><code>extern ulong fl_event_time;</code></h4><ul>
|
||||
<h4><a name="fl_event_time">extern ulong fl_event_time</a></h4>
|
||||
|
||||
This is the time stamp from the most recent X event that reported it
|
||||
(not all do). Many X calls (like cut and paste) need this value.
|
||||
|
||||
</ul><h4><code>Window fl_xid(const Fl_Window*);</code></h4><ul>
|
||||
<h4><a name="fl_xid">Window fl_xid(const Fl_Window *)</a></h4>
|
||||
|
||||
Returns the xid for a window, or zero if not shown().
|
||||
Returns the XID for a window, or zero if not <tt>shown()</tt>.
|
||||
|
||||
</ul><h4><code>Fl_Window* fl_find(ulong xid);</code></h4><ul>
|
||||
<h4><a name="fl_find">Fl_Window *fl_find(ulong xid)</a></h4>
|
||||
|
||||
<p>Return the Fl_Window that corresponds to the given xid, or
|
||||
null if not found. This uses a cache so it is slightly faster than
|
||||
iterating through the windows yourself.
|
||||
Returns the <tt>Fl_Window</tt> that corresponds to the given XID, or
|
||||
<tt>NULL</tt> if not found. This uses a cache so it is slightly faster
|
||||
than iterating through the windows yourself.
|
||||
|
||||
</ul><h4><code>int fl_handle(const XEvent&);</code></h4><ul>
|
||||
<h4><a name="fl_handle">int fl_handle(const XEvent &)</a></h4>
|
||||
|
||||
This call allows you to supply the X events to fltk, which may allow
|
||||
fltk to cooperate with another toolkit or library. The return value
|
||||
is true if fltk understood the event (if the window does not belong to
|
||||
fltk and the add_handler() functions all ignore it this returns
|
||||
This call allows you to supply the X events to FLTK, which may allow
|
||||
FLTK to cooperate with another toolkit or library. The return value
|
||||
is true if FLTK understood the event (if the window does not belong to
|
||||
FLTK and the <tt>add_handler()</tt> functions all ignore it this returns
|
||||
false).
|
||||
|
||||
<p>Besides feeding events your code should call <a
|
||||
href=Fl.html#flush>Fl::flush()</a> periodically so that fltk redraws
|
||||
it's windows.
|
||||
href="#flush"><tt>Fl::flush()</tt></a> periodically so that FLTK
|
||||
redraws its windows.
|
||||
|
||||
<p>This function will call the callback functions. It will not return
|
||||
until they complete. In particular if a callback pops up a modal
|
||||
window (by calling <a href=utilities.html#fl_ask>fl_ask()</a>, for
|
||||
window (by calling <a href="#fl_ask"><tt>fl_ask()</tt></a>, for
|
||||
instance) it will not return until the modal function returns.
|
||||
|
||||
</ul>
|
||||
<p><hr>
|
||||
<h3>Drawing using Xlib</h3>
|
||||
|
||||
<a name=draw>
|
||||
<h2>Drawing using Xlib</h2>
|
||||
The following global variables are set before
|
||||
<tt>Fl_Widget::draw()</tt> is called, or by <a
|
||||
href="#Fl_Window.make_current"><tt>Fl_Window::make_current()</tt></a>:
|
||||
|
||||
</ul><h4><code>
|
||||
extern Display* fl_display;<br>
|
||||
extern Window fl_window;<br>
|
||||
extern GC fl_gc;<br>
|
||||
extern int fl_screen;<br>
|
||||
extern XVisualInfo* fl_visual;<br>
|
||||
extern Colormap fl_colormap;</code></h4><ul>
|
||||
<ul><pre>
|
||||
extern Display *fl_display;
|
||||
extern Window fl_window;
|
||||
extern GC fl_gc;
|
||||
extern int fl_screen;
|
||||
extern XVisualInfo *fl_visual;
|
||||
extern Colormap fl_colormap;
|
||||
</pre></ul>
|
||||
|
||||
These global variables are set before Fl_Widget::draw() is called, or
|
||||
by <a href=Fl_Window.html#make_current>Fl_Window::make_current()</a>
|
||||
You must use them to produce Xlib calls. Don't attempt to change
|
||||
them. A typical X drawing call is written like this:
|
||||
|
||||
<ul><p><code>XDrawSomething(fl_display, fl_window, fl_gc, ...);</code></ul>
|
||||
<ul><pre>
|
||||
XDrawSomething(fl_display, fl_window, fl_gc, ...);
|
||||
</pre></ul>
|
||||
|
||||
<p>Other information such as the position or size of the X window can be
|
||||
Other information such as the position or size of the X window can be
|
||||
found by looking at <a
|
||||
href=Fl_Window.html#make_current><code>Fl_Window::current()</code></a>,
|
||||
which returns a pointer to the Fl_Window being drawn.
|
||||
href="#Fl_Window.make_current"><tt>Fl_Window::current()</tt></a>, which
|
||||
returns a pointer to the <tt>Fl_Window</tt> being drawn.
|
||||
|
||||
</ul><h4><code>unsigned long fl_xpixel(Fl_Color i);</code></h4><ul>
|
||||
<h4><a name="fl_xpixel">unsigned long fl_xpixel(Fl_Color i)<br>
|
||||
unsigned long fl_xpixel(uchar r, uchar g, uchar b)</a></h4>
|
||||
|
||||
Returns the X pixel number used to draw the given fltk color index.
|
||||
This is the X pixel that <a href=Draw.html#fl_color>fl_color(i)</a> would use.
|
||||
Returns the X pixel number used to draw the given FLTK color index or
|
||||
RGB color. This is the X pixel that <a
|
||||
href="#fl_color"><tt>fl_color()</tt></a> would use.
|
||||
|
||||
</ul><h4><code>unsigned long fl_xpixel(uchar r, uchar g, uchar
|
||||
b);</code></h4><ul>
|
||||
|
||||
Return the X pixel number used to draw the given rgb color. This is
|
||||
the X pixel that <a href=Draw.html#fl_rgbcolor>fl_color(r,g,b)</a> would use.
|
||||
|
||||
</ul><h4><code>extern XFontStruct* fl_xfont;</code></h4><ul>
|
||||
<h4><a name="fl_xfont">extern XFontStruct *fl_xfont</a></h4>
|
||||
|
||||
Points at the font selected by the most recent <a
|
||||
href=Draw.html#fl_font>fl_font(font,size)</a>. This is not
|
||||
necessarily the current font of fl_gc (that's not set until <a
|
||||
href=Draw.html#text>fl_draw(const char*,...)</a> is called).
|
||||
href="#fl_font"><tt>fl_font()</tt></a>. This is not necessarily the
|
||||
current font of <tt>fl_gc</tt>, which is not set until <a
|
||||
href="#fl_draw"><tt>fl_draw()</tt></a> is called.
|
||||
|
||||
</ul>
|
||||
<h3>Changing the Display, Screen, or X Visual</h3>
|
||||
|
||||
<p><hr>
|
||||
FLTK uses only a single display, screen, X visual, and X colormap. This
|
||||
greatly simplifies its internal structure and makes it much smaller and
|
||||
faster. You can change which it uses by setting global variables
|
||||
<i>before the first <tt>Fl_Window::show()</tt> is called</i>. You may
|
||||
also want to call <a href="#visual">Fl::visual()</a>, which is a
|
||||
portable interface to get a full color and/or double buffered visual.
|
||||
|
||||
<a name=visuals>
|
||||
<h2>Changing the display, screen, or X visual</h2>
|
||||
|
||||
<p>Fltk uses only a single display, screen, X visual, and X colormap.
|
||||
This greatly simplifies it's internal structure and makes it much
|
||||
smaller and faster. You can change which it uses by setting global
|
||||
variables <i>before the first Fl_Window::show() is called</i>.
|
||||
You may also want to call <a
|
||||
href=Fl.html#visual>Fl::visual(int)</a>, which is a portable interface
|
||||
to get a full color and/or double buffered visual.
|
||||
|
||||
</ul><h4><code>int Fl::display(const char *)</code></h4><ul>
|
||||
<h4><a name="display">int Fl::display(const char *)</a></h4>
|
||||
|
||||
Set which X display to use. This actually does
|
||||
<code>setenv("DISPLAY", x)</code> so that child programs will
|
||||
display on the same screen if called with exec(). This must be done
|
||||
before the display is opened. This call is provided on MSWindows, but
|
||||
it just sets the environment variable and has no other effect.
|
||||
<tt>putenv("DISPLAY=...")</tt> so that child programs will display on
|
||||
the same screen if called with <tt>exec()</tt>. This must be done
|
||||
before the display is opened. This call is provided under WIN32 but
|
||||
it has no effect.
|
||||
|
||||
</ul><h4><code>extern Display* fl_display;</code></h4><ul>
|
||||
<h4><a name="fl_display">extern Display *fl_display</a></h4>
|
||||
|
||||
The open X display. This is needed as an argument to most Xlib calls.
|
||||
Don't attempt to change it! This is zero before the display is opened.
|
||||
Don't attempt to change it! This is <tt>NULL</tt> before the display is opened.
|
||||
|
||||
</ul><h4><code>void fl_open_display();</code></h4><ul>
|
||||
<h4><a name="fl_open_display">void fl_open_display()</a></h4>
|
||||
|
||||
Open the display. Does nothing if it is already open. This will make
|
||||
sure <code>fl_display</code> is non-zero. You should call this if you
|
||||
Opens the display. Does nothing if it is already open. This will make
|
||||
sure <tt>fl_display</tt> is non-zero. You should call this if you
|
||||
wish to do X calls and there is a chance that your code will be called
|
||||
before the first show() of a window.
|
||||
before the first <tt>show()</tt> of a window.
|
||||
|
||||
<p>This may call Fl::abort() if there is an error opening the display.
|
||||
<p>This may call <tt>Fl::abort()</tt> if there is an error opening the display.
|
||||
|
||||
</ul><h4><code>void fl_close_display();</code></h4><ul>
|
||||
<h4><a name="fl_close_display">void fl_close_display()</a></h4>
|
||||
|
||||
This closes the X connection. You do <i>not</i> need to call this to
|
||||
exit, and in fact it is faster to not do so! It may be useful to call
|
||||
this if you want your program to continue without the X connection.
|
||||
You cannot open the display again, and probably cannot call any fltk
|
||||
You cannot open the display again, and probably cannot call any FLTK
|
||||
functions.
|
||||
|
||||
</ul><h4><code>extern int fl_screen;</code></h4><ul>
|
||||
<h4><a name="fl_screen">extern int fl_screen</a></h4>
|
||||
|
||||
Which screen to use. This is set by fl_open_display() to the default
|
||||
screen. You can change it by setting this to a different value
|
||||
immediately afterwards. It can also be set by changing the last
|
||||
number in the Fl::display() string: host:0,#.
|
||||
Which screen number to use. This is set by <tt>fl_open_display()</tt>
|
||||
to the default screen. You can change it by setting this to a
|
||||
different value immediately afterwards. It can also be set by changing
|
||||
the last number in the <tt>Fl::display()</tt> string to "host:0,#".
|
||||
|
||||
</ul><h4><code>extern XVisualInfo* fl_visual;<br>
|
||||
extern Colormap fl_colormap;</code></h4><ul>
|
||||
<h4><a name="fl_visual">extern XVisualInfo *fl_visual</a><br>
|
||||
<a name="fl_colormap">extern Colormap fl_colormap</a></h4>
|
||||
|
||||
<p>The visual and colormap that fltk will use for all windows. These
|
||||
are set by fl_open_display() to the default visual and colormap. You
|
||||
can change them before calling show() on the first window. Typical
|
||||
code for changing the default visual:
|
||||
The visual and colormap that FLTK will use for all windows. These
|
||||
are set by <tt>fl_open_display()</tt> to the default visual and colormap. You
|
||||
can change them before calling <tt>show()</tt> on the first window. Typical
|
||||
code for changing the default visual is:
|
||||
|
||||
<ul><code><pre>
|
||||
<ul><pre>
|
||||
Fl::args(argc, argv); // do this first so $DISPLAY is set
|
||||
fl_open_display();
|
||||
fl_visual = find_a_good_visual(fl_display, fl_screen);
|
||||
@ -186,50 +173,32 @@ if (!fl_visual) Fl::abort("No good visual");
|
||||
fl_colormap = make_a_colormap(fl_display, fl_visual->visual, fl_visual->depth);
|
||||
// it is now ok to show() windows:
|
||||
window->show(argc, argv);
|
||||
</pre></code></ul>
|
||||
</pre></ul>
|
||||
|
||||
</ul>
|
||||
<h3>Using a Subclass of Fl_Window for Special X Stuff</h3>
|
||||
|
||||
<p><hr>
|
||||
<a name=window>
|
||||
<h2>Using a subclass of Fl_Window for special X stuff</h2>
|
||||
FLTK can manage an X window on a different screen, visual and/or
|
||||
colormap, you just can't use FLTK's drawing routines to draw into it.
|
||||
But you can write your own <tt>draw()</tt> method that uses Xlib
|
||||
(and/or OpenGL) calls only.
|
||||
|
||||
Fltk can manage an X window on a different screen, visual and/or
|
||||
colormap, you just can't use fltk's drawing routines to draw into it.
|
||||
But you can write your own draw() method that uses Xlib calls only.
|
||||
|
||||
<p>Fltk can also manage xid's provided by other libraries or programs,
|
||||
<p>FLTK can also manage XID's provided by other libraries or programs,
|
||||
and call those libraries when the window needs to be redrawn.
|
||||
|
||||
<p>To do this, you need to make a subclass of <a
|
||||
href=Fl_Window.html>Fl_Window</a> and override some of these virtual
|
||||
href="#Fl_Window"><tt>Fl_Window</tt></a> and override some of these virtual
|
||||
functions:
|
||||
|
||||
</ul><h4><code>virtual void Fl_Window::show()</code></h4><ul>
|
||||
<h4>virtual void Fl_Window::show()</h4>
|
||||
|
||||
<p>If the window is already shown() this must cause it to be raised,
|
||||
this can usually be done by calling Fl_Window::show(). If not shown()
|
||||
your implementation must call either Fl_X::set_xid() or
|
||||
Fl_X::make_xid():
|
||||
If the window is already <tt>shown()</tt> this must cause it to be raised,
|
||||
this can usually be done by calling <tt>Fl_Window::show()</tt>. If not <tt>shown()</tt>
|
||||
your implementation must call either <tt>Fl_X::set_xid()</tt> or
|
||||
<tt>Fl_X::make_xid()</tt>.
|
||||
|
||||
<h4><code>Fl_X* Fl_X::set_xid(Fl_Window*, Window xid);</code></h4><ul>
|
||||
<p>An example:
|
||||
|
||||
Allocate a hidden structure called an Fl_X, put the xid into it, and
|
||||
set a pointer to it from the Fl_Window. This causes
|
||||
Fl_Window::shown() to return true.
|
||||
|
||||
</ul><h4><code>void Fl_X::make_xid(Fl_Window*, XVisualInfo* =
|
||||
fl_visual, Colormap = fl_colormap);</code></h4><ul>
|
||||
|
||||
This static method does the most onerous parts of creating an X window,
|
||||
including setting the label, resize limitations, etc. It then does
|
||||
set_xid with this new window and maps the window.
|
||||
|
||||
</ul>
|
||||
|
||||
<p>Example:
|
||||
|
||||
<pre>
|
||||
<ul><pre>
|
||||
void MyWindow::show() {
|
||||
if (shown()) {Fl_Window::show(); return;} // you must do this!
|
||||
fl_open_display(); // necessary if this is first window
|
||||
@ -243,47 +212,60 @@ void MyWindow::show() {
|
||||
}
|
||||
Fl_X::make_xid(this, visual, colormap);
|
||||
}
|
||||
</pre>
|
||||
</pre></ul>
|
||||
|
||||
</ul><h4><code>virtual void Fl_Window::flush()</code></h4><ul>
|
||||
<h4>Fl_X *Fl_X::set_xid(Fl_Window *, Window xid)</h4>
|
||||
|
||||
This virtual function is called by Fl::flush() to update the window.
|
||||
For fltk's own windows it does this by setting the global variables
|
||||
fl_window and fl_gc and then calling the draw() method. For your own
|
||||
windows you might just want to put all the drawing code in here.
|
||||
Allocate a hidden structure called an <tt>Fl_X</tt>, put the XID into it, and
|
||||
set a pointer to it from the <tt>Fl_Window</tt>. This causes
|
||||
<tt>Fl_Window::shown()</tt> to return true.
|
||||
|
||||
<p>The X region that is a combination of all damage() calls done so
|
||||
far is in <code>Fl_X::i(this)->region</code>. If null then
|
||||
you should redraw the entire window. The undocumented function
|
||||
<code>fl_clip_region(XRegion)</code> will initialize the fl clip stack
|
||||
with a region or null for no clipping. You must set region to null
|
||||
afterwards as fl_clip_region() now owns it and will delete it when
|
||||
done.
|
||||
<h4>void Fl_X::make_xid(Fl_Window *, XVisualInfo *= fl_visual, Colormap = fl_colormap)</h4>
|
||||
|
||||
<p>If <code>damage()==2</code> then only X expose events have
|
||||
happened. This may be useful if you have an undamaged image (such as
|
||||
a backing buffer) around.
|
||||
This static method does the most onerous parts of creating an X window,
|
||||
including setting the label, resize limitations, etc. It then does
|
||||
<tt>Fl_X::set_xid()</tt> with this new window and maps the window.
|
||||
|
||||
<h4>virtual void Fl_Window::flush()</h4>
|
||||
|
||||
This virtual function is called by <tt>Fl::flush()</tt> to update the
|
||||
window. For FLTK's own windows it does this by setting the global
|
||||
variables <tt>fl_window</tt> and <tt>fl_gc</tt> and then calling the
|
||||
<tt>draw()</tt> method. For your own windows you might just want to
|
||||
put all the drawing code in here.
|
||||
|
||||
<p>The X region that is a combination of all <tt>damage()</tt> calls
|
||||
done so far is in <tt>Fl_X::i(this)->region</tt>. If <tt>NULL</tt>
|
||||
then you should redraw the entire window. The undocumented function
|
||||
<tt>fl_clip_region(XRegion)</tt> will initialize the FLTK clip stack
|
||||
with a region or <tt>NULL</tt> for no clipping. You must set region to
|
||||
<tt>NULL</tt> afterwards as <tt>fl_clip_region()</tt> now owns it and
|
||||
will delete it when done.
|
||||
|
||||
<p>If <tt>damage() & FL_DAMAGE_EXPOSE</tt> then only X expose events
|
||||
have happened. This may be useful if you have an undamaged image (such
|
||||
as a backing buffer) around.
|
||||
|
||||
<p>Here is a sample where an undamaged image is kept somewhere:
|
||||
|
||||
<pre>
|
||||
<ul><pre>
|
||||
void MyWindow::flush() {
|
||||
fl_clip_region(Fl_X::i(this)->region);
|
||||
Fl_X::i(this)->region = 0;
|
||||
if (damage() != 2) {... draw things into backing store ...}
|
||||
... copy backing store to window ...
|
||||
}
|
||||
</pre>
|
||||
</pre></ul>
|
||||
|
||||
</ul><h4><code>virtual void Fl_Window::hide()</code></h4><ul>
|
||||
<h4>virtual void Fl_Window::hide()</h4>
|
||||
|
||||
Destroy the window server copy of the window. Usually you will
|
||||
destroy contexts, pixmaps, or other resources used by the window, and
|
||||
then call Fl_Window::hide() to get rid of the main window identified
|
||||
by xid(). If you override this, you must also override the destructor
|
||||
as shown:
|
||||
Destroy the window server copy of the window. Usually you will destroy
|
||||
contexts, pixmaps, or other resources used by the window, and then call
|
||||
<tt>Fl_Window::hide()</tt> to get rid of the main window identified by
|
||||
<tt>xid()</tt>. If you override this, you must also override the
|
||||
destructor as shown:
|
||||
|
||||
<pre>
|
||||
<ul><pre>
|
||||
void MyWindow::hide() {
|
||||
if (mypixmap) {
|
||||
XFreePixmap(fl_display,mypixmap);
|
||||
@ -291,165 +273,183 @@ void MyWindow::hide() {
|
||||
}
|
||||
Fl_Window::hide(); // you must call this
|
||||
}
|
||||
</pre>
|
||||
</pre></ul>
|
||||
|
||||
</ul><h4><code>virtual void Fl_Window::~Fl_Window()</code></h4><ul>
|
||||
<h4>virtual void Fl_Window::~Fl_Window()</h4>
|
||||
|
||||
Because of the way C++ works, if you override hide() you <i>must</i>
|
||||
override the destructor as well (otherwise only the base class hide()
|
||||
Because of the way C++ works, if you override <tt>hide()</tt> you <i>must</i>
|
||||
override the destructor as well (otherwise only the base class <tt>hide()</tt>
|
||||
is called):
|
||||
|
||||
<pre>
|
||||
<ul><pre>
|
||||
MyWindow::~MyWindow() {
|
||||
hide();
|
||||
}
|
||||
</pre>
|
||||
</pre></ul>
|
||||
|
||||
</ul>
|
||||
<h3>Setting the Icon of a Window</h3>
|
||||
|
||||
<p><a href = index.html>(back to contents)</a>
|
||||
<title>Fltk MSWindows-specific interface</title>
|
||||
<h2>#include <FL/x.H><br>
|
||||
Fltk MSWindows-specific interface</h2>
|
||||
FLTK currently supports setting a window's icon *before* it is shown using
|
||||
the <tt>Fl_Window::icon()</tt> method.
|
||||
|
||||
The <FL/x.H> header file defines the interface to fltk's
|
||||
MSWindows-specific functions. Be warned that some of the structures
|
||||
and calls in it are subject to change in future version of fltk. Try
|
||||
<h4>void Fl_Window::icon(char *)</h4>
|
||||
|
||||
Sets the icon for the window to the passed pointer. You will need to
|
||||
cast the icon <tt>Pixmap</tt> to a <tt>char *</tt> when calling this
|
||||
method. To set the icon using a bitmap compiled with your application
|
||||
use:
|
||||
|
||||
<ul><pre>
|
||||
#include "icon.xbm"
|
||||
|
||||
Pixmap p = XCreatePixmapFromBitmapData(fl_display,
|
||||
DefaultRootWindow(fl_display), icon_bits,
|
||||
icon_width, icon_height,
|
||||
BlackPixel(fl_display, DefaultScreen(fl_display)),
|
||||
WhitePixel(fl_display, DefaultScreen(fl_display)),
|
||||
DefaultDepth(fl_display, DefaultScreen(fl_display)))
|
||||
|
||||
window->icon((char *)p);
|
||||
</ul></pre>
|
||||
|
||||
<h2>WIN32-Specific Interface</h2>
|
||||
|
||||
<ul><pre>
|
||||
#include <FL/x.H>
|
||||
</pre></ul>
|
||||
|
||||
The <tt><FL/x.H></tt> header file defines the interface to FLTK's
|
||||
WIN32-specific functions. Be warned that some of the structures
|
||||
and calls in it are subject to change in future version of FLTK. Try
|
||||
to avoid doing this so your code is portable.
|
||||
|
||||
<p><hr>
|
||||
<h3>Handling Other WIN32 Messages</h3>
|
||||
|
||||
<h2>Handling other MSWindows messages</h2>
|
||||
By default a single WNDCLASSEX called "FLTK" is created. All
|
||||
<tt>Fl_Windows</tt> are of this class unless you use
|
||||
<tt>Fl_Window::xclass()</tt>. The window class is created the first
|
||||
time <tt>Fl_Window::show()</tt> is called.
|
||||
|
||||
<p>A single WNDCLASSEX called "FLTK" is created. All
|
||||
Fl_Windows are of this class. This window class is created the first
|
||||
time Fl_Window::show() is called.
|
||||
|
||||
<p>You can probably combine fltk with other libraries that make their
|
||||
own MSWindows window classes. The easiest way is to call Fl::wait(), it
|
||||
will call DispatchMessage for all messages to the other windows. If
|
||||
<p>You can probably combine FLTK with other libraries that make their
|
||||
own WIN32 window classes. The easiest way is to call <tt>Fl::wait()</tt>, it
|
||||
will call <tt>DispatchMessage</tt> for all messages to the other windows. If
|
||||
necessary you can let the other library take over (as long as it calls
|
||||
DispatchMessage()), but you will have to arrange for the function
|
||||
Fl::flush() to be called regularily (otherwise widgets will not
|
||||
update), and timeouts and the idle function will not work.
|
||||
<tt>DispatchMessage()</tt>), but you will have to arrange for the function
|
||||
<tt>Fl::flush()</tt> to be called regularily so that widgets are updated,
|
||||
timeouts are handled, and the idle functions are called.
|
||||
|
||||
<a name=fl_msg>
|
||||
</ul><h4><code>extern MSG fl_msg;</code></h4><ul>
|
||||
<h4><a name="fl_msg">extern MSG fl_msg</a></h4>
|
||||
|
||||
The most recent message read by GetMessage (which is called by
|
||||
<a href=Fl.html#wait>Fl::wait()</a>. This may not be the most recent
|
||||
message sent to an fltk window, because silly MSWindows calls the
|
||||
The most recent message read by <tt>GetMessage</tt> (which is called by
|
||||
<a href="#wait"><tt>Fl::wait()</tt></a>. This may not be the most
|
||||
recent message sent to an FLTK window, because silly WIN32 calls the
|
||||
handle procedures directly for some events (sigh).
|
||||
|
||||
<a name=add_handler>
|
||||
</ul><h4><code>void Fl::add_handler(int (*f)(int));</code></h4><ul>
|
||||
<h4><a name="WIN32.add_handler">void Fl::add_handler(int (*f)(int))</a></h4>
|
||||
|
||||
Install a function to parse unrecognized messages sent to fltk
|
||||
windows. If fltk cannot figure out what to do with a message, it
|
||||
Install a function to parse unrecognized messages sent to FLTK
|
||||
windows. If FLTK cannot figure out what to do with a message, it
|
||||
calls each of these functions (most recent first) until one of them
|
||||
returns non-zero. The argument passed to the fuctions is zero. If
|
||||
all the handlers return zero then fltk calls DefWindowProc(...).
|
||||
all the handlers return zero then FLTK calls <tt>DefWindowProc()</tt>.
|
||||
|
||||
</ul><h4><code>HWND fl_xid(const Fl_Window*);</code></h4><ul>
|
||||
<h4><a name="WIN32.fl_xid">HWND fl_xid(const Fl_Window *)</a></h4>
|
||||
|
||||
Returns the window handle for a Fl_Window, or zero if not shown().
|
||||
Returns the window handle for a <tt>Fl_Window</tt>, or zero if not
|
||||
<tt>shown()</tt>.
|
||||
|
||||
</ul><h4><code>Fl_Window* fl_find(HWND xid)</code></h4><ul>
|
||||
<h4><a name="WIN32.fl_find">Fl_Window *fl_find(HWND xid)</a></h4>
|
||||
|
||||
<p>Return the Fl_Window that corresponds to the given window handle,
|
||||
or null if not found. This uses a cache so it is slightly faster than
|
||||
iterating through the windows yourself.
|
||||
Return the <tt>Fl_Window</tt> that corresponds to the given window
|
||||
handle, or <tt>NULL</tt> if not found. This uses a cache so it is
|
||||
slightly faster than iterating through the windows yourself.
|
||||
|
||||
</ul>
|
||||
<h3>Drawing Things Using the WIN32 GDI</h3>
|
||||
|
||||
<p><hr>
|
||||
|
||||
<a name=gdi>
|
||||
<h2>Drawing things using the MSWindows GDI</h2>
|
||||
|
||||
<p>When the virtual function Fl_Widget::draw() is called, fltk has
|
||||
When the virtual function <tt>Fl_Widget::draw()</tt> is called, FLTK has
|
||||
stashed in some global variables all the silly extra arguments you
|
||||
need to make a proper GDI call. These are:
|
||||
|
||||
</ul><h4><code>
|
||||
extern HINSTANCE fl_display;<br>
|
||||
extern HWND fl_window;<br>
|
||||
extern HDC fl_gc;<br>
|
||||
COLORREF fl_RGB();<br>
|
||||
HPEN fl_pen();<br>
|
||||
HBRUSH fl_brush();</code></h4><ul>
|
||||
<ul><pre>
|
||||
extern HINSTANCE fl_display;
|
||||
extern HWND fl_window;
|
||||
extern HDC fl_gc;
|
||||
COLORREF fl_RGB();
|
||||
HPEN fl_pen();
|
||||
HBRUSH fl_brush();
|
||||
</pre></ul>
|
||||
|
||||
These global variables are set before draw() is called, or by <a
|
||||
href=Fl_Window.html#make_current>Fl_Window::make_current()</a> You can
|
||||
These global variables are set before <tt>draw()</tt> is called, or by <a
|
||||
href="#Fl_Window.make_current"><tt>Fl_Window::make_current()</tt></a>. You can
|
||||
refer to them when needed to produce GDI calls. Don't attempt to
|
||||
change them. The functions return GDI objects for the current color
|
||||
set by fl_color(), these are created as needed and cached. A typical
|
||||
set by <tt>fl_color()</tt> and are created as needed and cached. A typical
|
||||
GDI drawing call is written like this:
|
||||
|
||||
<ul><p><code>DrawSomething(fl_gc, ..., fl_brush());</code></ul>
|
||||
<ul><pre>
|
||||
DrawSomething(fl_gc, ..., fl_brush());
|
||||
</pre></ul>
|
||||
|
||||
<p>It may also be useful to refer to <a
|
||||
href=Fl_Window.html#make_current><code>Fl_Window::current()</code></a>
|
||||
to get the window's size or position.
|
||||
It may also be useful to refer to <a
|
||||
href="#Fl_Window.make_current"><tt>Fl_Window::current()</tt></a> to get
|
||||
the window's size or position.
|
||||
|
||||
</ul>
|
||||
<p><hr>
|
||||
<h2>How to not get a MSDOS console window</h2>
|
||||
<h3>Setting the Icon of a Window</h3>
|
||||
|
||||
MSWindows has a really stupid mode switch stored in the executables that
|
||||
controls whether or not to make a console window (hint to Mr Gates:
|
||||
why not leave it hidden until the program prints something?).
|
||||
FLTK currently supports setting a window's icon *before* it is shown using
|
||||
the <tt>Fl_Window::icon()</tt> method.
|
||||
|
||||
<p>To not produce a "console" window when you run your program add the
|
||||
following secret incantation to the Micro$oft linker:
|
||||
<h4>void Fl_Window::icon(char *)</h4>
|
||||
|
||||
<p><pre> /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup</pre>
|
||||
Sets the icon for the window to the passed pointer. You will need to
|
||||
cast the <tt>HICON</tt> handle to a <tt>char *</tt> when calling this
|
||||
method. To set the icon using an icon resource compiled with your
|
||||
application use:
|
||||
|
||||
<p>Unfortunately this seems to completely disable stdin/stdout, even
|
||||
if you run the program from a console. So don't do this until you
|
||||
have debugged your program!
|
||||
<ul><pre>
|
||||
window->icon((char *)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
|
||||
</ul></pre>
|
||||
|
||||
<p><hr>
|
||||
<h2>Other hints</h2>
|
||||
<h3>How to Not Get a MSDOS Console Window</h3>
|
||||
|
||||
<p>I use capital C as the extension for c++ source code, for instace
|
||||
for Fluid output. Unfortunately there is no way to convince VC++ to
|
||||
use this except to tell it to compile *everything* using C++ by
|
||||
putting the switch "/TP" in the options. This makes it impossible to
|
||||
combine old C code and fltk code.
|
||||
WIN32 has a really stupid mode switch stored in the executables that
|
||||
controls whether or not to make a console window.
|
||||
|
||||
<p><hr>
|
||||
<h2>Known bugs</h2>
|
||||
<p>To always get a console window you simply create a console
|
||||
application (the "/SUBSYSTEM:CONSOLE" option for the linker). For a
|
||||
GUI-only application create a WIN32 application (the
|
||||
"/SUBSYSTEM:WINDOWS" option for the linker).
|
||||
|
||||
<p>If program is deactivated, Fl::wait() does not return until it is
|
||||
activated again, even though many events are delivered to the program.
|
||||
This can cause idle background processes to stop unexpectedly. This
|
||||
also happens while the user is dragging or resizing windows or
|
||||
otherwise holding the mouse down. I was forced to remove most of the
|
||||
efficiency fltk uses for redrawing in order to get windows to update
|
||||
while being moved. This is a design error in MSWindows and probably
|
||||
impossible to get around.
|
||||
<p>FLTK includes a <tt>WinMain()</tt> function that calls the ANSI
|
||||
standard <tt>main()</tt> entry point for you. <i>This function creates
|
||||
a console window when you use the debug version of the library.</i>
|
||||
|
||||
<p>Fl_Gl_Window::can_do_overlay() returns true until the first time it
|
||||
attempts to draw an overlay, and then correctly returns whether or not
|
||||
there is overlay hardware.
|
||||
<p>WIN32 applications without a console cannot write to <tt>stdout</tt> or
|
||||
<tt>stderr</tt>, even if they are run from a console window. Any output
|
||||
is silently thrown away.
|
||||
|
||||
<h3>Known Bugs</h3>
|
||||
|
||||
If a program is deactivated, <tt>Fl::wait()</tt> does not return until
|
||||
it is activated again, even though many events are delivered to the
|
||||
program. This can cause idle background processes to stop
|
||||
unexpectedly. This also happens while the user is dragging or resizing
|
||||
windows or otherwise holding the mouse down. I was forced to remove
|
||||
most of the efficiency FLTK uses for redrawing in order to get windows
|
||||
to update while being moved. This is a design error in WIN32 and
|
||||
probably impossible to get around.
|
||||
|
||||
<p><tt>Fl_Gl_Window::can_do_overlay()</tt> returns true until the first
|
||||
time it attempts to draw an overlay, and then correctly returns whether
|
||||
or not there is overlay hardware.
|
||||
|
||||
<p>Cut text contains ^J rather than ^M^J to break lines. This is a
|
||||
feature, not a bug.
|
||||
|
||||
<p>I can't seem to get SetCapture (used by Fl::grab()) to work, and I
|
||||
can't find a way to stop the main window title from turning gray while
|
||||
menus are popped up.
|
||||
|
||||
<p>glpuzzle program does not animate unless you resize it first. Unknown why.
|
||||
|
||||
<p>Fl_Window::fullscreen() not implemented (should take over the screen
|
||||
without a title bar). Currently does maximize instead.
|
||||
|
||||
<p>Import .bmp files into fluid. Wonko has the specs.
|
||||
|
||||
<p>Can't set icon of windows.
|
||||
|
||||
|
||||
<p><tt>SetCapture</tt> (used by <tt>Fl::grab()</tt>) doesn't work, and
|
||||
the main window title bar turns gray while menus are popped up.
|
||||
|
||||
<p>FLUID does not support BMP files yet.
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META NAME="Author" CONTENT="Michael Sweet">
|
||||
<META NAME="Copyright" CONTENT="Copyright 1998 by Bill Spizak and Others.">
|
||||
<META NAME="Copyright" CONTENT="Copyright 1998-1999 by Bill Spizak and Others.">
|
||||
<META NAME="DocNumber" CONTENT="Revision 0">
|
||||
<TITLE>FLTK 1.0 Programming Manual</TITLE>
|
||||
</HEAD>
|
||||
@ -23,15 +23,18 @@ This manual is organized into the following chapters and appendices:
|
||||
<LI><A HREF="#basics">Chapter 2 - FLTK Basics</A>
|
||||
<LI><A HREF="#common">Chapter 3 - Common Widgets and Attributes</A>
|
||||
<LI><A HREF="#editor">Chapter 4 - Designing a Simple Text Editor</A>
|
||||
<LI><A HREF="#subclasseing">Chapter 5 - Extending and Adding Widgets</A>
|
||||
<LI><A HREF="#fluid">Chapter 6 - Programming With FLUID</A>
|
||||
<LI><A HREF="#opengl">Chapter 7 - Using OpenGL</A>
|
||||
<LI><A HREF="#drawing">Chapter 5 - Drawing Things in FLTK</A>
|
||||
<LI><A HREF="#events">Chapter 6 - Handling Events</A>
|
||||
<LI><A HREF="#subclassing">Chapter 7 - Extending and Adding Widgets</A>
|
||||
<LI><A HREF="#fluid">Chapter 8 - Programming With FLUID</A>
|
||||
<LI><A HREF="#opengl">Chapter 9 - Using OpenGL</A>
|
||||
<LI><A HREF="#widgets">Appendix A - Widget Reference</A>
|
||||
<LI><A HREF="#functions">Appendix B - Function Reference</A>
|
||||
<LI><A HREF="#enumerations">Appendix C - Enumeration Reference</A>
|
||||
<LI><A HREF="#glut">Appendix D - GLUT Compatibility</A>
|
||||
<LI><A HREF="#forms">Appendix E - Forms Compatibility</A>
|
||||
<LI><A HREF="#license">Appendix F - Software License</A>
|
||||
<LI><A HREF="#license">Appendix F - Operating System Issues</A>
|
||||
<LI><A HREF="#license">Appendix G - Software License</A>
|
||||
</UL>
|
||||
|
||||
<H2>Conventions</H2>
|
||||
@ -63,7 +66,7 @@ The following abbreviations are used in this manual:
|
||||
|
||||
<H2>Copyrights and Trademarks</H2>
|
||||
|
||||
FLTK is Copyright 1998 by Bill Spitzak and others. Use and distribution of FLTK is
|
||||
FLTK is Copyright 1998-1999 by Bill Spitzak and others. Use and distribution of FLTK is
|
||||
governed by the GNU Library General Public License, located in
|
||||
<A HREF=#license>Appendix D</A>.
|
||||
|
||||
|
@ -1,427 +1,338 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<H1 ALIGN=RIGHT><A NAME="subclassing">5 - Adding and Extending Widgets</A></H1>
|
||||
<H1 ALIGN=RIGHT><A NAME="subclassing">7 - Adding and Extending Widgets</A></H1>
|
||||
|
||||
This chapter describes how to add your own widgets or extend existing widgets in FLTK.
|
||||
This chapter describes how to add your own widgets or extend existing
|
||||
widgets in FLTK.
|
||||
|
||||
<H2>Subclassing</H2>
|
||||
|
||||
<H2>Adding Syntax Highlighting to the Fl_Input Widget</H2>
|
||||
New widgets are created by <i>subclassing</i> an existing FLTK widget,
|
||||
typically <tt>Fl_Widget</tt> for controls and <tt>Fl_Group</tt> for
|
||||
containers.
|
||||
|
||||
<H2>Drawing Functions</H2>
|
||||
<p>A control widget typically interacts with the user to receive and/or
|
||||
display a value of some sort.
|
||||
|
||||
<H3>Lines, Rectangles, and Curves, Oh, My!</H3>
|
||||
<p>A container widget holds a list of child widgets and handles moving,
|
||||
sizing, showing, or hiding them as needed. <tt>Fl_Group</tt> is the
|
||||
main container widget class in FLTK, and all of the other containers
|
||||
(<tt>Fl_Pack</tt>, <tt>Fl_Scroll</tt>, <tt>Fl_Tabs</tt>, <tt>Fl_Tile</tt>,
|
||||
and <tt>Fl_Window</tt>) are subclasses of it.
|
||||
|
||||
<H3>Colors</H3>
|
||||
<p>You can also subclass other existing widgets to provide a different look
|
||||
or user-interface. For example, the button widgets are all subclasses of
|
||||
<tt>Fl_Button</tt> since they all interact with the user via a mouse button
|
||||
click. The only difference is the code that draws the face of the button.
|
||||
|
||||
<H3>Fonts</H3>
|
||||
<H2>Making a Subclass of Fl_Widget</H2>
|
||||
|
||||
<H3>Images</H3>
|
||||
Your subclasses can directly descend from <tt>Fl_Widget</tt> or any
|
||||
subclass of <tt>Fl_Widget</tt>. <tt>Fl_Widget</tt> has only four
|
||||
virtual methods, and overriding some or all of these may be necessary.
|
||||
|
||||
<H2><A NAME="Fl_Table">Writing a Table Widget</A></H2>
|
||||
<H2>The Constructor</H2>
|
||||
|
||||
<H3>Methods</H3>
|
||||
The constructor should access the following arguments:
|
||||
|
||||
<H3>Cut and Paste Support</H3>
|
||||
<ul><pre>
|
||||
MyClass(int x, int y, int w, int h, const char *label = 0);
|
||||
</pre></ul>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
<title>Cut & paste</title>
|
||||
<h2>Cut & paste</h2>
|
||||
|
||||
Fltk provides routines to cut and paste ASCII text (in the future this
|
||||
may be UTF-8) between applications. It may be possible to cut/paste
|
||||
non-ascii data under X by using <a
|
||||
href=events.html#add_handler>Fl::add_handler()</a>.
|
||||
|
||||
</ul><h4><code>void Fl::paste(Fl_Widget *receiver)</code></h4><ul>
|
||||
|
||||
<P>Set things up so the receiver widget will be called with an <a
|
||||
href=events.html#paste>FL_PASTE</a> event some time in the future.
|
||||
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.
|
||||
|
||||
</ul><h4><code>void Fl::selection(Fl_Widget *owner, const char *stuff, int len);
|
||||
</code></h4><ul>
|
||||
|
||||
<p>Change the current selection. The block of text is copied to an
|
||||
internal buffer by Fltk (be careful if doing this in response to an
|
||||
FL_PASTE as this <i>may</i> be the same buffer returned by
|
||||
event_text()). The selection_owner is set to the passed owner
|
||||
(possibly sending FL_SELECTIONCLEAR to the previous owner).
|
||||
|
||||
</ul><h4><code>const char* Fl::selection();
|
||||
<br>int Fl::selection_length();</code></h4><ul>
|
||||
|
||||
You can look at the buffer containing the current selection. Contents
|
||||
of this buffer are undefined if this program does not own the X
|
||||
selection.
|
||||
|
||||
</ul><h4><code>Fl_Widget *Fl::selection_owner() const;
|
||||
<br>void Fl::selection_owner(Fl_Widget *);</code></h4><ul>
|
||||
|
||||
<p>The single-argument selection_owner(x) call can be used to move the
|
||||
selection to another widget or to set the owner to NULL, without
|
||||
changing the actual text of the selection. FL_SELECTIONCLEAR is sent
|
||||
to the old selection owner, if any.
|
||||
|
||||
</ul>
|
||||
|
||||
<p><i>Copying the buffer every time the selection is changed is
|
||||
obviously wasteful, especially for large selections. I expect an
|
||||
interface will be added in a future version to allow the selection to
|
||||
be made by a callback function. The current interface will be
|
||||
emulated on top of this.</i>
|
||||
|
||||
<title>Making a subclass of Fl_Widget</title>
|
||||
</ul><h2>Making a subclass of Fl_Widget</h2>
|
||||
|
||||
<p>Your subclasses can directly descend from Fl_Widget or any
|
||||
subclass of Fl_Widget. Fl_Widget has only four virtual methods, and
|
||||
overriding some or all of these may be necessary.
|
||||
|
||||
<p>Parts of this document:
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href=#constructor>Constructing your Fl_Widget</a>
|
||||
|
||||
<li><a href=#protected>Protected methods of Fl_Widget</a>
|
||||
|
||||
<li>Virtual functions to override:
|
||||
|
||||
<ul>
|
||||
|
||||
<li><code><a href=#handle>int Fl_Widget::handle(int
|
||||
event);</a></code>
|
||||
|
||||
<li><code><a href=#draw>void Fl_Widget::draw();</a></code>
|
||||
|
||||
<li><code><a href=#resize>void
|
||||
Fl_Widget::resize(int,int,int,int);</a></code>
|
||||
|
||||
<li><code><a href=#destructor>Fl_Widget::~Fl_Widget();</a></code>
|
||||
|
||||
</ul>
|
||||
|
||||
<li><a href=#composite>Making a Composite/Group Widget</a>
|
||||
|
||||
<li><a href=#window>Making a subclass of Fl_Window</a>
|
||||
|
||||
</ul>
|
||||
|
||||
<a name=constructor>
|
||||
<h2>Constructing your Fl_Widget</h2>
|
||||
|
||||
I recommend your constructor be of this form:
|
||||
|
||||
<p><pre>
|
||||
Class(int x, int y, int w, int h, const char* label = 0);
|
||||
</pre>
|
||||
|
||||
<p>This will allow the class name to be typed into <a
|
||||
href=fluid.html>fluid</a> and it will produce the correct call.
|
||||
This will allow the class to be used in <a href="#fluid">Fluid</a> without
|
||||
problems.
|
||||
|
||||
<p>The constructor must call the constructor for the base class and
|
||||
pass the same arguments. Fl_Widget's protected constructor sets x(),
|
||||
y(), w(), h(), and label() to the passed values and initializes the
|
||||
other instance variables to:
|
||||
pass the same arguments:
|
||||
|
||||
<p><pre>
|
||||
type(0);
|
||||
box(FL_NO_BOX);
|
||||
color(FL_GRAY);
|
||||
selection_color(FL_GRAY);
|
||||
labeltype(FL_NORMAL_LABEL);
|
||||
labelstyle(FL_NORMAL_STYLE);
|
||||
labelsize(FL_NORMAL_SIZE);
|
||||
labelcolor(FL_BLACK);
|
||||
align(FL_ALIGN_CENTER);
|
||||
callback(default_callback,0);
|
||||
flags(ACTIVE|VISIBLE);
|
||||
</pre>
|
||||
<ul><pre>
|
||||
MyClass::MyClass(int x, int y, int w, int h, const char *label)
|
||||
: Fl_Widget(x, y, w, h, label) {
|
||||
// do initialization stuff...
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
<a name=protected>
|
||||
<h2>Protected methods of Fl_Widget</h2>
|
||||
<tt>Fl_Widget</tt>'s protected constructor sets <tt>x()</tt>,
|
||||
<tt>y()</tt>, <tt>w()</tt>, <tt>h()</tt>, and <tt>label()</tt> to the
|
||||
passed values and initializes the other instance variables to:
|
||||
|
||||
<p>These methods are provided for subclasses to use.
|
||||
<ul><pre>
|
||||
type(0);
|
||||
box(FL_NO_BOX);
|
||||
color(FL_GRAY);
|
||||
selection_color(FL_GRAY);
|
||||
labeltype(FL_NORMAL_LABEL);
|
||||
labelstyle(FL_NORMAL_STYLE);
|
||||
labelsize(FL_NORMAL_SIZE);
|
||||
labelcolor(FL_BLACK);
|
||||
align(FL_ALIGN_CENTER);
|
||||
callback(default_callback,0);
|
||||
flags(ACTIVE|VISIBLE);
|
||||
</pre></ul>
|
||||
|
||||
</ul><h4><code>uchar Fl_Widget::type() const;
|
||||
<br>void Fl_Widget::type(uchar);
|
||||
</code></h4><ul>
|
||||
<H2>Protected Methods of Fl_Widget</H2>
|
||||
|
||||
The property Fl_Widget::type() can return an arbitrary 8-bit
|
||||
identifier, and can be set with the protected method type(uchar).
|
||||
This value had to be provided for Forms compatability, but you can use
|
||||
it for any purpose you want. Try to keep the value less than 100 to
|
||||
not interfere with reserved values.
|
||||
The following methods are provided for subclasses to use:
|
||||
|
||||
<p>Fltk does not use RTTI (Run Time Typing Infomation), to enhance
|
||||
portability. But this may change in the near future if RTTI becomes
|
||||
standard everywhere.
|
||||
<ul>
|
||||
<li><a name="#clear_visible">clear_visible</a>
|
||||
<li><a name="#damage">damage</a>
|
||||
<li><a name="#draw_box">draw_box</a>
|
||||
<li><a name="#draw_label">draw_label</a>
|
||||
<li><a name="#set_flag">set_flag</a>
|
||||
<li><a name="#set_visible">set_visible</a>
|
||||
<li><a name="#test_shortcut">test_shortcut</a>
|
||||
<li><a name="#type">type</a>
|
||||
</ul>
|
||||
|
||||
<p>If you don't have RTTI you can use the clumsy fltk mechanisim, by
|
||||
having type() have a unique value. These unique values must be
|
||||
greater than the symbol FL_RESERVED_TYPE (which is 100). Grep through
|
||||
the header files for "FL_RESERVED_TYPE" to find an unused number. If
|
||||
you make a subclass of Fl_Group you must use FL_GROUP+n, and if you
|
||||
make a subclass of Fl_Window you must use FL_WINDOW+n (in both cases n
|
||||
is in the range 1-7).
|
||||
<H3><a name="damage">void Fl_Widget::damage(uchar mask)<br>
|
||||
void Fl_Widget::damage(uchar mask, int x, int y, int w, int h)<br>
|
||||
uchar Fl_Widget::damage()</a></H3>
|
||||
|
||||
<a name=test_shortcut>
|
||||
</ul><h4><code>void Fl_Widget::set_flag(SHORTCUT_LABEL);</code></h4><ul>
|
||||
The first form indicates that a partial update of the object is
|
||||
needed. The bits in mask are OR'd into <tt>damage()</tt>. Your
|
||||
<tt>draw()</tt> routine can examine these bits to limit what it is
|
||||
drawing. The public method <tt>Fl_Widget::redraw()</tt> simply does
|
||||
<tt>Fl_Widget::damage(FL_DAMAGE_ALL)</tt>.
|
||||
|
||||
If your constructor calls this it modifies draw_label() so that '&'
|
||||
characters cause an underscore to be printed under the next letter.
|
||||
<p>The second form indicates that a region is damaged. If only these
|
||||
calls are done in a window (no calls to <tt>damage(n)</tt>) then FLTK
|
||||
will clip to the union of all these calls before drawing anything.
|
||||
This can greatly speed up incremental displays. The mask bits are or'd
|
||||
into <tt>damage()</tt> unless this is a <tt>Fl_Window</tt> widget.
|
||||
|
||||
</ul><h4><code>int Fl_Widget::test_shortcut() const;<br>
|
||||
static int Fl_Widget::test_shortcut(const char *);</code></h4><ul>
|
||||
<p>The third form returns the bitwise-OR of all <tt>damage(n)</tt>
|
||||
calls done since the last <tt>draw()</tt>. The public method
|
||||
<tt>redraw()</tt> does <tt>damage(FL_DAMAGE_ALL)</tt>, but the
|
||||
implementation of your widget can call the private <tt>damage(n)</tt>.
|
||||
|
||||
The first version tests Fl_Widget::label() against the current event
|
||||
(which should be a FL_SHORTCUT event). If the label contains a '&'
|
||||
character and the character after it matches the key press, this
|
||||
returns true. This returns false if the SHORTCUT_LABEL flag is off,
|
||||
if the label is null or does not have a '&' character in it, or if the
|
||||
keypress does not match the character.
|
||||
<H3><a name="draw_box">void Fl_Widget::draw_box() const<br>
|
||||
</a>void Fl_Widget::draw_box(Fl_Boxtype b, ulong c) const</H3>
|
||||
|
||||
<p>The second version lets you do this test to an arbitrary string.
|
||||
The first form draws this widget's <tt>box()</tt>, using the dimensions
|
||||
of the widget.
|
||||
|
||||
</ul><h4><code>void Fl_Widget::x(short);
|
||||
<br>void Fl_Widget::y(short);
|
||||
<br>void Fl_Widget::w(short);
|
||||
<br>void Fl_Widget::h(short);</code></h4><ul>
|
||||
The second form uses <tt>b</tt> as the box type and <tt>c</tt> as the
|
||||
color for the box.
|
||||
|
||||
You can directly clobber the values for <a
|
||||
href=Fl_Widget.html#xywh>x(), y(), w(), and h()</a>. Make sure you
|
||||
know what you are doing. This is most useful for temporarily
|
||||
replacing the values before calling handle() or draw() on the base
|
||||
class to "fool" it into working in a different area.
|
||||
<H3><a name="draw_label">void Fl_Widget::draw_label() const<br>
|
||||
void Fl_Widget::draw_label(int x, int y, int w, int h) const<br>
|
||||
void Fl_Widget::draw_label(int x, int y, int w, int h, Fl_Align align) const</a></H3>
|
||||
|
||||
<a name=damage>
|
||||
</ul><h4><code>void Fl_Widget::damage(uchar mask);</code></h4><ul>
|
||||
|
||||
Indicate that a partial update of the object is needed. The bits in
|
||||
mask are or'd into damage(). Your draw() routine can examine these
|
||||
bits to limit what it is drawing. The public method
|
||||
Fl_Widget::redraw() simply does Fl_Widget::damage(-1).
|
||||
|
||||
</ul><h4><code>void Fl_Widget::damage(uchar mask,int x,int y,int w,int
|
||||
h);</code></h4><ul>
|
||||
|
||||
Indicate that a region is damaged. If only these calls are done in a
|
||||
window (no calls to damage(n)) then fltk will clip to the union of all
|
||||
these calls before drawing anything. This can greatly speed up
|
||||
incremental displays. The mask bits are or'd into damage() (unless
|
||||
this is a Fl_Window, in which case they are forced to the value 6 for
|
||||
internal reasons).
|
||||
|
||||
</ul><h4><code>void Fl_Widget::clear_damage(uchar value = 0);</code></h4><ul>
|
||||
|
||||
Directly set damage() to the passed value. This is provided for
|
||||
kludges only.
|
||||
|
||||
</ul><h4><code>uchar Fl_Widget::damage()</code></h4><ul>
|
||||
|
||||
Return the bitwise-or of all damage(n) calls done since the last
|
||||
draw(). The public method redraw() does damage(-1), but the
|
||||
implementation of your widget can call the private damage(n).
|
||||
|
||||
</ul><h4><code>void Fl_Widget::set_visible();
|
||||
<br>void Fl_Widget::clear_visible();</code></h4><ul>
|
||||
|
||||
Fast inline versions of Fl_Widget::hide() and Fl_Widget::show().
|
||||
These do not send the FL_HIDE and FL_SHOW events to the widget.
|
||||
|
||||
</ul><h4><code>void Fl_Widget::draw_box() const ;</code></h4><ul>
|
||||
|
||||
Draw this widget's box(), using the dimensions of the widget.
|
||||
|
||||
</ul><h4><code>void Fl_Widget::draw_box(Fl_Boxtype b,ulong c) const
|
||||
;</code></h4><ul>
|
||||
|
||||
Pretend the box()==b and the color()==c and draw this widget's box.
|
||||
|
||||
<a name=draw_label>
|
||||
</ul><h4><code>void Fl_Widget::draw_label() const ;</code></h4><ul>
|
||||
|
||||
This is the usual function for a draw() method to call to draw the
|
||||
widget's label. It does not draw the label if it is supposed to be
|
||||
This is the usual function for a <tt>draw()</tt> method to call to draw
|
||||
the widget's label. It does not draw the label if it is supposed to be
|
||||
outside the box (on the assumption that the enclosing group will draw
|
||||
those labels).
|
||||
|
||||
</ul><h4><code>void Fl_Widget::draw_label(int x,int y,int w,int h) const
|
||||
;</code></h4><ul>
|
||||
<p>The second form uses the passed bounding box instead of the widget's
|
||||
bounding box. This is useful so "centered" labels are aligned with some
|
||||
feature, such as a moving slider.
|
||||
|
||||
Do the same thing except use the passed bounding box. This is useful
|
||||
so "centered" labels are aligned with some feature, such as a moving
|
||||
slider.
|
||||
<p>The third form draws the label anywhere. It acts as though
|
||||
<tt>FL_ALIGN_INSIDE</tt> has been forced on, the label will appear
|
||||
inside the passed bounding box. This is designed for parent groups to
|
||||
draw labels with.
|
||||
|
||||
</ul><h4><code>void Fl_Widget::draw_label(int x,int y,int w,int
|
||||
h,Fl_Align align) const ;</code></h4><ul>
|
||||
<H3><a name="set_flag">void Fl_Widget::set_flag(SHORTCUT_LABEL)</a></H3>
|
||||
|
||||
Draw the label anywhere. It acts as though FL_ALIGN_INSIDE has been
|
||||
forced on, the label will appear inside the passed bounding box. This
|
||||
is designed for parent groups to draw labels with.
|
||||
If your constructor calls this it modifies <tt>draw_label()</tt> so
|
||||
that '&' characters cause an underscore to be printed under the next
|
||||
letter.
|
||||
|
||||
</ul>
|
||||
<a name=handle>
|
||||
<h2>virtual int Fl_Widget::handle()</h2>
|
||||
<H3><a name="set_visible">void Fl_Widget::set_visible()</a><br>
|
||||
<a name="clear_visible">void Fl_Widget::clear_visible()</a></H3>
|
||||
|
||||
The virtual method <b><code>int Fl_Widget::handle(int
|
||||
event)</code></b> is called to handle each event passed to the widget.
|
||||
It can:<ul>
|
||||
Fast inline versions of <tt>Fl_Widget::hide()</tt> and
|
||||
<tt>Fl_Widget::show()</tt>. These do not send the <tt>FL_HIDE</tt> and
|
||||
<tt>FL_SHOW</tt> events to the widget.
|
||||
|
||||
<li>Change the state of the widget.
|
||||
<H3><a name="test_shortcut">int Fl_Widget::test_shortcut() const<br>
|
||||
static int Fl_Widget::test_shortcut(const char *s)</a></H3>
|
||||
|
||||
<li>Call <a href=Fl_Widget.html>Fl_Widget::redraw()</a> if the widget
|
||||
needs to be redisplayed.
|
||||
The first version tests <tt>Fl_Widget::label()</tt> against the current
|
||||
event (which should be a <tt>FL_SHORTCUT</tt> event). If the label
|
||||
contains a '&' character and the character after it matches the key
|
||||
press, this returns true. This returns false if the
|
||||
<tt>SHORTCUT_LABEL</tt> flag is off, if the label is <tt>NULL</tt> or
|
||||
does not have a '&' character in it, or if the keypress does not match
|
||||
the character.
|
||||
|
||||
<li>Call <a href=#damage>Fl_Widget::damage(n)</a> if the widget needs
|
||||
a partial-update (assumming you provide support for this in your
|
||||
Fl_Widget::draw() method).
|
||||
<p>The second version lets you do this test against an arbitrary string.
|
||||
|
||||
<li>Call <a href=Fl_Widget.html>Fl_Widget::do_callback()</a> if a
|
||||
callback should be generated.
|
||||
<H3><a name="type">uchar Fl_Widget::type() const<br>
|
||||
void Fl_Widget::type(uchar t)</a></H3>
|
||||
|
||||
<li>Call Fl_Widget::handle() on child widgets.
|
||||
The property <tt>Fl_Widget::type()</tt> can return an arbitrary 8-bit
|
||||
identifier, and can be set with the protected method <tt>type(uchar t)</tt>.
|
||||
This value had to be provided for Forms compatibility, but you can use
|
||||
it for any purpose you want. Try to keep the value less than 100 to
|
||||
not interfere with reserved values.
|
||||
|
||||
<p>FLTK does not use RTTI (Run Time Typing Infomation), to enhance
|
||||
portability. But this may change in the near future if RTTI becomes
|
||||
standard everywhere.
|
||||
|
||||
<p>If you don't have RTTI you can use the clumsy FLTK mechanisim, by
|
||||
having <tt>type()</tt> have a unique value. These unique values must
|
||||
be greater than the symbol <tt>FL_RESERVED_TYPE</tt> (which is 100).
|
||||
Look through the header files for <tt>FL_RESERVED_TYPE</tt> to find an
|
||||
unused number. If you make a subclass of <tt>Fl_Group</tt> you must
|
||||
use <tt>FL_GROUP + n</tt>, and if you make a subclass of
|
||||
<tt>Fl_Window<tt> you must use <tt>FL_WINDOW + n</tt> (in both cases
|
||||
<tt>n is in the range 1 to 7).
|
||||
|
||||
<H2>Handling Events</H2>
|
||||
|
||||
The virtual method <tt>int Fl_Widget::handle(int event)</tt> is called
|
||||
to handle each event passed to the widget. It can:
|
||||
|
||||
<ul>
|
||||
<li>Change the state of the widget.
|
||||
|
||||
<li>Call <a href="#Fl_Widget.redraw"><tt>Fl_Widget::redraw()</tt></a>
|
||||
if the widget needs to be redisplayed.
|
||||
|
||||
<li>Call <a
|
||||
href="#Fl_Widget.damage"><tt>Fl_Widget::damage(n)</tt></a> if
|
||||
the widget needs a partial-update (assumming you provide
|
||||
support for this in your <tt>Fl_Widget::draw()</tt> method).
|
||||
|
||||
<li>Call <a
|
||||
href="#Fl_Widget.do_callback"><tt>Fl_Widget::do_callback()</tt></a>
|
||||
if a callback should be generated.
|
||||
|
||||
<li>Call <tt>Fl_Widget::handle()</tt> on child widgets.
|
||||
</ul>
|
||||
|
||||
<p>Events are identified the small integer argument. Other
|
||||
information about the most recent event is stored in static locations
|
||||
and aquired by calling <a href=events.html><code>Fl::event_*()</code></a>.
|
||||
This other information remains valid until another event is read from
|
||||
the X server.
|
||||
Events are identified by the integer argument. Other information about
|
||||
the most recent event is stored in static locations and aquired by
|
||||
calling the <a href="#events"><tt>Fl::event_*()</tt></a> functions.
|
||||
This information remains valid until another event is handled.
|
||||
|
||||
<p>Here is a sample Fl_Widget::handle(), for a widget that acts as a
|
||||
<p>Here is a sample <tt>handle()</tt> method for a widget that acts as a
|
||||
pushbutton and also accepts the keystroke 'x' to cause the callback:
|
||||
|
||||
<ul><pre>int Fl_Pushbutton::handle(int event) {
|
||||
<ul><pre>
|
||||
int MyClass::handle(int event) {
|
||||
switch(event) {
|
||||
case FL_PUSH:
|
||||
highlight = 1; redraw();
|
||||
highlight = 1;
|
||||
redraw();
|
||||
return 1;
|
||||
case FL_DRAG:
|
||||
{int t = Fl::event_inside(this);
|
||||
if (t != highlight) {highlight = t; redraw();}}
|
||||
case FL_DRAG: {
|
||||
int t = Fl::event_inside(this);
|
||||
if (t != highlight) {
|
||||
highlight = t;
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
case FL_RELEASE:
|
||||
if (highlight) {
|
||||
highlight = 0; redraw();
|
||||
highlight = 0;
|
||||
redraw();
|
||||
do_callback();
|
||||
// never do anything after a callback, so that the callback
|
||||
// never do anything after a callback, as the callback
|
||||
// may delete the widget!
|
||||
}
|
||||
return 1;
|
||||
case FL_SHORTCUT:
|
||||
if (Fl::event_key() == 'x') {do_callback(); return 1;}
|
||||
if (Fl::event_key() == 'x') {
|
||||
do_callback();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
<p>You must return non-zero if your handle() method used the event.
|
||||
If you return zero it indicates to the parent that it can try sending
|
||||
another widget the event.
|
||||
You must return non-zero if your <tt>handle()</tt> method uses the
|
||||
event. If you return zero it indicates to the parent widget that it can
|
||||
try sending the event to another widget.
|
||||
|
||||
<p>It looks like it is best to make the handle() method public.
|
||||
<H2>Drawing the Widget</H2>
|
||||
|
||||
<a name=draw>
|
||||
<h2>virtual void Fl_Widget::draw()</h2>
|
||||
The <tt>draw()</tt> virtual method is called when FLTK wants you to
|
||||
redraw your widget. It will be called if and only if <tt>damage()</tt>
|
||||
is non-zero, and <tt>damage()</tt> will be cleared to zero after it
|
||||
returns. <tt>draw()</tt> should be declared protected, so that it can't
|
||||
be called from non-drawing code.
|
||||
|
||||
<p>The virtual method Fl_Widget::draw() is called when fltk wants you
|
||||
to redraw your widget. It will be called if and only if damage() is
|
||||
non-zero, and damage() will be cleared to zero after it returns.
|
||||
draw() should be declared protected, so that subclasses may call it
|
||||
but it can't be called from non-drawing code.
|
||||
|
||||
<p>damage() contains the bitwise-or of all the damage(n) calls to this
|
||||
<p><tt>damage()</tt> contains the bitwise-OR of all the <tt>damage(n)</tt> calls to this
|
||||
widget since it was last drawn. This can be used for minimal update,
|
||||
by only redrawing the parts whose bits are set. Fltk will turn
|
||||
by only redrawing the parts whose bits are set. FLTK will turn
|
||||
<i>all</i> the bits on if it thinks the entire widget must be redrawn
|
||||
(for instance due to an expose event). It is easiest to program to
|
||||
handle this by pretending a bit (usually damage()&128) draw the
|
||||
non-minimal-update parts of your widget (such as the box()).
|
||||
(for instance due to an expose event).
|
||||
|
||||
<p>Expose events (and the above damage(b,x,y,w,h)) will cause draw()
|
||||
to be called with fltk's <a href=Draw.html#clipping>clipping</a>
|
||||
turned on. You can greatly speed up redrawing in some cases by
|
||||
testing <code>fl_clipped</code> and <code>fl_current_clip</code>
|
||||
and skipping invisible parts.
|
||||
<p>Expose events (and the above <tt>damage(b,x,y,w,h)</tt>) will cause
|
||||
<tt>draw()</tt> to be called with FLTK's <a
|
||||
href="#clipping">clipping</a> turned on. You can greatly speed up
|
||||
redrawing in some cases by testing <tt>fl_clipped</tt> and
|
||||
<tt>fl_current_clip</tt> and skipping invisible parts.
|
||||
|
||||
<p>The functions you can use to draw are described in <a
|
||||
href=Draw.html><FL/fl_draw.H></a> or any of the protected
|
||||
Fl_Widget::draw_* methods described above.
|
||||
<p>Besides the protected methods described above, FLTK provide a large
|
||||
number of basic drawing functions, which are described <a
|
||||
href=#drawing>below</a>.
|
||||
|
||||
<a name=resize>
|
||||
<h2>virtual void Fl_Widget::resize(int,int,int,int);</h2>
|
||||
<H2>Resizing the Widget</H2>
|
||||
|
||||
This is called when the widget is being resized or moved. The
|
||||
arguments are the new position, width, and height. x(), y(), w(), and
|
||||
h() still return the old size. You must call resize() on your
|
||||
base class with the same arguments to get the widget size to actually
|
||||
change.
|
||||
The <tt>resize(int x, int y, int w, int h)</tt> method is called when
|
||||
the widget is being resized or moved. The arguments are the new
|
||||
position, width, and height. <tt>x()</tt>, <tt>y()</tt>, <tt>w()</tt>,
|
||||
and <tt>h()</tt> still remain the old size. You must call
|
||||
<tt>resize()</tt> on your base class with the same arguments to get the
|
||||
widget size to actually change.
|
||||
|
||||
<p>This should <i>not</i> call redraw(), at least if only the x() and
|
||||
y() change. This is because group objects like <a
|
||||
href=Fl_Scroll.html>Fl_Scroll</a> may have a more efficient way of
|
||||
drawing the new position.
|
||||
<p>This should <i>not</i> call <tt>redraw()</tt>, at least if only the
|
||||
<tt>x()</tt> and <tt>y()</tt> change. This is because group objects
|
||||
like <a href="#Fl_Scroll"><tt>Fl_Scroll</tt></a> may have a more
|
||||
efficient way of drawing the new position.
|
||||
|
||||
<p>It may be useful to refer to the size the widget was constructed
|
||||
at, these are stored in Fl_Widget::ix(), iy(), iw(), and ih().
|
||||
|
||||
<p>Resize should be declared public.
|
||||
|
||||
<a name=destructor>
|
||||
<h2>virtual Fl_Widget::~Fl_Widget();</h2>
|
||||
|
||||
We all know why the destructor must be virtual don't we? Don't forget
|
||||
to make it public.
|
||||
|
||||
<a name=composite>
|
||||
<h2>Making a Composite/Group Widget</h2>
|
||||
<H2>Making a Composite/Group Widget</H2>
|
||||
|
||||
A "composite" widget contains one or more "child" widgets. To do this
|
||||
you should subclass <a href=Fl_Group.html>Fl_Group</a> (it is
|
||||
you should subclass <a href="#Fl_Group"><tt>Fl_Group</tt></a>. It is
|
||||
possible to make a composite object that is not a subclass of
|
||||
Fl_Group, but this is very difficult).
|
||||
<tt>Fl_Group</tt>, but you'll have to duplicate the code in <tt>Fl_Group</tt>
|
||||
anyways.
|
||||
|
||||
<p>Instances of the child widgets may be included in the parent:
|
||||
|
||||
<ul><pre>class MyClass : public Fl_Group {
|
||||
<ul><pre>
|
||||
class MyClass : public Fl_Group {
|
||||
Fl_Button the_button;
|
||||
Fl_Slider the_slider;
|
||||
...
|
||||
};
|
||||
</pre></ul>
|
||||
|
||||
<p>The constructor has to initialize these instances. They are
|
||||
automatically add()ed to the group, since the Fl_Group constructor
|
||||
does begin(). <i>Don't forget to call end():</i>
|
||||
The constructor has to initialize these instances. They are
|
||||
automatically <tt>add()</tt>ed to the group, since the
|
||||
<tt>Fl_Group</tt> constructor does <tt>begin()</tt>. <i>Don't forget
|
||||
to call <tt>end()</tt> or use the <a href="#Fl_End"><tt>Fl_End</tt></a>
|
||||
pseudo-class:</i>
|
||||
|
||||
<ul><pre>MyClass::MyClass(int x,int y,int w,int h) :
|
||||
Fl_Group(x,y,w,h),
|
||||
the_button(x+5,y+5,100,20),
|
||||
the_slider(x,y+50,w,20)
|
||||
<ul><pre>
|
||||
MyClass::MyClass(int x, int y, int w, int h) :
|
||||
Fl_Group(x, y, w, h),
|
||||
the_button(x + 5, y + 5, 100, 20),
|
||||
the_slider(x, y + 50, w, 20)
|
||||
{
|
||||
...(you could add dynamically created child widgets here)...
|
||||
end(); // don't forget to do this!
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
<p>The child widgets need callbacks. These will be called with a
|
||||
pointer to the children, but the widget itself may be found in the
|
||||
parent() pointer of the child. Usually these callbacks can be static
|
||||
private methods, with a matching private method:
|
||||
The child widgets need callbacks. These will be called with a pointer
|
||||
to the children, but the widget itself may be found in the
|
||||
<tt>parent()</tt> pointer of the child. Usually these callbacks can be
|
||||
static private methods, with a matching private method:
|
||||
|
||||
<ul><pre>void MyClass::slider_cb(Fl_Widget* v, void *) { // static method
|
||||
<ul><pre>
|
||||
void MyClass::slider_cb(Fl_Widget* v, void *) { // static method
|
||||
((MyClass*)(v->parent())->slider_cb();
|
||||
}
|
||||
void MyClass::slider_cb() { // normal method
|
||||
@ -429,31 +340,33 @@ void MyClass::slider_cb() { // normal method
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
<p>If you make the handle() method, you can quickly pass all the
|
||||
events to the children (notice that you don't need to override
|
||||
handle() if your composite widget does nothing other than pass events
|
||||
to the children):
|
||||
If you make the <tt>handle()</tt> method, you can quickly pass all the
|
||||
events to the children using the <tt>Fl_Group::handle()</tt> method.
|
||||
Note that you don't need to override <tt>handle()</tt> if your
|
||||
composite widget does nothing other than pass events to the children:
|
||||
|
||||
<ul><pre>int MyClass::handle(int event) {
|
||||
<ul><pre>
|
||||
int MyClass::handle(int event) {
|
||||
if (Fl_Group::handle(event)) return 1;
|
||||
... handle events that children don't want ...
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
<p>If you override draw() you need to draw all the children. If
|
||||
redraw() or damage() is called on a child, damage(1) is done to the
|
||||
group. Thus the 1 bit of damage() can be used to indicate that a
|
||||
child needs to be drawn. It is fastest if you avoid drawing anything
|
||||
else in this case:
|
||||
If you override <tt>draw()</tt> you need to draw all the children. If
|
||||
<tt>redraw()</tt> or <tt>damage()</tt> is called on a child,
|
||||
<tt>damage(FL_DAMAGE_CHILD)</tt> is done to the group, so this bit of
|
||||
<tt>damage()</tt> can be used to indicate that a child needs to be
|
||||
drawn. It is fastest if you avoid drawing anything else in this case:
|
||||
|
||||
<ul><pre>int MyClass::draw() {
|
||||
Fl_Widget*const* a = array();
|
||||
if (damage()==1) { // only redraw some children
|
||||
for (int i=children(); i--; a++) update_child(**a);
|
||||
<ul><pre>
|
||||
int MyClass::draw() {
|
||||
Fl_Widget *const*a = array();
|
||||
if (damage() == FL_DAMAGE_CHILD) { // only redraw some children
|
||||
for (int i = children(); i --; a ++) update_child(**a);
|
||||
} else { // total redraw
|
||||
... draw background graphics ...
|
||||
// now draw all the children atop the background:
|
||||
for (int i=children_; i--; a++) {
|
||||
for (int i = children_; i --; a ++) {
|
||||
draw_child(**a);
|
||||
draw_outside_label(**a); // you may not want to do this
|
||||
}
|
||||
@ -461,59 +374,84 @@ else in this case:
|
||||
}
|
||||
</pre></ul>
|
||||
|
||||
<p>Fl_Group provides some protected methods to make drawing easier:
|
||||
|
||||
</ul><h4><code>void Fl_Group::draw_outside_label(Fl_Widget&) const;</code></h4><ul>
|
||||
|
||||
Draw the labels that are <i>not</i> drawn by <a
|
||||
href=#draw_label>draw_label()</a>. If you want more control over the
|
||||
label positions you might want to call child->draw_label(x,y,w,h,a).
|
||||
|
||||
</ul><h4><code>void Fl_Group::draw_child(Fl_Widget&);</code></h4><ul>
|
||||
|
||||
This will force the child's damage() bits all to one and call draw()
|
||||
on it, then clear the damage(). You should call this on all children
|
||||
if a total redraw of your widget is requested, or if you draw
|
||||
something (like a background box) that damages the child. Nothing is
|
||||
done if the child is not visible() or if it is clipped.
|
||||
|
||||
</ul><h4><code>void Fl_Group::update_child(Fl_Widget&);</code></h4><ul>
|
||||
|
||||
Draws the child only if it's damage() is non-zero. You should call
|
||||
this on all the children if your own damage is equal to 1. Nothing is
|
||||
done if the child is not visible() or if it is clipped.
|
||||
<tt>Fl_Group</tt> provides some protected methods to make drawing easier:
|
||||
|
||||
<ul>
|
||||
<li><a href="#draw_child">draw_child</a>
|
||||
<li><a href="#draw_outside_label">draw_outside_label</a>
|
||||
<li><a href="#update_child">update_child</a>
|
||||
</ul>
|
||||
|
||||
<a name=window>
|
||||
<h2>Making a subclass of Fl_Window</h2>
|
||||
<H3><a name="draw_child">void Fl_Group::draw_child(Fl_Widget&)</a></H3>
|
||||
|
||||
<p>You may want your widget to be a subclass of Fl_Window. This can
|
||||
be useful if your widget wants to occupy an entire window, and can
|
||||
This will force the child's <tt>damage()</tt> bits all to one and call
|
||||
<tt>draw()</tt> on it, then clear the <tt>damage()</tt>. You should
|
||||
call this on all children if a total redraw of your widget is
|
||||
requested, or if you draw something (like a background box) that
|
||||
damages the child. Nothing is done if the child is not
|
||||
<tt>visible()</tt> or if it is clipped.
|
||||
|
||||
<H3><a name="draw_outside_label">void Fl_Group::draw_outside_label(Fl_Widget&) const</a></H3>
|
||||
|
||||
Draw the labels that are <i>not</i> drawn by
|
||||
<a href="#draw_label"><tt>draw_label()</tt></a>. If you want more control
|
||||
over the label positions you might want to call
|
||||
<tt>child->draw_label(x,y,w,h,a)</tt>.
|
||||
|
||||
<H3><a name="update_child">void Fl_Group::update_child(Fl_Widget&)</a></H3>
|
||||
|
||||
Draws the child only if it's <tt>damage()</tt> is non-zero. You should
|
||||
call this on all the children if your own damage is equal to
|
||||
FL_DAMAGE_CHILD. Nothing is done if the child is not
|
||||
<tt>visible()</tt> or if it is clipped.
|
||||
|
||||
<H2>Cut and Paste Support</H2>
|
||||
|
||||
FLTK provides routines to cut and paste ASCII text (in the future this
|
||||
may be UTF-8) between applications:
|
||||
|
||||
<ul>
|
||||
<li><a href="#paste">Fl::paste</a>
|
||||
<li><a href="#selection">Fl::selection</a>
|
||||
<li><a href="#selection_length">Fl::selection_length</a>
|
||||
<li><a href="#selection_owner">Fl::selection_owner</a>
|
||||
</ul>
|
||||
|
||||
|
||||
It may be possible to cut/paste non-ASCII data by using <a
|
||||
href="#add_handler"><tt>Fl::add_handler()</tt></a>.
|
||||
|
||||
<H2>Making a subclass of Fl_Window</H2>
|
||||
|
||||
You may want your widget to be a subclass of <tt>Fl_Window</tt>. This
|
||||
can be useful if your widget wants to occupy an entire window, and can
|
||||
also be used to take advantage of system-provided clipping, or to work
|
||||
with a library that expects a system window id to indicate where to
|
||||
draw.
|
||||
|
||||
<p>Subclassing Fl_Window is almost exactly like subclassing Fl_Widget,
|
||||
in fact you can easily switch a subclass back and forth. Watch out
|
||||
for the following differences:
|
||||
<p>Subclassing <tt>Fl_Window</tt> is almost exactly like subclassing
|
||||
<tt>Fl_Widget</tt>, in fact you can easily switch a subclass back and
|
||||
forth. Watch out for the following differences:
|
||||
|
||||
<ol>
|
||||
|
||||
<li>Fl_Window is a subclass of Fl_Group so <i>make sure your constructor
|
||||
calls end()</i> (unless you actually want children added to your
|
||||
window).
|
||||
|
||||
<li>When handling events and drawing, the lower-left corner is at 0,0,
|
||||
not x(),y() as in other Fl_Widgets. For instance, to draw a box
|
||||
around the widget, call draw_box(0,0,w(),h()), rather than
|
||||
draw_box(x(),y(),w(),h()).
|
||||
<li><tt>Fl_Window</tt> is a subclass of <tt>Fl_Group</tt> so
|
||||
<i>make sure your constructor calls <tt>end()</tt></i> (unless
|
||||
you actually want children added to your window).
|
||||
|
||||
<li>When handling events and drawing, the upper-left corner is
|
||||
at 0,0, not <tt>x(),y()</tt> as in other <tt>Fl_Widget</tt>s.
|
||||
For instance, to draw a box around the widget, call
|
||||
<tt>draw_box(0, 0, w(), h())</tt>, rather than
|
||||
<tt>draw_box( x(), y(), w(), h())</tt>.
|
||||
|
||||
</ol>
|
||||
|
||||
<p>You may also want to subclass Fl_Window in order to get access to
|
||||
different X visuals or to change other X attributes of the windows,
|
||||
<a href=x.html#window>See here for details</a>.
|
||||
You may also want to subclass <tt>Fl_Window</tt> in order to get access to
|
||||
different visuals or to change other attributes of the windows. See
|
||||
<a href="#osissues">Appendix F - Operating System Issues</a> for more
|
||||
information.
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
<p><a href = index.html>(back to contents)</a>
|
||||
|
@ -1,6 +1,11 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
<H1 ALIGN=RIGHT>A - Widget Reference</H1>
|
||||
|
||||
This appendix describes all of the widget classes in FLTK. For a
|
||||
description of the <tt>fl_</tt> functions and <tt>Fl::</tt> methods,
|
||||
see <a href="#functions"> Appendix B</a>.
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user