4
4
#include < qcontainerfwd.h>
5
5
#include < qlogging.h>
6
6
#include < qobject.h>
7
+ #include < qquickitem.h>
7
8
#include < qsize.h>
8
9
#include < qtmetamacros.h>
9
10
#include < qwindow.h>
@@ -25,14 +26,11 @@ bool PopupAnchor::isDirty() const {
25
26
void PopupAnchor::markClean () { this ->lastState = this ->state ; }
26
27
void PopupAnchor::markDirty () { this ->lastState .reset (); }
27
28
28
- QObject* PopupAnchor::window () const { return this ->mWindow ; }
29
- ProxyWindowBase* PopupAnchor::proxyWindow () const { return this ->mProxyWindow ; }
30
-
31
29
QWindow* PopupAnchor::backingWindow () const {
32
30
return this ->mProxyWindow ? this ->mProxyWindow ->backingWindow () : nullptr ;
33
31
}
34
32
35
- void PopupAnchor::setWindow (QObject* window) {
33
+ void PopupAnchor::setWindowInternal (QObject* window) {
36
34
if (window == this ->mWindow ) return ;
37
35
38
36
if (this ->mWindow ) {
@@ -78,25 +76,69 @@ void PopupAnchor::setWindow(QObject* window) {
78
76
}
79
77
}
80
78
79
+ void PopupAnchor::setWindow (QObject* window) {
80
+ this ->setItem (nullptr );
81
+ this ->setWindowInternal (window);
82
+ }
83
+
84
+ void PopupAnchor::setItem (QQuickItem* item) {
85
+ if (item == this ->mItem ) return ;
86
+
87
+ if (this ->mItem ) {
88
+ QObject::disconnect (this ->mItem , nullptr , this , nullptr );
89
+ }
90
+
91
+ this ->mItem = item;
92
+ this ->onItemWindowChanged ();
93
+
94
+ if (item) {
95
+ QObject::connect (item, &QObject::destroyed, this , &PopupAnchor::onItemDestroyed);
96
+ QObject::connect (item, &QQuickItem::windowChanged, this , &PopupAnchor::onItemWindowChanged);
97
+ }
98
+ }
99
+
81
100
void PopupAnchor::onWindowDestroyed () {
82
101
this ->mWindow = nullptr ;
83
102
this ->mProxyWindow = nullptr ;
84
103
emit this ->windowChanged ();
85
104
emit this ->backingWindowVisibilityChanged ();
86
105
}
87
106
88
- Box PopupAnchor::rect () const { return this ->state .rect ; }
107
+ void PopupAnchor::onItemDestroyed () {
108
+ this ->mItem = nullptr ;
109
+ emit this ->itemChanged ();
110
+ this ->setWindowInternal (nullptr );
111
+ }
112
+
113
+ void PopupAnchor::onItemWindowChanged () {
114
+ if (auto * window = qobject_cast<ProxiedWindow*>(this ->mItem ->window ())) {
115
+ this ->setWindowInternal (window->proxy ());
116
+ } else {
117
+ this ->setWindowInternal (nullptr );
118
+ }
119
+ }
89
120
90
121
void PopupAnchor::setRect (Box rect) {
91
- if (rect == this ->state .rect ) return ;
92
122
if (rect.w <= 0 ) rect.w = 1 ;
93
123
if (rect.h <= 0 ) rect.h = 1 ;
124
+ if (rect == this ->mUserRect ) return ;
94
125
95
- this ->state . rect = rect;
126
+ this ->mUserRect = rect;
96
127
emit this ->rectChanged ();
128
+
129
+ this ->setWindowRect (rect);
130
+ }
131
+
132
+ void PopupAnchor::setWindowRect (Box rect) {
133
+ if (rect.w <= 0 ) rect.w = 1 ;
134
+ if (rect.h <= 0 ) rect.h = 1 ;
135
+ if (rect == this ->state .rect ) return ;
136
+
137
+ this ->state .rect = rect;
138
+ emit this ->windowRectChanged ();
97
139
}
98
140
99
- Edges::Flags PopupAnchor::edges () const { return this ->state . edges ; }
141
+ void PopupAnchor::resetRect () { this ->mUserRect = Box () ; }
100
142
101
143
void PopupAnchor::setEdges (Edges::Flags edges) {
102
144
if (edges == this ->state .edges ) return ;
@@ -110,8 +152,6 @@ void PopupAnchor::setEdges(Edges::Flags edges) {
110
152
emit this ->edgesChanged ();
111
153
}
112
154
113
- Edges::Flags PopupAnchor::gravity () const { return this ->state .gravity ; }
114
-
115
155
void PopupAnchor::setGravity (Edges::Flags gravity) {
116
156
if (gravity == this ->state .gravity ) return ;
117
157
@@ -124,8 +164,6 @@ void PopupAnchor::setGravity(Edges::Flags gravity) {
124
164
emit this ->gravityChanged ();
125
165
}
126
166
127
- PopupAdjustment::Flags PopupAnchor::adjustment () const { return this ->state .adjustment ; }
128
-
129
167
void PopupAnchor::setAdjustment (PopupAdjustment::Flags adjustment) {
130
168
if (adjustment == this ->state .adjustment ) return ;
131
169
this ->state .adjustment = adjustment;
@@ -137,6 +175,19 @@ void PopupAnchor::updatePlacement(const QPoint& anchorpoint, const QSize& size)
137
175
this ->state .size = size;
138
176
}
139
177
178
+ void PopupAnchor::updateAnchor () {
179
+ if (this ->mItem && this ->mProxyWindow ) {
180
+ auto rect = this ->mProxyWindow ->contentItem ()->mapRectFromItem (
181
+ this ->mItem ,
182
+ this ->mUserRect .isEmpty () ? this ->mItem ->boundingRect () : this ->mUserRect .qrect ()
183
+ );
184
+
185
+ this ->setWindowRect (rect);
186
+ }
187
+
188
+ emit this ->anchoring ();
189
+ }
190
+
140
191
static PopupPositioner* POSITIONER = nullptr ; // NOLINT
141
192
142
193
void PopupPositioner::reposition (PopupAnchor* anchor, QWindow* window, bool onlyIfDirty) {
@@ -148,15 +199,15 @@ void PopupPositioner::reposition(PopupAnchor* anchor, QWindow* window, bool only
148
199
auto parentGeometry = parentWindow->geometry ();
149
200
auto windowGeometry = window->geometry ();
150
201
151
- emit anchor->anchoring ();
202
+ anchor->updateAnchor ();
152
203
anchor->updatePlacement (parentGeometry.topLeft (), windowGeometry.size ());
153
204
154
205
if (onlyIfDirty && !anchor->isDirty ()) return ;
155
206
anchor->markClean ();
156
207
157
208
auto adjustment = anchor->adjustment ();
158
209
auto screenGeometry = parentWindow->screen ()->geometry ();
159
- auto anchorRectGeometry = anchor->rect ().qrect ().translated (parentGeometry.topLeft ());
210
+ auto anchorRectGeometry = anchor->windowRect ().qrect ().translated (parentGeometry.topLeft ());
160
211
161
212
auto anchorEdges = anchor->edges ();
162
213
auto anchorGravity = anchor->gravity ();
0 commit comments