The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
distributor.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2017 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 /**
18  * @file
19  * Contains the event distributor.
20  *
21  * The event distributor exists of several classes which are combined in one
22  * templated distributor class. The classes are closely tight together.
23  *
24  * All classes have direct access to each others members since they should act
25  * as one. (Since the buttons are a templated subclass it's not possible to use
26  * private subclasses.)
27  *
28  * The mouse_motion class handles the mouse motion and holds the owner of us
29  * since all classes virtually inherit us.
30  *
31  * The mouse_button classes are templated classes per mouse button, the
32  * template parameters are used to make the difference between the mouse
33  * buttons. Although it's easily possible to add more mouse buttons in the
34  * code several places only expect a left, middle and right button.
35  *
36  * distributor is the main class to be used in the user code. This class
37  * contains the handling of the keyboard as well.
38  */
39 
42 #include "sdl/point.hpp"
44 #include "video.hpp"
45 
46 #include <string>
47 #include <vector>
48 
49 namespace gui2
50 {
51 
52 class widget;
53 
54 namespace event
55 {
56 
57 /***** ***** ***** ***** mouse_motion ***** ***** ***** ***** *****/
58 
60 {
61 public:
62  mouse_motion(widget& owner, const dispatcher::queue_position queue_position);
63 
64  ~mouse_motion();
65 
66  /**
67  * Captures the mouse input.
68  *
69  * When capturing the widget that has the mouse focus_ does the capturing.
70  *
71  * @param capture Set or release the capturing.
72  */
73  void capture_mouse( // widget* widget);
74  const bool capture = true);
75 
76 protected:
77  /** The widget that currently has the mouse focus_. */
79 
80  /** Did the current widget capture the focus_? */
82 
83  /** The widget that owns us. */
85 
86  /** The timer for the hover event. */
87  size_t hover_timer_;
88 
89  /** The widget which should get the hover event. */
91 
92  /** The anchor point of the hover event. */
94 
95  /**
96  * Has the hover been shown for the widget?
97  *
98  * A widget won't get a second hover event after the tooltip has been
99  * triggered. Only after (shortly) entering another widget it will be shown
100  * again for this widget.
101  */
103 
104  /**
105  * Starts the hover timer.
106  *
107  * @param widget The widget that wants the tooltip.
108  * @param coordinate The anchor coordinate.
109  */
111 
112  /** Stops the current hover timer. */
113  void stop_hover_timer();
114 
115  /**
116  * Called when the mouse enters a widget.
117  *
118  * @param mouse_over The widget that should receive the event.
119  */
120  void mouse_enter(widget* mouse_over);
121 
122  /** Called when the mouse leaves the current widget. */
123  void mouse_leave();
124 
125 private:
126  /**
127  * Called when the mouse moves over a widget.
128  *
129  * @param mouse_over The widget that should receive the event.
130  * @param coordinate The current screen coordinate of the mouse.
131  */
132  void mouse_hover(widget* mouse_over, const point& coordinate);
133 
134  /** Called when the mouse wants the widget to show its tooltip. */
135  void show_tooltip();
136 
139  bool& handled,
140  const point& coordinate);
141 
142  void signal_handler_sdl_wheel(const event::ui_event event,
143  bool& handled,
144  const point& coordinate);
145 
147  bool& handled,
148  const point& coordinate);
149 };
150 
151 /***** ***** ***** ***** mouse_button ***** ***** ***** ***** *****/
152 
153 /**
154  * Small helper metastruct to specialize mouse_button with and provide ui_event type
155  * aliases without needing to make mouse_button take a million template types.
156  */
157 template<
158  ui_event sdl_button_down,
159  ui_event sdl_button_up,
160  ui_event button_down,
161  ui_event button_up,
162  ui_event button_click,
163  ui_event button_double_click>
165 {
166  static const ui_event sdl_button_down_event = sdl_button_down;
167  static const ui_event sdl_button_up_event = sdl_button_up;
168  static const ui_event button_down_event = button_down;
169  static const ui_event button_up_event = button_up;
170  static const ui_event button_click_event = button_click;
171  static const ui_event button_double_click_event = button_double_click;
172 };
173 
174 template<typename T>
175 class mouse_button : public virtual mouse_motion
176 {
177 public:
179  widget& owner,
180  const dispatcher::queue_position queue_position);
181 
182  /**
183  * Initializes the state of the button.
184  *
185  * @param is_down The initial state of the button, if true down
186  * else initialized as up.
187  */
188  void initialize_state(const bool is_down);
189 
190 protected:
191  /** The time of the last click used for double clicking. */
193 
194  /** The widget the last click was on, used for double clicking. */
196 
197  /**
198  * If the mouse isn't captured we need to verify the up is on the same
199  * widget as the down so we send a proper click, also needed to send the
200  * up to the right widget.
201  */
203 
204 private:
205  /** used for debug messages. */
207 
208  /** Is the button down? */
209  bool is_down_;
210 
213  bool& handled,
214  const point& coordinate);
215 
218  bool& handled,
219  const point& coordinate);
220 
221 
223 };
224 
225 /***** ***** ***** ***** distributor ***** ***** ***** ***** *****/
226 
235  >;
236 
245  >;
246 
255  >;
256 
257 
258 /** The event handler class for the widget library. */
259 class distributor :
260  public mouse_button_left,
261  public mouse_button_middle,
262  public mouse_button_right
263 {
264 public:
265  distributor(widget& owner, const dispatcher::queue_position queue_position);
266 
267  ~distributor();
268 
269  /**
270  * Initializes the state of the keyboard and mouse.
271  *
272  * Needed after initialization and reactivation.
273  */
274  void initialize_state();
275 
276  /**
277  * Captures the keyboard input.
278  *
279  * @param widget The widget which should capture the keyboard.
280  * Sending nullptr releases the capturing.
281  */
283 
284  /**
285  * Adds the widget to the keyboard chain.
286  *
287  * @param widget The widget to add to the chain. The widget
288  * should be valid widget, which hasn't been
289  * added to the chain yet.
290  */
291  void keyboard_add_to_chain(widget* widget);
292 
293  /**
294  * Remove the widget from the keyboard chain.
295  *
296  * @param widget The widget to be removed from the chain.
297  */
298  void keyboard_remove_from_chain(widget* widget);
299 
300  /**
301  * Return the widget currently capturing keyboard input.
302  */
303  widget* keyboard_focus() const;
304 
305 private:
307  {
308  public:
309  virtual void handle_event(const SDL_Event& ) {}
310  virtual void handle_window_event(const SDL_Event& ) {}
311  layer() : video2::draw_layering(false) { }
312  };
313 
314  // make sure the appropriate things happens when we close.
316 
317 #if 0
318  bool hover_pending_; /**< Is there a hover event pending? */
319  unsigned hover_id_; /**< Id of the pending hover event. */
320  SDL_Rect hover_box_; /**< The area the mouse can move in,
321  * moving outside invalidates the
322  * pending hover event.
323  */
324 
325  bool had_hover_; /**< A widget only gets one hover event
326  * per enter cycle.
327  */
328 
329  /** The widget of the currently active tooltip. */
330  widget* tooltip_;
331 
332  /** The widget of the currently active help popup. */
333  widget* help_popup_;
334 #endif
335  /** The widget that holds the keyboard focus_. */
337 
338  /**
339  * Fall back keyboard focus_ items.
340  *
341  * When the focused widget didn't handle the keyboard event (or no handler
342  * for the keyboard focus_) it is send all widgets in this vector. The order
343  * is from rbegin() to rend(). If the keyboard_focus_ is in the vector it
344  * won't get the event twice. The first item added to the vector should be
345  * the window, so it will be the last handler and can dispatch the hotkeys
346  * registered.
347  */
348  std::vector<widget*> keyboard_focus_chain_;
349 
350  /**
351  * Set of functions that handle certain events and sends them to the proper
352  * widget. These functions are called by the SDL event handling functions.
353  */
354 
355  void signal_handler_sdl_key_down(const SDL_Keycode key,
356  const SDL_Keymod modifier,
357  const utf8::string& unicode);
358 
359  void signal_handler_sdl_text_input(const utf8::string& unicode, int32_t start, int32_t len);
360  void signal_handler_sdl_text_editing(const utf8::string& unicode, int32_t start, int32_t len);
361 
362  template<typename Fcn, typename P1, typename P2, typename P3>
363  void signal_handler_keyboard_internal(event::ui_event evt, P1&& p1, P2&& p2, P3&& p3);
364 
365  void signal_handler_notify_removal(dispatcher& widget, const ui_event event);
366 };
367 
368 } // namespace event
369 
370 } // namespace gui2
widget * last_clicked_widget_
The widget the last click was on, used for double clicking.
widget * keyboard_focus() const
Return the widget currently capturing keyboard input.
bool hover_shown_
Has the hover been shown for the widget?
draw_layering(const bool auto_join=true)
Definition: video.cpp:46
std::vector< char_t > string
void mouse_button_click(widget *widget)
std::vector< widget * > keyboard_focus_chain_
Fall back keyboard focus_ items.
A left mouse button down event for a widget.
Definition: handler.hpp:68
Uint32 last_click_stamp_
The time of the last click used for double clicking.
void signal_handler_sdl_button_down(const event::ui_event event, bool &handled, const point &coordinate)
Base class for event handling.
Definition: dispatcher.hpp:161
void signal_handler_sdl_wheel(const event::ui_event event, bool &handled, const point &coordinate)
See LEFT_BUTTON_CLICK.
Definition: handler.hpp:84
void signal_handler_sdl_text_input(const utf8::string &unicode, int32_t start, int32_t len)
An SDL left mouse button down event.
Definition: handler.hpp:66
void keyboard_capture(widget *widget)
Captures the keyboard input.
Base class for all widgets.
Definition: widget.hpp:48
See LEFT_BUTTON_DOUBLE_CLICK.
Definition: handler.hpp:85
See LEFT_BUTTON_CLICK.
Definition: handler.hpp:77
An SDL right mouse button down event.
Definition: handler.hpp:80
See LEFT_BUTTON_DOWN.
Definition: handler.hpp:75
-file util.hpp
See LEFT_BUTTON_UP.
Definition: handler.hpp:83
widget * focus_
If the mouse isn't captured we need to verify the up is on the same widget as the down so we send a p...
void mouse_hover(widget *mouse_over, const point &coordinate)
Called when the mouse moves over a widget.
Generic file dialog.
Definition: field-fwd.hpp:22
void signal_handler_show_helptip(const event::ui_event event, bool &handled, const point &coordinate)
void initialize_state(const bool is_down)
Initializes the state of the button.
const std::string name_
used for debug messages.
The event handler class for the widget library.
void keyboard_add_to_chain(widget *widget)
Adds the widget to the keyboard chain.
mouse_button(const std::string &name_, widget &owner, const dispatcher::queue_position queue_position)
distributor(widget &owner, const dispatcher::queue_position queue_position)
void signal_handler_keyboard_internal(event::ui_event evt, P1 &&p1, P2 &&p2, P3 &&p3)
widget & owner_
The widget that owns us.
Definition: distributor.hpp:84
A left mouse button up event for a widget.
Definition: handler.hpp:69
widget * keyboard_focus_
The widget that holds the keyboard focus_.
An SDL middle mouse button down event.
Definition: handler.hpp:73
virtual void handle_window_event(const SDL_Event &)
void start_hover_timer(widget *widget, const point &coordinate)
Starts the hover timer.
void signal_handler_sdl_text_editing(const utf8::string &unicode, int32_t start, int32_t len)
point hover_position_
The anchor point of the hover event.
Definition: distributor.hpp:93
An SDL middle mouse button up event.
Definition: handler.hpp:74
Definition: video.cpp:42
void signal_handler_notify_removal(dispatcher &widget, const ui_event event)
void mouse_enter(widget *mouse_over)
Called when the mouse enters a widget.
void capture_mouse(const bool capture=true)
Captures the mouse input.
widget * mouse_focus_
The widget that currently has the mouse focus_.
Definition: distributor.hpp:78
A left mouse button double click event for a widget.
Definition: handler.hpp:71
Holds a 2D point.
Definition: point.hpp:22
void mouse_leave()
Called when the mouse leaves the current widget.
virtual void handle_event(const SDL_Event &)
void signal_handler_sdl_mouse_motion(const event::ui_event event, bool &handled, const point &coordinate)
queue_position
The position where to add a new callback in the signal handler.
Definition: dispatcher.hpp:335
void keyboard_remove_from_chain(widget *widget)
Remove the widget from the keyboard chain.
bool mouse_captured_
Did the current widget capture the focus_?
Definition: distributor.hpp:81
An SDL left mouse button up event.
Definition: handler.hpp:67
mouse_motion(widget &owner, const dispatcher::queue_position queue_position)
void stop_hover_timer()
Stops the current hover timer.
void signal_handler_sdl_button_up(const event::ui_event event, bool &handled, const point &coordinate)
size_t hover_timer_
The timer for the hover event.
Definition: distributor.hpp:87
void show_tooltip()
Called when the mouse wants the widget to show its tooltip.
void signal_handler_sdl_key_down(const SDL_Keycode key, const SDL_Keymod modifier, const utf8::string &unicode)
Set of functions that handle certain events and sends them to the proper widget.
widget * hover_widget_
The widget which should get the hover event.
Definition: distributor.hpp:90
See LEFT_BUTTON_DOWN.
Definition: handler.hpp:82
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
An SDL right mouse button up event.
Definition: handler.hpp:81
Small helper metastruct to specialize mouse_button with and provide ui_event type aliases without nee...
See LEFT_BUTTON_DOUBLE_CLICK.
Definition: handler.hpp:78
bool is_down_
Is the button down?
A left mouse button click event for a widget.
Definition: handler.hpp:70
void initialize_state()
Initializes the state of the keyboard and mouse.
See LEFT_BUTTON_UP.
Definition: handler.hpp:76
ui_event
The event send to the dispatcher.
Definition: handler.hpp:55
std::string string
EXIT_STATUS start(const config &game_conf, CVideo &video, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
Definition: editor_main.cpp:28