The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
distributor.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2016 by Mark de Wever <[email protected]>
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 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
18 
19 #include "events.hpp"
20 #include "gui/core/log.hpp"
21 #include "gui/core/timer.hpp"
22 #include "gui/widgets/settings.hpp"
23 #include "gui/widgets/widget.hpp"
24 #include "gui/widgets/window.hpp"
25 
26 #include "utils/functional.hpp"
27 
28 namespace gui2
29 {
30 
31 namespace event
32 {
33 
34 /**
35  * SDL_AddTimer() callback for the hover event.
36  *
37  * When this callback is called it pushes a new hover event in the event queue.
38  *
39  * @param interval The time parameter of SDL_AddTimer.
40  * @param param Pointer to a widget that's able to show the
41  * tooltip (will be used as a dispatcher).
42  *
43  * @returns The new timer interval, 0 to stop.
44  */
45 
46 #if 0
47 /**
48  * SDL_AddTimer() callback for the popup event.
49  *
50  * This event makes sure the popup is removed again.
51  *
52  * @param interval The time parameter of SDL_AddTimer.
53  * @param param Pointer to parameter structure.
54  *
55  * @returns The new timer interval, 0 to stop.
56  */
57 static Uint32 popup_callback(Uint32 /*interval*/, void* /*param*/)
58 {
59  DBG_GUI_E << "Pushing popup removal event in queue.\n";
60 
61  SDL_Event event;
62  SDL_UserEvent data;
63 
64  data.type = HOVER_REMOVE_POPUP_EVENT;
65  data.code = 0;
66  data.data1 = 0;
67  data.data2 = 0;
68 
69  event.type = HOVER_REMOVE_POPUP_EVENT;
70  event.user = data;
71 
72  SDL_PushEvent(&event);
73  return 0;
74 }
75 #endif
76 
77 /**
78  * Small helper to keep a resource (boolean) locked.
79  *
80  * Some of the event handling routines can't be called recursively, this due to
81  * the fact that they are attached to the pre queue and when the forward an
82  * event the pre queue event gets triggered recursively causing infinite
83  * recursion.
84  *
85  * To prevent that those functions check the lock and exit when the lock is
86  * held otherwise grab the lock here.
87  */
88 class tlock
89 {
90 public:
91  tlock(bool& locked) : locked_(locked)
92  {
93  assert(!locked_);
94  locked_ = true;
95  }
96 
98  {
99  assert(locked_);
100  locked_ = false;
101  }
102 
103 private:
104  bool& locked_;
105 };
106 
107 
108 /***** ***** ***** ***** tmouse_motion ***** ***** ***** ***** *****/
109 
110 #define LOG_HEADER "distributor mouse motion [" << owner_.id() << "]: "
111 
113  const tdispatcher::tposition queue_position)
114  : mouse_focus_(nullptr)
115  , mouse_captured_(false)
116  , owner_(owner)
117  , hover_timer_(0)
118  , hover_widget_(nullptr)
119  , hover_position_(0, 0)
120  , hover_shown_(true)
121  , signal_handler_sdl_mouse_motion_entered_(false)
122 {
125  this,
126  _2,
127  _3,
128  _5),
129  queue_position);
130 
132  &tmouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
134  &tmouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
136  &tmouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
138  &tmouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
139 
142  this,
143  _2,
144  _3,
145  _5),
146  queue_position);
147 }
148 
150 {
152 }
153 
154 void tmouse_motion::capture_mouse(const bool capture)
155 {
156  assert(mouse_focus_);
157  mouse_captured_ = capture;
158 }
159 
161  bool& handled,
162  const tpoint& coordinate)
163 {
165  return;
166  }
168 
169  DBG_GUI_E << LOG_HEADER << event << ".\n";
170 
171  if(mouse_captured_) {
172  assert(mouse_focus_);
173  if(!owner_.fire(event, *mouse_focus_, coordinate)) {
174  mouse_motion(mouse_focus_, coordinate);
175  }
176  } else {
177  twidget* mouse_over = owner_.find_at(coordinate, true);
178  while(mouse_over && !mouse_over->can_mouse_focus() && mouse_over->parent()) {
179  mouse_over = mouse_over->parent();
180  }
181  if(mouse_over) {
182  DBG_GUI_E << LOG_HEADER << "Firing: " << event << ".\n";
183  if(owner_.fire(event, *mouse_over, coordinate)) {
184  return;
185  }
186  }
187 
188  if(!mouse_focus_ && mouse_over) {
189  mouse_enter(mouse_over);
190  } else if(mouse_focus_ && !mouse_over) {
191  mouse_leave();
192  } else if(mouse_focus_ && mouse_focus_ == mouse_over) {
193  mouse_motion(mouse_over, coordinate);
194  } else if(mouse_focus_ && mouse_over) {
195  // moved from one widget to the next
196  mouse_leave();
197  mouse_enter(mouse_over);
198  } else {
199  assert(!mouse_focus_ && !mouse_over);
200  }
201  }
202  handled = true;
203 }
204 
206  bool& handled,
207  const tpoint& coordinate)
208 {
209  DBG_GUI_E << LOG_HEADER << event << ".\n";
210 
211  if(mouse_captured_) {
212  assert(mouse_focus_);
213  owner_.fire(event, *mouse_focus_, coordinate);
214  } else {
215  twidget* mouse_over = owner_.find_at(coordinate, true);
216  if(mouse_over) {
217  owner_.fire(event, *mouse_over, coordinate);
218  }
219  }
220  handled = true;
221 }
222 
224  bool& handled,
225  const tpoint& coordinate)
226 {
227  DBG_GUI_E << LOG_HEADER << event << ".\n";
228 
229  if(mouse_captured_) {
230  assert(mouse_focus_);
231  if(owner_.fire(event, *mouse_focus_, coordinate)) {
233  }
234  } else {
235  twidget* mouse_over = owner_.find_at(coordinate, true);
236  if(mouse_over) {
237  DBG_GUI_E << LOG_HEADER << "Firing: " << event << ".\n";
238  if(owner_.fire(event, *mouse_over, coordinate)) {
240  }
241  }
242  }
243 
244  handled = true;
245 }
246 
248 {
249  DBG_GUI_E << LOG_HEADER << "Firing: " << event::MOUSE_ENTER << ".\n";
250 
251  assert(mouse_over);
252 
253  mouse_focus_ = mouse_over;
254  owner_.fire(event::MOUSE_ENTER, *mouse_over);
255 
256  hover_shown_ = false;
257  start_hover_timer(mouse_over, get_mouse_position());
258 }
259 
260 void tmouse_motion::mouse_motion(twidget* mouse_over, const tpoint& coordinate)
261 {
262  DBG_GUI_E << LOG_HEADER << "Firing: " << event::MOUSE_MOTION << ".\n";
263 
264  assert(mouse_over);
265 
266  owner_.fire(event::MOUSE_MOTION, *mouse_over, coordinate);
267 
268  if(hover_timer_) {
269  if((abs(hover_position_.x - coordinate.x) > 5)
270  || (abs(hover_position_.y - coordinate.y) > 5)) {
271 
273  start_hover_timer(mouse_over, coordinate);
274  }
275  }
276 }
277 
279 {
280  DBG_GUI_E << LOG_HEADER << "Firing: " << event::SHOW_TOOLTIP << ".\n";
281 
282  if(!hover_widget_) {
283  // See tmouse_motion::stop_hover_timer.
284  ERR_GUI_E << LOG_HEADER << event::SHOW_TOOLTIP
285  << " bailing out, no hover widget.\n";
286  return;
287  }
288 
289  /*
290  * Ignore the result of the event, always mark the tooltip as shown. If
291  * there was no handler, there is no reason to assume there will be one
292  * next time.
293  */
295 
296  hover_shown_ = true;
297 
298  hover_timer_ = 0;
299  hover_widget_ = nullptr;
300  hover_position_ = tpoint(0, 0);
301 }
302 
304 {
305  DBG_GUI_E << LOG_HEADER << "Firing: " << event::MOUSE_LEAVE << ".\n";
306 
307  tcontrol* control = dynamic_cast<tcontrol*>(mouse_focus_);
308  if(!control || control->get_active()) {
309  owner_.fire(event::MOUSE_LEAVE, *mouse_focus_);
310  }
311 
313 
314  mouse_focus_ = nullptr;
315 
317 }
318 
319 void tmouse_motion::start_hover_timer(twidget* widget, const tpoint& coordinate)
320 {
321  assert(widget);
323 
324  if(hover_shown_ || !widget->wants_mouse_hover()) {
325  return;
326  }
327 
328  DBG_GUI_E << LOG_HEADER << "Start hover timer for widget '" << widget->id()
329  << "' at address " << widget << ".\n";
330 
332  = add_timer(50, std::bind(&tmouse_motion::show_tooltip, this));
333 
334  if(hover_timer_) {
335  hover_widget_ = widget;
336  hover_position_ = coordinate;
337  } else {
338  ERR_GUI_E << LOG_HEADER << "Failed to add hover timer." << std::endl;
339  }
340 }
341 
343 {
344  if(hover_timer_) {
345  assert(hover_widget_);
346  DBG_GUI_E << LOG_HEADER << "Stop hover timer for widget '"
347  << hover_widget_->id() << "' at address " << hover_widget_
348  << ".\n";
349 
350  if(!remove_timer(hover_timer_)) {
351  ERR_GUI_E << LOG_HEADER << "Failed to remove hover timer."
352  << std::endl;
353  }
354 
355  hover_timer_ = 0;
356  hover_widget_ = nullptr;
357  hover_position_ = tpoint(0, 0);
358  }
359 }
360 
361 /***** ***** ***** ***** tmouse_button ***** ***** ***** ***** *****/
362 
363 #undef LOG_HEADER
364 #define LOG_HEADER \
365  "distributor mouse button " << name_ << " [" << owner_.id() << "]: "
366 
367 template <tevent sdl_button_down,
368  tevent sdl_button_up,
369  tevent button_down,
370  tevent button_up,
371  tevent button_click,
372  tevent button_double_click>
373 tmouse_button<sdl_button_down,
374  sdl_button_up,
375  button_down,
376  button_up,
377  button_click,
378  button_double_click>::tmouse_button(const std::string& name_,
379  twidget& owner,
381  queue_position)
382  : tmouse_motion(owner, queue_position)
383  , last_click_stamp_(0)
384  , last_clicked_widget_(nullptr)
385  , focus_(0)
386  , name_(name_)
387  , is_down_(false)
388  , signal_handler_sdl_button_down_entered_(false)
389  , signal_handler_sdl_button_up_entered_(false)
390 {
391  owner_.connect_signal<sdl_button_down>(
392  std::bind(&tmouse_button<sdl_button_down,
393  sdl_button_up,
394  button_down,
395  button_up,
396  button_click,
397  button_double_click>::
399  this,
400  _2,
401  _3,
402  _5),
403  queue_position);
404  owner_.connect_signal<sdl_button_up>(
405  std::bind(&tmouse_button<sdl_button_down,
406  sdl_button_up,
407  button_down,
408  button_up,
409  button_click,
410  button_double_click>::
412  this,
413  _2,
414  _3,
415  _5),
416  queue_position);
417 }
418 
419 template <tevent sdl_button_down,
420  tevent sdl_button_up,
421  tevent button_down,
422  tevent button_up,
423  tevent button_click,
424  tevent button_double_click>
425 void tmouse_button<sdl_button_down,
426  sdl_button_up,
427  button_down,
428  button_up,
429  button_click,
430  button_double_click>::initialize_state(const bool is_down)
431 {
432  last_click_stamp_ = 0;
433  last_clicked_widget_ = nullptr;
434  focus_ = 0;
435  is_down_ = is_down;
436 }
437 
438 template <tevent sdl_button_down,
439  tevent sdl_button_up,
440  tevent button_down,
441  tevent button_up,
442  tevent button_click,
443  tevent button_double_click>
444 void tmouse_button<sdl_button_down,
445  sdl_button_up,
446  button_down,
447  button_up,
448  button_click,
449  button_double_click>::
450  signal_handler_sdl_button_down(const event::tevent event,
451  bool& handled,
452  const tpoint& coordinate)
453 {
454  if(signal_handler_sdl_button_down_entered_) {
455  return;
456  }
457  tlock lock(signal_handler_sdl_button_down_entered_);
458 
459  DBG_GUI_E << LOG_HEADER << event << ".\n";
460 
461  if(is_down_) {
462  WRN_GUI_E << LOG_HEADER << event
463  << ". The mouse button is already down, "
464  << "we missed an event.\n";
465  return;
466  }
467  is_down_ = true;
468 
469  if(mouse_captured_) {
470  assert(mouse_focus_);
471  focus_ = mouse_focus_;
472  DBG_GUI_E << LOG_HEADER << "Firing: " << sdl_button_down << ".\n";
473  if(!owner_.fire(sdl_button_down, *focus_, coordinate)) {
474  DBG_GUI_E << LOG_HEADER << "Firing: " << button_down << ".\n";
475  owner_.fire(button_down, *mouse_focus_);
476  }
477  } else {
478  twidget* mouse_over = owner_.find_at(coordinate, true);
479  if(!mouse_over) {
480  return;
481  }
482 
483  if(mouse_over != mouse_focus_) {
484  WRN_GUI_E << LOG_HEADER << ". Mouse down on non focused widget "
485  << "and mouse not captured, we missed events.\n";
486  mouse_focus_ = mouse_over;
487  }
488 
489  focus_ = mouse_over;
490  DBG_GUI_E << LOG_HEADER << "Firing: " << sdl_button_down << ".\n";
491  if(!owner_.fire(sdl_button_down, *focus_, coordinate)) {
492  DBG_GUI_E << LOG_HEADER << "Firing: " << button_down << ".\n";
493  owner_.fire(button_down, *focus_);
494  }
495  }
496  handled = true;
497 }
498 
499 template <tevent sdl_button_down,
500  tevent sdl_button_up,
501  tevent button_down,
502  tevent button_up,
503  tevent button_click,
504  tevent button_double_click>
505 void tmouse_button<sdl_button_down,
506  sdl_button_up,
507  button_down,
508  button_up,
509  button_click,
510  button_double_click>::
511  signal_handler_sdl_button_up(const event::tevent event,
512  bool& handled,
513  const tpoint& coordinate)
514 {
515  if(signal_handler_sdl_button_up_entered_) {
516  return;
517  }
518  tlock lock(signal_handler_sdl_button_up_entered_);
519 
520  DBG_GUI_E << LOG_HEADER << event << ".\n";
521 
522  if(!is_down_) {
523  WRN_GUI_E << LOG_HEADER << event
524  << ". The mouse button is already up, we missed an event.\n";
525  return;
526  }
527  is_down_ = false;
528 
529  if(focus_) {
530  DBG_GUI_E << LOG_HEADER << "Firing: " << sdl_button_up << ".\n";
531  if(!owner_.fire(sdl_button_up, *focus_, coordinate)) {
532  DBG_GUI_E << LOG_HEADER << "Firing: " << button_up << ".\n";
533  owner_.fire(button_up, *focus_);
534  }
535  }
536 
537  twidget* mouse_over = owner_.find_at(coordinate, true);
538  if(mouse_captured_) {
539  const unsigned mask = SDL_BUTTON_LMASK | SDL_BUTTON_MMASK
540  | SDL_BUTTON_RMASK;
541 
542  if((SDL_GetMouseState(nullptr, nullptr) & mask) == 0) {
543  mouse_captured_ = false;
544  }
545 
546  if(mouse_focus_ == mouse_over) {
547  mouse_button_click(mouse_focus_);
548  } else if(!mouse_captured_) {
549  mouse_leave();
550 
551  if(mouse_over) {
552  mouse_enter(mouse_over);
553  }
554  }
555  } else if(focus_ && focus_ == mouse_over) {
556  mouse_button_click(focus_);
557  }
558 
559  focus_ = nullptr;
560  handled = true;
561 }
562 
563 template <tevent sdl_button_down,
564  tevent sdl_button_up,
565  tevent button_down,
566  tevent button_up,
567  tevent button_click,
568  tevent button_double_click>
569 void tmouse_button<sdl_button_down,
570  sdl_button_up,
571  button_down,
572  button_up,
573  button_click,
574  button_double_click>::mouse_button_click(twidget* widget)
575 {
576  Uint32 stamp = SDL_GetTicks();
577  if(last_click_stamp_ + settings::double_click_time >= stamp
578  && last_clicked_widget_ == widget) {
579 
580  DBG_GUI_E << LOG_HEADER << "Firing: " << button_double_click << ".\n";
581 
582  owner_.fire(button_double_click, *widget);
583  last_click_stamp_ = 0;
584  last_clicked_widget_ = nullptr;
585 
586  } else {
587 
588  DBG_GUI_E << LOG_HEADER << "Firing: " << button_click << ".\n";
589  owner_.fire(button_click, *widget);
590  last_click_stamp_ = stamp;
591  last_clicked_widget_ = widget;
592  }
593 }
594 
595 /***** ***** ***** ***** tdistributor ***** ***** ***** ***** *****/
596 
597 #undef LOG_HEADER
598 #define LOG_HEADER "distributor mouse motion [" << owner_.id() << "]: "
599 
600 /**
601  * @todo Test whether the state is properly tracked when an input blocker is
602  * used.
603  */
605  const tdispatcher::tposition queue_position)
606  : tmouse_motion(owner, queue_position)
607  , tmouse_button_left("left", owner, queue_position)
608  , tmouse_button_middle("middle", owner, queue_position)
609  , tmouse_button_right("right", owner, queue_position)
610 #if 0
611  , hover_pending_(false)
612  , hover_id_(0)
613  , hover_box_()
614  , had_hover_(false)
615  , tooltip_(0)
616  , help_popup_(0)
617 #endif
618  , keyboard_focus_(0)
619  , keyboard_focus_chain_()
620 {
621  if(SDL_WasInit(SDL_INIT_TIMER) == 0) {
622  if(SDL_InitSubSystem(SDL_INIT_TIMER) == -1) {
623  assert(false);
624  }
625  }
626 
628  &tdistributor::signal_handler_sdl_key_down, this, _5, _6, _7));
629 
632 
634 }
635 
637 {
639  &tdistributor::signal_handler_sdl_key_down, this, _5, _6, _7));
640 
643 }
644 
646 {
647  const Uint8 button_state = SDL_GetMouseState(nullptr, nullptr);
648 
649  tmouse_button_left::initialize_state((button_state & SDL_BUTTON(1)) != 0);
650  tmouse_button_middle::initialize_state((button_state & SDL_BUTTON(2)) != 0);
651  tmouse_button_right::initialize_state((button_state & SDL_BUTTON(3)) != 0);
652 
654 }
655 
657 {
658  if(keyboard_focus_) {
660  << ".\n";
661 
662  owner_.fire(event::LOSE_KEYBOARD_FOCUS, *keyboard_focus_, nullptr);
663  }
664 
665  keyboard_focus_ = widget;
666 
667  if(keyboard_focus_) {
669  << ".\n";
670 
671  owner_.fire(event::RECEIVE_KEYBOARD_FOCUS, *keyboard_focus_, nullptr);
672  }
673 }
674 
676 {
677  assert(widget);
678  assert(std::find(keyboard_focus_chain_.begin(),
679  keyboard_focus_chain_.end(),
680  widget) == keyboard_focus_chain_.end());
681 
682  keyboard_focus_chain_.push_back(widget);
683 }
684 
686 {
687  assert(widget);
689  keyboard_focus_chain_.begin(), keyboard_focus_chain_.end(), widget);
690 
691  if(itor != keyboard_focus_chain_.end()) {
692  keyboard_focus_chain_.erase(itor);
693  }
694 }
695 
697  const SDLMod modifier,
698  const utf8::string& unicode)
699 {
700  /** @todo Test whether recursion protection is needed. */
701 
703 
704  if(keyboard_focus_) {
705  // Attempt to cast to control, to avoid sending events if the
706  // widget is disabled. If the cast fails, we assume the widget
707  // is enabled and ready to receive events.
708  tcontrol* control = dynamic_cast<tcontrol*>(keyboard_focus_);
709  if(!control || control->get_active()) {
710  DBG_GUI_E << LOG_HEADER << "Firing: " << event::SDL_KEY_DOWN
711  << ".\n";
712  if(owner_.fire(event::SDL_KEY_DOWN,
714  key,
715  modifier,
716  unicode)) {
717  return;
718  }
719  }
720  }
721 
722  for(std::vector<twidget*>::reverse_iterator ritor
723  = keyboard_focus_chain_.rbegin();
724  ritor != keyboard_focus_chain_.rend();
725  ++ritor) {
726 
727  if(*ritor == keyboard_focus_) {
728  continue;
729  }
730 
731  if(*ritor == &owner_) {
732  /**
733  * @todo Make sure we're not in the event chain.
734  *
735  * No idea why we're here, but needs to be fixed, otherwise we keep
736  * calling this function recursively upon unhandled events...
737  *
738  * Probably added to make sure the window can grab the events and
739  * handle + block them when needed, this is no longer needed with
740  * the chain.
741  */
742  continue;
743  }
744 
745  // Attempt to cast to control, to avoid sending events if the
746  // widget is disabled. If the cast fails, we assume the widget
747  // is enabled and ready to receive events.
748  tcontrol* control = dynamic_cast<tcontrol*>(keyboard_focus_);
749  if(control != nullptr && !control->get_active()) {
750  continue;
751  }
752 
753  DBG_GUI_E << LOG_HEADER << "Firing: " << event::SDL_KEY_DOWN << ".\n";
754  if(owner_.fire(event::SDL_KEY_DOWN, **ritor, key, modifier, unicode)) {
755 
756  return;
757  }
758  }
759 }
760 
762  const tevent event)
763 {
764  DBG_GUI_E << LOG_HEADER << event << ".\n";
765 
766  /**
767  * @todo Evaluate whether moving the cleanup parts in the subclasses.
768  *
769  * It might be cleaner to do it that way, but creates extra small
770  * functions...
771  */
772 
773  if(hover_widget_ == &widget) {
775  }
776 
777  if(tmouse_button_left::last_clicked_widget_ == &widget) {
778  tmouse_button_left::last_clicked_widget_ = nullptr;
779  }
780  if(tmouse_button_left::focus_ == &widget) {
781  tmouse_button_left::focus_ = nullptr;
782  }
783 
784  if(tmouse_button_middle::last_clicked_widget_ == &widget) {
785  tmouse_button_middle::last_clicked_widget_ = nullptr;
786  }
787  if(tmouse_button_middle::focus_ == &widget) {
788  tmouse_button_middle::focus_ = nullptr;
789  }
790 
791  if(tmouse_button_right::last_clicked_widget_ == &widget) {
792  tmouse_button_right::last_clicked_widget_ = nullptr;
793  }
794  if(tmouse_button_right::focus_ == &widget) {
795  tmouse_button_right::focus_ = nullptr;
796  }
797 
798  if(mouse_focus_ == &widget) {
799  mouse_focus_ = nullptr;
800  }
801 
802  if(keyboard_focus_ == &widget) {
803  keyboard_focus_ = nullptr;
804  }
807  keyboard_focus_chain_.end(),
808  &widget);
809  if(itor != keyboard_focus_chain_.end()) {
810  keyboard_focus_chain_.erase(itor);
811  }
812 }
813 
814 } // namespace event
815 
816 } // namespace gui2
Define the common log macros for the gui toolkit.
#define ERR_GUI_E
Definition: log.hpp:38
Widget loses keyboard focus.
Definition: handler.hpp:144
twidget & owner_
The widget that owns us.
Definition: distributor.hpp:85
void stop_hover_timer()
Stops the current hover timer.
void capture_mouse(const bool capture=true)
Captures the mouse input.
bool mouse_captured_
Did the current widget capture the focus_?
Definition: distributor.hpp:82
#define SDLMod
Definition: compat.hpp:30
A mouse leave event for a widget.
Definition: handler.hpp:70
unsigned double_click_time
Definition: settings.cpp:55
void start_hover_timer(twidget *widget, const tpoint &coordinate)
Starts the hover timer.
A mouse enter event for a widget.
Definition: handler.hpp:66
void show_tooltip()
Called when the mouse wants the widget to show its tooltip.
void signal_handler_sdl_wheel(const event::tevent event, bool &handled, const tpoint &coordinate)
Widget gets keyboard focus.
Definition: handler.hpp:142
boost::enable_if< boost::mpl::has_key< tset_event, boost::mpl::int_< E > > >::type disconnect_signal(const tsignal_function &signal, const tposition position=back_child)
Disconnect a signal for callback in tset_event.
Definition: dispatcher.hpp:297
This file contains the window object, this object is a top level container which has the event manage...
SDL_AddTimer() callback for the hover event.
Definition: distributor.cpp:88
bool remove_timer(const size_t id)
Removes a timer.
Definition: timer.cpp:144
Contains the event distributor.
Base class for event handling.
Definition: dispatcher.hpp:122
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
boost::enable_if< boost::mpl::has_key< tset_event, boost::mpl::int_< E > > >::type connect_signal(const tsignal_function &signal, const tposition position=back_child)
Connect a signal for callback in tset_event.
Definition: dispatcher.hpp:278
Request the widget to show its hover helptip.
Definition: handler.hpp:165
#define SDLKey
Definition: compat.hpp:29
void keyboard_add_to_chain(twidget *widget)
Adds the widget to the keyboard chain.
void signal_handler_sdl_key_down(const SDLKey key, const SDLMod modifier, const utf8::string &unicode)
Set of functions that handle certain events and sends them to the proper widget.
void signal_handler_sdl_button_up(const event::tevent event, bool &handled, const tpoint &coordinate)
std::vector< twidget * > keyboard_focus_chain_
Fall back keyboard focus_ items.
void signal_handler_show_helptip(const event::tevent event, bool &handled, const tpoint &coordinate)
A SDL mouse motion event.
Definition: handler.hpp:64
void init_mouse_location()
Initializes the location of the mouse.
Definition: handler.cpp:788
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
twidget * parent()
Definition: widget.cpp:155
void initialize_state()
Initializes the state of the keyboard and mouse.
A SDL wheel right event.
Definition: handler.hpp:120
twidget * mouse_focus_
The widget that currently has the mouse focus_.
Definition: distributor.hpp:79
This file contains the settings handling of the widget library.
bool fire(const tevent event, twidget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:144
int y
y coordinate.
Definition: point.hpp:34
tpoint hover_position_
The anchor point of the hover event.
Definition: distributor.hpp:94
size_t hover_timer_
The timer for the hover event.
Definition: distributor.hpp:88
tposition
The position where to add a new callback in the signal handler.
Definition: dispatcher.hpp:249
tpoint get_mouse_position()
Returns the current mouse position.
Definition: helper.cpp:149
A SDL wheel left event.
Definition: handler.hpp:118
A mouse motion event for a widget.
Definition: handler.hpp:68
A SDL wheel up event.
Definition: handler.hpp:122
GLenum GLint GLuint mask
Definition: glew.h:1813
void signal_handler_sdl_mouse_motion(const event::tevent event, bool &handled, const tpoint &coordinate)
tevent
The event send to the dispatcher.
Definition: handler.hpp:54
bool wants_mouse_hover() const
int x
x coordinate.
Definition: point.hpp:31
Request the widget to show its hover tooltip.
Definition: handler.hpp:146
void keyboard_capture(twidget *widget)
Captures the keyboard input.
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
#define DBG_GUI_E
Definition: log.hpp:35
bool hover_shown_
Has the hover been shown for the widget?
#define WRN_GUI_E
Definition: log.hpp:37
void mouse_enter(twidget *mouse_over)
Called when the mouse enters a widget.
const std::string & id() const
Definition: widget.cpp:109
Contains the gui2 timer routines.
Holds a 2D point.
Definition: point.hpp:24
void keyboard_remove_from_chain(twidget *widget)
Remove the widget from the keyboard chain.
void signal_handler_sdl_button_down(const event::tevent event, bool &handled, const tpoint &coordinate)
#define HOVER_REMOVE_POPUP_EVENT
Definition: events.hpp:25
void mouse_leave()
Called when the mouse leaves the current widget.
Send by a widget to notify others it's being destroyed.
Definition: handler.hpp:128
virtual twidget * find_at(const tpoint &coordinate, const bool must_be_active)
Returns the widget at the wanted coordinates.
Definition: widget.cpp:547
Request the widget to show its hover tooltip.
Definition: handler.hpp:151
Base class for all visible items.
Definition: control.hpp:34
twidget * hover_widget_
The widget which should get the hover event.
Definition: distributor.hpp:91
A SDL wheel down event.
Definition: handler.hpp:124
twidget * keyboard_focus_
The widget that holds the keyboard focus_.
bool find(E event, F functor)
Tests whether an event handler is available.
cl_event event
Definition: glew.h:3070
#define LOG_HEADER
Base class for all widgets.
Definition: widget.hpp:49
CALLABLE_WRAPPER_INPUT_END if(key=="terrain")
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
tdistributor(twidget &owner, const tdispatcher::tposition queue_position)
virtual bool get_active() const =0
Gets the active state of the control.
void signal_handler_notify_removal(tdispatcher &widget, const tevent event)
size_t add_timer(const Uint32 interval, const std::function< void(size_t id)> &callback, const bool repeat)
Adds a new timer.
Definition: timer.cpp:112
void mouse_motion(twidget *mouse_over, const tpoint &coordinate)
Called when the mouse moves over a widget.
A SDL key down event.
Definition: handler.hpp:126
GLsizei const GLcharARB ** string
Definition: glew.h:4503
tlock(bool &locked)
Definition: distributor.cpp:91
std::string string
virtual bool can_mouse_focus() const
Whether the mouse move/click event go 'through' this widget.
Definition: widget.hpp:349
tmouse_motion(twidget &owner, const tdispatcher::tposition queue_position)