mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 21:27:45 +00:00
WindowServer+LibGUI: Handle mouse wheel deltas in the mouse event stream.
The wheel events will end up in GWidget::mousewheel_event(GMouseEvent&) on the client-side. This patch also implements basic wheel scrolling in GScrollableWidget via this mechanism. :^)
This commit is contained in:
parent
dae8eb6454
commit
dab9901235
13 changed files with 58 additions and 25 deletions
|
@ -19,6 +19,7 @@ public:
|
|||
MouseMove,
|
||||
MouseDown,
|
||||
MouseUp,
|
||||
MouseWheel,
|
||||
Enter,
|
||||
Leave,
|
||||
KeyDown,
|
||||
|
@ -44,7 +45,6 @@ public:
|
|||
explicit GEvent(Type type) : CEvent(type) { }
|
||||
virtual ~GEvent() { }
|
||||
|
||||
bool is_mouse_event() const { return type() == MouseMove || type() == MouseDown || type() == MouseUp; }
|
||||
bool is_key_event() const { return type() == KeyUp || type() == KeyDown; }
|
||||
bool is_paint_event() const { return type() == Paint; }
|
||||
};
|
||||
|
@ -244,12 +244,13 @@ private:
|
|||
|
||||
class GMouseEvent final : public GEvent {
|
||||
public:
|
||||
GMouseEvent(Type type, const Point& position, unsigned buttons, GMouseButton button, unsigned modifiers)
|
||||
GMouseEvent(Type type, const Point& position, unsigned buttons, GMouseButton button, unsigned modifiers, int wheel_delta)
|
||||
: GEvent(type)
|
||||
, m_position(position)
|
||||
, m_buttons(buttons)
|
||||
, m_button(button)
|
||||
, m_modifiers(modifiers)
|
||||
, m_wheel_delta(wheel_delta)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -259,10 +260,12 @@ public:
|
|||
GMouseButton button() const { return m_button; }
|
||||
unsigned buttons() const { return m_buttons; }
|
||||
unsigned modifiers() const { return m_modifiers; }
|
||||
int wheel_delta() const { return m_wheel_delta; }
|
||||
|
||||
private:
|
||||
Point m_position;
|
||||
unsigned m_buttons { 0 };
|
||||
GMouseButton m_button { GMouseButton::None };
|
||||
unsigned m_modifiers { 0 };
|
||||
int m_wheel_delta { 0 };
|
||||
};
|
||||
|
|
|
@ -152,13 +152,14 @@ void GEventLoop::handle_key_event(const WSAPI_ServerMessage& event, GWindow& win
|
|||
void GEventLoop::handle_mouse_event(const WSAPI_ServerMessage& event, GWindow& window)
|
||||
{
|
||||
#ifdef GEVENTLOOP_DEBUG
|
||||
dbgprintf("WID=%x MouseEvent %d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y);
|
||||
dbgprintf("WID=%x MouseEvent %d,%d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y, event.mouse.wheel_delta);
|
||||
#endif
|
||||
GMouseEvent::Type type;
|
||||
switch (event.type) {
|
||||
case WSAPI_ServerMessage::Type::MouseMove: type = GEvent::MouseMove; break;
|
||||
case WSAPI_ServerMessage::Type::MouseUp: type = GEvent::MouseUp; break;
|
||||
case WSAPI_ServerMessage::Type::MouseDown: type = GEvent::MouseDown; break;
|
||||
case WSAPI_ServerMessage::Type::MouseWheel: type = GEvent::MouseWheel; break;
|
||||
default: ASSERT_NOT_REACHED(); break;
|
||||
}
|
||||
GMouseButton button { GMouseButton::None };
|
||||
|
@ -169,7 +170,7 @@ void GEventLoop::handle_mouse_event(const WSAPI_ServerMessage& event, GWindow& w
|
|||
case WSAPI_MouseButton::Middle: button = GMouseButton::Middle; break;
|
||||
default: ASSERT_NOT_REACHED(); break;
|
||||
}
|
||||
post_event(window, make<GMouseEvent>(type, event.mouse.position, event.mouse.buttons, button, event.mouse.modifiers));
|
||||
post_event(window, make<GMouseEvent>(type, event.mouse.position, event.mouse.buttons, button, event.mouse.modifiers, event.mouse.wheel_delta));
|
||||
}
|
||||
|
||||
void GEventLoop::handle_menu_event(const WSAPI_ServerMessage& event)
|
||||
|
@ -276,6 +277,7 @@ void GEventLoop::process_unprocessed_bundles()
|
|||
case WSAPI_ServerMessage::Type::MouseDown:
|
||||
case WSAPI_ServerMessage::Type::MouseUp:
|
||||
case WSAPI_ServerMessage::Type::MouseMove:
|
||||
case WSAPI_ServerMessage::Type::MouseWheel:
|
||||
handle_mouse_event(event, *window);
|
||||
break;
|
||||
case WSAPI_ServerMessage::Type::WindowActivated:
|
||||
|
|
|
@ -27,6 +27,12 @@ GScrollableWidget::~GScrollableWidget()
|
|||
{
|
||||
}
|
||||
|
||||
void GScrollableWidget::mousewheel_event(GMouseEvent& event)
|
||||
{
|
||||
// FIXME: The wheel delta multiplier should probably come from... somewhere?
|
||||
vertical_scrollbar().set_value(vertical_scrollbar().value() + event.wheel_delta() * 20);
|
||||
}
|
||||
|
||||
void GScrollableWidget::resize_event(GResizeEvent& event)
|
||||
{
|
||||
auto inner_rect = frame_inner_rect_for_size(event.size());
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
protected:
|
||||
explicit GScrollableWidget(GWidget* parent);
|
||||
virtual void resize_event(GResizeEvent&) override;
|
||||
virtual void mousewheel_event(GMouseEvent&) override;
|
||||
virtual void did_scroll() { }
|
||||
void set_content_size(const Size&);
|
||||
void set_size_occupied_by_fixed_elements(const Size&);
|
||||
|
|
|
@ -86,6 +86,8 @@ void GWidget::event(CEvent& event)
|
|||
return handle_mousedown_event(static_cast<GMouseEvent&>(event));
|
||||
case GEvent::MouseUp:
|
||||
return handle_mouseup_event(static_cast<GMouseEvent&>(event));
|
||||
case GEvent::MouseWheel:
|
||||
return mousewheel_event(static_cast<GMouseEvent&>(event));
|
||||
case GEvent::Enter:
|
||||
return handle_enter_event(event);
|
||||
case GEvent::Leave:
|
||||
|
@ -261,6 +263,10 @@ void GWidget::mousemove_event(GMouseEvent&)
|
|||
{
|
||||
}
|
||||
|
||||
void GWidget::mousewheel_event(GMouseEvent&)
|
||||
{
|
||||
}
|
||||
|
||||
void GWidget::context_menu_event(GContextMenuEvent&)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
virtual void mousemove_event(GMouseEvent&);
|
||||
virtual void mousedown_event(GMouseEvent&);
|
||||
virtual void mouseup_event(GMouseEvent&);
|
||||
virtual void mousewheel_event(GMouseEvent&);
|
||||
virtual void click_event(GMouseEvent&);
|
||||
virtual void doubleclick_event(GMouseEvent&);
|
||||
virtual void context_menu_event(GContextMenuEvent&);
|
||||
|
|
|
@ -170,19 +170,19 @@ void GWindow::set_override_cursor(GStandardCursor cursor)
|
|||
|
||||
void GWindow::event(CEvent& event)
|
||||
{
|
||||
if (event.type() == GEvent::MouseUp || event.type() == GEvent::MouseDown || event.type() == GEvent::MouseMove) {
|
||||
if (event.type() == GEvent::MouseUp || event.type() == GEvent::MouseDown || event.type() == GEvent::MouseMove || event.type() == GEvent::MouseWheel) {
|
||||
auto& mouse_event = static_cast<GMouseEvent&>(event);
|
||||
if (m_global_cursor_tracking_widget) {
|
||||
auto window_relative_rect = m_global_cursor_tracking_widget->window_relative_rect();
|
||||
Point local_point { mouse_event.x() - window_relative_rect.x(), mouse_event.y() - window_relative_rect.y() };
|
||||
auto local_event = make<GMouseEvent>((GEvent::Type)event.type(), local_point, mouse_event.buttons(), mouse_event.button(), mouse_event.modifiers());
|
||||
auto local_event = make<GMouseEvent>((GEvent::Type)event.type(), local_point, mouse_event.buttons(), mouse_event.button(), mouse_event.modifiers(), mouse_event.wheel_delta());
|
||||
m_global_cursor_tracking_widget->event(*local_event);
|
||||
return;
|
||||
}
|
||||
if (m_automatic_cursor_tracking_widget) {
|
||||
auto window_relative_rect = m_automatic_cursor_tracking_widget->window_relative_rect();
|
||||
Point local_point { mouse_event.x() - window_relative_rect.x(), mouse_event.y() - window_relative_rect.y() };
|
||||
auto local_event = make<GMouseEvent>((GEvent::Type)event.type(), local_point, mouse_event.buttons(), mouse_event.button(), mouse_event.modifiers());
|
||||
auto local_event = make<GMouseEvent>((GEvent::Type)event.type(), local_point, mouse_event.buttons(), mouse_event.button(), mouse_event.modifiers(), mouse_event.wheel_delta());
|
||||
m_automatic_cursor_tracking_widget->event(*local_event);
|
||||
if (mouse_event.buttons() == 0)
|
||||
m_automatic_cursor_tracking_widget = nullptr;
|
||||
|
@ -190,16 +190,14 @@ void GWindow::event(CEvent& event)
|
|||
}
|
||||
if (!m_main_widget)
|
||||
return;
|
||||
if (m_main_widget) {
|
||||
auto result = m_main_widget->hit_test(mouse_event.position());
|
||||
auto local_event = make<GMouseEvent>((GEvent::Type)event.type(), result.local_position, mouse_event.buttons(), mouse_event.button(), mouse_event.modifiers());
|
||||
ASSERT(result.widget);
|
||||
set_hovered_widget(result.widget);
|
||||
if (mouse_event.buttons() != 0 && !m_automatic_cursor_tracking_widget)
|
||||
m_automatic_cursor_tracking_widget = result.widget->make_weak_ptr();
|
||||
if (result.widget != m_global_cursor_tracking_widget.ptr())
|
||||
return result.widget->event(*local_event);
|
||||
}
|
||||
auto result = m_main_widget->hit_test(mouse_event.position());
|
||||
auto local_event = make<GMouseEvent>((GEvent::Type)event.type(), result.local_position, mouse_event.buttons(), mouse_event.button(), mouse_event.modifiers(), mouse_event.wheel_delta());
|
||||
ASSERT(result.widget);
|
||||
set_hovered_widget(result.widget);
|
||||
if (mouse_event.buttons() != 0 && !m_automatic_cursor_tracking_widget)
|
||||
m_automatic_cursor_tracking_widget = result.widget->make_weak_ptr();
|
||||
if (result.widget != m_global_cursor_tracking_widget.ptr())
|
||||
return result.widget->event(*local_event);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue