# Handling Events

FLTK Events are identified by the integer argument passed to the `fltk::Widget::handle()` virtual method.

All other information about the most recent event is stored in static locations and acquired by calling these functions. 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 `handle()` method). This allows the data to be accessed by callbacks and other functions without having to pass an event argument to them, and allows more fields to be added to events without breaking binary compatability. These are all trivial inline functions and thus very fast and small:

- `int fltk::event()`
- `int fltk::event_x()`
- `int fltk::event_y()`
- `int fltk::event_dx()`
- `int fltk::event_dy()`
- `int fltk::event_x_root()`
- `int fltk::event_y_root()`
- `int fltk::event_clicks()`
- `bool fltk::event_is_click()`
- `int fltk::event_button()`
- `int fltk::event_state()`
- `int fltk::event_key()`
- `bool fltk::event_key_state(int)`
- `const char* fltk::event_text()`
- `int fltk::event_length()`

The following functions call the above functions to compute more information about the current event:

- `bool fltk::event_inside(int,int,int,int)`
- `bool fltk::test_shortcut(int)`
- `const char* fltk::key_name(int)`
- `bool fltk::compose(int& del)`
- `void fltk::compose_reset()`

The following functions do not return parts of the current event, instead they directly inquire about the current state of devices:

- `bool fltk::get_key_state(int)`
- `void fltk::get_mouse(int&,int&)`

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 `fltk::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 fltk::Window containing the event, and those widgets are responsible for finding and sending the events to child widgets. Some events are sent directly to fltk::Widgets, this is controlled by the following methods, which the container widgets are required to call:

- `void fltk::belowmouse(fltk::Widget*)`
- `void fltk::pushed(fltk::Widget*)`
- `void fltk::focus(fltk::Widget*)`
- `fltk::modal(fltk::Widget*, bool grab=false)`

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 `fltk::add_handler(int (*)(int,fltk::Window*))`.

You can generate fake events by calling `handle(int)` on the correct widgets (usally a window). Currently you can change the values returned by the `fltk::event_*()` functions by storing the desired value into the static variables `fltk::e_*`, but this may change in future versions.

## Mouse Events

#### fltk::PUSH

A mouse button has gone down with the mouse pointing at this widget. You can find out what button by calling `fltk::event_button()`. You find out the mouse position by calling `fltk::event_x()` and `fltk::event_y()`. These positions are relative to the corner of the widget whose handle() method is being called.

A widget indicates that it "wants" the mouse click by returning non-zero from its `handle()` method. It will then become the `fltk::pushed()` widget (this is done by the enclosing group widget) and will get `fltk::DRAG` and the matching `fltk::RELEASE` events.

#### fltk::DRAG

The mouse has moved with a button held down. The current button state is in `fltk::event_state()`. The mouse position, relative to this widget, is in `fltk::event_x()` and `fltk::event_y()`.

To receive `fltk::DRAG` events you must return non-zero when passed a `fltk::PUSH` event.

#### fltk::RELEASE

A mouse button has been released. You can find out what button by calling `fltk::event_button()`.

To receive `fltk::RELEASE` events you must return non-zero when passed a `fltk::PUSH` event.

#### fltk::ENTER

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 `handle()` method. It then becomes the `fltk::belowmouse()` widget and will receive `fltk::MOVE` and `fltk::LEAVE` events.

#### fltk::MOVE

The mouse has moved without any mouse buttons held down. This event is sent to the `fltk::belowmouse()` widget.

#### fltk::LEAVE

The mouse has moved out of the widget. To get this event you must return 1 in response to a `fltk::ENTER` event.

#### fltk::MOUSEWHEEL

The wheel was moved on the mouse. `fltk::event_dy()` contains how many clicks the wheel moved, positive for up and negative for down. There is also a `fltk::event_dx()` for any kind of horizontal scrolling device but nothing produces that yet. This event is sent directly to the `fltk::focus()` widget (?).

## Keyboard Events

#### fltk::FOCUS

This indicates an attempt to give a widget the keyboard focus.

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 `handle()` method. It then becomes the `fltk::focus()` widget and gets `fltk::KEY`, `fltk::KEYUP` and `fltk::UNFOCUS` events.

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 `fltk::event_key()` to figure out why it moved, for navigation it will be the key pressed and for switching windows it will be zero.

#### fltk::UNFOCUS

Sent to the previous `fltk::focus()` widget when another widget gets the focus.

#### fltk::KEY

A key press event. Fltk sends these directly to the `fltk::focus()` widget. If it returns zero then fltk will change the event into `fltk::SHORTCUT` and try the widgets under the mouse.

The key pressed can be found in `fltk::event_key()`. The text that the key should insert can be found with `fltk::event_text()` and its length is in `fltk::event_length()`.

If you are actually doing text editing, you should use `fltk::compose()` to process the individual keystrokes into I18N characters.

#### fltk::KEYUP

Sent to the `fltk::focus()` widget. The key that was released can be found in `fltk::event_key()` (`fltk::event_text()` is not set).

#### fltk::SHORTCUT

If the `fltk::focus()` widget is zero or it returns zero for an `fltk::KEY` event then FLTK tries sending this event to every widget it can, until one of them returns non-zero. `fltk::SHORTCUT` is first sent to the `belowmouse()` 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!

You can also make "global" shortcuts by using `fltk::add_handler()`. A global shortcut will work no matter what windows are displayed or which one has the focus.

## Widget Events

#### fltk::DEACTIVATE

The method `deactivate()` has been called on this widget or one of its parents. The function `active_r()` will now return `false`.

#### fltk::ACTIVATE

The method `activate()` has been called on this widget or one of its parents. The function `active_r()` will now return `true`.

#### fltk::HIDE

This widget is no longer visible, due to `hide()` being called on it or one of its parents, or due to a parent window being minimized. The function `visible_r()` will now return `false`.

If you implement a widget class it is important to call your base class with this same event. Fltk relies on this to communicate the visiblilty of widgets that are windows to the system.

#### fltk::SHOW

This widget is visible, due to `show()` being called on it or one of its parents, or due to a parent window being restored from minimized state. The function `visible_r()` will now return `true`.

If you implement a widget class it is important to call your base class with this same event. Fltk relies on this to communicate the visiblilty of widgets that are windows to the system.

## Clipboard Events

#### fltk::PASTE

You should get this event some time after you call `fltk::paste()` or you return true for `fltk::DND_RELEASE`. The contents of `fltk::event_text()` is the text to insert and the number of characters is in `fltk::event_length()`.

#### fltk::DND_ENTER

The user is dragging something over your widget. Return 1 if you are intersted in getting `fltk::DND_DRAG` and `fltk::DND_RELEASE` events.

It is impossible to examine the text of the drag until you release it. There are system-specific variables that can be examined to determine the type of drag being done, but unless you are making a file-management application that wants to delete or rename the source files, you should not need this information.

#### fltk::DND_DRAG

The user moved the mouse some more while dragging something. You might use this to move around a cursor indicating where the insertion will go.

#### fltk::DND_LEAVE

The user moved out of the widget without releasing the dragged object.

#### fltk::DND_RELEASE

The user let go of the mouse and dropped something on your widget. Return 1 if you are interested in getting this data. In this case you will get an `fltk::PASTE` event with the text of object. This is usually a URL string, such as a filename with "file:" on the start. All fltk widgets just insert the data as text into text editors.