diff --git a/src/gui/core/event/dispatcher.cpp b/src/gui/core/event/dispatcher.cpp index 67801ac1a0c2..4e085d177a9d 100644 --- a/src/gui/core/event/dispatcher.cpp +++ b/src/gui/core/event/dispatcher.cpp @@ -31,6 +31,8 @@ dispatcher::dispatcher() , signal_queue_() , signal_mouse_queue_() , signal_keyboard_queue_() + , signal_touch_motion_queue_() + , signal_touch_gesture_queue_() , signal_notification_queue_() , signal_message_queue_() , connected_(false) @@ -64,6 +66,12 @@ bool dispatcher::has_event(const ui_event event, const event_queue_type event_ty << find(event, dispatcher_implementation ::has_handler(event_type, *this)) << " keyboard " + << find(event, dispatcher_implementation + ::has_handler(event_type, *this)) + << " touch_motion " + << find(event, dispatcher_implementation + ::has_handler(event_type, *this)) + << " touch_gesture " << find(event, dispatcher_implementation ::has_handler(event_type, *this)) << " notification " @@ -83,7 +91,9 @@ bool dispatcher::has_event(const ui_event event, const event_queue_type event_ty event, dispatcher_implementation::has_handler(event_type, *this)) || find( event, dispatcher_implementation::has_handler(event_type, *this)) - || find( + || find( + event, dispatcher_implementation::has_handler(event_type, *this)) + || find( event, dispatcher_implementation::has_handler(event_type, *this)) || find( event, dispatcher_implementation::has_handler(event_type, *this)) @@ -154,6 +164,18 @@ bool dispatcher::fire(const ui_event event, return fire_event(event, this, &target, key, modifier, unicode); } +bool dispatcher::fire(const ui_event event, widget& target, const point& pos, const point& distance) +{ + assert(find(event, event_in_set())); + return fire_event(event, this, &target, pos, distance); +} + +bool dispatcher::fire(const ui_event event, widget& target, const point& center, float dTheta, float dDist, Uint8 numFingers) +{ + assert(find(event, event_in_set())); + return fire_event(event, this, &target, center, dTheta, dDist, numFingers); +} + bool dispatcher::fire(const ui_event event, widget& target, const SDL_Event& sdlevent) { assert(find(event, event_in_set())); @@ -166,12 +188,6 @@ bool dispatcher::fire(const ui_event event, widget& target, const std::string& t return fire_event(event, this, &target, text, start, len); } -bool dispatcher::fire(const ui_event event, widget& target, const point& pos, const point& distance) -{ - assert(find(event, event_in_set())); - return fire_event(event, this, &target, pos, distance); -} - bool dispatcher::fire(const ui_event event, widget& target, void*) { assert(find(event, event_in_set())); diff --git a/src/gui/core/event/dispatcher.hpp b/src/gui/core/event/dispatcher.hpp index d5cc324966d4..6d7d25e247ab 100644 --- a/src/gui/core/event/dispatcher.hpp +++ b/src/gui/core/event/dispatcher.hpp @@ -80,14 +80,28 @@ typedef std::function signal_touch_function; + const point& distance)> signal_touch_motion_function; + +/** + * Callback function signature. + * + * This function is used for the callbacks in set_event_touch_gesture. + */ +typedef std::function signal_touch_gesture_function; /** * Callback function signature. @@ -226,7 +240,7 @@ class dispatcher const std::string& unicode); /** - * Fires an event which takes touch parameters. + * Fires an event which takes touch-motion parameters. * * @param event The event to fire. * @param target The widget that should receive the event. @@ -237,6 +251,23 @@ class dispatcher widget& target, const point& pos, const point& distance); + + + /** + * Fires an event which takes touch-gesture parameters. + * + * @param event The event to fire. + * @param target The widget that should receive the event. + * @param pos The location touched. + * @param distance The distance moved. + */ + bool fire(const ui_event event, + widget& target, + const point& center, + float dTheta, + float dDist, + Uint8 numFingers); + /** * Fires an event which takes notification parameters. @@ -448,18 +479,18 @@ class dispatcher } /** - * Connect a signal for callback in set_event_touch. + * Connect a signal for callback in set_event_touch_motion. * * @tparam E The event the callback needs to react to. * @param signal The callback function. * @param position The position to place the callback. */ template - std::enable_if_t::value> - connect_signal(const signal_touch_function& signal, + std::enable_if_t::value> + connect_signal(const signal_touch_motion_function& signal, const queue_position position = back_child) { - signal_touch_queue_.connect_signal(E, position, signal); + signal_touch_motion_queue_.connect_signal(E, position, signal); } /** @@ -473,11 +504,44 @@ class dispatcher * was added in front or back.) */ template - std::enable_if_t::value> - disconnect_signal(const signal_touch_function& signal, + std::enable_if_t::value> + disconnect_signal(const signal_touch_motion_function& signal, const queue_position position = back_child) { - signal_touch_queue_.disconnect_signal(E, position, signal); + signal_touch_motion_queue_.disconnect_signal(E, position, signal); + } + + /** + * Connect a signal for callback in set_event_touch_gesture. + * + * @tparam E The event the callback needs to react to. + * @param signal The callback function. + * @param position The position to place the callback. + */ + template + std::enable_if_t::value> + connect_signal(const signal_touch_gesture_function& signal, + const queue_position position = back_child) + { + signal_touch_gesture_queue_.connect_signal(E, position, signal); + } + + /** + * Disconnect a signal for callback in set_event_touch. + * + * @tparam E The event the callback was used for. + * @param signal The callback function. + * @param position The place where the function was added. + * Needed remove the event from the right + * place. (The function doesn't care whether + * was added in front or back.) + */ + template + std::enable_if_t::value> + disconnect_signal(const signal_touch_gesture_function& signal, + const queue_position position = back_child) + { + signal_touch_gesture_queue_.disconnect_signal(E, position, signal); } /** @@ -824,7 +888,10 @@ class dispatcher signal_queue signal_keyboard_queue_; /** Signal queue for callbacks in set_event_touch. */ - signal_queue signal_touch_queue_; + signal_queue signal_touch_motion_queue_; + + /** Signal queue for callbacks in set_event_touch. */ + signal_queue signal_touch_gesture_queue_; /** Signal queue for callbacks in set_event_notification. */ signal_queue signal_notification_queue_; diff --git a/src/gui/core/event/dispatcher_private.hpp b/src/gui/core/event/dispatcher_private.hpp index 34c38efc70db..05ddba387a35 100644 --- a/src/gui/core/event/dispatcher_private.hpp +++ b/src/gui/core/event/dispatcher_private.hpp @@ -105,7 +105,8 @@ struct dispatcher_implementation IMPLEMENT_EVENT_SIGNAL_WRAPPER(mouse) IMPLEMENT_EVENT_SIGNAL_WRAPPER(keyboard) - IMPLEMENT_EVENT_SIGNAL_WRAPPER(touch) + IMPLEMENT_EVENT_SIGNAL_WRAPPER(touch_motion) + IMPLEMENT_EVENT_SIGNAL_WRAPPER(touch_gesture) IMPLEMENT_EVENT_SIGNAL_WRAPPER(notification) IMPLEMENT_EVENT_SIGNAL_WRAPPER(message) IMPLEMENT_EVENT_SIGNAL_WRAPPER(raw_event) diff --git a/src/gui/core/event/handler.cpp b/src/gui/core/event/handler.cpp index c099ee9f45b7..e29b8a4fab0a 100644 --- a/src/gui/core/event/handler.cpp +++ b/src/gui/core/event/handler.cpp @@ -224,12 +224,35 @@ class sdl_event_handler : public events::sdl_handler dispatcher* keyboard_dispatcher(); /** - * Fires a generic touch event. + * Fires a touch-moved event. * * @param position The position touched. * @param distance The distance moved. */ void touch_motion(const point& position, const point& distance); + + /** + * Fires a touch "finger down" event. + * + * @param position The position touched. + */ + void touch_down(const point& position); + + /** + * Fires a touch "finger up" event. + * + * @param position The position touched. + */ + void touch_up(const point& position); + + /** + * Fires a touch gesture event. + * @param center the center of gesture + * @param dTheta the amount that the fingers rotated during this motion + * @param dDist the amount that the fingers pinched during this motion + * @param numFingers the number of fingers used in the gesture + */ + void touch_multi_gesture(const point& center, float dTheta, float dDist, Uint8 numFingers); /** * Handles a hat motion event. @@ -445,6 +468,19 @@ void sdl_event_handler::handle_event(const SDL_Event& event) touch_motion(point(event.tfinger.x, event.tfinger.y), point(event.tfinger.dx, event.tfinger.dy)); break; + case SDL_FINGERUP: + touch_up(point(event.tfinger.x, event.tfinger.y)); + break; + + case SDL_FINGERDOWN: + touch_down(point(event.tfinger.x, event.tfinger.y)); + break; + + case SDL_MULTIGESTURE: + touch_multi_gesture(point(event.mgesture.x, event.mgesture.y), + event.mgesture.dTheta, event.mgesture.dDist, event.mgesture.numFingers); + break; + #if(defined(_X11) && !defined(__APPLE__)) || defined(_WIN32) case SDL_SYSWMEVENT: /* DO NOTHING */ @@ -454,8 +490,6 @@ void sdl_event_handler::handle_event(const SDL_Event& event) // Silently ignored events. case SDL_KEYUP: case DOUBLE_CLICK_EVENT: - case SDL_FINGERUP: - case SDL_FINGERDOWN: break; default: @@ -677,6 +711,27 @@ void sdl_event_handler::touch_motion(const point& position, const point& distanc } } +void sdl_event_handler::touch_up(const point& position) +{ + for(auto& dispatcher : boost::adaptors::reverse(dispatchers_)) { + dispatcher->fire(SDL_TOUCH_UP, dynamic_cast(*dispatcher), position); + } +} + +void sdl_event_handler::touch_down(const point& position) +{ + for(auto& dispatcher : boost::adaptors::reverse(dispatchers_)) { + dispatcher->fire(SDL_TOUCH_DOWN, dynamic_cast(*dispatcher), position); + } +} + +void sdl_event_handler::touch_multi_gesture(const point& center, float dTheta, float dDist, Uint8 numFingers) +{ + for(auto& dispatcher : boost::adaptors::reverse(dispatchers_)) { + dispatcher->fire(SDL_TOUCH_MULTI_GESTURE, dynamic_cast(*dispatcher), center, dTheta, dDist, numFingers); + } +} + void sdl_event_handler::hat_motion(const SDL_Event& event) { const hotkey::hotkey_ptr& hk = hotkey::get_hotkey(event); @@ -1009,6 +1064,9 @@ std::ostream& operator<<(std::ostream& stream, const ui_event event) case SDL_TOUCH_DOWN: stream << "SDL touch down"; break; + case SDL_TOUCH_MULTI_GESTURE: + stream << "SDL multi-touch gesture"; + break; case SDL_RAW_EVENT: stream << "SDL raw event"; break; diff --git a/src/gui/core/event/handler.hpp b/src/gui/core/event/handler.hpp index 59a71e7c3cf3..a9bc8ec4210b 100644 --- a/src/gui/core/event/handler.hpp +++ b/src/gui/core/event/handler.hpp @@ -116,6 +116,7 @@ enum ui_event { SDL_TOUCH_MOTION, SDL_TOUCH_UP, SDL_TOUCH_DOWN, + SDL_TOUCH_MULTI_GESTURE, SDL_RAW_EVENT /**< Raw SDL event. */ }; @@ -168,7 +169,9 @@ typedef boost::mpl::set, boost::mpl::int_, boost::mpl::int_, boost::mpl::int_, - boost::mpl::int_> set_event_mouse; + boost::mpl::int_, + boost::mpl::int_, + boost::mpl::int_> set_event_mouse; /** * Helper for catching use error of dispatcher::connect_signal. @@ -181,12 +184,18 @@ typedef boost::mpl::set> set_event_keyboard; /** * Helper for catching use error of dispatcher::connect_signal. * - * This version is for callbacks of touch events. + * This version is for callbacks of touch motion events. */ -typedef boost::mpl::set, - boost::mpl::int_, - boost::mpl::int_> -set_event_touch; +typedef boost::mpl::set> +set_event_touch_motion; + +/** + * Helper for catching use error of dispatcher::connect_signal. + * + * This version is for callbacks of touch gestures events. + */ +typedef boost::mpl::set> +set_event_touch_gesture; /** * Helper for catching use error of dispatcher::connect_signal.