diff --git a/Widgets/AbstractScreen.cpp b/Widgets/AbstractScreen.cpp index 72e02439d9..d9453ca3be 100644 --- a/Widgets/AbstractScreen.cpp +++ b/Widgets/AbstractScreen.cpp @@ -3,12 +3,9 @@ #include "Event.h" #include "Widget.h" #include -#include "TerminalWidget.h" static AbstractScreen* s_the; -extern TerminalWidget* g_tw; - AbstractScreen& AbstractScreen::the() { ASSERT(s_the); @@ -28,35 +25,3 @@ AbstractScreen::~AbstractScreen() { } -void AbstractScreen::event(Event& event) -{ - if (event.type() == Event::MouseMove - || event.type() == Event::MouseDown - || event.type() == Event::MouseUp) { - auto& me = static_cast(event); - //printf("AbstractScreen::onMouseMove: %d, %d\n", me.x(), me.y()); - 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); - } - - if (event.type() == Event::KeyDown || event.type() == Event::KeyUp) { - // FIXME: Implement proper focus. - Widget* focusedWidget = g_tw; - return focusedWidget->event(event); - } - - return Object::event(event); -} - -void AbstractScreen::setRootWidget(Widget* widget) -{ - // FIXME: Should we support switching root widgets? - ASSERT(!m_rootWidget); - ASSERT(widget); - - m_rootWidget = widget; - EventLoop::main().postEvent(m_rootWidget, make()); -} diff --git a/Widgets/AbstractScreen.h b/Widgets/AbstractScreen.h index f56d7fdb28..fdf6bd33ca 100644 --- a/Widgets/AbstractScreen.h +++ b/Widgets/AbstractScreen.h @@ -2,8 +2,6 @@ #include "Object.h" -class Widget; - class AbstractScreen : public Object { public: virtual ~AbstractScreen(); @@ -11,20 +9,13 @@ public: unsigned width() const { return m_width; } unsigned height() const { return m_height; } - Widget* rootWidget() { return m_rootWidget; } - void setRootWidget(Widget*); - static AbstractScreen& the(); protected: AbstractScreen(unsigned width, unsigned height); private: - virtual void event(Event&) override; - unsigned m_width { 0 }; unsigned m_height { 0 }; - - Widget* m_rootWidget { nullptr }; }; diff --git a/Widgets/EventLoopSDL.cpp b/Widgets/EventLoopSDL.cpp index e0d670ca76..ad0d8a9060 100644 --- a/Widgets/EventLoopSDL.cpp +++ b/Widgets/EventLoopSDL.cpp @@ -1,9 +1,9 @@ #include "EventLoopSDL.h" #include "Event.h" #include -#include "AbstractScreen.h" #include "Widget.h" #include "TerminalWidget.h" +#include "WindowManager.h" #include int g_fd; @@ -46,23 +46,23 @@ void EventLoopSDL::waitForEvent() if (sdlEvent.window.event == SDL_WINDOWEVENT_EXPOSED) { // Spam paint events whenever we get exposed. // This is obviously not ideal, but the SDL backend here is just a prototype anyway. - postEvent(AbstractScreen::the().rootWidget(), make()); + postEvent(&WindowManager::the(), make()); } return; case SDL_MOUSEMOTION: - postEvent(&AbstractScreen::the(), make(Event::MouseMove, sdlEvent.motion.x, sdlEvent.motion.y)); + postEvent(&WindowManager::the(), make(Event::MouseMove, sdlEvent.motion.x, sdlEvent.motion.y)); return; case SDL_MOUSEBUTTONDOWN: - postEvent(&AbstractScreen::the(), make(Event::MouseDown, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); + postEvent(&WindowManager::the(), make(Event::MouseDown, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); return; case SDL_MOUSEBUTTONUP: - postEvent(&AbstractScreen::the(), make(Event::MouseUp, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); + postEvent(&WindowManager::the(), make(Event::MouseUp, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); return; case SDL_KEYDOWN: - postEvent(&AbstractScreen::the(), make(Event::KeyDown, toKey(sdlEvent.key.keysym))); + postEvent(&WindowManager::the(), make(Event::KeyDown, toKey(sdlEvent.key.keysym))); return; case SDL_KEYUP: - postEvent(&AbstractScreen::the(), make(Event::KeyUp, toKey(sdlEvent.key.keysym))); + postEvent(&WindowManager::the(), make(Event::KeyUp, toKey(sdlEvent.key.keysym))); return; } } diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp index 1a21b194fb..9d48e1de95 100644 --- a/Widgets/WindowManager.cpp +++ b/Widgets/WindowManager.cpp @@ -3,6 +3,10 @@ #include "Widget.h" #include "Window.h" #include "AbstractScreen.h" +#include "TerminalWidget.h" +#include "EventLoop.h" + +extern TerminalWidget* g_tw; WindowManager& WindowManager::the() { @@ -26,7 +30,7 @@ void WindowManager::paintWindowFrames() void WindowManager::paintWindowFrame(Window& window) { - Painter p(*AbstractScreen::the().rootWidget()); + Painter p(*m_rootWidget); printf("WM: paintWindowFrame {%p}, rect: %d,%d %dx%d\n", &window, window.rect().x(), window.rect().y(), window.rect().width(), window.rect().height()); @@ -103,3 +107,40 @@ void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const newRect.width(), newRect.height()); } + +void WindowManager::event(Event& 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); + } + + if (event.type() == Event::KeyDown || event.type() == Event::KeyUp) { + // FIXME: Implement proper focus. + Widget* focusedWidget = g_tw; + return focusedWidget->event(event); + } + + if (event.type() == Event::Paint) { + return m_rootWidget->event(event); + } + + return Object::event(event); +} + +void WindowManager::setRootWidget(Widget* widget) +{ + // FIXME: Should we support switching root widgets? + ASSERT(!m_rootWidget); + ASSERT(widget); + + m_rootWidget = widget; + EventLoop::main().postEvent(m_rootWidget, make()); +} diff --git a/Widgets/WindowManager.h b/Widgets/WindowManager.h index 05a8798783..02b6ff2433 100644 --- a/Widgets/WindowManager.h +++ b/Widgets/WindowManager.h @@ -1,11 +1,12 @@ #pragma once -class Window; - #include "Object.h" #include "Rect.h" #include +class Widget; +class Window; + class WindowManager : public Object { public: static WindowManager& the(); @@ -16,11 +17,16 @@ public: void notifyTitleChanged(Window&); void notifyRectChanged(Window&, const Rect& oldRect, const Rect& newRect); + Widget* rootWidget() { return m_rootWidget; } + void setRootWidget(Widget*); + private: WindowManager(); ~WindowManager(); - void paintWindowFrame(Window&); + virtual void event(Event&) override; + void paintWindowFrame(Window&); HashTable m_windows; + Widget* m_rootWidget { nullptr }; }; diff --git a/Widgets/test.cpp b/Widgets/test.cpp index 9cd7b8580c..46f588fd72 100644 --- a/Widgets/test.cpp +++ b/Widgets/test.cpp @@ -16,9 +16,7 @@ int main(int c, char** v) EventLoopSDL loop; RootWidget w; - fb.setRootWidget(&w); - - WindowManager::the(); + WindowManager::the().setRootWidget(&w); auto* l1 = new Label(&w); l1->setRect(Rect(100, 100, 300, 20));