Skip to content

Commit

Permalink
3 kinds of touch event compiled: up/down (combined with mouse), swipe…
Browse files Browse the repository at this point in the history
… and multi-finger gesture.
  • Loading branch information
singalen authored and jyrkive committed Oct 28, 2018
1 parent 19c2c93 commit ea2e16d
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 28 deletions.
30 changes: 23 additions & 7 deletions src/gui/core/event/dispatcher.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -64,6 +66,12 @@ bool dispatcher::has_event(const ui_event event, const event_queue_type event_ty
<< find<set_event_mouse>(event, dispatcher_implementation
::has_handler(event_type, *this))
<< " keyboard "
<< find<set_event_touch_motion>(event, dispatcher_implementation
::has_handler(event_type, *this))
<< " touch_motion "
<< find<set_event_touch_gesture>(event, dispatcher_implementation
::has_handler(event_type, *this))
<< " touch_gesture "
<< find<set_event_keyboard>(event, dispatcher_implementation
::has_handler(event_type, *this))
<< " notification "
Expand All @@ -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<set_event_text_input>(
event, dispatcher_implementation::has_handler(event_type, *this))
|| find<set_event_touch>(
|| find<set_event_touch_motion>(
event, dispatcher_implementation::has_handler(event_type, *this))
|| find<set_event_touch_gesture>(
event, dispatcher_implementation::has_handler(event_type, *this))
|| find<set_event_notification>(
event, dispatcher_implementation::has_handler(event_type, *this))
Expand Down Expand Up @@ -154,6 +164,18 @@ bool dispatcher::fire(const ui_event event,
return fire_event<signal_keyboard_function>(event, this, &target, key, modifier, unicode);
}

bool dispatcher::fire(const ui_event event, widget& target, const point& pos, const point& distance)
{
assert(find<set_event_touch_motion>(event, event_in_set()));
return fire_event<signal_touch_motion_function>(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<set_event_touch_gesture>(event, event_in_set()));
return fire_event<signal_touch_gesture_function>(event, this, &target, center, dTheta, dDist, numFingers);
}

bool dispatcher::fire(const ui_event event, widget& target, const SDL_Event& sdlevent)
{
assert(find<set_event_raw_event>(event, event_in_set()));
Expand All @@ -166,12 +188,6 @@ bool dispatcher::fire(const ui_event event, widget& target, const std::string& t
return fire_event<signal_text_input_function>(event, this, &target, text, start, len);
}

bool dispatcher::fire(const ui_event event, widget& target, const point& pos, const point& distance)
{
assert(find<set_event_touch>(event, event_in_set()));
return fire_event<signal_touch_function>(event, this, &target, pos, distance);
}

bool dispatcher::fire(const ui_event event, widget& target, void*)
{
assert(find<set_event_notification>(event, event_in_set()));
Expand Down
89 changes: 78 additions & 11 deletions src/gui/core/event/dispatcher.hpp
Expand Up @@ -80,14 +80,28 @@ typedef std::function<void(widget& dispatcher,
/**
* Callback function signature.
*
* This function is used for the callbacks in set_event_touch.
* This function is used for the callbacks in set_event_touch_motion.
*/
typedef std::function<void(widget& dispatcher,
const ui_event event,
bool& handled,
bool& halt,
const point& pos,
const point& distance)> 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<void(dispatcher& dispatcher,
const ui_event event,
bool& handled,
bool& halt,
const point& center,
float dTheta,
float dDist,
Uint8 numFingers)> signal_touch_gesture_function;

/**
* Callback function signature.
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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 <ui_event E>
std::enable_if_t<has_key<set_event_touch, E>::value>
connect_signal(const signal_touch_function& signal,
std::enable_if_t<has_key<set_event_touch_motion, E>::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);
}

/**
Expand All @@ -473,11 +504,44 @@ class dispatcher
* was added in front or back.)
*/
template <ui_event E>
std::enable_if_t<has_key<set_event_touch, E>::value>
disconnect_signal(const signal_touch_function& signal,
std::enable_if_t<has_key<set_event_touch_motion, E>::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 <ui_event E>
std::enable_if_t<has_key<set_event_touch_gesture, E>::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 <ui_event E>
std::enable_if_t<has_key<set_event_touch_gesture, E>::value>
disconnect_signal(const signal_touch_gesture_function& signal,
const queue_position position = back_child)
{
signal_touch_gesture_queue_.disconnect_signal(E, position, signal);
}

/**
Expand Down Expand Up @@ -824,7 +888,10 @@ class dispatcher
signal_queue<signal_keyboard_function> signal_keyboard_queue_;

/** Signal queue for callbacks in set_event_touch. */
signal_queue<signal_touch_function> signal_touch_queue_;
signal_queue<signal_touch_motion_function> signal_touch_motion_queue_;

/** Signal queue for callbacks in set_event_touch. */
signal_queue<signal_touch_gesture_function> signal_touch_gesture_queue_;

/** Signal queue for callbacks in set_event_notification. */
signal_queue<signal_notification_function> signal_notification_queue_;
Expand Down
3 changes: 2 additions & 1 deletion src/gui/core/event/dispatcher_private.hpp
Expand Up @@ -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)
Expand Down
64 changes: 61 additions & 3 deletions src/gui/core/event/handler.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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 */
Expand All @@ -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:
Expand Down Expand Up @@ -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<widget&>(*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<widget&>(*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<widget&>(*dispatcher), center, dTheta, dDist, numFingers);
}
}

void sdl_event_handler::hat_motion(const SDL_Event& event)
{
const hotkey::hotkey_ptr& hk = hotkey::get_hotkey(event);
Expand Down Expand Up @@ -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;
Expand Down
21 changes: 15 additions & 6 deletions src/gui/core/event/handler.hpp
Expand Up @@ -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. */
};
Expand Down Expand Up @@ -168,7 +169,9 @@ typedef boost::mpl::set<boost::mpl::int_<SDL_VIDEO_RESIZE>,
boost::mpl::int_<SDL_WHEEL_UP>,
boost::mpl::int_<SDL_WHEEL_DOWN>,
boost::mpl::int_<SDL_WHEEL_LEFT>,
boost::mpl::int_<SDL_WHEEL_RIGHT>> set_event_mouse;
boost::mpl::int_<SDL_WHEEL_RIGHT>,
boost::mpl::int_<SDL_TOUCH_UP>,
boost::mpl::int_<SDL_TOUCH_DOWN>> set_event_mouse;

/**
* Helper for catching use error of dispatcher::connect_signal.
Expand All @@ -181,12 +184,18 @@ typedef boost::mpl::set<boost::mpl::int_<SDL_KEY_DOWN>> 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_<SDL_TOUCH_MOTION>,
boost::mpl::int_<SDL_TOUCH_UP>,
boost::mpl::int_<SDL_TOUCH_DOWN>>
set_event_touch;
typedef boost::mpl::set<boost::mpl::int_<SDL_TOUCH_MOTION>>
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<boost::mpl::int_<SDL_TOUCH_MULTI_GESTURE>>
set_event_touch_gesture;

/**
* Helper for catching use error of dispatcher::connect_signal.
Expand Down

0 comments on commit ea2e16d

Please sign in to comment.