| | |
| | | // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) |
| | | // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) |
| | | // SPDX-License-Identifier: Apache-2.0 |
| | | |
| | | #include "quickwindowagent.h" |
| | | #include "quickwindowagent_p.h" |
| | | #include "quickitemdelegate_p.h" |
| | | |
| | | #include <QtQuick/QQuickWindow> |
| | | #include <QtQuick/QQuickPaintedItem> |
| | | #include <QtQuick/private/qquickitem_p.h> |
| | | #include <QtQuick/private/qquickanchors_p.h> |
| | | |
| | | #include "quickitemdelegate_p.h" |
| | | |
| | | namespace QWK { |
| | | |
| | | class BorderItem : public QQuickPaintedItem { |
| | | Q_OBJECT |
| | | public: |
| | | explicit BorderItem(AbstractWindowContext *ctx, QQuickItem *parent = nullptr); |
| | | ~BorderItem() override; |
| | | /*! |
| | | \class QuickWindowAgent |
| | | \brief QuickWindowAgent is the window agent for QtQuick. |
| | | |
| | | void updateHeight(); |
| | | It provides interfaces for QtQuick and processes some Qt events related to the QQuickItem |
| | | instance. The usage of all APIs is consistent with the \a Widgets module. |
| | | */ |
| | | |
| | | public: |
| | | void paint(QPainter *painter) override; |
| | | void itemChange(ItemChange change, const ItemChangeData &data) override; |
| | | QuickWindowAgentPrivate::QuickWindowAgentPrivate() = default; |
| | | |
| | | private: |
| | | AbstractWindowContext *context; |
| | | |
| | | void _q_windowActivityChanged(); |
| | | }; |
| | | |
| | | 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(10); |
| | | } |
| | | |
| | | BorderItem::~BorderItem() = default; |
| | | |
| | | void BorderItem::updateHeight() { |
| | | bool native = false; |
| | | quint32 thickness = 0; |
| | | void *args[] = { |
| | | &native, |
| | | &thickness, |
| | | }; |
| | | context->virtual_hook(AbstractWindowContext::BorderThicknessHook, &args); |
| | | setHeight(thickness); |
| | | } |
| | | |
| | | void BorderItem::paint(QPainter *painter) { |
| | | QRect rect(QPoint(0, 0), size().toSize()); |
| | | QRegion region(rect); |
| | | void *args[] = { |
| | | painter, |
| | | &rect, |
| | | ®ion, |
| | | }; |
| | | 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, |
| | | &BorderItem::_q_windowActivityChanged); |
| | | } |
| | | Q_FALLTHROUGH(); |
| | | case ItemVisibleHasChanged: |
| | | case ItemDevicePixelRatioHasChanged: |
| | | updateHeight(); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | void BorderItem::_q_windowActivityChanged() { |
| | | update(); |
| | | } |
| | | |
| | | QuickWindowAgentPrivate::QuickWindowAgentPrivate() { |
| | | } |
| | | |
| | | QuickWindowAgentPrivate::~QuickWindowAgentPrivate() { |
| | | } |
| | | QuickWindowAgentPrivate::~QuickWindowAgentPrivate() = default; |
| | | |
| | | void QuickWindowAgentPrivate::init() { |
| | | } |
| | |
| | | : QuickWindowAgent(*new QuickWindowAgentPrivate(), parent) { |
| | | } |
| | | |
| | | QuickWindowAgent::~QuickWindowAgent() { |
| | | } |
| | | QuickWindowAgent::~QuickWindowAgent() = default; |
| | | |
| | | bool QuickWindowAgent::setup(QQuickWindow *window) { |
| | | Q_ASSERT(window); |
| | |
| | | return false; |
| | | } |
| | | |
| | | if (!d->setup(window, new QuickItemDelegate())) { |
| | | return false; |
| | | } |
| | | d->setup(window, new QuickItemDelegate()); |
| | | d->hostWindow = window; |
| | | |
| | | if (bool needPaintBorder = false; |
| | | d->context->virtual_hook(AbstractWindowContext::NeedsDrawBordersHook, &needPaintBorder), |
| | | needPaintBorder) { |
| | | d->borderItem = std::make_unique<BorderItem>(d->context.get(), window->contentItem()); |
| | | } |
| | | #if defined(Q_OS_WINDOWS) && QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS) |
| | | d->setupWindows10BorderWorkaround(); |
| | | #endif |
| | | return true; |
| | | } |
| | | |
| | |
| | | if (!d->context->setTitleBar(item)) { |
| | | return; |
| | | } |
| | | #ifdef Q_OS_MAC |
| | | setSystemButtonArea(nullptr); |
| | | #endif |
| | | Q_EMIT titleBarWidgetChanged(item); |
| | | } |
| | | |
| | |
| | | Q_EMIT systemButtonChanged(button, item); |
| | | } |
| | | |
| | | #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) |
| | | bool QuickWindowAgent::isHitTestVisible(QQuickItem *item) const { |
| | | #else |
| | | bool QuickWindowAgent::isHitTestVisible(const QQuickItem *item) const { |
| | | #endif |
| | | Q_D(const QuickWindowAgent); |
| | | return d->context->isHitTestVisible(item); |
| | | } |
| | | |
| | | void QuickWindowAgent::setHitTestVisible_item(const QQuickItem *item, bool visible) { |
| | | void QuickWindowAgent::setHitTestVisible(QQuickItem *item, bool visible) { |
| | | Q_D(QuickWindowAgent); |
| | | d->context->setHitTestVisible(item, visible); |
| | | } |
| | | |
| | | void QuickWindowAgent::setHitTestVisible_rect(const QRect &rect, bool visible) { |
| | | Q_D(QuickWindowAgent); |
| | | d->context->setHitTestVisible(rect, visible); |
| | | } |
| | | |
| | | /*! |
| | | \internal |
| | | */ |
| | | QuickWindowAgent::QuickWindowAgent(QuickWindowAgentPrivate &d, QObject *parent) |
| | | : WindowAgentBase(d, parent) { |
| | | d.init(); |
| | | } |
| | | |
| | | } |
| | | |
| | | #include "quickwindowagent.moc" |