KDDockWidgets API Documentation 2.0
Loading...
Searching...
No Matches
qtquick/Platform.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2020 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6
7 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8
9 Contact KDAB at <info@kdab.com> for commercial licensing options.
10*/
11
12#include "Platform.h"
13#include "core/Utils_p.h"
14#include "kddockwidgets/KDDockWidgets.h"
15#include "kddockwidgets/qtcommon/View.h"
16#include "Config.h"
17#include "QmlTypes.h"
18
19#include "Helpers_p.h"
20#include "Window_p.h"
21#include "views/View.h"
22#include "qtquick/Window_p.h"
23#include "core/DockRegistry.h"
24#include "core/Platform_p.h"
25#include "ViewFactory.h"
26#include "views/ViewWrapper_p.h"
27
28#include "views/DockWidget.h"
30
31#include <QQmlEngine>
32#include <QQuickStyle>
33#include <QQuickWindow>
34#include <QWindow>
35#include <QScreen>
36#include <QQuickItem>
37#include <QGuiApplication>
38#include <QQmlContext>
39
40#if defined(KDDOCKWIDGETS_STATICLIB) || defined(QT_STATIC)
41static void initResources()
42{
43 Q_INIT_RESOURCE(kddockwidgets_resources);
44 Q_INIT_RESOURCE(kddockwidgets_qtquick);
45}
46#endif
47
48using namespace KDDockWidgets;
49using namespace KDDockWidgets::QtQuick;
50
51inline QQuickItem *mouseAreaForPos(QQuickItem *item, QPointF globalPos)
52{
53 QRectF rect = item->boundingRect();
54 rect.moveTopLeft(item->mapToGlobal(QPointF(0, 0)));
55
56 // Assumes children are inside its parent. That's fine for KDDW's purposes.
57 if (!rect.contains(globalPos)) {
58 return nullptr;
59 }
60
61 const QList<QQuickItem *> children = item->childItems();
62
63 for (auto it = children.rbegin(), end = children.rend(); it != end; ++it) {
64 if (QQuickItem *receiver = mouseAreaForPos(*it, globalPos))
65 return receiver;
66 }
67
68 if (QLatin1String(item->metaObject()->className()) == QLatin1String("QQuickMouseArea"))
69 return item;
70
71 return nullptr;
72}
73
75 : m_qquickHelpers(new QtQuickHelpers())
76{
77 init();
78}
79
80void Platform::init()
81{
82#if defined(KDDOCKWIDGETS_STATICLIB) || defined(QT_STATIC)
83 initResources();
84#endif
85
87 QQuickWindow::setDefaultAlphaBuffer(true);
88
89 qGuiApp->connect(qApp, &QGuiApplication::focusObjectChanged, qApp, [this](QObject *obj) {
90 d->focusedViewChanged.emit(ViewWrapper::create(obj));
91 });
92}
93
95{
96 delete m_qquickHelpers;
97}
98
99const char *Platform::name() const
100{
101 return "qtquick";
102}
103
104std::shared_ptr<Core::View> Platform::qobjectAsView(QObject *obj) const
105{
106 if (obj && isWayland()) {
107 if (auto dropArea = obj->property("dropAreaCpp").value<QObject *>()) {
108 // This is a special case for QtQuick on wayland
109 // The receiver of QDrag events needs to be a View. Which for QtWidgets is straightforward
110 // but for QtQuick it's the .qml item receiving it
111 obj = dropArea;
112 }
113 }
114
115 return ViewWrapper::create(obj);
116}
117
118std::shared_ptr<Core::Window> Platform::windowFromQWindow(QWindow *qwindow) const
119{
120 return std::shared_ptr<Core::Window>(new Window(qwindow));
121}
122
127
128Core::Window::Ptr Platform::windowAt(QPoint globalPos) const
129{
130 if (auto qwindow = qGuiApp->QGuiApplication::topLevelAt(globalPos)) {
131 auto window = new Window(qwindow);
132 return Core::Window::Ptr(window);
133 }
134
135 return {};
136}
137
139{
140 if (auto item = qobject_cast<QQuickItem *>(QtCommon::View_qt::asQObject(view))) {
141 if (QWindow *qtwindow = item->window())
142 return screenNumberForQWindow(qtwindow);
143 }
144
145 return -1;
146}
147
149{
150 if (auto item = qobject_cast<QQuickItem *>(QtCommon::View_qt::asQObject(view))) {
151 if (QWindow *qtwindow = item->window())
152 if (QScreen *screen = qtwindow->screen())
153 return screen->size();
154 }
155
156 return {};
157}
158
159QQmlEngine *Platform::qmlEngine() const
160{
161 if (!m_qmlEngine)
162 qWarning() << "Please call KDDockWidgets::QtQuick::Platform::self()->setQmlEngine(engine)";
163
164 return m_qmlEngine;
165}
166
167void Platform::setQmlEngine(QQmlEngine *qmlEngine)
168{
169 if (m_qmlEngine) {
170 qWarning() << Q_FUNC_INFO << "Already has QML engine";
171 return;
172 }
173
174 if (!qmlEngine) {
175 qWarning() << Q_FUNC_INFO << "Null QML engine";
176 return;
177 }
178
179 m_qmlEngine = qmlEngine;
180
181 auto dr = DockRegistry::self(); // make sure our QML types are registered
182 QQmlContext *context = qmlEngine->rootContext();
183 context->setContextProperty(QStringLiteral("_kddwHelpers"), m_qquickHelpers);
184 context->setContextProperty(QStringLiteral("_kddwDockRegistry"), dr);
185 context->setContextProperty(QStringLiteral("_kddw_widgetFactory"),
187}
188
190{
191 return static_cast<ViewFactory *>(Config::self().viewFactory());
192}
193
195{
196 return new QtQuick::View(controller, Core::ViewType::None, QtQuick::asQQuickItem(parent));
197}
198
201{
202 auto p = Core::Platform::instance();
203 if (p->isQtQuick())
204 return static_cast<Platform *>(p);
205 return nullptr;
206}
207
209{
210 // For QtQuick we use the global event filter as mouse delivery is flaky
211 // For example, the same QQuickItem that receives the press isn't receiving the mouse moves
212 // when the top-level window moves.
213 return true;
214}
215
217{
218 auto window = qobject_cast<QQuickWindow *>(qGuiApp->topLevelAt(globalPos));
219 if (!window)
220 return false;
221
222 QQuickItem *item = mouseAreaForPos(window->contentItem(), globalPos);
223 if (!item)
224 return false;
225 return item->objectName() != QLatin1String("draggableMouseArea");
226}
227
229{
230 const QWindowList windows = qGuiApp->topLevelWindows();
231 for (QWindow *window : windows) {
232 if (auto quickWindow = qobject_cast<QQuickWindow *>(window)) {
233 if (QQuickItem *grabber = quickWindow->mouseGrabberItem())
234 grabber->ungrabMouse();
235 }
236 }
237}
238
240{
241 if (!item)
242 return nullptr;
243
244 if (auto dwView = qobject_cast<QtQuick::DockWidget *>(item))
245 return dwView->dockWidget();
246
247 if (auto dwi = qobject_cast<DockWidgetInstantiator *>(item))
248 if (auto view = dwi->dockWidget())
249 return view->dockWidget();
250
251 return nullptr;
252}
Application-wide config to tune certain behaviours of the framework.
Namespace-level methods related to registering QML types.
Core::ViewFactory * viewFactory() const
getter for the framework view factory
Definition Config.cpp:182
static Config & self()
returns the singleton Config instance
Definition Config.cpp:88
The DockWidget base-class. DockWidget and Core::DockWidget are only split in two so we can share some...
static Platform * instance()
Returns the platform singleton.
A factory class for allowing the user to customize some internal views. This is optional,...
static DockRegistry * self()
QVector< std::shared_ptr< Core::Window > > windows() const override
Returns all windows.
static QObject * asQObject(View *)
implements functions specific to a particular platform A platform can be for example qtwidgets,...
Core::View * createView(Core::Controller *controller, Core::View *parent=nullptr) const override
Create an empty view For Qt this would just returns a empty QWidget or QQuickItem other frontends can...
QSize screenSizeFor(Core::View *) const override
Returns the size of the screen where this view is in.
std::shared_ptr< Core::View > qobjectAsView(QObject *) const override
Returns the specified QObject casted to View Nullptr if it's not a view.
bool inDisallowedDragView(QPoint globalPos) const override
Core::ViewFactory * createDefaultViewFactory() override
Creates and returns the default ViewFactory.
const char * name() const override
Returns the name of the platform, only "qtwidgets" and "qtquick".
void ungrabMouse() override
Releases the mouse grab, if any.
bool usesFallbackMouseGrabber() const override
Return whether we use the global event filter based mouse grabber.
std::shared_ptr< Core::Window > windowAt(QPoint globalPos) const override
int screenNumberForView(Core::View *) const override
Returns the screen index for the specified view or window. It's up to the platform to decide how scre...
static Core::DockWidget * dockWidgetForItem(QQuickItem *)
std::shared_ptr< Core::Window > windowFromQWindow(QWindow *) const override
QtQuick::ViewFactory * viewFactory() const
The default ViewFactory for QtQuick frontend.
QQuickItem * asQQuickItem(Core::View *view)
Class to abstract QAction, so code still works with QtQuick and Flutter.
void registerQmlTypes()
Definition QmlTypes.cpp:21
void focusObjectChanged(QObject *focusObject)
QList::reverse_iterator rbegin()
QList::reverse_iterator rend()
QVariant property(const char *name) const const
bool contains(const QRectF &rectangle) const const
void moveTopLeft(const QPointF &position)
QQuickItem * mouseAreaForPos(QQuickItem *item, QPointF globalPos)
A factory class for allowing the user to customize some internal widgets.
T value() const const

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated by doxygen 1.9.8