GUI2/Distributor: wrap ui_event types in a helper metastruct to reduce huge template lists

This commit is contained in:
Charles Dang 2017-05-04 22:21:10 +11:00
parent dc0cd76b0e
commit 039463e78c
2 changed files with 86 additions and 128 deletions

View file

@ -364,21 +364,9 @@ void mouse_motion::stop_hover_timer()
#define LOG_HEADER \
"distributor mouse button " << name_ << " [" << owner_.id() << "]: "
template <ui_event sdl_button_down,
ui_event sdl_button_up,
ui_event button_down,
ui_event button_up,
ui_event button_click,
ui_event button_double_click>
mouse_button<sdl_button_down,
sdl_button_up,
button_down,
button_up,
button_click,
button_double_click>::mouse_button(const std::string& name_,
widget& owner,
const dispatcher::queue_position
queue_position)
template<typename T>
mouse_button<T>::mouse_button(const std::string& name_, widget& owner,
const dispatcher::queue_position queue_position)
: mouse_motion(owner, queue_position)
, last_click_stamp_(0)
, last_clicked_widget_(nullptr)
@ -388,27 +376,15 @@ mouse_button<sdl_button_down,
, signal_handler_sdl_button_down_entered_(false)
, signal_handler_sdl_button_up_entered_(false)
{
owner_.connect_signal<sdl_button_down>(
std::bind(&mouse_button<sdl_button_down,
sdl_button_up,
button_down,
button_up,
button_click,
button_double_click>::
signal_handler_sdl_button_down,
owner_.connect_signal<T::sdl_button_down_t>(
std::bind(&mouse_button<T>::signal_handler_sdl_button_down,
this,
_2,
_3,
_5),
queue_position);
owner_.connect_signal<sdl_button_up>(
std::bind(&mouse_button<sdl_button_down,
sdl_button_up,
button_down,
button_up,
button_click,
button_double_click>::
signal_handler_sdl_button_up,
owner_.connect_signal<T::sdl_button_up_t>(
std::bind(&mouse_button<T>::signal_handler_sdl_button_up,
this,
_2,
_3,
@ -416,18 +392,8 @@ mouse_button<sdl_button_down,
queue_position);
}
template <ui_event sdl_button_down,
ui_event sdl_button_up,
ui_event button_down,
ui_event button_up,
ui_event button_click,
ui_event button_double_click>
void mouse_button<sdl_button_down,
sdl_button_up,
button_down,
button_up,
button_click,
button_double_click>::initialize_state(const bool is_down)
template<typename T>
void mouse_button<T>::initialize_state(const bool is_down)
{
last_click_stamp_ = 0;
last_clicked_widget_ = nullptr;
@ -435,21 +401,9 @@ void mouse_button<sdl_button_down,
is_down_ = is_down;
}
template <ui_event sdl_button_down,
ui_event sdl_button_up,
ui_event button_down,
ui_event button_up,
ui_event button_click,
ui_event button_double_click>
void mouse_button<sdl_button_down,
sdl_button_up,
button_down,
button_up,
button_click,
button_double_click>::
signal_handler_sdl_button_down(const event::ui_event event,
bool& handled,
const point& coordinate)
template<typename T>
void mouse_button<T>::signal_handler_sdl_button_down(const event::ui_event event, bool& handled,
const point& coordinate)
{
if(signal_handler_sdl_button_down_entered_) {
return;
@ -471,10 +425,10 @@ void mouse_button<sdl_button_down,
if(mouse_captured_) {
assert(mouse_focus_);
focus_ = mouse_focus_;
DBG_GUI_E << LOG_HEADER << "Firing: " << sdl_button_down << ".\n";
if(!owner_.fire(sdl_button_down, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << button_down << ".\n";
owner_.fire(button_down, *mouse_focus_);
DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_down_t << ".\n";
if(!owner_.fire(T::sdl_button_down_t, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_down_t << ".\n";
owner_.fire(T::button_down_t, *mouse_focus_);
}
} else {
widget* mouse_over = owner_.find_at(coordinate, true);
@ -491,30 +445,18 @@ void mouse_button<sdl_button_down,
}
focus_ = mouse_over;
DBG_GUI_E << LOG_HEADER << "Firing: " << sdl_button_down << ".\n";
if(!owner_.fire(sdl_button_down, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << button_down << ".\n";
owner_.fire(button_down, *focus_);
DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_down_t << ".\n";
if(!owner_.fire(T::sdl_button_down_t, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_down_t << ".\n";
owner_.fire(T::button_down_t, *focus_);
}
}
handled = true;
}
template <ui_event sdl_button_down,
ui_event sdl_button_up,
ui_event button_down,
ui_event button_up,
ui_event button_click,
ui_event button_double_click>
void mouse_button<sdl_button_down,
sdl_button_up,
button_down,
button_up,
button_click,
button_double_click>::
signal_handler_sdl_button_up(const event::ui_event event,
bool& handled,
const point& coordinate)
template<typename T>
void mouse_button<T>::signal_handler_sdl_button_up(const event::ui_event event, bool& handled,
const point& coordinate)
{
if(signal_handler_sdl_button_up_entered_) {
return;
@ -531,10 +473,10 @@ void mouse_button<sdl_button_down,
is_down_ = false;
if(focus_) {
DBG_GUI_E << LOG_HEADER << "Firing: " << sdl_button_up << ".\n";
if(!owner_.fire(sdl_button_up, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << button_up << ".\n";
owner_.fire(button_up, *focus_);
DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_up_t << ".\n";
if(!owner_.fire(T::sdl_button_up_t, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_up_t << ".\n";
owner_.fire(T::button_up_t, *focus_);
}
}
@ -564,33 +506,23 @@ void mouse_button<sdl_button_down,
handled = true;
}
template <ui_event sdl_button_down,
ui_event sdl_button_up,
ui_event button_down,
ui_event button_up,
ui_event button_click,
ui_event button_double_click>
void mouse_button<sdl_button_down,
sdl_button_up,
button_down,
button_up,
button_click,
button_double_click>::mouse_button_click(widget* widget)
template<typename T>
void mouse_button<T>::mouse_button_click(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: " << T::button_double_click_t << ".\n";
owner_.fire(button_double_click, *widget);
owner_.fire(T::button_double_click_t, *widget);
last_click_stamp_ = 0;
last_clicked_widget_ = nullptr;
} else {
DBG_GUI_E << LOG_HEADER << "Firing: " << button_click << ".\n";
owner_.fire(button_click, *widget);
DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_click_t << ".\n";
owner_.fire(T::button_click_t, *widget);
last_click_stamp_ = stamp;
last_clicked_widget_ = widget;
}

View file

@ -151,12 +151,28 @@ private:
/***** ***** ***** ***** mouse_button ***** ***** ***** ***** *****/
template <ui_event sdl_button_down,
ui_event sdl_button_up,
ui_event button_down,
ui_event button_up,
ui_event button_click,
ui_event button_double_click>
/**
* Small helper metastruct to specialize mouse_button with and provide ui_event type
* aliases without needing to make mouse_button take a million template types.
*/
template<
ui_event sdl_button_down,
ui_event sdl_button_up,
ui_event button_down,
ui_event button_up,
ui_event button_click,
ui_event button_double_click>
struct mouse_button_event_types_wrapper
{
static const ui_event sdl_button_down_t = sdl_button_down;
static const ui_event sdl_button_up_t = sdl_button_up;
static const ui_event button_down_t = button_down;
static const ui_event button_up_t = button_up;
static const ui_event button_click_t = button_click;
static const ui_event button_double_click_t = button_double_click;
};
template<typename T>
class mouse_button : public virtual mouse_motion
{
public:
@ -209,32 +225,42 @@ private:
/***** ***** ***** ***** distributor ***** ***** ***** ***** *****/
typedef mouse_button<SDL_LEFT_BUTTON_DOWN,
SDL_LEFT_BUTTON_UP,
LEFT_BUTTON_DOWN,
LEFT_BUTTON_UP,
LEFT_BUTTON_CLICK,
LEFT_BUTTON_DOUBLE_CLICK> mouse_button_left;
using mouse_button_left = mouse_button<
mouse_button_event_types_wrapper<
SDL_LEFT_BUTTON_DOWN,
SDL_LEFT_BUTTON_UP,
LEFT_BUTTON_DOWN,
LEFT_BUTTON_UP,
LEFT_BUTTON_CLICK,
LEFT_BUTTON_DOUBLE_CLICK>
>;
typedef mouse_button<SDL_MIDDLE_BUTTON_DOWN,
SDL_MIDDLE_BUTTON_UP,
MIDDLE_BUTTON_DOWN,
MIDDLE_BUTTON_UP,
MIDDLE_BUTTON_CLICK,
MIDDLE_BUTTON_DOUBLE_CLICK> mouse_button_middle;
using mouse_button_middle = mouse_button<
mouse_button_event_types_wrapper<
SDL_MIDDLE_BUTTON_DOWN,
SDL_MIDDLE_BUTTON_UP,
MIDDLE_BUTTON_DOWN,
MIDDLE_BUTTON_UP,
MIDDLE_BUTTON_CLICK,
MIDDLE_BUTTON_DOUBLE_CLICK>
>;
typedef mouse_button<SDL_RIGHT_BUTTON_DOWN,
SDL_RIGHT_BUTTON_UP,
RIGHT_BUTTON_DOWN,
RIGHT_BUTTON_UP,
RIGHT_BUTTON_CLICK,
RIGHT_BUTTON_DOUBLE_CLICK> mouse_button_right;
using mouse_button_right = mouse_button<
mouse_button_event_types_wrapper<
SDL_RIGHT_BUTTON_DOWN,
SDL_RIGHT_BUTTON_UP,
RIGHT_BUTTON_DOWN,
RIGHT_BUTTON_UP,
RIGHT_BUTTON_CLICK,
RIGHT_BUTTON_DOUBLE_CLICK>
>;
/** The event handler class for the widget library. */
class distributor : public mouse_button_left,
public mouse_button_middle,
public mouse_button_right
class distributor :
public mouse_button_left,
public mouse_button_middle,
public mouse_button_right
{
public:
distributor(widget& owner, const dispatcher::queue_position queue_position);