Skip to content

Commit 4a0f638

Browse files
committed
core/window: expose coordinate mapping functions on QsWindow
1 parent 6d42d26 commit 4a0f638

File tree

4 files changed

+215
-2
lines changed

4 files changed

+215
-2
lines changed

src/window/proxywindow.cpp

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
#include <qcoreevent.h>
55
#include <qevent.h>
66
#include <qguiapplication.h>
7+
#include <qlogging.h>
78
#include <qnamespace.h>
89
#include <qobject.h>
10+
#include <qpoint.h>
911
#include <qqmlcontext.h>
1012
#include <qqmlengine.h>
1113
#include <qqmlinfo.h>
@@ -461,12 +463,71 @@ QQmlListProperty<QObject> ProxyWindowBase::data() {
461463
void ProxyWindowBase::onWidthChanged() { this->mContentItem->setWidth(this->width()); }
462464
void ProxyWindowBase::onHeightChanged() { this->mContentItem->setHeight(this->height()); }
463465

466+
QPointF ProxyWindowBase::itemPosition(QQuickItem* item) const {
467+
if (!item) {
468+
qCritical() << "Cannot map position of null item.";
469+
return {};
470+
}
471+
472+
return this->mContentItem->mapFromItem(item, 0, 0);
473+
}
474+
475+
QRectF ProxyWindowBase::itemRect(QQuickItem* item) const {
476+
if (!item) {
477+
qCritical() << "Cannot map position of null item.";
478+
return {};
479+
}
480+
481+
return this->mContentItem->mapFromItem(item, item->boundingRect());
482+
}
483+
484+
QPointF ProxyWindowBase::mapFromItem(QQuickItem* item, QPointF point) const {
485+
if (!item) {
486+
qCritical() << "Cannot map position of null item.";
487+
return {};
488+
}
489+
490+
return this->mContentItem->mapFromItem(item, point);
491+
}
492+
493+
QPointF ProxyWindowBase::mapFromItem(QQuickItem* item, qreal x, qreal y) const {
494+
if (!item) {
495+
qCritical() << "Cannot map position of null item.";
496+
return {};
497+
}
498+
499+
return this->mContentItem->mapFromItem(item, x, y);
500+
}
501+
502+
QRectF ProxyWindowBase::mapFromItem(QQuickItem* item, QRectF rect) const {
503+
if (!item) {
504+
qCritical() << "Cannot map position of null item.";
505+
return {};
506+
}
507+
508+
return this->mContentItem->mapFromItem(item, rect);
509+
}
510+
511+
QRectF
512+
ProxyWindowBase::mapFromItem(QQuickItem* item, qreal x, qreal y, qreal width, qreal height) const {
513+
if (!item) {
514+
qCritical() << "Cannot map position of null item.";
515+
return {};
516+
}
517+
518+
return this->mContentItem->mapFromItem(item, x, y, width, height);
519+
}
520+
464521
ProxyWindowAttached::ProxyWindowAttached(QQuickItem* parent): QsWindowAttached(parent) {
465522
this->updateWindow();
466523
}
467524

468-
QObject* ProxyWindowAttached::window() const { return this->mWindow; }
469-
QQuickItem* ProxyWindowAttached::contentItem() const { return this->mWindow->contentItem(); }
525+
QObject* ProxyWindowAttached::window() const { return this->mWindowInterface; }
526+
ProxyWindowBase* ProxyWindowAttached::proxyWindow() const { return this->mWindow; }
527+
528+
QQuickItem* ProxyWindowAttached::contentItem() const {
529+
return this->mWindow ? this->mWindow->contentItem() : nullptr;
530+
}
470531

471532
void ProxyWindowAttached::updateWindow() {
472533
auto* window = static_cast<QQuickItem*>(this->parent())->window(); // NOLINT
@@ -481,6 +542,7 @@ void ProxyWindowAttached::updateWindow() {
481542
void ProxyWindowAttached::setWindow(ProxyWindowBase* window) {
482543
if (window == this->mWindow) return;
483544
this->mWindow = window;
545+
this->mWindowInterface = window ? qobject_cast<WindowInterface*>(window->parent()) : nullptr;
484546
emit this->windowChanged();
485547
}
486548

src/window/proxywindow.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <qevent.h>
66
#include <qnamespace.h>
77
#include <qobject.h>
8+
#include <qpoint.h>
89
#include <qproperty.h>
910
#include <qqmllist.h>
1011
#include <qqmlparserstatus.h>
@@ -13,6 +14,8 @@
1314
#include <qsurfaceformat.h>
1415
#include <qtmetamacros.h>
1516
#include <qtypes.h>
17+
#include <qvariant.h>
18+
#include <qvectornd.h>
1619
#include <qwindow.h>
1720

1821
#include "../core/qmlscreen.hpp"
@@ -67,6 +70,14 @@ class ProxyWindowBase: public Reloadable {
6770
void operator=(ProxyWindowBase&) = delete;
6871
void operator=(ProxyWindowBase&&) = delete;
6972

73+
Q_INVOKABLE [[nodiscard]] QPointF itemPosition(QQuickItem* item) const;
74+
Q_INVOKABLE [[nodiscard]] QRectF itemRect(QQuickItem* item) const;
75+
Q_INVOKABLE [[nodiscard]] QPointF mapFromItem(QQuickItem* item, QPointF point) const;
76+
Q_INVOKABLE [[nodiscard]] QPointF mapFromItem(QQuickItem* item, qreal x, qreal y) const;
77+
Q_INVOKABLE [[nodiscard]] QRectF mapFromItem(QQuickItem* item, QRectF rect) const;
78+
Q_INVOKABLE [[nodiscard]] QRectF
79+
mapFromItem(QQuickItem* item, qreal x, qreal y, qreal width, qreal height) const;
80+
7081
void onReload(QObject* oldInstance) override;
7182
void ensureQWindow();
7283
void createWindow();
@@ -201,13 +212,15 @@ class ProxyWindowAttached: public QsWindowAttached {
201212
explicit ProxyWindowAttached(QQuickItem* parent);
202213

203214
[[nodiscard]] QObject* window() const override;
215+
[[nodiscard]] ProxyWindowBase* proxyWindow() const override;
204216
[[nodiscard]] QQuickItem* contentItem() const override;
205217

206218
protected:
207219
void updateWindow() override;
208220

209221
private:
210222
ProxyWindowBase* mWindow = nullptr;
223+
WindowInterface* mWindowInterface = nullptr;
211224

212225
void setWindow(ProxyWindowBase* window);
213226
};

src/window/windowinterface.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,96 @@
11
#include "windowinterface.hpp"
22

3+
#include <qlogging.h>
34
#include <qobject.h>
45
#include <qquickitem.h>
6+
#include <qtypes.h>
57

68
#include "proxywindow.hpp"
79

10+
QPointF WindowInterface::itemPosition(QQuickItem* item) const {
11+
return this->proxyWindow()->itemPosition(item);
12+
}
13+
14+
QRectF WindowInterface::itemRect(QQuickItem* item) const {
15+
return this->proxyWindow()->itemRect(item);
16+
}
17+
18+
QPointF WindowInterface::mapFromItem(QQuickItem* item, QPointF point) const {
19+
return this->proxyWindow()->mapFromItem(item, point);
20+
}
21+
22+
QPointF WindowInterface::mapFromItem(QQuickItem* item, qreal x, qreal y) const {
23+
return this->proxyWindow()->mapFromItem(item, x, y);
24+
}
25+
26+
QRectF WindowInterface::mapFromItem(QQuickItem* item, QRectF rect) const {
27+
return this->proxyWindow()->mapFromItem(item, rect);
28+
}
29+
30+
QRectF
31+
WindowInterface::mapFromItem(QQuickItem* item, qreal x, qreal y, qreal width, qreal height) const {
32+
return this->proxyWindow()->mapFromItem(item, x, y, width, height);
33+
}
34+
835
QsWindowAttached::QsWindowAttached(QQuickItem* parent): QObject(parent) {
936
QObject::connect(parent, &QQuickItem::windowChanged, this, &QsWindowAttached::updateWindow);
1037
}
1138

39+
QPointF QsWindowAttached::itemPosition(QQuickItem* item) const {
40+
if (auto* proxyWindow = this->proxyWindow()) {
41+
return proxyWindow->itemPosition(item);
42+
} else {
43+
qCritical() << "Cannot call itemPosition before item is a member of a window.";
44+
return {};
45+
}
46+
}
47+
48+
QRectF QsWindowAttached::itemRect(QQuickItem* item) const {
49+
if (auto* proxyWindow = this->proxyWindow()) {
50+
return proxyWindow->itemRect(item);
51+
} else {
52+
qCritical() << "Cannot call itemRect before item is a member of a window.";
53+
return {};
54+
}
55+
}
56+
57+
QPointF QsWindowAttached::mapFromItem(QQuickItem* item, QPointF point) const {
58+
if (auto* proxyWindow = this->proxyWindow()) {
59+
return proxyWindow->mapFromItem(item, point);
60+
} else {
61+
qCritical() << "Cannot call mapFromItem before item is a member of a window.";
62+
return {};
63+
}
64+
}
65+
66+
QPointF QsWindowAttached::mapFromItem(QQuickItem* item, qreal x, qreal y) const {
67+
if (auto* proxyWindow = this->proxyWindow()) {
68+
return proxyWindow->mapFromItem(item, x, y);
69+
} else {
70+
qCritical() << "Cannot call mapFromItem before item is a member of a window.";
71+
return {};
72+
}
73+
}
74+
75+
QRectF QsWindowAttached::mapFromItem(QQuickItem* item, QRectF rect) const {
76+
if (auto* proxyWindow = this->proxyWindow()) {
77+
return proxyWindow->mapFromItem(item, rect);
78+
} else {
79+
qCritical() << "Cannot call mapFromItem before item is a member of a window.";
80+
return {};
81+
}
82+
}
83+
84+
QRectF
85+
QsWindowAttached::mapFromItem(QQuickItem* item, qreal x, qreal y, qreal width, qreal height) const {
86+
if (auto* proxyWindow = this->proxyWindow()) {
87+
return proxyWindow->mapFromItem(item, x, y, width, height);
88+
} else {
89+
qCritical() << "Cannot call mapFromItem before item is a member of a window.";
90+
return {};
91+
}
92+
}
93+
1294
QsWindowAttached* WindowInterface::qmlAttachedProperties(QObject* object) {
1395
while (object && !qobject_cast<QQuickItem*>(object)) {
1496
object = object->parent();

src/window/windowinterface.hpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class QsSurfaceFormat {
4242
/// It provides the following properties
4343
/// - `window` - the `QSWindow` object.
4444
/// - `contentItem` - the `contentItem` property of the window.
45+
///
46+
/// @@itemPosition(), @@itemRect(), and @@mapFromItem() can also be called directly
47+
/// on the attached object.
4548
class WindowInterface: public Reloadable {
4649
Q_OBJECT;
4750
// clang-format off
@@ -150,6 +153,49 @@ class WindowInterface: public Reloadable {
150153
public:
151154
explicit WindowInterface(QObject* parent = nullptr): Reloadable(parent) {}
152155

156+
/// Returns the given Item's position relative to the window. Does not update reactively.
157+
///
158+
/// Equivalent to calling `window.contentItem.mapFromItem(item, 0, 0)`
159+
///
160+
/// See also: @@QtQuick.Item.mapFromItem()
161+
Q_INVOKABLE [[nodiscard]] QPointF itemPosition(QQuickItem* item) const;
162+
/// Returns the given Item's geometry relative to the window. Does not update reactively.
163+
///
164+
/// Equivalent to calling `window.contentItem.mapFromItem(item, 0, 0, 0, 0)`
165+
///
166+
/// See also: @@QtQuick.Item.mapFromItem()
167+
Q_INVOKABLE [[nodiscard]] QRectF itemRect(QQuickItem* item) const;
168+
/// Maps the given point in the coordinate space of `item` to one in the coordinate space
169+
/// of this window. Does not update reactively.
170+
///
171+
/// Equivalent to calling `window.contentItem.mapFromItem(item, point)`
172+
///
173+
/// See also: @@QtQuick.Item.mapFromItem()
174+
Q_INVOKABLE [[nodiscard]] QPointF mapFromItem(QQuickItem* item, QPointF point) const;
175+
/// Maps the given point in the coordinate space of `item` to one in the coordinate space
176+
/// of this window. Does not update reactively.
177+
///
178+
/// Equivalent to calling `window.contentItem.mapFromItem(item, x, y)`
179+
///
180+
/// See also: @@QtQuick.Item.mapFromItem()
181+
Q_INVOKABLE [[nodiscard]] QPointF mapFromItem(QQuickItem* item, qreal x, qreal y) const;
182+
/// Maps the given rect in the coordinate space of `item` to one in the coordinate space
183+
/// of this window. Does not update reactively.
184+
///
185+
/// Equivalent to calling `window.contentItem.mapFromItem(item, rect)`
186+
///
187+
/// See also: @@QtQuick.Item.mapFromItem()
188+
Q_INVOKABLE [[nodiscard]] QRectF mapFromItem(QQuickItem* item, QRectF rect) const;
189+
// clang-format off
190+
/// Maps the given rect in the coordinate space of `item` to one in the coordinate space
191+
/// of this window. Does not update reactively.
192+
///
193+
/// Equivalent to calling `window.contentItem.mapFromItem(item, x, y, width, height)`
194+
///
195+
/// See also: @@QtQuick.Item.mapFromItem()
196+
Q_INVOKABLE [[nodiscard]] QRectF mapFromItem(QQuickItem* item, qreal x, qreal y, qreal width, qreal height) const;
197+
// clang-format on
198+
153199
[[nodiscard]] virtual ProxyWindowBase* proxyWindow() const = 0;
154200
[[nodiscard]] virtual QQuickItem* contentItem() const = 0;
155201

@@ -213,8 +259,18 @@ class QsWindowAttached: public QObject {
213259

214260
public:
215261
[[nodiscard]] virtual QObject* window() const = 0;
262+
[[nodiscard]] virtual ProxyWindowBase* proxyWindow() const = 0;
216263
[[nodiscard]] virtual QQuickItem* contentItem() const = 0;
217264

265+
Q_INVOKABLE [[nodiscard]] QPointF itemPosition(QQuickItem* item) const;
266+
Q_INVOKABLE [[nodiscard]] QRectF itemRect(QQuickItem* item) const;
267+
Q_INVOKABLE [[nodiscard]] QPointF mapFromItem(QQuickItem* item, QPointF point) const;
268+
Q_INVOKABLE [[nodiscard]] QPointF mapFromItem(QQuickItem* item, qreal x, qreal y) const;
269+
Q_INVOKABLE [[nodiscard]] QRectF mapFromItem(QQuickItem* item, QRectF rect) const;
270+
271+
Q_INVOKABLE [[nodiscard]] QRectF
272+
mapFromItem(QQuickItem* item, qreal x, qreal y, qreal width, qreal height) const;
273+
218274
signals:
219275
void windowChanged();
220276

0 commit comments

Comments
 (0)