diff --git a/Widgets/Event.h b/Widgets/Event.h index 2ab0aa6433..070f21d947 100644 --- a/Widgets/Event.h +++ b/Widgets/Event.h @@ -1,6 +1,7 @@ #pragma once #include +#include "Point.h" static const char* eventNames[] = { "Invalid", @@ -37,6 +38,9 @@ public: const char* name() const { return eventNames[(unsigned)m_type]; } + bool isMouseEvent() const { return m_type == MouseMove || m_type == MouseDown || m_type == MouseUp; } + bool isKeyEvent() const { return m_type == KeyUp || m_type == KeyDown; } + protected: explicit Event(Type type) : m_type(type) { } @@ -101,19 +105,18 @@ class MouseEvent : public Event { public: MouseEvent(Type type, int x, int y, MouseButton button = MouseButton::None) : Event(type) - , m_x(x) - , m_y(y) + , m_position(x, y) , m_button(button) { } - int x() const { return m_x; } - int y() const { return m_y; } + Point position() const { return m_position; } + int x() const { return m_position.x(); } + int y() const { return m_position.y(); } MouseButton button() const { return m_button; } private: - int m_x { 0 }; - int m_y { 0 }; + Point m_position; MouseButton m_button { MouseButton::None }; }; diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp index 9d48e1de95..7bf9a196ec 100644 --- a/Widgets/WindowManager.cpp +++ b/Widgets/WindowManager.cpp @@ -108,21 +108,32 @@ void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const newRect.height()); } -void WindowManager::event(Event& event) +void WindowManager::processMouseEvent(MouseEvent& event) { - if (event.type() == Event::MouseMove - || event.type() == Event::MouseDown - || event.type() == Event::MouseUp) { - auto& me = static_cast(event); - - auto result = m_rootWidget->hitTest(me.x(), me.y()); - //printf("hit test for %d,%d found: %s{%p} %d,%d\n", me.x(), me.y(), result.widget->className(), result.widget, result.localX, result.localY); - auto localEvent = make(event.type(), result.localX, result.localY, me.button()); - result.widget->event(*localEvent); - return Object::event(event); + // First step: hit test windows. + for (auto* window : m_windows) { + // FIXME: z-order... + if (window->rect().contains(event.position())) { + // FIXME: Re-use the existing event instead of crafting a new one? + auto localEvent = make(event.type(), event.x() - window->rect().x(), event.y() - window->rect().y(), event.button()); + return; + } } - if (event.type() == Event::KeyDown || event.type() == Event::KeyUp) { + // Otherwise: send it to root the root widget... + auto result = m_rootWidget->hitTest(event.x(), event.y()); + //printf("hit test for %d,%d found: %s{%p} %d,%d\n", me.x(), me.y(), result.widget->className(), result.widget, result.localX, result.localY); + // FIXME: Re-use the existing event instead of crafting a new one? + auto localEvent = make(event.type(), result.localX, result.localY, event.button()); + result.widget->event(*localEvent); +} + +void WindowManager::event(Event& event) +{ + if (event.isMouseEvent()) + return processMouseEvent(static_cast(event)); + + if (event.isKeyEvent()) { // FIXME: Implement proper focus. Widget* focusedWidget = g_tw; return focusedWidget->event(event); diff --git a/Widgets/WindowManager.h b/Widgets/WindowManager.h index 02b6ff2433..6b18831514 100644 --- a/Widgets/WindowManager.h +++ b/Widgets/WindowManager.h @@ -4,6 +4,7 @@ #include "Rect.h" #include +class MouseEvent; class Widget; class Window; @@ -24,6 +25,8 @@ private: WindowManager(); ~WindowManager(); + void processMouseEvent(MouseEvent&); + virtual void event(Event&) override; void paintWindowFrame(Window&);