From 64127e06378259515006f876440ce0ecd5fa7728 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 12 Oct 2018 02:24:05 +0200 Subject: [PATCH] Very hacky support for dragging a window around. --- Widgets/Painter.cpp | 19 +++++++++++++ Widgets/Painter.h | 2 ++ Widgets/Rect.h | 5 ++++ Widgets/Widget.cpp | 2 +- Widgets/Window.h | 3 ++ Widgets/WindowManager.cpp | 58 ++++++++++++++++++++++++++++++--------- Widgets/WindowManager.h | 5 ++++ 7 files changed, 80 insertions(+), 14 deletions(-) diff --git a/Widgets/Painter.cpp b/Widgets/Painter.cpp index 19b38224b8..2d481a7f49 100644 --- a/Widgets/Painter.cpp +++ b/Widgets/Painter.cpp @@ -54,6 +54,25 @@ void Painter::drawRect(const Rect& rect, Color color) } } +void Painter::xorRect(const Rect& rect, Color color) +{ + Rect r = rect; + r.moveBy(m_widget.x(), m_widget.y()); + + for (int y = r.top(); y < r.bottom(); ++y) { + dword* bits = scanline(y); + if (y == r.top() || y == (r.bottom() - 1)) { + for (int x = r.left(); x < r.right(); ++x) { + bits[x] ^= color.value(); + } + } else { + bits[r.left()] ^= color.value(); + bits[r.right() - 1] ^= color.value(); + } + } +} + + void Painter::drawText(const Rect& rect, const String& text, TextAlignment alignment, const Color& color) { Point point; diff --git a/Widgets/Painter.h b/Widgets/Painter.h index 857815fd88..624ae4baac 100644 --- a/Widgets/Painter.h +++ b/Widgets/Painter.h @@ -17,6 +17,8 @@ public: void drawRect(const Rect&, Color); void drawText(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, const Color& = Color()); + void xorRect(const Rect&, Color); + const Font& font() const; private: diff --git a/Widgets/Rect.h b/Widgets/Rect.h index 339db76cd4..93d960434a 100644 --- a/Widgets/Rect.h +++ b/Widgets/Rect.h @@ -12,6 +12,11 @@ public: { } + bool isEmpty() const + { + return width() == 0 || height() == 0; + } + void moveBy(int dx, int dy) { m_location.moveBy(dx, dy); diff --git a/Widgets/Widget.cpp b/Widgets/Widget.cpp index 30de0f5d82..7c073042d8 100644 --- a/Widgets/Widget.cpp +++ b/Widgets/Widget.cpp @@ -49,7 +49,7 @@ void Widget::event(Event& event) void Widget::onPaint(PaintEvent& event) { - printf("Widget::onPaint :)\n"); + //printf("Widget::onPaint :)\n"); for (auto* ch : children()) { auto* child = (Widget*)ch; child->onPaint(event); diff --git a/Widgets/Window.h b/Widgets/Window.h index 1ce434c08c..93119c08f9 100644 --- a/Widgets/Window.h +++ b/Widgets/Window.h @@ -22,6 +22,9 @@ public: const Rect& rect() const { return m_rect; } void setRect(const Rect&); + Point position() const { return m_rect.location(); } + void setPosition(const Point& position) { setRect({ position.x(), position.y(), width(), height() }); } + Widget* mainWidget() { return m_mainWidget; } const Widget* mainWidget() const { return m_mainWidget; } diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp index fe7a6ce338..889676159a 100644 --- a/Widgets/WindowManager.cpp +++ b/Widgets/WindowManager.cpp @@ -47,7 +47,7 @@ void WindowManager::paintWindowFrame(Window& window) { 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()); + //printf("[WM] paintWindowFrame {%p}, rect: %d,%d %dx%d\n", &window, window.rect().x(), window.rect().y(), window.rect().width(), window.rect().height()); Rect topRect = titleBarRectForWindow(window); @@ -78,6 +78,18 @@ void WindowManager::paintWindowFrame(Window& window) windowFrameWidth + windowTitleBarHeight + window.rect().height() + 4 }; + if (!m_lastDragRect.isEmpty()) { + p.xorRect(m_lastDragRect, Color(255, 0, 0)); + m_lastDragRect = Rect(); + } + + if (m_dragWindow == &window) { + borderRect.inflate(2, 2); + p.xorRect(borderRect, Color(255, 0, 0)); + m_lastDragRect = borderRect; + return; + } + p.drawRect(borderRect, Color(255, 255, 255)); borderRect.inflate(2, 2); p.drawRect(borderRect, m_windowBorderColor); @@ -97,34 +109,54 @@ void WindowManager::addWindow(Window& window) void WindowManager::notifyTitleChanged(Window& window) { - printf("[WM] ]Window{%p} title set to '%s'\n", &window, window.title().characters()); + //printf("[WM] Window{%p} title set to '%s'\n", &window, window.title().characters()); } void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const Rect& newRect) { - printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", - &window, - oldRect.x(), - oldRect.y(), - oldRect.width(), - oldRect.height(), - newRect.x(), - newRect.y(), - newRect.width(), - newRect.height()); + //printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, oldRect.x(), oldRect.y(), oldRect.width(), oldRect.height(), newRect.x(), newRect.y(), newRect.width(), newRect.height()); } void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event) { + if (event.type() == Event::MouseDown) { + printf("[WM] Begin dragging Window{%p}\n", &window); + m_dragWindow = &window; + m_dragOrigin = event.position(); + m_dragWindowOrigin = window.position(); + return; + } +#if 0 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); +#endif } void WindowManager::processMouseEvent(MouseEvent& event) { + if (event.type() == Event::MouseUp) { + if (m_dragWindow) { + printf("[WM] Finish dragging Window{%p}\n", m_dragWindow); + m_dragWindow = nullptr; + EventLoop::main().postEvent(this, make()); + return; + } + } + + if (event.type() == Event::MouseMove) { + if (m_dragWindow) { + Point pos = m_dragWindowOrigin; + printf("[WM] Dragging [origin: %d,%d] now: %d,%d\n", m_dragOrigin.x(), m_dragOrigin.y(), event.x(), event.y()); + pos.moveBy(event.x() - m_dragOrigin.x(), event.y() - m_dragOrigin.y()); + m_dragWindow->setPosition(pos); + paintWindowFrame(*m_dragWindow); + return; + } + } + // FIXME: Respect z-order of windows... for (auto* window : m_windows) { if (titleBarRectForWindow(*window).contains(event.position())) { @@ -150,7 +182,7 @@ void WindowManager::processMouseEvent(MouseEvent& event) void WindowManager::handlePaintEvent(PaintEvent& event) { - printf("[WM] paint event\n"); + //printf("[WM] paint event\n"); m_rootWidget->event(event); paintWindowFrames(); } diff --git a/Widgets/WindowManager.h b/Widgets/WindowManager.h index a4c6ce1b10..a81135f0fa 100644 --- a/Widgets/WindowManager.h +++ b/Widgets/WindowManager.h @@ -38,4 +38,9 @@ private: void paintWindowFrame(Window&); HashTable m_windows; Widget* m_rootWidget { nullptr }; + + Window* m_dragWindow { nullptr }; + Point m_dragOrigin; + Point m_dragWindowOrigin; + Rect m_lastDragRect; };