Change the handling of double clicks.

The engine now always tries to generate a double click, if a double
click is generated it looks whether a widget wants double clicks when
building the event chain. Depending whether or not it supports a double
click it tries to send a double or single click.
After this decision it looks whether a handler is installed, but only
test the click or double click.
This commit is contained in:
Mark de Wever 2009-10-14 18:49:09 +00:00
parent eded0cd2c1
commit ef5162244a
4 changed files with 103 additions and 35 deletions

View file

@ -105,10 +105,47 @@ public:
bool tdispatcher::fire(const tevent event, twidget& target)
{
return fire_event<tsignal_function>(event
, dynamic_cast<twidget*>(this)
, &target
, ttrigger());
switch(event) {
case LEFT_BUTTON_DOUBLE_CLICK :
return fire_event_double_click<
LEFT_BUTTON_CLICK
, LEFT_BUTTON_DOUBLE_CLICK
, &tevent_executor::wants_mouse_left_double_click
, tsignal_function
>(
dynamic_cast<twidget*>(this)
, &target
, ttrigger());
case MIDDLE_BUTTON_DOUBLE_CLICK :
return fire_event_double_click<
MIDDLE_BUTTON_CLICK
, MIDDLE_BUTTON_DOUBLE_CLICK
, &tevent_executor::wants_mouse_middle_double_click
, tsignal_function
>(
dynamic_cast<twidget*>(this)
, &target
, ttrigger());
case RIGHT_BUTTON_DOUBLE_CLICK :
return fire_event_double_click<
RIGHT_BUTTON_CLICK
, RIGHT_BUTTON_DOUBLE_CLICK
, &tevent_executor::wants_mouse_right_double_click
, tsignal_function
>(
dynamic_cast<twidget*>(this)
, &target
, ttrigger());
default :
return fire_event<tsignal_function>(event
, dynamic_cast<twidget*>(this)
, &target
, ttrigger());
}
}
/** Helper struct to wrap the functor call. */

View file

@ -546,6 +546,58 @@ inline bool fire_event(const tevent event
, functor);
}
template<
tevent click
, tevent double_click
, bool(tevent_executor::*wants_double_click) () const
, class T
, class F
>
inline bool fire_event_double_click(
twidget* dispatcher
, twidget* widget
, F functor)
{
assert(dispatcher);
assert(widget);
std::vector<std::pair<twidget*, tevent> > event_chain;
twidget* w = widget;
while(w!= dispatcher) {
w = w->parent();
assert(w);
if((w->*wants_double_click)()) {
if(w->has_event(double_click, tdispatcher::tevent_type(
tdispatcher::pre | tdispatcher::post))) {
event_chain.push_back(std::make_pair(w, double_click));
}
} else {
if(w->has_event(click, tdispatcher::tevent_type(
tdispatcher::pre | tdispatcher::post))) {
event_chain.push_back(std::make_pair(w, click));
}
}
}
if((widget->*wants_double_click)()) {
return implementation::fire_event<T>(double_click
, event_chain
, dispatcher
, widget
, functor);
} else {
return implementation::fire_event<T>(click
, event_chain
, dispatcher
, widget
, functor);
}
}
} // namespace event
} // namespace gui2

View file

@ -224,7 +224,6 @@ template<
, tevent button_up
, tevent button_click
, tevent button_double_click
, bool(tevent_executor::*wants_double_click) () const
> tmouse_button<
sdl_button_down
, sdl_button_up
@ -232,7 +231,6 @@ template<
, button_up
, button_click
, button_double_click
, wants_double_click
>::tmouse_button(
const std::string& name_
, twidget& owner
@ -254,7 +252,6 @@ template<
, button_up
, button_click
, button_double_click
, wants_double_click
>::signal_handler_sdl_button_down, this, _2, _3, _5)
, queue_position);
owner_.connect_signal<sdl_button_up>(
@ -265,7 +262,6 @@ template<
, button_up
, button_click
, button_double_click
, wants_double_click
>::signal_handler_sdl_button_up, this, _2, _3, _5)
, queue_position);
}
@ -277,7 +273,6 @@ template<
, tevent button_up
, tevent button_click
, tevent button_double_click
, bool(tevent_executor::*wants_double_click) () const
> void tmouse_button<
sdl_button_down
, sdl_button_up
@ -285,7 +280,6 @@ template<
, button_up
, button_click
, button_double_click
, wants_double_click
>::signal_handler_sdl_button_down(
const event::tevent event
, bool& handled
@ -344,7 +338,6 @@ template<
, tevent button_up
, tevent button_click
, tevent button_double_click
, bool(tevent_executor::*wants_double_click) () const
> void tmouse_button<
sdl_button_down
, sdl_button_up
@ -352,7 +345,6 @@ template<
, button_up
, button_click
, button_double_click
, wants_double_click
>::signal_handler_sdl_button_up(
const event::tevent event
, bool& handled
@ -413,7 +405,6 @@ template<
, tevent button_up
, tevent button_click
, tevent button_double_click
, bool(tevent_executor::*wants_double_click) () const
> void tmouse_button<
sdl_button_down
, sdl_button_up
@ -421,33 +412,25 @@ template<
, button_up
, button_click
, button_double_click
, wants_double_click
>::mouse_button_click(twidget* widget)
{
if((widget->*wants_double_click)()) {
Uint32 stamp = SDL_GetTicks();
if(last_click_stamp_ + settings::double_click_time >= stamp
&& last_clicked_widget_ == widget) {
Uint32 stamp = SDL_GetTicks();
if(last_click_stamp_ + settings::double_click_time >= stamp
&& last_clicked_widget_ == widget) {
DBG_GUI_E << LOG_HEADER << "Firing: "
<< button_double_click << ".\n";
DBG_GUI_E << LOG_HEADER << "Firing: "
<< button_double_click << ".\n";
owner_.fire(button_double_click, *widget);
last_click_stamp_ = 0;
last_clicked_widget_ = NULL;
} else {
DBG_GUI_E << LOG_HEADER << "Firing: " << button_click << ".\n";
owner_.fire(button_click, *widget);
last_click_stamp_ = stamp;
last_clicked_widget_ = widget;
}
owner_.fire(button_double_click, *widget);
last_click_stamp_ = 0;
last_clicked_widget_ = NULL;
} else {
DBG_GUI_E << LOG_HEADER << "Firing: " << button_click << ".\n";
owner_.fire(button_click, *widget);
last_click_stamp_ = stamp;
last_clicked_widget_ = widget;
}
}

View file

@ -119,7 +119,6 @@ template<
, tevent button_up
, tevent button_click
, tevent button_double_click
, bool(tevent_executor::*wants_double_click) () const
>
class tmouse_button
: public virtual tmouse_motion
@ -176,7 +175,6 @@ typedef tmouse_button<
, LEFT_BUTTON_UP
, LEFT_BUTTON_CLICK
, LEFT_BUTTON_DOUBLE_CLICK
, &tevent_executor::wants_mouse_left_double_click
> tmouse_button_left;
typedef tmouse_button<
@ -186,7 +184,6 @@ typedef tmouse_button<
, MIDDLE_BUTTON_UP
, MIDDLE_BUTTON_CLICK
, MIDDLE_BUTTON_DOUBLE_CLICK
, &tevent_executor::wants_mouse_middle_double_click
> tmouse_button_middle;
typedef tmouse_button<
@ -196,7 +193,6 @@ typedef tmouse_button<
, RIGHT_BUTTON_UP
, RIGHT_BUTTON_CLICK
, RIGHT_BUTTON_DOUBLE_CLICK
, &tevent_executor::wants_mouse_right_double_click
> tmouse_button_right;