From 2f6c83c095724bbba0f43b2f2893ba73c17949a6 Mon Sep 17 00:00:00 2001
From: Zhao Yuhang <2546789017@qq.com>
Date: 周一, 11 12月 2023 21:57:40 +0800
Subject: [PATCH] add quick border

---
 src/quick/quickwindowagent.cpp |  105 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 88 insertions(+), 17 deletions(-)

diff --git a/src/quick/quickwindowagent.cpp b/src/quick/quickwindowagent.cpp
index be70ca6..74a032b 100644
--- a/src/quick/quickwindowagent.cpp
+++ b/src/quick/quickwindowagent.cpp
@@ -1,12 +1,83 @@
 #include "quickwindowagent.h"
 #include "quickwindowagent_p.h"
+#include "quickitemdelegate_p.h"
 
 #include <QtQuick/QQuickWindow>
-
-#include "quickitemdelegate_p.h"
-#include "quickwindowcontext_p.h"
+#include <QtQuick/QQuickPaintedItem>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickanchors_p.h>
 
 namespace QWK {
+
+    class BorderItem : public QQuickPaintedItem {
+        Q_OBJECT
+
+    public:
+        explicit BorderItem(AbstractWindowContext *ctx, QQuickItem *parent = nullptr);
+        ~BorderItem() override;
+
+        void updateHeight();
+
+        void paint(QPainter *painter) override;
+
+        void itemChange(ItemChange change, const ItemChangeData &data) override;
+
+    private:
+        AbstractWindowContext *context;
+    };
+
+    BorderItem::BorderItem(AbstractWindowContext *ctx, QQuickItem *parent) : QQuickPaintedItem(parent), context(ctx) {
+        setAntialiasing(true); // ### FIXME: do we need to enable or disable this?
+        setMipmap(true); // ### FIXME: do we need to enable or disable this?
+        setFillColor({}); // Will improve the performance a little bit.
+        setOpaquePainting(true); // Will also improve the performance, we don't draw semi-transparent borders of course.
+
+        auto parentPri = QQuickItemPrivate::get(parent);
+        auto anchors = QQuickItemPrivate::get(this)->anchors();
+        anchors->setTop(parentPri->top());
+        anchors->setLeft(parentPri->left());
+        anchors->setRight(parentPri->right());
+
+        setZ(std::numeric_limits<qreal>::max());
+    }
+
+    BorderItem::~BorderItem() = default;
+
+    void BorderItem::updateHeight() {
+        bool native = false;
+        quint32 thickness = 0;
+        void *args[] = { &native, &thickness };
+        context->virtual_hook(AbstractWindowContext::QueryBorderThicknessHook, &args);
+        setHeight(thickness);
+    }
+
+    void BorderItem::paint(QPainter *painter) {
+        auto rect = QRect{ QPoint{ 0, 0}, size().toSize() };
+        auto region = QRegion{ rect };
+        void *args[] = {
+            painter,
+            &rect,
+            &region
+        };
+        context->virtual_hook(AbstractWindowContext::DrawBordersHook, args);
+    }
+
+    void BorderItem::itemChange(ItemChange change, const ItemChangeData &data) {
+        QQuickPaintedItem::itemChange(change, data);
+        switch (change) {
+            case ItemSceneChange:
+                if (data.window) {
+                    connect(data.window, &QQuickWindow::activeChanged, this, [this](){ update(); });
+                }
+                Q_FALLTHROUGH();
+            case ItemVisibleHasChanged:
+            case ItemDevicePixelRatioHasChanged:
+                updateHeight();
+                break;
+            default:
+                break;
+        }
+    }
 
     QuickWindowAgentPrivate::QuickWindowAgentPrivate() {
     }
@@ -15,10 +86,7 @@
     }
 
     void QuickWindowAgentPrivate::init() {
-    }
-
-    AbstractWindowContext *QuickWindowAgentPrivate::createContext() const {
-        return new QuickWindowContext();
+        borderItem = std::make_unique<BorderItem>(context.get(), hostWindow->contentItem());
     }
 
     QuickWindowAgent::QuickWindowAgent(QObject *parent)
@@ -40,18 +108,18 @@
         }
 
         if (!d->setup(window, new QuickItemDelegate())) {
-            return true;
+            return false;
         }
         d->hostWindow = window;
         return true;
     }
 
-    const QQuickItem *QuickWindowAgent::titleBar() const {
+    QQuickItem *QuickWindowAgent::titleBar() const {
         Q_D(const QuickWindowAgent);
-        return static_cast<const QQuickItem *>(d->context->titleBar());
+        return static_cast<QQuickItem *>(d->context->titleBar());
     }
 
-    void QuickWindowAgent::setTitleBar(const QQuickItem *item) {
+    void QuickWindowAgent::setTitleBar(QQuickItem *item) {
         Q_D(QuickWindowAgent);
         if (!d->context->setTitleBar(item)) {
             return;
@@ -59,12 +127,12 @@
         Q_EMIT titleBarWidgetChanged(item);
     }
 
-    const QQuickItem *QuickWindowAgent::systemButton(SystemButton button) const {
+    QQuickItem *QuickWindowAgent::systemButton(SystemButton button) const {
         Q_D(const QuickWindowAgent);
-        return static_cast<const QQuickItem *>(d->context->systemButton(button));
+        return static_cast<QQuickItem *>(d->context->systemButton(button));
     }
 
-    void QuickWindowAgent::setSystemButton(SystemButton button, const QQuickItem *item) {
+    void QuickWindowAgent::setSystemButton(SystemButton button, QQuickItem *item) {
         Q_D(QuickWindowAgent);
         if (!d->context->setSystemButton(button, item)) {
             return;
@@ -77,18 +145,21 @@
         return d->context->isHitTestVisible(item);
     }
 
-    void QuickWindowAgent::setHitTestVisible(const QQuickItem *item, bool visible) {
+    void QuickWindowAgent::setHitTestVisible_item(const QQuickItem *item, bool visible) {
         Q_D(QuickWindowAgent);
         d->context->setHitTestVisible(item, visible);
     }
 
-    void QuickWindowAgent::setHitTestVisible(const QRect &rect, bool visible) {
+    void QuickWindowAgent::setHitTestVisible_rect(const QRect &rect, bool visible) {
         Q_D(QuickWindowAgent);
         d->context->setHitTestVisible(rect, visible);
     }
 
     QuickWindowAgent::QuickWindowAgent(QuickWindowAgentPrivate &d, QObject *parent)
-        : CoreWindowAgent(d, parent) {
+        : WindowAgentBase(d, parent) {
         d.init();
     }
+
 }
+
+#include "quickwindowagent.moc"
\ No newline at end of file

--
Gitblit v1.9.1