Doxygen documentation update.
This commit is contained in:
parent
e87abf9202
commit
bc7e6e2a34
1 changed files with 207 additions and 2 deletions
|
@ -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.))
|
||||
*/
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue