Added some rudimentary mouse handling support.
This commit is contained in:
parent
f091fbc440
commit
85661240b1
5 changed files with 122 additions and 24 deletions
|
@ -48,7 +48,9 @@ tevent_info::tevent_info() :
|
|||
mouse_last_middle_button_down(false),
|
||||
mouse_last_right_button_down(false),
|
||||
|
||||
event_mouse_button(-1)
|
||||
event_mouse_button(-1),
|
||||
|
||||
mouse_focus(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
namespace gui2{
|
||||
|
||||
class twidget;
|
||||
|
||||
struct tevent_info
|
||||
{
|
||||
tevent_info();
|
||||
|
@ -42,6 +44,9 @@ struct tevent_info
|
|||
bool mouse_last_right_button_down; //! Was the right mouse button down in the last event?
|
||||
|
||||
int event_mouse_button; //! If a mouse event it shows which button changed.
|
||||
|
||||
twidget* mouse_focus;
|
||||
|
||||
};
|
||||
|
||||
} // namespace gui2
|
||||
|
|
|
@ -65,12 +65,25 @@ struct terror
|
|||
class tevent_executor
|
||||
{
|
||||
public:
|
||||
tevent_executor(const bool send_double_click = true) :
|
||||
send_double_click_(send_double_click)
|
||||
tevent_executor(const bool want_double_click = false/* true */) :
|
||||
want_double_click_(want_double_click)
|
||||
{}
|
||||
virtual ~tevent_executor() {}
|
||||
|
||||
//! Happens when a mouse goes down on the widget.
|
||||
// Description of various event generating scenarios
|
||||
//
|
||||
// mouse moves on a widget and the focus isn't stolen:
|
||||
// - mouse enter
|
||||
//
|
||||
// mouse on widget clicked without moving
|
||||
// - mouse down
|
||||
// - mouse up
|
||||
// wait for possible double click if widget wants double click
|
||||
// - mouse click
|
||||
|
||||
|
||||
//! Happens when a mouse goes down on the widget. When the mouse goes
|
||||
//! down this widget steals the mouse focus until the button is released.
|
||||
virtual void mouse_down(const tevent_info&, bool&) {}
|
||||
|
||||
//! Happens when a mouse down focussed this widget and is released
|
||||
|
@ -79,10 +92,19 @@ public:
|
|||
|
||||
//! Happens when a mouse down and up happen on the same widget.
|
||||
virtual void mouse_click(const tevent_info&, bool&) {}
|
||||
|
||||
|
||||
//! Happens when a mouse down and up happen twice on the same widget.
|
||||
virtual void mouse_double_click(const tevent_info& event, bool& handled)
|
||||
{ if(!send_double_click_) mouse_click(event, handled); }
|
||||
virtual void mouse_double_click(const tevent_info&, bool&) {}
|
||||
|
||||
//! Happens when the mouse moves over the widget and the focus
|
||||
//! isn't stolen by another widget.
|
||||
virtual void mouse_enter(const tevent_info&, bool&) {}
|
||||
|
||||
//! Happens when the mouse leaves a widget, execpt when the focus
|
||||
//! is captured. If this widget captures the focus the event is
|
||||
//! send after the mouse button is released.
|
||||
virtual void mouse_leave(const tevent_info&, bool&) {}
|
||||
|
||||
|
||||
#if 0
|
||||
virtual void mouse_enter();
|
||||
|
@ -107,12 +129,12 @@ public:
|
|||
// children.
|
||||
virtual void layout() {}
|
||||
|
||||
|
||||
bool want_double_click() const { return want_double_click_; }
|
||||
|
||||
private:
|
||||
//! If a widget doesn't want a double click we need to send a second
|
||||
//! click instead of double click.
|
||||
bool send_double_click_;
|
||||
bool want_double_click_;
|
||||
};
|
||||
|
||||
//! Base class for all widgets.
|
||||
|
@ -120,7 +142,7 @@ private:
|
|||
class twidget : public virtual tevent_executor
|
||||
{
|
||||
public:
|
||||
twidget(const std::string& id = "") :
|
||||
twidget(const std::string& id = "") :
|
||||
id_(id),
|
||||
parent_(0),
|
||||
x_(-1),
|
||||
|
@ -517,7 +539,12 @@ public:
|
|||
|
||||
virtual void set_height(const int height);
|
||||
|
||||
void mouse_down(const tevent_info& /*event*/, bool& /*handled*/) { std::cerr << "Hit me again\n"; }
|
||||
void mouse_down(const tevent_info& /*event*/, bool& /*handled*/) { std::cerr << "mouse down\n"; }
|
||||
void mouse_up(const tevent_info& /*event*/, bool& /*handled*/) { std::cerr << "mouse up\n"; }
|
||||
void mouse_click(const tevent_info& /*event*/, bool& /*handled*/) { std::cerr << "mouse click\n"; }
|
||||
void mouse_double_click(const tevent_info& /*event*/, bool& /*handled*/) { std::cerr << "mouse double click\n"; }
|
||||
void mouse_enter(const tevent_info& /*event*/, bool& /*handled*/) { std::cerr << "mouse enter\n"; }
|
||||
void mouse_leave(const tevent_info& /*event*/, bool& /*handled*/) { std::cerr << "mouse leave\n"; }
|
||||
|
||||
void draw(surface& canvas);
|
||||
|
||||
|
|
|
@ -165,10 +165,10 @@ void twindow::handle_event(const SDL_Event& event)
|
|||
handle_event_mouse_down(event);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
// std::cerr << "Mouse up on control " << typeid(this).name() << '\n';
|
||||
handle_event_mouse_up(event);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
// std::cerr << "Mouse move on control " << typeid(this).name() << '\n';
|
||||
handle_event_mouse_move(event);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -180,10 +180,15 @@ void twindow::handle_event_mouse_down(const SDL_Event& event)
|
|||
event_info_.event_mouse_button = event.button.button;
|
||||
event_info_.mouse_x = event.button.x;
|
||||
event_info_.mouse_y = event.button.y;
|
||||
event_info_.mouse_focus = get_widget(tpoint(event_info_.mouse_x - get_x(), event_info_.mouse_y - get_y()));
|
||||
|
||||
bool handled = false;
|
||||
switch(event_info_.event_mouse_button) {
|
||||
case SDL_BUTTON_LEFT :
|
||||
event_info_.mouse_left_button_down = true;
|
||||
if(event_info_.mouse_focus) {
|
||||
event_info_.mouse_focus->mouse_down(event_info_, handled);
|
||||
}
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE :
|
||||
event_info_.mouse_middle_button_down = true;
|
||||
|
@ -195,21 +200,74 @@ void twindow::handle_event_mouse_down(const SDL_Event& event)
|
|||
// Note: other mouse buttons are ignored, the event
|
||||
// is send but the status won't be remembered.
|
||||
}
|
||||
}
|
||||
|
||||
//! Handler for a mouse down.
|
||||
void twindow::handle_event_mouse_up(const SDL_Event& event)
|
||||
{
|
||||
event_info_.event_mouse_button = event.button.button;
|
||||
event_info_.mouse_x = event.button.x;
|
||||
event_info_.mouse_y = event.button.y;
|
||||
twidget* mouse_focus = get_widget(tpoint(event_info_.mouse_x - get_x(), event_info_.mouse_y - get_y()));
|
||||
|
||||
// Send the event to the widget at this location.
|
||||
// Note containers first send the event to their child
|
||||
// and when not handled it's handled by the container.
|
||||
bool handled = false;
|
||||
for(tsizer::iterator itor = begin(); itor != end(); ++itor) {
|
||||
// for(std::multimap<std::string, twidget *>::iterator itor =
|
||||
// children().begin(); itor != children().end(); ++itor) {
|
||||
|
||||
|
||||
twidget* widget = *itor;
|
||||
if(widget) {
|
||||
widget->mouse_down(event_info_, handled);
|
||||
switch(event_info_.event_mouse_button) {
|
||||
case SDL_BUTTON_LEFT :
|
||||
if(event_info_.mouse_focus) {
|
||||
|
||||
event_info_.mouse_focus->mouse_up(event_info_, handled);
|
||||
|
||||
if(event_info_.mouse_focus == mouse_focus) {
|
||||
|
||||
if(event_info_.mouse_focus->want_double_click()) {
|
||||
|
||||
// double click not implemented atm.
|
||||
assert(false);
|
||||
|
||||
|
||||
} else {
|
||||
event_info_.mouse_focus->mouse_click(event_info_, handled);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event_info_.mouse_left_button_down = false;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE :
|
||||
event_info_.mouse_middle_button_down = false;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT :
|
||||
event_info_.mouse_right_button_down = false;
|
||||
break;
|
||||
|
||||
// Note: other mouse buttons are ignored, the event
|
||||
// is send but the status won't be remembered.
|
||||
}
|
||||
|
||||
event_info_.mouse_focus = 0; // Note to see what to do after moving
|
||||
}
|
||||
|
||||
//! Handler for a mouse movement.
|
||||
void twindow::handle_event_mouse_move(const SDL_Event& event)
|
||||
{
|
||||
event_info_.mouse_x = event.button.x;
|
||||
event_info_.mouse_y = event.button.y;
|
||||
twidget* mouse_focus = get_widget(tpoint(event_info_.mouse_x - get_x(), event_info_.mouse_y - get_y()));
|
||||
|
||||
if(mouse_focus != event_info_.mouse_focus) {
|
||||
if(event_info_.mouse_focus) {
|
||||
bool handled = false;
|
||||
event_info_.mouse_focus->mouse_leave(event_info_, handled);
|
||||
}
|
||||
|
||||
if(mouse_focus) {
|
||||
bool handled = false;
|
||||
mouse_focus->mouse_enter(event_info_, handled);
|
||||
}
|
||||
}
|
||||
|
||||
event_info_.mouse_focus = mouse_focus;
|
||||
}
|
||||
|
||||
} // namespace gui2
|
||||
|
|
|
@ -91,6 +91,12 @@ private:
|
|||
//! Handler for a mouse down.
|
||||
void handle_event_mouse_down(const SDL_Event& event);
|
||||
|
||||
//! Handler for a mouse up.
|
||||
void handle_event_mouse_up(const SDL_Event& event);
|
||||
|
||||
//! Handler for a mouse movement.
|
||||
void handle_event_mouse_move(const SDL_Event& event);
|
||||
|
||||
};
|
||||
|
||||
} // namespace gui2
|
||||
|
|
Loading…
Add table
Reference in a new issue