The Battle for Wesnoth  1.13.10+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 - 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 #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"
26 #include "sdl/userevent.hpp"
27 
28 #include "utils/functional.hpp"
29 
30 namespace gui2
31 {
32 
33 namespace event
34 {
35 
36 /**
37  * SDL_AddTimer() callback for the hover event.
38  *
39  * When this callback is called it pushes a new hover event in the event queue.
40  *
41  * @param interval The time parameter of SDL_AddTimer.
42  * @param param Pointer to a widget that's able to show the
43  * tooltip (will be used as a dispatcher).
44  *
45  * @returns The new timer interval, 0 to stop.
46  */
47 
48 #if 0
49 /**
50  * SDL_AddTimer() callback for the popup event.
51  *
52  * This event makes sure the popup is removed again.
53  *
54  * @param interval The time parameter of SDL_AddTimer.
55  * @param param Pointer to parameter structure.
56  *
57  * @returns The new timer interval, 0 to stop.
58  */
59 static Uint32 popup_callback(Uint32 /*interval*/, void* /*param*/)
60 {
61  DBG_GUI_E << "Pushing popup removal event in queue.\n";
62 
63  SDL_Event event;
65 
66  event.type = HOVER_REMOVE_POPUP_EVENT;
67  event.user = data;
68 
69  SDL_PushEvent(&event);
70  return 0;
71 }
72 #endif
73 
74 /**
75  * Small helper to keep a resource (boolean) locked.
76  *
77  * Some of the event handling routines can't be called recursively, this due to
78  * the fact that they are attached to the pre queue and when the forward an
79  * event the pre queue event gets triggered recursively causing infinite
80  * recursion.
81  *
82  * To prevent that those functions check the lock and exit when the lock is
83  * held otherwise grab the lock here.
84  */
86 {
87 public:
88  resource_locker(bool& locked) : locked_(locked)
89  {
90  assert(!locked_);
91  locked_ = true;
92  }
93 
95  {
96  assert(locked_);
97  locked_ = false;
98  }
99 
100 private:
101  bool& locked_;
102 };
103 
104 
105 /***** ***** ***** ***** mouse_motion ***** ***** ***** ***** *****/
106 
107 #define LOG_HEADER "distributor mouse motion [" << owner_.id() << "]: "
108 
110  const dispatcher::queue_position queue_position)
111  : mouse_focus_(nullptr)
112  , mouse_captured_(false)
113  , owner_(owner)
114  , hover_timer_(0)
115  , hover_widget_(nullptr)
116  , hover_position_(0, 0)
117  , hover_shown_(true)
118  , signal_handler_sdl_mouse_motion_entered_(false)
119 {
122  this,
123  _2,
124  _3,
125  _5),
126  queue_position);
127 
129  &mouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
131  &mouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
133  &mouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
135  &mouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
136 
139  this,
140  _2,
141  _3,
142  _5),
143  queue_position);
144 }
145 
147 {
149 }
150 
151 void mouse_motion::capture_mouse(const bool capture)
152 {
153  assert(mouse_focus_);
154  mouse_captured_ = capture;
155 }
156 
158  bool& handled,
159  const point& coordinate)
160 {
162  return;
163  }
165 
166  DBG_GUI_E << LOG_HEADER << event << ".\n";
167 
168  if(mouse_captured_) {
169  assert(mouse_focus_);
170  if(!owner_.fire(event, *mouse_focus_, coordinate)) {
171  mouse_hover(mouse_focus_, coordinate);
172  }
173  } else {
174  widget* mouse_over = owner_.find_at(coordinate, true);
175  while(mouse_over && !mouse_over->can_mouse_focus() && mouse_over->parent()) {
176  mouse_over = mouse_over->parent();
177  }
178  if(mouse_over) {
179  DBG_GUI_E << LOG_HEADER << "Firing: " << event << ".\n";
180  if(owner_.fire(event, *mouse_over, coordinate)) {
181  return;
182  }
183  }
184 
185  if(!mouse_focus_ && mouse_over) {
186  mouse_enter(mouse_over);
187  } else if(mouse_focus_ && !mouse_over) {
188  mouse_leave();
189  } else if(mouse_focus_ && mouse_focus_ == mouse_over) {
190  mouse_hover(mouse_over, coordinate);
191  } else if(mouse_focus_ && mouse_over) {
192  // moved from one widget to the next
193  mouse_leave();
194  mouse_enter(mouse_over);
195  } else {
196  assert(!mouse_focus_ && !mouse_over);
197  }
198  }
199  handled = true;
200 }
201 
203  bool& handled,
204  const point& coordinate)
205 {
206  DBG_GUI_E << LOG_HEADER << event << ".\n";
207 
208  if(mouse_captured_) {
209  assert(mouse_focus_);
210  owner_.fire(event, *mouse_focus_, coordinate);
211  } else {
212  widget* mouse_over = owner_.find_at(coordinate, true);
213  if(mouse_over) {
214  owner_.fire(event, *mouse_over, coordinate);
215  }
216  }
217  handled = true;
218 }
219 
221  bool& handled,
222  const point& coordinate)
223 {
224  DBG_GUI_E << LOG_HEADER << event << ".\n";
225 
226  if(mouse_captured_) {
227  assert(mouse_focus_);
228  if(owner_.fire(event, *mouse_focus_, coordinate)) {
230  }
231  } else {
232  widget* mouse_over = owner_.find_at(coordinate, true);
233  if(mouse_over) {
234  DBG_GUI_E << LOG_HEADER << "Firing: " << event << ".\n";
235  if(owner_.fire(event, *mouse_over, coordinate)) {
237  }
238  }
239  }
240 
241  handled = true;
242 }
243 
245 {
246  DBG_GUI_E << LOG_HEADER << "Firing: " << event::MOUSE_ENTER << ".\n";
247 
248  assert(mouse_over);
249 
250  mouse_focus_ = mouse_over;
251  owner_.fire(event::MOUSE_ENTER, *mouse_over);
252 
253  hover_shown_ = false;
254  start_hover_timer(mouse_over, get_mouse_position());
255 }
256 
258 {
259  DBG_GUI_E << LOG_HEADER << "Firing: " << event::MOUSE_MOTION << ".\n";
260 
261  assert(mouse_over);
262 
263  owner_.fire(event::MOUSE_MOTION, *mouse_over, coordinate);
264 
265  if(hover_timer_) {
266  if((std::abs(hover_position_.x - coordinate.x) > 5)
267  || (std::abs(hover_position_.y - coordinate.y) > 5)) {
268 
270  start_hover_timer(mouse_over, coordinate);
271  }
272  }
273 }
274 
276 {
277  DBG_GUI_E << LOG_HEADER << "Firing: " << event::SHOW_TOOLTIP << ".\n";
278 
279  if(!hover_widget_) {
280  // See mouse_motion::stop_hover_timer.
281  ERR_GUI_E << LOG_HEADER << event::SHOW_TOOLTIP
282  << " bailing out, no hover widget.\n";
283  return;
284  }
285 
286  /*
287  * Ignore the result of the event, always mark the tooltip as shown. If
288  * there was no handler, there is no reason to assume there will be one
289  * next time.
290  */
292 
293  hover_shown_ = true;
294 
295  hover_timer_ = 0;
296  hover_widget_ = nullptr;
298 }
299 
301 {
302  DBG_GUI_E << LOG_HEADER << "Firing: " << event::MOUSE_LEAVE << ".\n";
303 
304  styled_widget* control = dynamic_cast<styled_widget*>(mouse_focus_);
305  if(!control || control->get_active()) {
306  owner_.fire(event::MOUSE_LEAVE, *mouse_focus_);
307  }
308 
310 
311  mouse_focus_ = nullptr;
312 
314 }
315 
317 {
318  assert(widget);
320 
321  if(hover_shown_ || !widget->wants_mouse_hover()) {
322  return;
323  }
324 
325  DBG_GUI_E << LOG_HEADER << "Start hover timer for widget '" << widget->id()
326  << "' at address " << widget << ".\n";
327 
329  = add_timer(50, std::bind(&mouse_motion::show_tooltip, this));
330 
331  if(hover_timer_) {
332  hover_widget_ = widget;
334  } else {
335  ERR_GUI_E << LOG_HEADER << "Failed to add hover timer." << std::endl;
336  }
337 }
338 
340 {
341  if(hover_timer_) {
342  assert(hover_widget_);
343  DBG_GUI_E << LOG_HEADER << "Stop hover timer for widget '"
344  << hover_widget_->id() << "' at address " << hover_widget_
345  << ".\n";
346 
347  if(!remove_timer(hover_timer_)) {
348  ERR_GUI_E << LOG_HEADER << "Failed to remove hover timer."
349  << std::endl;
350  }
351 
352  hover_timer_ = 0;
353  hover_widget_ = nullptr;
355  }
356 }
357 
358 /***** ***** ***** ***** mouse_button ***** ***** ***** ***** *****/
359 
360 #undef LOG_HEADER
361 #define LOG_HEADER \
362  "distributor mouse button " << name_ << " [" << owner_.id() << "]: "
363 
364 template<typename T>
366  const dispatcher::queue_position queue_position)
367  : mouse_motion(owner, queue_position)
368  , last_click_stamp_(0)
369  , last_clicked_widget_(nullptr)
370  , focus_(nullptr)
371  , name_(name_)
372  , is_down_(false)
373  , signal_handler_sdl_button_down_entered_(false)
374  , signal_handler_sdl_button_up_entered_(false)
375 {
376  owner_.connect_signal<T::sdl_button_down_event>(
378  this,
379  _2,
380  _3,
381  _5),
382  queue_position);
383  owner_.connect_signal<T::sdl_button_up_event>(
385  this,
386  _2,
387  _3,
388  _5),
389  queue_position);
390 }
391 
392 template<typename T>
393 void mouse_button<T>::initialize_state(const bool is_down)
394 {
395  last_click_stamp_ = 0;
396  last_clicked_widget_ = nullptr;
397  focus_ = 0;
398  is_down_ = is_down;
399 }
400 
401 template<typename T>
403  const point& coordinate)
404 {
405  if(signal_handler_sdl_button_down_entered_) {
406  return;
407  }
408  resource_locker lock(signal_handler_sdl_button_down_entered_);
409 
410  DBG_GUI_E << LOG_HEADER << event << ".\n";
411 
412  if(is_down_) {
413 #ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
414  WRN_GUI_E << LOG_HEADER << event
415  << ". The mouse button is already down, "
416  << "we missed an event.\n";
417 #endif
418  return;
419  }
420  is_down_ = true;
421 
422  if(mouse_captured_) {
423  assert(mouse_focus_);
424  focus_ = mouse_focus_;
425  DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_down_event << ".\n";
426  if(!owner_.fire(T::sdl_button_down_event, *focus_, coordinate)) {
427  DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_down_event << ".\n";
428  owner_.fire(T::button_down_event, *mouse_focus_);
429  }
430  } else {
431  widget* mouse_over = owner_.find_at(coordinate, true);
432  if(!mouse_over) {
433  return;
434  }
435 
436  if(mouse_over != mouse_focus_) {
437 #ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
438  WRN_GUI_E << LOG_HEADER << ". Mouse down on non focused widget "
439  << "and mouse not captured, we missed events.\n";
440 #endif
441  mouse_focus_ = mouse_over;
442  }
443 
444  focus_ = mouse_over;
445  DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_down_event << ".\n";
446  if(!owner_.fire(T::sdl_button_down_event, *focus_, coordinate)) {
447  DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_down_event << ".\n";
448  owner_.fire(T::button_down_event, *focus_);
449  }
450  }
451  handled = true;
452 }
453 
454 template<typename T>
456  const point& coordinate)
457 {
458  if(signal_handler_sdl_button_up_entered_) {
459  return;
460  }
461  resource_locker lock(signal_handler_sdl_button_up_entered_);
462 
463  DBG_GUI_E << LOG_HEADER << event << ".\n";
464 
465  if(!is_down_) {
466  WRN_GUI_E << LOG_HEADER << event
467  << ". The mouse button is already up, we missed an event.\n";
468  return;
469  }
470  is_down_ = false;
471 
472  if(focus_) {
473  DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_up_event << ".\n";
474  if(!owner_.fire(T::sdl_button_up_event, *focus_, coordinate)) {
475  DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_up_event << ".\n";
476  owner_.fire(T::button_up_event, *focus_);
477  }
478  }
479 
480  widget* mouse_over = owner_.find_at(coordinate, true);
481  if(mouse_captured_) {
482  const unsigned mask = SDL_BUTTON_LMASK | SDL_BUTTON_MMASK
483  | SDL_BUTTON_RMASK;
484 
485  if((SDL_GetMouseState(nullptr, nullptr) & mask) == 0) {
486  mouse_captured_ = false;
487  }
488 
489  if(mouse_focus_ == mouse_over) {
490  mouse_button_click(mouse_focus_);
491  } else if(!mouse_captured_) {
492  mouse_leave();
493 
494  if(mouse_over) {
495  mouse_enter(mouse_over);
496  }
497  }
498  } else if(focus_ && focus_ == mouse_over) {
499  mouse_button_click(focus_);
500  }
501 
502  focus_ = nullptr;
503  handled = true;
504 }
505 
506 template<typename T>
508 {
509  Uint32 stamp = SDL_GetTicks();
510  if(last_click_stamp_ + settings::double_click_time >= stamp
511  && last_clicked_widget_ == widget) {
512 
513  DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_double_click_event << ".\n";
514 
515  owner_.fire(T::button_double_click_event, *widget);
516  last_click_stamp_ = 0;
517  last_clicked_widget_ = nullptr;
518 
519  } else {
520 
521  DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_click_event << ".\n";
522  owner_.fire(T::button_click_event, *widget);
523  last_click_stamp_ = stamp;
524  last_clicked_widget_ = widget;
525  }
526 }
527 
528 /***** ***** ***** ***** distributor ***** ***** ***** ***** *****/
529 
530 #undef LOG_HEADER
531 #define LOG_HEADER "distributor mouse motion [" << owner_.id() << "]: "
532 
533 /**
534  * @todo Test whether the state is properly tracked when an input blocker is
535  * used.
536  */
538  const dispatcher::queue_position queue_position)
539  : mouse_motion(owner, queue_position)
540  , mouse_button_left("left", owner, queue_position)
541  , mouse_button_middle("middle", owner, queue_position)
542  , mouse_button_right("right", owner, queue_position)
543 #if 0
544  , hover_pending_(false)
545  , hover_id_(0)
546  , hover_box_()
547  , had_hover_(false)
548  , tooltip_(nullptr)
549  , help_popup_(nullptr)
550 #endif
551  , keyboard_focus_(nullptr)
552  , keyboard_focus_chain_()
553 {
554  if(SDL_WasInit(SDL_INIT_TIMER) == 0) {
555  if(SDL_InitSubSystem(SDL_INIT_TIMER) == -1) {
556  assert(false);
557  }
558  }
559 
561  &distributor::signal_handler_sdl_key_down, this, _5, _6, _7));
562 
564  &distributor::signal_handler_sdl_text_input, this, _5, _6, _7));
565 
568 
571 
573 }
574 
576 {
578  &distributor::signal_handler_sdl_key_down, this, _5, _6, _7));
579 
581  &distributor::signal_handler_sdl_text_input, this, _5, _6, _7));
582 
585 
588 }
589 
591 {
592  const Uint8 button_state = SDL_GetMouseState(nullptr, nullptr);
593 
594  mouse_button_left::initialize_state((button_state & SDL_BUTTON(1)) != 0);
595  mouse_button_middle::initialize_state((button_state & SDL_BUTTON(2)) != 0);
596  mouse_button_right::initialize_state((button_state & SDL_BUTTON(3)) != 0);
597 
599 }
600 
602 {
603  return keyboard_focus_;
604 }
605 
607 {
608  if(keyboard_focus_) {
610  << ".\n";
611 
612  owner_.fire(event::LOSE_KEYBOARD_FOCUS, *keyboard_focus_, nullptr);
613  }
614 
615  keyboard_focus_ = widget;
616 
617  if(keyboard_focus_) {
619  << ".\n";
620 
621  owner_.fire(event::RECEIVE_KEYBOARD_FOCUS, *keyboard_focus_, nullptr);
622  }
623 }
624 
626 {
627  assert(widget);
628  assert(std::find(keyboard_focus_chain_.begin(),
629  keyboard_focus_chain_.end(),
630  widget) == keyboard_focus_chain_.end());
631 
632  keyboard_focus_chain_.push_back(widget);
633 }
634 
636 {
637  assert(w);
640 
641  if(itor != keyboard_focus_chain_.end()) {
642  keyboard_focus_chain_.erase(itor);
643  }
644 }
645 
646 template<typename Fcn, typename P1, typename P2, typename P3>
648 {
649  /** @todo Test whether recursion protection is needed. */
650 
651  DBG_GUI_E << LOG_HEADER << evt << ".\n";
652 
653  if(keyboard_focus_) {
654  // Attempt to cast to styled_widget, to avoid sending events if the
655  // widget is disabled. If the cast fails, we assume the widget
656  // is enabled and ready to receive events.
657  styled_widget* control = dynamic_cast<styled_widget*>(keyboard_focus_);
658  if(!control || control->get_active()) {
659  DBG_GUI_E << LOG_HEADER << "Firing: " << evt
660  << ".\n";
661  if(owner_.fire(evt, *keyboard_focus_, p1, p2, p3)) {
662  return;
663  }
664  }
665  if(text_box_base* tb = dynamic_cast<text_box_base*>(keyboard_focus_)) {
666  if(tb->is_composing()) {
667  return; // Skip the keyboard chain if composition is in progress.
668  }
669  }
670  }
671 
672  for(std::vector<widget*>::reverse_iterator ritor
673  = keyboard_focus_chain_.rbegin();
674  ritor != keyboard_focus_chain_.rend();
675  ++ritor) {
676 
677  if(*ritor == keyboard_focus_) {
678  continue;
679  }
680 
681  if(*ritor == &owner_) {
682  /**
683  * @todo Make sure we're not in the event chain.
684  *
685  * No idea why we're here, but needs to be fixed, otherwise we keep
686  * calling this function recursively upon unhandled events...
687  *
688  * Probably added to make sure the window can grab the events and
689  * handle + block them when needed, this is no longer needed with
690  * the chain.
691  */
692  continue;
693  }
694 
695  // Attempt to cast to styled_widget, to avoid sending events if the
696  // widget is disabled. If the cast fails, we assume the widget
697  // is enabled and ready to receive events.
698  styled_widget* control = dynamic_cast<styled_widget*>(keyboard_focus_);
699  if(control != nullptr && !control->get_active()) {
700  continue;
701  }
702 
703  DBG_GUI_E << LOG_HEADER << "Firing: " << evt << ".\n";
704  if(owner_.fire(evt, **ritor, p1, p2, p3)) {
705 
706  return;
707  }
708  }
709 }
710 
711 void distributor::signal_handler_sdl_key_down(const SDL_Keycode key, const SDL_Keymod modifier, const utf8::string& unicode)
712 {
713  signal_handler_keyboard_internal<signal_keyboard_function>(event::SDL_KEY_DOWN, key, modifier, unicode);
714 }
715 
716 void distributor::signal_handler_sdl_text_input(const utf8::string& unicode, int32_t start, int32_t end)
717 {
718  signal_handler_keyboard_internal<signal_text_input_function>(event::SDL_TEXT_INPUT, unicode, start, end);
719 }
720 
721 void distributor::signal_handler_sdl_text_editing(const utf8::string& unicode, int32_t start, int32_t end)
722 {
723  signal_handler_keyboard_internal<signal_text_input_function>(event::SDL_TEXT_EDITING, unicode, start, end);
724 }
725 
727  const ui_event event)
728 {
729  DBG_GUI_E << LOG_HEADER << event << ".\n";
730 
731  /**
732  * @todo Evaluate whether moving the cleanup parts in the subclasses.
733  *
734  * It might be cleaner to do it that way, but creates extra small
735  * functions...
736  */
737 
738  if(hover_widget_ == &w) {
740  }
741 
744  }
745  if(mouse_button_left::focus_ == &w) {
746  mouse_button_left::focus_ = nullptr;
747  }
748 
751  }
752  if(mouse_button_middle::focus_ == &w) {
753  mouse_button_middle::focus_ = nullptr;
754  }
755 
758  }
759  if(mouse_button_right::focus_ == &w) {
760  mouse_button_right::focus_ = nullptr;
761  }
762 
763  if(mouse_focus_ == &w) {
764  mouse_focus_ = nullptr;
765  }
766 
767  if(keyboard_focus_ == &w) {
768  keyboard_focus_ = nullptr;
769  }
772  keyboard_focus_chain_.end(),
773  &w);
774  if(itor != keyboard_focus_chain_.end()) {
775  keyboard_focus_chain_.erase(itor);
776  }
777 }
778 
779 } // namespace event
780 
781 } // namespace gui2
Define the common log macros for the gui toolkit.
#define ERR_GUI_E
Definition: log.hpp:37
Request the widget to show its hover helptip.
Definition: handler.hpp:113
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?
An SDL text editing (IME) event.
Definition: handler.hpp:93
std::vector< char_t > string
void mouse_button_click(widget *widget)
Abstract base class for text items.
std::vector< widget * > keyboard_focus_chain_
Fall back keyboard focus_ items.
Widget loses keyboard focus.
Definition: handler.hpp:108
unsigned double_click_time
Definition: settings.cpp:50
void signal_handler_sdl_button_down(const event::ui_event event, bool &handled, const point &coordinate)
An SDL wheel right event.
Definition: handler.hpp:88
Base class for event handling.
Definition: dispatcher.hpp:161
void signal_handler_sdl_wheel(const event::ui_event event, bool &handled, const point &coordinate)
virtual bool get_active() const =0
Gets the active state of the styled_widget.
int x
x coordinate.
Definition: point.hpp:34
void signal_handler_sdl_text_input(const utf8::string &unicode, int32_t start, int32_t len)
void keyboard_capture(widget *widget)
Captures the keyboard input.
const std::string & id() const
Definition: widget.cpp:107
This file contains the window object, this object is a top level container which has the event manage...
An SDL key down event.
Definition: handler.hpp:91
Base class for all widgets.
Definition: widget.hpp:48
A mouse leave event for a widget.
Definition: handler.hpp:64
Holds a 2D point.
Definition: point.hpp:23
bool remove_timer(const size_t id)
Removes a timer.
Definition: timer.cpp:143
int y
y coordinate.
Definition: point.hpp:37
Contains the event distributor.
An SDL wheel down event.
Definition: handler.hpp:90
Widget gains keyboard focus.
Definition: handler.hpp:107
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...
Request the widget to show its hover tooltip.
Definition: handler.hpp:110
void mouse_hover(widget *mouse_over, const point &coordinate)
Called when the mouse moves over a widget.
void init_mouse_location()
Initializes the location of the mouse.
Definition: handler.cpp:837
Generic file dialog.
Definition: text.hpp:37
virtual bool can_mouse_focus() const
Whether the mouse move/click event go 'through' this widget.
Definition: widget.hpp:343
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.
Request the widget to remove its hover tooltip.
Definition: handler.hpp:111
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)
SDL_AddTimer() callback for the hover event.
Definition: distributor.cpp:85
This file contains the settings handling of the widget library.
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
widget * keyboard_focus_
The widget that holds the keyboard focus_.
Sent by a widget to notify others it's being destroyed.
Definition: handler.hpp:95
widget * parent()
Definition: widget.cpp:163
if(win_locale=="af") win_locale
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 wheel up event.
Definition: handler.hpp:89
void signal_handler_notify_removal(dispatcher &widget, const ui_event event)
void mouse_enter(widget *mouse_over)
Called when the mouse enters a widget.
#define DBG_GUI_E
Definition: log.hpp:34
void capture_mouse(const bool capture=true)
Captures the mouse input.
An SDL wheel left event.
Definition: handler.hpp:87
widget * mouse_focus_
The widget that currently has the mouse focus_.
Definition: distributor.hpp:78
A mouse motion event for a widget.
Definition: handler.hpp:63
bool wants_mouse_hover() const
#define WRN_GUI_E
Definition: log.hpp:36
A mouse enter event for a widget.
Definition: handler.hpp:62
Contains the gui2 timer routines.
void mouse_leave()
Called when the mouse leaves the current widget.
#define HOVER_REMOVE_POPUP_EVENT
Definition: events.hpp:25
int w
Base class for all visible items.
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.
utils::enable_if_t< has_key< set_event, E >::value > disconnect_signal(const signal_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_event.
Definition: dispatcher.hpp:381
bool mouse_captured_
Did the current widget capture the focus_?
Definition: distributor.hpp:81
point get_mouse_position()
Returns the current mouse position.
Definition: helper.cpp:131
mouse_motion(widget &owner, const dispatcher::queue_position queue_position)
void stop_hover_timer()
Stops the current hover timer.
bool find(E event, F functor)
Tests whether an event handler is available.
void signal_handler_sdl_button_up(const event::ui_event event, bool &handled, const point &coordinate)
#define LOG_HEADER
size_t hover_timer_
The timer for the hover event.
Definition: distributor.hpp:87
utils::enable_if_t< has_key< set_event, E >::value > connect_signal(const signal_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_event.
Definition: dispatcher.hpp:363
void show_tooltip()
Called when the mouse wants the widget to show its tooltip.
An SDL text input (commit) event.
Definition: handler.hpp:92
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.
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:120
widget * hover_widget_
The widget which should get the hover event.
Definition: distributor.hpp:90
virtual widget * find_at(const point &coordinate, const bool must_be_active)
Returns the widget at the wanted coordinates.
Definition: widget.cpp:576
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
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:111
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
void initialize_state()
Initializes the state of the keyboard and mouse.
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
An SDL mouse motion event.
Definition: handler.hpp:61