44 #define ERR_GEN LOG_STREAM(err, lg::general)
47 #define LOG_DP LOG_STREAM(info, log_display)
50 #define LOG_EV LOG_STREAM(info, log_event)
51 #define DBG_EV LOG_STREAM(debug, log_event)
55 struct invoked_function_data
57 explicit invoked_function_data(
const std::function<
void(
void)>& func)
64 const std::function<void(
void)>&
f;
67 std::promise<void> finished;
78 finished.set_exception(std::current_exception());
108 static int depth = 0;
172 while(current != last) {
173 if(current !=
handlers.end() && (*current)->requires_event_focus()) {
189 if(
i !=
handlers.end() && (*i)->requires_event_focus()) {
203 if(
h->has_joined()) {
204 h->has_joined_ =
false;
207 if(
h->has_joined_global()) {
208 h->has_joined_global_ =
false;
245 , has_joined_global_(false)
255 : has_joined_(that.has_joined_)
256 , has_joined_global_(that.has_joined_global_)
262 bool found_context =
false;
265 found_context =
true;
271 if (!found_context) {
272 throw std::logic_error(
"Copy-constructing a sdl_handler that has_joined_ but can't be found by searching contexts");
357 if(members.empty()) {
361 for(
auto member : members) {
390 member->join_global();
397 member->leave_global();
427 if(foc == handlers.end()) {
433 if(foc_hand == hand) {
438 for(
auto i = handlers.rbegin();
i != handlers.rend(); ++
i) {
446 handlers.splice(handlers.end(), handlers, foc);
448 return thief_hand == hand;
460 handler->handle_window_event(event);
465 global_handler->handle_window_event(event);
486 SDL_Event temp_event;
488 int begin_ignoring = 0;
490 std::vector<SDL_Event>
events;
491 while(SDL_PollEvent(&temp_event)) {
493 static_cast<invoked_function_data*
>(temp_event.user.data1)->call();
499 if(!begin_ignoring && temp_event.type == SDL_WINDOWEVENT && (
500 temp_event.window.event == SDL_WINDOWEVENT_ENTER ||
501 temp_event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
503 begin_ignoring = poll_count;
504 }
else if(begin_ignoring > 0 &&
is_input(temp_event)) {
509 events.push_back(temp_event);
512 auto ev_it =
events.begin();
513 for(
int i = 1;
i < begin_ignoring; ++
i) {
516 ev_it =
events.erase(ev_it);
522 for(SDL_Event& event :
events) {
524 c.add_staging_handlers();
527 #ifdef MOUSE_TOUCH_EMULATION
528 switch (event.type) {
530 case SDL_MOUSEMOTION:
531 if(event.motion.which != SDL_TOUCH_MOUSEID && event.motion.state == 0) {
535 if(event.motion.state & SDL_BUTTON(SDL_BUTTON_RIGHT))
541 SDL_Event touch_event;
542 touch_event.type = SDL_FINGERMOTION;
543 touch_event.tfinger.type = SDL_FINGERMOTION;
544 touch_event.tfinger.timestamp =
event.motion.timestamp;
545 touch_event.tfinger.touchId = 1;
546 touch_event.tfinger.fingerId = 1;
547 touch_event.tfinger.dx =
static_cast<float>(
event.motion.xrel) /
c.x;
548 touch_event.tfinger.dy =
static_cast<float>(event.motion.yrel) /
c.y;
549 touch_event.tfinger.x =
static_cast<float>(
event.motion.x) /
c.x;
550 touch_event.tfinger.y =
static_cast<float>(event.motion.y) /
c.y;
551 touch_event.tfinger.pressure = 1;
552 ::SDL_PushEvent(&touch_event);
554 event.motion.state = SDL_BUTTON(SDL_BUTTON_LEFT);
555 event.motion.which = SDL_TOUCH_MOUSEID;
558 case SDL_MOUSEBUTTONDOWN:
559 case SDL_MOUSEBUTTONUP:
560 if(event.button.button == SDL_BUTTON_RIGHT)
562 event.button.button = SDL_BUTTON_LEFT;
563 event.button.which = SDL_TOUCH_MOUSEID;
568 SDL_Event touch_event;
569 touch_event.type = (
event.type == SDL_MOUSEBUTTONDOWN) ? SDL_FINGERDOWN : SDL_FINGERUP;
570 touch_event.tfinger.type = touch_event.type;
571 touch_event.tfinger.timestamp =
event.button.timestamp;
572 touch_event.tfinger.touchId = 1;
573 touch_event.tfinger.fingerId = 1;
574 touch_event.tfinger.dx = 0;
575 touch_event.tfinger.dy = 0;
576 touch_event.tfinger.x =
static_cast<float>(
event.button.x) /
c.x;
577 touch_event.tfinger.y =
static_cast<float>(event.button.y) /
c.y;
578 touch_event.tfinger.pressure = 1;
579 ::SDL_PushEvent(&touch_event);
589 case SDL_WINDOWEVENT:
590 switch(event.window.event) {
591 case SDL_WINDOWEVENT_ENTER:
592 case SDL_WINDOWEVENT_FOCUS_GAINED:
596 case SDL_WINDOWEVENT_LEAVE:
597 case SDL_WINDOWEVENT_FOCUS_LOST:
603 case SDL_WINDOWEVENT_SIZE_CHANGED:
604 LOG_DP <<
"events/SIZE_CHANGED "
605 <<
event.window.data1 <<
'x' <<
event.window.data2;
612 case SDL_WINDOWEVENT_RESIZED:
613 LOG_DP <<
"events/RESIZED "
614 <<
event.window.data1 <<
'x' <<
event.window.data2;
620 case SDL_WINDOWEVENT_EXPOSED:
621 LOG_DP <<
"events/EXPOSED";
625 case SDL_WINDOWEVENT_MAXIMIZED:
626 LOG_DP <<
"events/MAXIMIZED";
629 case SDL_WINDOWEVENT_RESTORED:
630 LOG_DP <<
"events/RESTORED";
633 case SDL_WINDOWEVENT_SHOWN:
634 case SDL_WINDOWEVENT_MOVED:
644 case SDL_MOUSEMOTION: {
651 case SDL_MOUSEBUTTONDOWN: {
654 if(event.button.button == SDL_BUTTON_LEFT || event.button.which == SDL_TOUCH_MOUSEID) {
655 if(event.button.clicks == 2) {
657 ::SDL_PushEvent(
reinterpret_cast<SDL_Event*
>(&user_event));
665 if(event.key.keysym.sym == SDLK_F4 &&
666 (event.key.keysym.mod == KMOD_RALT || event.key.keysym.mod == KMOD_LALT)
676 case SDL_SYSWMEVENT: {
689 global_handler->handle_event(event);
698 size_t h_size =
h.size();
699 for(
auto it =
h.begin(); it !=
h.end(); ++it) {
701 (*it)->handle_event(event);
704 LOG_EV <<
"ec size changed! bugging out";
707 if(h_size !=
h.size()) {
708 LOG_EV <<
"h size changed! bugging out";
732 handler->process_event();
741 event.window.type = SDL_WINDOWEVENT;
742 event.window.event = SDL_WINDOWEVENT_SIZE_CHANGED;
743 event.window.windowID = 0;
744 event.window.data1 =
size.x;
745 event.window.data2 =
size.y;
754 handler->process_tooltip_string(mousex, mousey);
760 #define INPUT_MIN 0x300
761 #define INPUT_MAX 0x8FF
781 invoked_function_data fdata{
f};
787 sdl_event.user = sdl_userevent;
789 SDL_PushEvent(&sdl_event);
792 fdata.finished.get_future().wait();
void set_focus(const sdl_handler *ptr)
bool has_handler(const sdl_handler *ptr) const
Returns true if ptr is found in either the handlers or staging_handlers lists.
handler_list::iterator focused_handler
std::vector< sdl_handler * > staging_handlers
void add_handler(sdl_handler *ptr)
bool remove_handler(sdl_handler *ptr)
void add_staging_handlers()
virtual bool requires_event_focus(const SDL_Event *=nullptr) const
virtual std::vector< sdl_handler * > handler_members()
virtual void join_global()
virtual void join_same(sdl_handler *parent)
virtual void leave_global()
sdl_handler & operator=(sdl_handler &&)=delete
Moving would require two instances' context membership to be handled, it's simpler to delete these an...
sdl_handler(sdl_handler &&)=delete
void set_resolution(const point &res)
static void quit_to_desktop()
Type that can be thrown as an exception to quit to desktop.
static void handle_system_event(const SDL_Event &event)
Frees resources when a notification disappears, switches user to the wesnoth window if the notificati...
static lg::log_domain log_display("display")
static lg::log_domain log_event("event")
#define INVOKE_FUNCTION_EVENT
#define DOUBLE_CLICK_EVENT
std::vector< events::sdl_handler * > sdl_handler_vector
std::string id
Text to match against addon_info.tags()
Standard logging facilities (interface).
void set_focus(bool focus)
void invalidate_all()
Mark the entire screen as requiring redraw.
void sparkle()
Ensure that everything which needs to be drawn is drawn.
Handling of system events.
void raise_resize_event()
bool has_focus(const sdl_handler *hand, const SDL_Event *event)
void discard_input()
Discards all input events.
void draw()
Trigger a draw cycle.
static void raise_window_event(const SDL_Event &event)
bool is_input(const SDL_Event &event)
Is the event an input event?
std::deque< context > event_contexts
std::vector< pump_monitor * > pump_monitors
void call_in_main_thread(const std::function< void(void)> &f)
void raise_process_event()
void process_tooltip_strings(int mousex, int mousey)
Triggered by mouse-motion, sends the cursor position to all handlers to check whether a tooltip shoul...
std::list< sdl_handler * > handler_list
static const std::thread::id main_thread
void pump()
Process all events currently in the queue.
void focus_handler(const sdl_handler *ptr)
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
auto reversed_view(T &container)
std::size_t erase(Container &container, const Value &value)
Convenience wrapper for using std::remove on a container.
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
point game_canvas_size()
The size of the game canvas, in drawing coordinates / game pixels.
point window_size()
Returns the size of the window in display units / screen coordinates.
void update_buffers(bool autoupdate)
Update buffers to match current resolution and pixel scale settings.
std::string::const_iterator iterator