summaryrefslogtreecommitdiff
path: root/documentation/events.html
blob: 88ec9b9f3aa7ba8af91e5172d61c1b09f42b744e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
<HTML><BODY>
<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 by the integer argument passed to the <A href=functions.html#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>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><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=functions.html#event_y>
<TT>Fl::event_y()</TT></A>. 
<P>A widget indicates that it &quot;wants&quot; the mouse click by returning 
non-zero from its <A href=functions.html#handle><TT>handle()</TT></A>
 method. It will then become the <A href=functions.html#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. </P>
<H3>FL_DRAG</H3>
The mouse has moved with a button held down. The current button state is
in <a href="#event_state"><tt>Fl::event_state()</tt></a>. The mouse position
is in <a href="#event_x"><tt>Fl::event_x()</tt></a> and
<a href="#event_y"><tt>Fl::event_y()</tt></a>.

<P>To receive <CODE>FL_DRAG</CODE> events you must also respond to the
<CODE>FL_PUSH</CODE> and <CODE>FL_RELEASE</CODE> events.

<H3>FL_RELEASE</H3>
 A mouse button has been released.  You can find out what button by 
calling <A href=#event_button><TT>Fl::event_button()</TT></A>. 
<H3>FL_MOVE</H3>
 The mouse has moved without any mouse buttons held down.  This event 
is sent to the <A href="functions.html#belowmouse"><TT>Fl::belowmouse()</TT></A>
widget.
<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=functions.html#handle>
<TT>handle()</TT></A> method. It then becomes the <A href=functions.html#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. 
<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 its <A href=functions.html#handle>
<TT>handle()</TT></A> method.  It then becomes the <A href=functions.html#focus>
<TT>Fl::focus()</TT></A> widget and gets <TT>FL_KEYBOARD</TT> and <TT>
FL_UNFOCUS</TT> events. </P>
<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=functions.html#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. </P>
<H3>FL_UNFOCUS</H3>
Sent to the previous <A href=functions.html#focus><TT>Fl::focus()</TT></A>
widget when another widget gets the focus. 
<H2>Keyboard Events</H2>
<H3>FL_KEYBOARD</H3>
 A key press.  The key pressed can be found in <A href=functions.html#event_key>
<TT>Fl::event_key()</TT></A>. The text that the key should insert can 
be found with <A href=functions.html#event_text><TT>Fl::event_text()</TT>
</A> and its length is in <A href=functions.html#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. 

<P>To receive <CODE>FL_KEYBOARD</CODE> events you must also respond to the
<CODE>FL_FOCUS</CODE> and <CODE>FL_UNFOCUS</CODE> events.

<H3>FL_SHORTCUT</H3>
If the <A href=functions.html#focus><TT>Fl::focus()</TT></A> widget 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 &quot;global&quot; shortcuts by using <A href=osissues.html#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. </P>
<H2>Widget Events</H2>
<H3>FL_DEACTIVATE</H3>
 This widget is no longer active, due to <A href=Fl_Widget.html#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). 
<H3>FL_ACTIVATE</H3>
 This widget is now active, due to <A href=Fl_Widget.html#Fl_Widget.activate>
<TT>activate()</TT></A> being called on it or one of its parents. 
<H3>FL_HIDE</H3>
 This widget is no longer visible, due to <A #Fl_Widget.show" href="#Fl_Widget.hide><tt>hide()</tt></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).

<h3>FL_SHOW</h3>

This widget is visible again, due to <a
href=">
<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>
<H2>Clipboard Events</H2>
<H3>FL_PASTE</H3>
 You should get this event some time after you call <A href=functions.html#paste>
<TT>Fl::paste()</TT></A>.  The contents of <A href=functions.html#event_text>
<TT>Fl::event_text()</TT></A> is the text to insert and the number of 
characters is in <A href=functions.html#event_length><TT>
Fl::event_length()</TT></A>. 
<H3>FL_SELECTIONCLEAR</H3>
 The <A href=functions.html#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. 
<H2><A name=event_xxx>Fl::event_*() methods</A></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 <TT>handle()</TT> and <TT>callback()</TT>
 methods. 
<P>These are all trivial inline functions and thus very fast and small: </P>
<UL>
<LI><A href=functions.html#event_button><TT>Fl::event_button</TT></A></LI>
<LI><A href=functions.html#event_clicks><TT>Fl::event_clicks</TT></A></LI>
<LI><A href=functions.html#event_inside><TT>Fl::event_inside</TT></A></LI>
<LI><A href=functions.html#event_is_click><TT>Fl::event_is_click</TT></A></LI>
<LI><A href=functions.html#event_key><TT>Fl::event_key</TT></A></LI>
<LI><A href=functions.html#event_length><TT>Fl::event_length</TT></A></LI>
<LI><A href=functions.html#event_state><TT>Fl::event_state</TT></A></LI>
<LI><A href=functions.html#event_text><TT>Fl::event_text</TT></A></LI>
<LI><A href=functions.html#event_x><TT>Fl::event_x</TT></A></LI>
<LI><A href=functions.html#event_x_root><TT>Fl::event_x_root</TT></A></LI>
<LI><A href=functions.html#event_y><TT>Fl::event_y</TT></A></LI>
<LI><A href=functions.html#event_y_root><TT>Fl::event_y_root</TT></A></LI>
<LI><A href=functions.html#get_key><TT>Fl::get_key</TT></A></LI>
<LI><A href=functions.html#get_mouse><TT>Fl::get_mouse</TT></A></LI>
<LI><A href=functions.html#test_shortcut><TT>Fl::test_shortcut</TT></A></LI>
</UL>
<H2><A name=propagation>Event Propagation</A></H2>
 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 &quot;interests&quot; (event masks or tables), and this is probably the main 
reason FLTK is much smaller than other toolkits. 
<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: </P>
<UL>
<LI><A href=osissues.html#add_handler><TT>Fl::add_handler</TT></A></LI>
<LI><A href=functions.html#belowmouse><TT>Fl::belowmouse</TT></A></LI>
<LI><A href=functions.html#focus><TT>Fl::focus</TT></A></LI>
<LI><A href=functions.html#grab><TT>Fl::grab</TT></A></LI>
<LI><A href=functions.html#modal><TT>Fl::modal</TT></A></LI>
<LI><A href=functions.html#pushed><TT>Fl::pushed</TT></A></LI>
<LI><A href=functions.html#release><TT>Fl::release</TT></A></LI>
<LI><A href=Fl_Widget.html#Fl_Widget.take_focus><TT>Fl_Widget::take_focus</TT></A>
</LI>
</UL>

<H2><A name=compose>FLTK Compose-Character Sequences</A></H2>

The <A href="#Fl_Input"><tt>Fl_Input</tt></a> widget lets you type all the
characters in the standard ISO-8859-1 character set.  Most fonts will
display these characters correctly.

<P>To insert them, type the [compose] key and then one or two
characters.  The two characters can be in either order.  The [compose]
key is any of: Ctrl+Q, the righthand control key, or any key your X server
calls <TT>XK_Multi_key</TT>.

<p><center><table border=1>
<tr>
	<th>Keys<th>Char<th>
	<th>Keys<th>Char<th>
	<th>Keys<th>Char<th>
	<th>Keys<th>Char<th>
	<th>Keys<th>Char<th>
	<th>Keys<th>Char
<tr>
	<td align=center><small>space</small><td align=center><small>nbsp</small><td>
	<td align=center><TT>*</TT><td align=center>°<td>
	<td align=center><TT>A`</TT><td align=center>À<td>
	<td align=center><TT>D-</TT><td align=center>Ð<td>
	<td align=center><TT>a`</TT><td align=center>à<td>
	<td align=center><TT>d-</TT><td align=center>ð
<tr>
	<td align=center><TT>!</TT><td align=center>¡<td>
	<td align=center><TT>+-</TT><td align=center>±<td>
	<td align=center><TT>A'</TT><td align=center>Á<td>
	<td align=center><TT>N~</TT><td align=center>Ñ<td>
	<td align=center><TT>a'</TT><td align=center>á<td>
	<td align=center><TT>n~</TT><td align=center>ñ
<tr>
	<td align=center><TT>%</TT><td align=center>¢<td>
	<td align=center><TT>2</TT><td align=center>²<td>
	<td align=center><TT>A^</TT><td align=center>Â<td>
	<td align=center><TT>O`</TT><td align=center>Ò<td>
	<td align=center><TT>a^</TT><td align=center>â<td>
	<td align=center><TT>o`</TT><td align=center>ò
<tr>
	<td align=center><TT>#</TT><td align=center>£<td>
	<td align=center><TT>3</TT><td align=center>³<td>
	<td align=center><TT>A~</TT><td align=center>Ã<td>
	<td align=center><TT>O'</TT><td align=center>Ó<td>
	<td align=center><TT>a~</TT><td align=center>ã<td>
	<td align=center><TT>o'</TT><td align=center>ó
<tr>
	<td align=center><TT>$</TT><td align=center>¤<td>
	<td align=center><TT>'</TT><td align=center>´<td>
	<td align=center><TT>A:</TT><td align=center>Ä<td>
	<td align=center><TT>O^</TT><td align=center>Ô<td>
	<td align=center><TT>a:</TT><td align=center>ä<td>
	<td align=center><TT>o^</TT><td align=center>ô
<tr>
	<td align=center><TT>y=</TT><td align=center>¥<td>
	<td align=center><TT>u</TT><td align=center>µ<td>
	<td align=center><TT>A*</TT><td align=center>Å<td>
	<td align=center><TT>O~</TT><td align=center>Õ<td>
	<td align=center><TT>a*</TT><td align=center>å<td>
	<td align=center><TT>o~</TT><td align=center>õ
<tr>
	<td align=center><TT>|</TT><td align=center>¦<td>
	<td align=center><TT>p</TT><td align=center>¶<td>
	<td align=center><TT>AE</TT><td align=center>Æ<td>
	<td align=center><TT>O:</TT><td align=center>Ö<td>
	<td align=center><TT>ae</TT><td align=center>æ<td>
	<td align=center><TT>o:</TT><td align=center>ö
<tr>
	<td align=center><TT>&amp;</TT><td align=center>§<td>
	<td align=center><TT>.</TT><td align=center>·<td>
	<td align=center><TT>C,</TT><td align=center>Ç<td>
	<td align=center><TT>x</TT><td align=center>×<td>
	<td align=center><TT>c,</TT><td align=center>ç<td>
	<td align=center><TT>-:</TT><td align=center>÷
<tr>
	<td align=center><TT>:</TT><td align=center>¨<td>
	<td align=center><TT>,</TT><td align=center>¸<td>
	<td align=center><TT>E`</TT><td align=center>È<td>
	<td align=center><TT>O/</TT><td align=center>Ø<td>
	<td align=center><TT>e`</TT><td align=center>è<td>
	<td align=center><TT>o/</TT><td align=center>ø
<tr>
	<td align=center><TT>c</TT><td align=center>©<td>
	<td align=center><TT>1</TT><td align=center>¹<td>
	<td align=center><TT>E'</TT><td align=center>É<td>
	<td align=center><TT>U`</TT><td align=center>Ù<td>
	<td align=center><TT>e'</TT><td align=center>é<td>
	<td align=center><TT>u`</TT><td align=center>ù
<tr>
	<td align=center><TT>a</TT><td align=center>ª<td>
	<td align=center><TT>o</TT><td align=center>º<td>
	<td align=center><TT>E^</TT><td align=center>Ê<td>
	<td align=center><TT>U'</TT><td align=center>Ú<td>
	<td align=center><TT>e^</TT><td align=center>ê<td>
	<td align=center><TT>u'</TT><td align=center>ú
<tr>
	<td align=center><TT>&lt;&lt;</TT><td align=center>«<td>
	<td align=center><TT>>></TT><td align=center>»<td>
	<td align=center><TT>E:</TT><td align=center>Ë<td>
	<td align=center><TT>U^</TT><td align=center>Û<td>
	<td align=center><TT>e:</TT><td align=center>ë<td>
	<td align=center><TT>u^</TT><td align=center>û
<tr>
	<td align=center><TT>~</TT><td align=center>¬<td>
	<td align=center><TT>14</TT><td align=center>¼<td>
	<td align=center><TT>I`</TT><td align=center>Ì<td>
	<td align=center><TT>U:</TT><td align=center>Ü<td>
	<td align=center><TT>i`</TT><td align=center>ì<td>
	<td align=center><TT>u:</TT><td align=center>ü
<tr>
	<td align=center><TT>-</TT><td align=center>­<td>
	<td align=center><TT>12</TT><td align=center>½<td>
	<td align=center><TT>I'</TT><td align=center>Í<td>
	<td align=center><TT>Y'</TT><td align=center>Ý<td>
	<td align=center><TT>i'</TT><td align=center>í<td>
	<td align=center><TT>y'</TT><td align=center>ý
<tr>
	<td align=center><TT>r</TT><td align=center>®<td>
	<td align=center><TT>34</TT><td align=center>¾<td>
	<td align=center><TT>I^</TT><td align=center>Î<td>
	<td align=center><TT>TH</TT><td align=center>Þ<td>
	<td align=center><TT>i^</TT><td align=center>î<td>
	<td align=center><TT>th</TT><td align=center>þ
<tr>
	<td align=center><TT>_</TT><td align=center>¯<td>
	<td align=center><TT>?</TT><td align=center>¿<td>
	<td align=center><TT>I:</TT><td align=center>Ï<td>
	<td align=center><TT>ss</TT><td align=center>ß<td>
	<td align=center><TT>i:</TT><td align=center>ï<td>
	<td align=center><TT>y:</TT><td align=center>ÿ
</table>
</center>

<p>For instance, to type "á" type [compose][a]['] or [compose]['][a].

<P>The character "nbsp" (non-breaking space) is typed by using
[compose][space].

<P>The single-character sequences may be followed by a space if
necessary to remove ambiguity.  For instance, if you really want to
type "ª~" rather than "ã" you must type [compose][a][space][~].

<P>If you wish to use the compose function in your own code, your
widget's <tt>handle()</tt> method must call <tt>fl_compose()</tt>
in response to <tt>FL_KEYPRESS</tt> events:

<h4><TT>int fl_compose(int state, char c, int &amp;del, char *buffer, int &amp;ins)</TT></h4>

Starts or adds a single ASCII character to a compose sequence.  This
will return the number of old bytes to delete and a set of new bytes to
insert, and a new <tt>state</tt> value.  If this returns zero you can
ignore the result (which just says to insert the character unchanged)
and handle the keystroke yourself.

<P><tt>state</tt> must either be the return value of the last call to
<tt>fl_compose()</tt> or zero to start a new compose sequence.  Be sure to reset
to zero if the user ever moves the cursor.

<P><tt>c</tt> is the ASCII character that the user typed.

<P><tt>del</tt> is set to the number of bytes to delete backwards.  This
will always be less or equal to the <tt>ins</tt> from the last call to
<tt>fl_compose()</tt>, and will be zero if <tt>state</tt> is zero.

<P><tt>buffer</tt> will have the first <tt>ins</tt> bytes set to the data
to insert and display (it is <I>not</I> nul-terminated).

<P><tt>ins</tt> will be the number of characters to insert.

</BODY></HTML>