From 22721e6729633f507a3df6c98ab440b536b1b24a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 12 Oct 2018 01:48:18 +0200 Subject: [PATCH] The WindowManager can now react to mouse events on the window title bar. --- Widgets/Event.h | 1 + Widgets/RootWidget.cpp | 1 - Widgets/WindowManager.cpp | 69 ++++++++++++++++++++++++++------------- Widgets/WindowManager.h | 10 ++++-- 4 files changed, 56 insertions(+), 25 deletions(-) diff --git a/Widgets/Event.h b/Widgets/Event.h index 070f21d947c..9dcde5827ec 100644 --- a/Widgets/Event.h +++ b/Widgets/Event.h @@ -40,6 +40,7 @@ public: bool isMouseEvent() const { return m_type == MouseMove || m_type == MouseDown || m_type == MouseUp; } bool isKeyEvent() const { return m_type == KeyUp || m_type == KeyDown; } + bool isPaintEvent() const { return m_type == Paint; } protected: explicit Event(Type type) : m_type(type) { } diff --git a/Widgets/RootWidget.cpp b/Widgets/RootWidget.cpp index dc3b260bad4..ed9c6ce891c 100644 --- a/Widgets/RootWidget.cpp +++ b/Widgets/RootWidget.cpp @@ -16,7 +16,6 @@ void RootWidget::onPaint(PaintEvent& event) //printf("RootWidget::onPaint\n"); Painter painter(*this); painter.fillRect(Rect(0, 0, 800, 600), Color(0x40, 0x40, 0x40)); - WindowManager::the().paintWindowFrames(); Widget::onPaint(event); } diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp index 84808a2d79f..fe7a6ce3386 100644 --- a/Widgets/WindowManager.cpp +++ b/Widgets/WindowManager.cpp @@ -8,6 +8,19 @@ extern TerminalWidget* g_tw; +static const int windowFrameWidth = 2; +static const int windowTitleBarHeight = 16; + +static inline Rect titleBarRectForWindow(const Window& window) +{ + return { + window.x() - windowFrameWidth, + window.y() - windowTitleBarHeight - windowFrameWidth, + window.width() + windowFrameWidth * 2, + windowTitleBarHeight + windowFrameWidth + }; +} + WindowManager& WindowManager::the() { static WindowManager* s_the = new WindowManager; @@ -16,6 +29,8 @@ WindowManager& WindowManager::the() WindowManager::WindowManager() { + m_windowBorderColor = Color(0x00, 0x00, 0x80); + m_windowTitleColor = Color(0xff, 0xff, 0xff); } WindowManager::~WindowManager() @@ -34,14 +49,7 @@ void WindowManager::paintWindowFrame(Window& window) printf("WM: paintWindowFrame {%p}, rect: %d,%d %dx%d\n", &window, window.rect().x(), window.rect().y(), window.rect().width(), window.rect().height()); - static const int windowFrameWidth = 2; - static const int windowTitleBarHeight = 16; - - Rect topRect { - window.x() - windowFrameWidth, - window.y() - windowTitleBarHeight - windowFrameWidth, - window.width() + windowFrameWidth * 2, - windowTitleBarHeight + windowFrameWidth }; + Rect topRect = titleBarRectForWindow(window); Rect bottomRect { window.x() - windowFrameWidth, @@ -63,25 +71,23 @@ void WindowManager::paintWindowFrame(Window& window) window.height() }; - static const Color windowBorderColor(0x00, 0x00, 0x80); - static const Color windowTitleColor(0xff, 0xff, 0xff); - Rect borderRect { topRect.x() - 1, topRect.y() - 1, topRect.width() + 2, windowFrameWidth + windowTitleBarHeight + window.rect().height() + 4 }; + p.drawRect(borderRect, Color(255, 255, 255)); borderRect.inflate(2, 2); - p.drawRect(borderRect, windowBorderColor); + p.drawRect(borderRect, m_windowBorderColor); - p.fillRect(topRect, windowBorderColor); - p.fillRect(bottomRect, windowBorderColor); - p.fillRect(leftRect, windowBorderColor); - p.fillRect(rightRect, windowBorderColor); + p.fillRect(topRect, m_windowBorderColor); + p.fillRect(bottomRect, m_windowBorderColor); + p.fillRect(leftRect, m_windowBorderColor); + p.fillRect(rightRect, m_windowBorderColor); - p.drawText(topRect, window.title(), Painter::TextAlignment::Center, windowTitleColor); + p.drawText(topRect, window.title(), Painter::TextAlignment::Center, m_windowTitleColor); } void WindowManager::addWindow(Window& window) @@ -108,11 +114,24 @@ void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const newRect.height()); } +void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event) +{ + byte r = (((double)rand()) / (double)RAND_MAX) * 255.0; + byte g = (((double)rand()) / (double)RAND_MAX) * 255.0; + byte b = (((double)rand()) / (double)RAND_MAX) * 255.0; + m_windowBorderColor = Color(r, g, b); + paintWindowFrame(window); +} + void WindowManager::processMouseEvent(MouseEvent& event) { - // First step: hit test windows. + // FIXME: Respect z-order of windows... for (auto* window : m_windows) { - // FIXME: z-order... + if (titleBarRectForWindow(*window).contains(event.position())) { + handleTitleBarMouseEvent(*window, event); + return; + } + 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()); @@ -129,6 +148,13 @@ void WindowManager::processMouseEvent(MouseEvent& event) result.widget->event(*localEvent); } +void WindowManager::handlePaintEvent(PaintEvent& event) +{ + printf("[WM] paint event\n"); + m_rootWidget->event(event); + paintWindowFrames(); +} + void WindowManager::event(Event& event) { if (event.isMouseEvent()) @@ -140,9 +166,8 @@ void WindowManager::event(Event& event) return focusedWidget->event(event); } - if (event.type() == Event::Paint) { - return m_rootWidget->event(event); - } + if (event.isPaintEvent()) + return handlePaintEvent(static_cast(event)); return Object::event(event); } diff --git a/Widgets/WindowManager.h b/Widgets/WindowManager.h index 6b188315142..a4c6ce1b108 100644 --- a/Widgets/WindowManager.h +++ b/Widgets/WindowManager.h @@ -2,16 +2,17 @@ #include "Object.h" #include "Rect.h" +#include "Color.h" #include class MouseEvent; +class PaintEvent; class Widget; class Window; class WindowManager : public Object { public: - static WindowManager& the(); - + static WindowManager& the(); void addWindow(Window&); void paintWindowFrames(); @@ -26,9 +27,14 @@ private: ~WindowManager(); void processMouseEvent(MouseEvent&); + void handleTitleBarMouseEvent(Window&, MouseEvent&); + void handlePaintEvent(PaintEvent&); virtual void event(Event&) override; + Color m_windowBorderColor; + Color m_windowTitleColor; + void paintWindowFrame(Window&); HashTable m_windows; Widget* m_rootWidget { nullptr };