diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 1998-12-29 14:21:17 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 1998-12-29 14:21:17 +0000 |
| commit | 87dd7f0d23eba5c09e71ec6efeb34c6844f5e95f (patch) | |
| tree | ecd25b3fbecdd2d1c6abf106d0c94ac2b1e9926e /documentation/events.html | |
| parent | 20adb6834b22523e9d1fecdb7bb8a117f7b6179a (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.html | 499 |
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> |
