summaryrefslogtreecommitdiff
path: root/documentation/events.html
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>1998-12-29 14:21:17 +0000
committerMichael R Sweet <michael.r.sweet@gmail.com>1998-12-29 14:21:17 +0000
commit87dd7f0d23eba5c09e71ec6efeb34c6844f5e95f (patch)
treeecd25b3fbecdd2d1c6abf106d0c94ac2b1e9926e /documentation/events.html
parent20adb6834b22523e9d1fecdb7bb8a117f7b6179a (diff)
Revised documentation files.
git-svn-id: file:///fltk/svn/fltk/trunk@177 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'documentation/events.html')
-rw-r--r--documentation/events.html499
1 files changed, 499 insertions, 0 deletions
diff --git a/documentation/events.html b/documentation/events.html
new file mode 100644
index 000000000..b4b5f1513
--- /dev/null
+++ b/documentation/events.html
@@ -0,0 +1,499 @@
+<HTML>
+<BODY>
+
+<H1 ALIGN=RIGHT>4 - Handling Events</H1>
+
+This chapter discusses the FLTK event model and how to handle events in your program or
+widget.
+
+<H2>The FLTK Event Model</H2>
+
+<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>
+
+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>.
+
+<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.
+
+</ul><h4><code>FL_DRAG (5)</code></h4><ul>
+
+The mouse has moved with the button held down.
+
+</ul><h4><code>FL_RELEASE (2)</code></h4><ul>
+
+A mouse button has been released. You can find out what button by
+calling <a href=#event_button>Fl::event_button()</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>
+
+The mouse has moved without any mouse buttons held down. This event
+is sent (sort of) to the belowmouse() widget.
+
+</ul><h4><code>FL_LEAVE (4)</code></h4><ul>
+
+The mouse has moved out of the widget.
+
+</ul><h4><code>FL_FOCUS (6)</code></h4><ul>
+
+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.
+
+<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
+window manager it will be zero.
+
+</ul><h4><code>FL_UNFOCUS (7)</code></h4><ul>
+
+Sent to the old <a href=#focus>Fl::focus()</a> when something else
+gets the focus.
+
+</ul><h4><code>FL_KEYBOARD (8)</code></h4><ul>
+
+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.
+
+</ul><h4><code>FL_SHORTCUT (11)</code></h4><ul>
+
+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
+
+<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.
+
+</ul><h4><code>FL_DEACTIVATE (13)</code></h4><ul>
+
+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.
+
+</ul><h4><code>FL_ACTIVATE (14)</code></h4><ul>
+
+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.
+
+</ul><h4><code>FL_HIDE (15)</code></h4><ul>
+
+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.
+
+</ul><h4><code>FL_SHOW (16)</code></h4><ul>
+
+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>
+
+<a name=paste>
+</ul><h4><code>FL_PASTE (17)</code></h4><ul>
+
+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>.
+
+</ul><h4><code>FL_SELECTIONCLEAR (18)</code></h4><ul>
+
+The <a href=cutpaste.html>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>
+
+<a name=information>
+<h2>Fl::event_*() methods</h2>
+
+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.
+
+<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>.
+
+</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.
+
+<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
+"interests" (event masks or tables), and this is probably the main
+reason fltk is much smaller than other X 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:
+
+<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>
+
+<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>