Enabled listbox scrolling with a mouse wheel.

Now it's possible to scroll in a listbox with the scrollwheel of a
mouse. Thanks to boucman for testing.
This commit is contained in:
Mark de Wever 2009-01-04 15:21:22 +00:00
parent 2f09b5c356
commit 48e897f5b7
6 changed files with 164 additions and 4 deletions

View file

@ -23,6 +23,7 @@ Version 1.5.7+svn:
* Fix the calculate feature in the test scenario.
* Fix an endian issue which rendered text wrong on big endian machines.
* A backspace in a textbox with selection, now clears the selection.
* Scrollwheel mouses can scroll the new listboxes.
Version 1.5.7:
* Campaigns:

View file

@ -160,6 +160,28 @@ public:
/** See mouse_left_button_double_click. */
virtual void mouse_right_button_double_click(tevent_handler&) {}
/***** ***** ***** ***** mouse wheel ***** ***** ***** *****/
/**
* Scrollwheel up.
*
* The scrollwheel events are trigger by the scrollwheel.
*
* @param event_handler The event handler that send the event.
* @param handled Do we handle the event.
*/
virtual void mouse_wheel_up(
tevent_handler& /*event_handler*/, bool& /*handled*/) {}
/** Scrollwheel down see mouse_wheel_up.*/
virtual void mouse_wheel_down(tevent_handler&, bool&) {}
/** Scrollwheel to the left see mouse_wheel_up.*/
virtual void mouse_wheel_left(tevent_handler&, bool&) {}
/** Scrollwheel to the right see mouse_wheel_up.*/
virtual void mouse_wheel_right(tevent_handler&, bool&) {}
/***** ***** ***** ***** focus ***** ***** ***** *****/
/**

View file

@ -150,6 +150,16 @@ void tevent_handler::handle_event(const SDL_Event& event)
case SDL_MOUSEBUTTONDOWN:
// The wheel buttons generate and up and down event we handle the
// up event so ignore the mouse if it's a down event
if(event.button.button == SDL_BUTTON_WHEELUP
|| event.button.button == SDL_BUTTON_WHEELDOWN
|| event.button.button == SDL_BUTTON_WHEELLEFT
|| event.button.button == SDL_BUTTON_WHEELRIGHT) {
break;
}
mouse_x_ = event.button.x;
mouse_y_ = event.button.y;
mouse_over = find_widget(tpoint(mouse_x_, mouse_y_), true);
@ -184,8 +194,7 @@ void tevent_handler::handle_event(const SDL_Event& event)
// cast to avoid being printed as char.
WRN_G_E << "Unhandled 'mouse button down' event for button "
<< static_cast<Uint32>(event.button.button) << ".\n";
// The scrollwheel also behaves like a button, so ignore it.
// assert(false);
assert(false);
break;
}
break;
@ -219,12 +228,19 @@ void tevent_handler::handle_event(const SDL_Event& event)
DBG_G_E << "Event: Right button up.\n";
mouse_button_up(event, mouse_over, right_);
break;
case SDL_BUTTON_WHEELUP :
case SDL_BUTTON_WHEELDOWN :
case SDL_BUTTON_WHEELLEFT :
case SDL_BUTTON_WHEELRIGHT :
DBG_G_E << "Event: Wheel\n";
mouse_wheel(event,
find_widget(tpoint(mouse_x_, mouse_y_), false));
break;
default:
// cast to avoid being printed as char.
WRN_G_E << "Unhandled 'mouse button up' event for button "
<< static_cast<Uint32>(event.button.button) << ".\n";
// The scrollwheel also behaves like a button, so ignore it.
// assert(false);
assert(false);
break;
}
break;
@ -533,6 +549,49 @@ void tevent_handler::mouse_click(twidget* widget, tmouse_button& button)
}
}
void tevent_handler::mouse_wheel(const SDL_Event& event, twidget* widget)
{
// If widget == NULL the loop won't run so no need for an explicit test.
bool handled = false;
while(widget != NULL && !handled) {
tcontrol* control = dynamic_cast<tcontrol*>(widget);
if(!control || control->get_active()) {
switch(event.button.button) {
case SDL_BUTTON_WHEELUP :
DBG_G_E << "Event: Wheel up.\n";
widget->mouse_wheel_up(*this, handled);
break;
case SDL_BUTTON_WHEELDOWN :
DBG_G_E << "Event: Wheel down.\n";
widget->mouse_wheel_down(*this, handled);
break;
case SDL_BUTTON_WHEELLEFT :
DBG_G_E << "Event: Wheel left.\n";
widget->mouse_wheel_left(*this, handled);
break;
case SDL_BUTTON_WHEELRIGHT :
DBG_G_E << "Event: Wheel right.\n";
widget->mouse_wheel_right(*this, handled);
break;
default:
// cast to avoid being printed as char.
WRN_G_E << "Unhandled wheel event for button "
<< static_cast<Uint32>(event.button.button) << ".\n";
assert(false);
break;
}
}
// If we handled the window abort.
if(dynamic_cast<twindow*>(widget)) {
return;
}
widget = widget->parent();
}
}
void tevent_handler::focus_parent_container(twidget* widget)
{
assert(widget);

View file

@ -310,6 +310,22 @@ private:
*/
void mouse_click(twidget* widget, tmouse_button& button);
/**
* Called when a scroll wheel is scrolled.
*
* The wheel event is always send to the widget underneath the mouse and
* ignores the focus. If a widget doesn't handle the event it's send to
* its parent. The event won't escape the current window. The event moves
* up through inactive widgets.
*
* @todo document this event in the event handling document.
*
* @param event The SDL_Event which was triggered.
* @param widget The widget the mouse is over, this widget
* might not be active and be NULL so the code
* needs to test for it.
*/
void mouse_wheel(const SDL_Event& event, twidget* widget);
/**
* Called when a mouse button is pressed.

View file

@ -639,6 +639,54 @@ void tscrollbar_container::set_scrollbar_button_status()
}
}
void tscrollbar_container::
mouse_wheel_up(tevent_handler& /*event_handler*/, bool& handled)
{
assert(vertical_scrollbar_grid_ && vertical_scrollbar_);
if(vertical_scrollbar_grid_->is_visible()) {
vertical_scrollbar_->scroll(tscrollbar_::HALF_JUMP_BACKWARDS);
scrollbar_moved();
handled = true;
}
}
void tscrollbar_container::
mouse_wheel_down(tevent_handler& /*event_handler*/, bool& handled)
{
assert(vertical_scrollbar_grid_ && vertical_scrollbar_);
if(vertical_scrollbar_grid_->is_visible()) {
vertical_scrollbar_->scroll(tscrollbar_::HALF_JUMP_FORWARD);
scrollbar_moved();
handled = true;
}
}
void tscrollbar_container::
mouse_wheel_left(tevent_handler& /*event_handler*/, bool& handled)
{
assert(horizontal_scrollbar_grid_ && horizontal_scrollbar_);
if(horizontal_scrollbar_grid_->is_visible()) {
horizontal_scrollbar_->scroll(tscrollbar_::HALF_JUMP_BACKWARDS);
scrollbar_moved();
handled = true;
}
}
void tscrollbar_container::
mouse_wheel_right(tevent_handler& /*event_handler*/, bool& handled)
{
assert(horizontal_scrollbar_grid_ && horizontal_scrollbar_);
if(horizontal_scrollbar_grid_->is_visible()) {
horizontal_scrollbar_->scroll(tscrollbar_::HALF_JUMP_FORWARD);
scrollbar_moved();
handled = true;
}
}
void tscrollbar_container::handle_key_home(SDLMod /*modifier*/, bool& handled)
{
assert(vertical_scrollbar_ && horizontal_scrollbar_);

View file

@ -198,6 +198,20 @@ protected:
*/
void set_scrollbar_button_status();
/***** ***** ***** ***** mouse wheel functions ***** ***** ***** *****/
/** Inherited from tevent_executor. */
void mouse_wheel_up(tevent_handler& event_handler, bool& handled);
/** Inherited from tevent_executor. */
void mouse_wheel_down(tevent_handler& event_handler, bool& handled);
/** Inherited from tevent_executor. */
void mouse_wheel_left(tevent_handler& event_handler, bool& handled);
/** Inherited from tevent_executor. */
void mouse_wheel_right(tevent_handler& event_handler, bool& handled);
/***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
/**