Doxygen documentation update.

This commit is contained in:
Mark de Wever 2009-10-17 09:55:21 +00:00
parent e87abf9202
commit bc7e6e2a34

View file

@ -276,6 +276,9 @@ bool tdispatcher::fire(const tevent event
* for solving the problem are discussed first and then the solution that is
* chosen in more detail.
*
* After SDL has generated and event it needs to be turned into an event which
* the widgets can use.
*
* @section handling_solution The implementation solutions.
*
* For the event handling we use a few use case scenarios and show the possible
@ -378,7 +381,7 @@ bool tdispatcher::fire(const tevent event
* - B child -> We can't scroll so ignore
* - C post child -> Scroll -> handled
*
* @section evaluation Evaluation
* @subsection evaluation Evaluation
*
* When using the first solution it's possible to drop the child queue since
* everything falls in pre or post. But there is a scenario that's a bit ugly
@ -411,7 +414,7 @@ bool tdispatcher::fire(const tevent event
* - C pre child -> handler 1 -> if last in queue -> solution 2 C child
*
* Click on button in panel:
* - W pre child
* - W pre child
* - C pre child -> handler 2 -> if !last in queue -> solution 2 C pre child
* - B pre child -> do button stuff -> handled
*
@ -422,4 +425,206 @@ bool tdispatcher::fire(const tevent event
* twice versus once in solution 2. Also the fact that the queues for the
* events are processed in reverse order on the way back sounds more
* initiative.
*
* @section processing_raw_events Processing the raw events.
*
* This section describes how the events generated by SDL are send as our own
* events to the various widgets. The first step in sending an event is to
* decode it and send it to a registered dispatcher.
*
* - gui2::event::thandler handles the SDL events.
* - gui2::event::tdispatcher has the registered dispatchers.
*
* In general a dispatcher is a window which then needs to send this event to
* the widgets. The dispatcher is just a simple part which fires events and
* finds a handler for the event. This is not to the liking of most widgets,
* they don't want to handle raw events but get a polished and clean event. No
* button up and down and then try to figure out whether it needs to act as if
* it was clicked upon, no simply op and down to change the appearance and a
* click event to do the clicking actions. And don't even try to convince a
* widget to determine whether this up event was a single or double click.
* Widgets like to sleep with nice dreams and not having nightmares where SDL
* events haunt them.
*
* In order to remedy that problem there's the gui2::event::tdistributor
* class, it's the class to do the dirty job of converting the raw event into
* these nice polished events. The distributor is in general linked to a window,
* but a widget can install it's own distributor if it needs to know more of the
* raw events as still left in the polished events. At the time of this writing
* no widget needs this feature, but the toggle panel might need it.
*
* After the distributor has polished the event and send it on its way to the
* widget the dispatcher needs to make sure the event is properly dispatched to
* the widget in question and also notify its parents by means of the previously
* described event chain.
*
* @subsection sdl_event Get the SDL events
*
* The first step in event handling is getting the events in the first place.
* Events are generated by SDL and placed in a queue. The Wesnoth code processes
* this queue and thus handles the events. The part which does the first
* handling isn't described here since it's (secretly) intended to be replaced
* by the @ref gui2::event::thandler class. Instead we directly jump to this
* class and explain what it does.
*
* The main handling function is @ref gui2::event::thandler::handle_event which
* as no real surprise handles the events. The function is a simple multiplexer
* which lets other subfunctions to the handling of specific events.
*
* @todo Describe drawing and resizing once the code is stable and working as
* wanted in these areas.
*
* @subsubsection thandler_mouse Mouse motion events
*
* If a dispatcher has captured the mouse it gets the event, no questions asked.
* If not it goes through all dispatchers and finds the first one willing to
* accept the mouse event.
*
* This means a mouse event is send to one dispatcher.
*
* @subsubsection thandler_mouse_button_down Mouse button down events
*
* Turning the mouse wheel on a mouse generates both an down and up event. It
* has been decided to handle the wheel event in the button up code so wheel
* events are here directly dropped on the floor and forgotten.
*
* The other buttons are handled as if they're normal mouse events but are
* decoded per button so instead of a button_down(id) you get button_down_id.
*
* @subsubsection thandler_mouse_button_up Mouse button up events
*
* The mouse wheel event is handled as if it's a keyboard event and like the
* button_down they are send as wheel_id events.
*
* The other mouse buttons are handled the same as the down buttons.
*
* @subsubsection thandler_keyboard Keyboard events
*
* There are three types of keyboard events, the already mentioned mouse wheel
* events, the key down and key up event. When a key is pressed for a longer
* time several key down events are generated and only one key up, this means
* the key up is rather useless. Guess what, the multiplexer already drops that
* event so we never get it.
*
* The keyboard event is send to either the dispatcher that captured the
* keyboard or the last in the dispatcher queue.
*
* @todo This might change in the near future.
*
* @subsection tdistributor Event polishing and distribution
*
* The event distributor has the job to find the widget that should receive the
* event and which event(s) to send from a single event. In general an event is
* first send to the widget as-is, sending the raw events allows other
* distributors to be nested between this distributor and the intended target
* widget. Or the intended widget might not really be the intended widget but
* another distributor that wants to dispatch the event internally.
*
* However in the common cases this raw event isn't handled and the distributor
* needs to send the polished events. In the following sections the details of
* the conversion from raw to polished is described, it intentionally lacks the
* part of sending the raw events as well since it adds no value.
*
* A widget can capture the mouse, which means all mouse events are send to this
* widget, regardless where the mouse is. This is normally done in a mouse down
* event (for a button) so all events following it are send to that widget.
*
* @subsection mouse_motion Mouse motion
*
* This section describes the conversion from a raw mouse motion to the polished
* events it can generate:
* - @ref gui2::event::MOUSE_ENTER "MOUSE_ENTER"
* - @ref gui2::event::MOUSE_LEAVE "MOUSE_LEAVE"
* - @ref gui2::event::MOUSE_MOTION "MOUSE_MOTION"
*
* When the mouse is captured that widget will only receive motion events.
*
* If not captured the code checks whether the widget underneath the mouse is
* the same widget as at the last motion if event. If so that widget gets a
* motion event.
* If not the widget that before was underneath the mouse pointer (if any) gets
* a leave event and the widget newly underneath the mouse pointer (if any) gets
* an enter event.
*
* @subsection mouse_button Mouse buttons
*
* The mouse button code is a bit more complex and is separated in the various
* events to be send.
*
* @subsubsection mouse_button_down Mouse button down
*
* Some things start simple, so does the event of pressing down a mouse button.
* All it does is send the event to the widget as one of the following events:
* - @ref gui2::event::LEFT_BUTTON_DOWN "LEFT_BUTTON_DOWN"
* - @ref gui2::event::MIDDLE_BUTTON_DOWN "MIDDLE_BUTTON_DOWN"
* - @ref gui2::event::RIGHT_BUTTON_DOWN "RIGHT_BUTTON_DOWN"
*
* @todo Validate the code it seems a down event with a captured mouse doesn't
* really work as wanted. (Rare case but should work properly.) In general the
* mouse event handling needs testing to see whether the proper events are send
* all the time.
*
* @subsubsection mouse_button_up Mouse button up
*
* Simplicity ends here.
*
* @todo Document further.
*
* @subsubsection mouse_click Mouse click
*
* So the button up event has asked for mouse click, now we need to test whether
* the click will be a click or a double click. A double click is generated when
* the same widget is clicked twice in a short time and causes the following
* events:
* - @ref gui2::event::LEFT_BUTTON_DOUBLE_CLICK "LEFT_BUTTON_DOUBLE_CLICK"
* - @ref gui2::event::MIDDLE_BUTTON_DOUBLE_CLICK "MIDDLE_BUTTON_DOUBLE_CLICK"
* - @ref gui2::event::RIGHT_BUTTON_DOUBLE_CLICK "RIGHT_BUTTON_DOUBLE_CLICK"
*
* Otherwise one of the following single clicks is generated:
* - @ref gui2::event::LEFT_BUTTON_CLICK "LEFT_BUTTON_CLICK"
* - @ref gui2::event::MIDDLE_BUTTON_CLICK "MIDDLE_BUTTON_CLICK"
* - @ref gui2::event::RIGHT_BUTTON_CLICK "RIGHT_BUTTON_CLICK"
*
* @subsubsection double_click To double click or not to double click
*
* Wait a second, a widget has a field whether or not it wants a double click
* for a certain mouse button and now I see that it's bluntly ignored by the
* distributor. Indeed the distributor doesn't care about what the widget wants,
* it does what it wants and leaves the sorting out what's wanted to the
* dispatcher.
*
* The problem is that in the chain events are send to one widget that may not
* be interested in a double click, but another widget in the chain is. There
* are several solutions to this problem:
* -# Sending a click followed by a double click.
* -# Sending a click with a tag field that it actually is a double click.
* -# Send a double click and turn it into a click if the double click is
* unwanted.
*
* The first solution has the disadvantage that a toggle panel likes a click and
* double click, the first click selects the second deselects and now the
* deselected panel gets a double click. When the panel now checks whether it's
* selected it's not and might take the wrong action upon it.
*
* The second option is possible but would be rather intrusive in the code,
* since it would generate another event signature. Adding a signature just for
* this special case seemed a bit too much effort vs. gain. Also the widget
* needs to check whether a click is a click or a double click and choose a
* different code path for it. This in turn would mean a signal handler
* secretly might handle two events and lowers the transparency of the code.
*
* The third option also adds some special case handling but the scope is
* limited and only one part knows about the tricks done.
*
* The last option has been chosen and the dispatcher build the event chain and
* while building the chain it looks whether the widget wants the double click
* or not. It does this test by looking at the wants double click function and
* not test for a handler. The double click test function is made for this
* purpose and depending on the handler might again do the wrong thing.
* (A certain toggle panel might not want to do something on a double click but
* also not being deselected upon a double click. The latter to keep the UI
* consistent, a double click on a toggle panel might execute a special function
* or not, but always keep the panel selected. (That is if the panel can be
* selected.))
*/