Fltk only thinks about one event at a time. Therefore all of the other data about the event is stored in static memory, rather than a typical "event structure". It is accessed with fast inline functions of the form event_*.
FLTK has very simple rules for sending events to widgets. The major unusual aspect of FLTK is that widgets indicate if they "handled" an event by returning non-zero from their Widget::handle() method. If they return zero, FLTK can then try the event elsewhere. This eliminates the need for "interests" (event masks or tables), and this is the main reason FLTK is much smaller than other toolkits.
Most events are sent to the outermost Window containing the event, and those widgets are responsible for finding and sending the events to child widgets. Some events are sent directly to Widgets, this is controlled by the following methods, which the container widgets are required to call:
If all the widgets that FLTK tries to send an event to return zero, then you can add global functions that FLTK will call with these events. This is done with add_event_handler()
You can generate fake events by calling handle(int) on the correct widgets (usually a window). Currently you can change the values returned by the event_*() functions by storing the desired value into the static variables e_*, but this may change in future versions.
|
|
Numbers passed to Widget::handle() and returned by event().
|
|
|
Values returned by event_key(), passed to event_key_state() and get_key_state(), and used for the low 16 bits of add_shortcut(). The actual values returned are based on X11 keysym values, though fltk always returns "unshifted" values much like Windows does. A given key always returns the same value no matter what shift keys are held down. Use event_text() to see the results of any shift keys. The lowercase letters 'a' through 'z' and the ascii symbols '`', '-', '=', '[', ']', '\', ',', '.', '/', ';', '\'' and space are used to identify the keys in the main keyboard. On X systems unrecognized keys are returned unchanged as their X keysym value. If they have no keysym it uses the scan code or'd with 0x8000, this is what all those blue buttons on a Microsoft keyboard will do. I don't know how to get those buttons on Windows.
|
|
|
Flags returned by event_state(), and used as the high 16 bits of Widget::add_shortcut() values (the low 16 bits are all zero, so these may be or'd with key values). The inline function BUTTON(n) will turn n (1-8) into the flag for a mouse button.
|
|
|
|
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. Currently this is called for these reasons:
|
|
|
Change the belowmouse() widget, the previous one and all parents (that don't contain the new widget) are sent LEAVE events. Changing this does not send ENTER to this or any widget, because sending ENTER is supposed to test if the widget wants the mouse (by it returning non-zero from handle()). |
|
|
Get the widget that is below the mouse. This is the last widget to respond to an ENTER event as long as the mouse is still pointing at it. This is for highlighting buttons and bringing up tooltips. It is not used to send PUSH or MOVE directly, for several obscure reasons, but those events typically go to this widget. |
|
|
Use of this function is very simple. Any text editing widget should call this for each KEY event. If true is returned, then it has modified the event_text() and event_length() to a set of bytes to insert (it may be of zero length!). It will also set the del parameter to the number of bytes to the left of the cursor to delete, this is used to delete the results of the previous call to compose(). Compose may consume the key, which is indicated by returning true, but both the length and del are set to zero. Compose returns false if it thinks the key is a function key that the widget should handle itself, and not an attempt by the user to insert text. Though the current implementation returns immediately, future versions may take quite awhile, as they may pop up a window or do other user-interface things to allow international characters to be selected. |
|
|
If the user moves the cursor, be sure to call compose_reset(). The next call to compose() will start out in an initial state. In particular it will not set "del" to non-zero. This call is very fast so it is ok to call it many times and in many places. |
|
||||||||||||||||
|
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 PASTE as this may be the same buffer returned by event_text()). The block of text may be retrieved (from this program or whatever program last set it) with paste(). There are actually two buffers. If clipboard is true then the text goes into the user-visible selection that is moved around with cut/copy/paste commands (on X this is the CLIPBOARD selection). If clipboard is false then the text goes into a less-visible buffer used for temporarily selecting text with the mouse and for drag & drop (on X this is the XA_PRIMARY selection). |
|
|
Drag and drop the data set by the most recent copy() (with the clipboard argument false). Returns true if the data was dropped on something that accepted it. By default only blocks of text are dragged. You can use system-specific variables to change the type of data. |
|
|
Returns the most recent event handled, such as PUSH or KEY. This is useful so callbacks can find out why they were called. |
|
|
Returns which mouse button was pressed or released by a PUSH or RELEASE event. Returns garbage for other events, so be careful (this actually is the same as event_key(), the buttons have been assigned the key values 1,2,3, etc. |
|
|
Setting this value can be used to make callbacks think things were (or were not) double-clicked, and thus act differently. |
|
|
Returns the number of extra times the mouse was clicked. For a normal PUSH this is zero, if the user "double-clicks" this is 1, and it is N-1 for each subsequent click. |
|
|
For MOUSEWHEEL events this is how many clicks the user moved in the x and y directions (currently dx is always zero). |
|
|
Reserved for future use if horizontal mouse wheels (or some kind of joystick on the mouse) becomes popular. |
|
|
Returns true if the current event_x() and event_y() put it inside the Rectangle. You should always call this rather than doing your own comparison so you are consistent about edge effects. |
|
|
You can set this to zero with event_is_click(0), this can be used to prevent the next mouse click from being considered a double click. Only false works, attempts to set this true are ignored. |
|
|
This is true for a short time after the mouse key is pressed. You test this on the RELEASE events to decide if the user "clicked" or "held" the mouse. It is very useful to do different actions depending on this. This turns off after a timeout (implemented on X only, currently), when the mouse is moved more than 5 pixels, and when the user presses other mouse or keyboard buttons while the mouse is down. On X this is used to decide if a click is a double-click, it is if this is still on during the next mouse press. On Windows and OS/X the system's indication is used for double-click. |
|
|
Returns which key on the keyboard was last pushed. Most non-keyboard events set this to values that do not correspond to any keys, so you can test this in callbacks without having to test first if the event really was a keystroke. The values returned are described under SpaceKey. |
|
|
True if the most recent KEY event was caused by a repeating held-down key on the keyboard. The value increments for each repeat. Note: older versions of fltk reused event_clicks() for this. This made it impossible to design a GUI where the user holds down keyboard keys while clicking the mouse, as well as being pretty hard to understand. So we had to change it for fltk 2. |
|
|
Returns true if the given key was held down (or pressed) during the last event. This is constant until the next event is read from the server. The possible values for the key are listed under SpaceKey. On Win32 event_key_state(KeypadEnter) does not work. |
|
|
Returns the length of the text in event_text(). There will always be a nul at this position in the text. However there may be a nul before that if the keystroke translates to a nul character or you paste a nul character. |
|
|
return the corresponding str of an event, should not consume memory if api is not used
|
|
|
Same as event_state()&mask, returns true if any of the passed bits were turned on during the last event. So doing event_state(SHIFT) will return true if the shift keys are held down. This is provided to make the calling code easier to read. The flags to pass are described under SHIFT. |
|
|
This is a bitfield of what shift states were on and what mouse buttons were held down during the most recent event. The flags to pass are described under SHIFT. Because Emacs screws up if any key returns the predefined META flag, lots of X servers have really botched up the key assignments trying to make Emacs work. Fltk tries to work around this but you may find that Alt or Meta don't work, since I have seen at least 3 mutually incompatible arrangements. Non-XFree86 machines may also have selected different values so that NUMLOCK, META, and SCROLLLOCK are mixed up. In addition X reports the state before the last key was pressed so the state looks backwards for any shift keys, currently fltk only fixes this bug for the mouse buttons. |
|
|
Returns the ASCII text (in the future this may be UTF-8) produced by the last KEY or 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. Under X this is the result of calling XLookupString(). |
|
|
Returns the distance the mouse is to the right of the left edge of the widget. Widget::send() modifies this as needed before calling the Widget::handle() method. |
|
|
Return the absolute horizontal position of the mouse. Usually this is relative to the left edge of the screen, but multiple Monitor setup may change that. To find the absolute position of the current widget, subtract event_x_root()-event_x(). |
|
|
Returns the distance the mouse is below the top edge of the widget. Widget::send() modifies this as needed before calling the Widget::handle() method. |
|
|
Return the absolute vertical position of the mouse. Zero is at the top. |
|
|
Turns on exit_modal_flag(). This may be used by user callbacks to cancel modal state. See also Window::make_exec_return(). |
|
|
True if exit_modal() has been called. The flag is also set by the destruction or hiding of the modal widget, and on Windows by other applications taking the focus when grab is on. |
|
|
Change focus() to the given widget, the previous widget and all parents (that don't contain the new widget) are sent UNFOCUS events, the new widget is sent an FOCUS event, and all parents of it get FOCUS_CHANGE events. focus() is set whether or not the applicaton has the focus or if the widgets accept the focus. You may want to use Widget::take_focus() instead, it will test first. |
|
|
Returns the widgets that will receive KEY events. This is NULL if the application does not have focus now, or if no widgets accepted focus. |
|
|
Returns true if the given key is held down now. This is different than event_key_state() as that returns how the key was during the last event. This can also be slower as it requires a round-trip query to the window server. The values to pass are described under SpaceKey. On Win32 get_key_state(KeypadEnter) does not work. |
|
||||||||||||
|
Return where the mouse is on the screen by doing a round-trip query to the server. You should use event_x_root() and event_y_root() if possible, but this is necessary if you are not sure if a mouse event has been processed recently (such as to position your first window). If the display is not open, this will open it. |
|
|
returns the current value of grab (this is always false if modal() is null). |
|
||||||||||||
|
This is the function called from the system-specific code for all events that can be passed to Widget::handle(). You can call it directly to fake events happening to your widgets. Currently data other than the event number can only be faked by writing to the undocumented e_* variables, for instance to make event_x() return 5, you should do e_x = 5. This may change in future versions. This will redirect events to the modal(), pushed(), belowmouse(), or focus() widget depending on those settings and the event type. It will turn MOVE into DRAG if any buttons are down. If the resulting widget returns 0 (or the window or widget is null) then the functions pointed to by add_event_handler() are called. |
|
|
Turn a string into a event_key() value or'd with event_shift() flags. The returned value can be used by by Widget::add_shortcut(). Any error, or a null or zero-length string, returns 0. Currently this understands prefixes of "Alt+", "Shift+", and "Ctrl+" to turn on ALT, SHIFT, and CTRL. Case is ignored and the '+' can be a '-' instead and the prefixes can be in any order. You can also use '#' instead of "Alt+", '+' instead of "Shift+", and '^' instead of Ctrl+. After the shift prefixes there can either be a single ASCII letter, "Fn" where n is a number to indicate a function key, or "0xnnnn" to get an arbitrary event_key() enumeration value. The inverse function to turn a number into a string is key_name(). Currently this function does not parse some strings key_name() can return, such as the names of arrow keys! |
|
|
Unparse a Widget::shortcut() or event_key() value into human-readable text. Returns a pointer to a human-readable string like "Alt+N". If hotkey is zero an empty string is returned. The return value points at a static buffer that is overwritten with each call. The opposite function is key(). |
|
|
Returns an array of shortcut assignments that match the current event, which should be a KEY, SHORTCUT, or KEYUP event. The number of matching ones is put in count. If there are no matches null is returned and count is set to zero. The returned array is temporary storage and can be overwritten by the next call to alter or query shortcuts! Also there may be entries with widget==0, ignore them. This is very similar to list_shortcuts(event_key()|event_state()) except if no exact match is found, it will try to locate a "close" matching key assignment and return that:
|
|
|
Returns an array of every shortcut assignment. They are sorted by the key, and then by shift flags. The returned array is temporary storage and will be overwritten by the next call to alter or query shortcuts! Also there may be entries with widget==0, ignore them. |
|
||||||||||||
|
Returns an array of shortcut assignments for this widget. The number of matching ones is put in count. Do not assumme any particular order for the returned array. Also there may be entries with key==0, ignore them. The returned array is temporary storage and can be overwritten by the next call to alter or query shortcuts! |
|
||||||||||||
|
Returns an array of shortcut assignments that match the given value for key. The number of matching ones is put in count. If there are no matches count is set to zero. Do not assumme any particular order for the returned array. Also there may be entries with widget==0, ignore them. The returned array is temporary storage and can be overwritten by the next call to alter or query shortcuts! |
|
|
Returns the current modal widget, or null if there isn't one. It is useful to test these in timeouts and file descriptor callbacks in order to block actions that should not happen while the modal window is up. You also need these in order to save and restore the modal state. |
|
||||||||||||
|
Restricts events to a certain widget. First thing: much of the time Window::exec() will do what you want, so try using that. This function sets the passed widget as the "modal widget". All user events are directed to it or a child of it, preventing the user from messing with other widgets. The modal widget does not have to be visible or even a child of an Window for this to work (but if it not visible, event_x() and event_y() are meaningless, use event_x_root() and event_y_root()). The calling code is responsible for saving the current value of modal() and grab() and restoring them by calling this after it is done. The code calling this should then loop calling wait() until exit_modal_flag() is set or you otherwise decide to get out of the modal state. It is the calling code's responsibility to monitor this flag and restore the modal widget to it's previous value when it turns on. grab indicates that the modal widget should get events from anywhere on the screen. This is done by messing with the window system. If exit_modal() is called in response to an PUSH event (rather than waiting for the drag or release event) fltk will "repost" the event so that it is handled after modal state is exited. This may also be done for keystrokes in the future. On both X and WIN32 grab will not work unless you have some visible window because the system interface needs a visible window id. On X be careful that your program does not enter an infinite loop while grab() is on, it will lock up your screen! |
|
||||||||||||
|
This is what a widget does when a "paste" command (like Ctrl+V or the middle mouse click) is done to it. Cause an PASTE event to be sent to the receiver with the contents of the current selection in the event_text(). The selection can be set by copy(). There are actually two buffers. If clipboard is true then the text is from the user-visible selection that is moved around with cut/copy/paste commands (on X this is the CLIPBOARD selection). If clipboard is false then the text is from a less-visible buffer used for temporarily selecting text with the mouse and for drag & drop (on X this is the XA_PRIMARY selection). The reciever should be prepared to be called directly by this, or for it to happen later, or possibly not at all. 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 most toolkits require. |
|
|
Change the pushed() widget. This sends no events. |
|
|
Get the widget that is being pushed. DRAG or RELEASE (and any more PUSH) events will be sent to this widget. This is null if no mouse button is being held down, or if no widget responded to the PUSH event. |
|
|
Try sending the current KEY event as a SHORTCUT event. Normally the focus() gets all keystrokes, and shortcuts are only tested if that widget indicates it is uninterested by returning zero from Widget::handle(). However in some cases the focus wants to use the keystroke only if it is not a shortcut. The most common example is Emacs-style editing keystrokes in text editing widgets, which conflict with Microsoft-compatable menu key bindings, but we want the editing keys to work if there is no conflict. This will send a SHORTCUT event just like the focus returned zero, to every widget in the focus window, and to the add_handler() calls, if any. It will return true if any widgets were found that were interested in it. A handle() method can call this in a KEY event. If it returns true, return 1 immediatly, as the shortcut will have executed and may very well have destroyed your widget. If this returns false, then do what you want the key to do. |
©2006 Bill Spitzak and others.