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());
105 static int depth = 0;
169 while(current != last) {
170 if(current !=
handlers.end() && (*current)->requires_event_focus()) {
186 if(
i !=
handlers.end() && (*i)->requires_event_focus()) {
200 if(
h->has_joined()) {
201 h->has_joined_ =
false;
204 if(
h->has_joined_global()) {
205 h->has_joined_global_ =
false;
242 , has_joined_global_(false)
252 : has_joined_(that.has_joined_)
253 , has_joined_global_(that.has_joined_global_)
259 bool found_context =
false;
262 found_context =
true;
268 if (!found_context) {
269 throw std::logic_error(
"Copy-constructing a sdl_handler that has_joined_ but can't be found by searching contexts");
354 if(members.empty()) {
358 for(
auto member : members) {
387 member->join_global();
394 member->leave_global();
424 if(foc == handlers.end()) {
430 if(foc_hand == hand) {
435 for(
auto i = handlers.rbegin();
i != handlers.rend(); ++
i) {
443 handlers.splice(handlers.end(), handlers, foc);
445 return thief_hand == hand;
457 handler->handle_window_event(event);
462 global_handler->handle_window_event(event);
487 SDL_Event temp_event;
489 int begin_ignoring = 0;
491 std::vector<SDL_Event>
events;
492 while(SDL_PollEvent(&temp_event)) {
494 static_cast<invoked_function_data*
>(temp_event.user.data1)->call();
500 if(!begin_ignoring && temp_event.type == SDL_WINDOWEVENT && (
501 temp_event.window.event == SDL_WINDOWEVENT_ENTER ||
502 temp_event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
504 begin_ignoring = poll_count;
505 }
else if(begin_ignoring > 0 &&
is_input(temp_event)) {
510 events.push_back(temp_event);
513 auto ev_it =
events.begin();
514 for(
int i = 1;
i < begin_ignoring; ++
i) {
517 ev_it =
events.erase(ev_it);
523 for(SDL_Event& event :
events) {
525 c.add_staging_handlers();
528 #ifdef MOUSE_TOUCH_EMULATION
529 switch (event.type) {
531 case SDL_MOUSEMOTION:
536 if(event.motion.state & SDL_BUTTON(SDL_BUTTON_RIGHT))
542 SDL_Event touch_event;
543 touch_event.type = SDL_FINGERMOTION;
544 touch_event.tfinger.type = SDL_FINGERMOTION;
545 touch_event.tfinger.timestamp =
event.motion.timestamp;
546 touch_event.tfinger.touchId = 1;
547 touch_event.tfinger.fingerId = 1;
548 touch_event.tfinger.dx =
static_cast<float>(
event.motion.xrel) /
c.x;
549 touch_event.tfinger.dy =
static_cast<float>(event.motion.yrel) /
c.y;
550 touch_event.tfinger.x =
static_cast<float>(
event.motion.x) /
c.x;
551 touch_event.tfinger.y =
static_cast<float>(event.motion.y) /
c.y;
552 touch_event.tfinger.pressure = 1;
553 ::SDL_PushEvent(&touch_event);
555 event.motion.state = SDL_BUTTON(SDL_BUTTON_LEFT);
556 event.motion.which = SDL_TOUCH_MOUSEID;
559 case SDL_MOUSEBUTTONDOWN:
560 case SDL_MOUSEBUTTONUP:
561 if(event.button.button == SDL_BUTTON_RIGHT)
563 event.button.button = SDL_BUTTON_LEFT;
564 event.button.which = SDL_TOUCH_MOUSEID;
569 SDL_Event touch_event;
570 touch_event.type = (
event.type == SDL_MOUSEBUTTONDOWN) ? SDL_FINGERDOWN : SDL_FINGERUP;
571 touch_event.tfinger.type = touch_event.type;
572 touch_event.tfinger.timestamp =
event.button.timestamp;
573 touch_event.tfinger.touchId = 1;
574 touch_event.tfinger.fingerId = 1;
575 touch_event.tfinger.dx = 0;
576 touch_event.tfinger.dy = 0;
577 touch_event.tfinger.x =
static_cast<float>(
event.button.x) /
c.x;
578 touch_event.tfinger.y =
static_cast<float>(event.button.y) /
c.y;
579 touch_event.tfinger.pressure = 1;
580 ::SDL_PushEvent(&touch_event);
590 case SDL_WINDOWEVENT:
591 switch(event.window.event) {
592 case SDL_WINDOWEVENT_ENTER:
593 case SDL_WINDOWEVENT_FOCUS_GAINED:
597 case SDL_WINDOWEVENT_LEAVE:
598 case SDL_WINDOWEVENT_FOCUS_LOST:
604 case SDL_WINDOWEVENT_SIZE_CHANGED:
605 LOG_DP <<
"events/SIZE_CHANGED "
606 <<
event.window.data1 <<
'x' <<
event.window.data2;
613 case SDL_WINDOWEVENT_RESIZED:
614 LOG_DP <<
"events/RESIZED "
615 <<
event.window.data1 <<
'x' <<
event.window.data2;
621 case SDL_WINDOWEVENT_EXPOSED:
622 LOG_DP <<
"events/EXPOSED";
626 case SDL_WINDOWEVENT_MAXIMIZED:
627 LOG_DP <<
"events/MAXIMIZED";
630 case SDL_WINDOWEVENT_RESTORED:
631 LOG_DP <<
"events/RESTORED";
634 case SDL_WINDOWEVENT_SHOWN:
635 case SDL_WINDOWEVENT_MOVED:
645 case SDL_MOUSEMOTION: {
652 case SDL_MOUSEBUTTONDOWN: {
660 if(event.key.keysym.sym == SDLK_F4 &&
661 (event.key.keysym.mod == KMOD_RALT || event.key.keysym.mod == KMOD_LALT)
671 case SDL_SYSWMEVENT: {
684 global_handler->handle_event(event);
693 std::size_t h_size =
h.size();
694 for(
auto it =
h.begin(); it !=
h.end(); ++it) {
696 (*it)->handle_event(event);
699 LOG_EV <<
"ec size changed! bugging out";
702 if(h_size !=
h.size()) {
703 LOG_EV <<
"h size changed! bugging out";
727 handler->process_event();
736 event.window.type = SDL_WINDOWEVENT;
737 event.window.event = SDL_WINDOWEVENT_SIZE_CHANGED;
738 event.window.windowID = 0;
739 event.window.data1 =
size.x;
740 event.window.data2 =
size.y;
749 handler->process_tooltip_string(mousex, mousey);
755 #define INPUT_MIN 0x300
756 #define INPUT_MAX 0x8FF
770 return event.which == SDL_TOUCH_MOUSEID;
775 return event.which == SDL_TOUCH_MOUSEID;
786 invoked_function_data fdata{
f};
792 sdl_event.user = sdl_userevent;
794 SDL_PushEvent(&sdl_event);
797 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
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 std::thread::id main_thread
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
void pump()
Process all events currently in the queue.
bool is_touch(const SDL_MouseButtonEvent &event)
Check if this mouse button event is caused by a touch.
void focus_handler(const sdl_handler *ptr)
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
std::size_t erase(Container &container, const Value &value)
Convenience wrapper for using std::remove on a container.
bool contains(const Container &container, const Value &value)
Returns true iff value is found in 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