1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QQUICKDRAG_P_H |
5 | #define QQUICKDRAG_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <QtQuick/qquickitem.h> |
19 | |
20 | #include <private/qintrusivelist_p.h> |
21 | #include <private/qqmlguard_p.h> |
22 | #include <private/qtquickglobal_p.h> |
23 | |
24 | #include <QtCore/qmimedata.h> |
25 | #include <QtCore/qstringlist.h> |
26 | #include <QtCore/qurl.h> |
27 | |
28 | QT_REQUIRE_CONFIG(quick_draganddrop); |
29 | |
30 | QT_BEGIN_NAMESPACE |
31 | |
32 | class QQuickItem; |
33 | class QQuickDrag; |
34 | |
35 | class QQuickDragGrabber |
36 | { |
37 | class Item : public QQmlGuard<QQuickItem> |
38 | { |
39 | public: |
40 | Item(QQuickItem *item) : QQmlGuard<QQuickItem>(Item::objectDestroyedImpl, item) {} |
41 | |
42 | QIntrusiveListNode node; |
43 | private: |
44 | static void objectDestroyedImpl(QQmlGuardImpl *guard) { delete static_cast<Item *>(guard); } |
45 | }; |
46 | |
47 | typedef QIntrusiveList<Item, &Item::node> ItemList; |
48 | |
49 | public: |
50 | QQuickDragGrabber() : m_target(nullptr) {} |
51 | ~QQuickDragGrabber() { while (!m_items.isEmpty()) delete m_items.first(); } |
52 | |
53 | |
54 | QObject *target() const |
55 | { |
56 | if (m_target) |
57 | return m_target; |
58 | else if (!m_items.isEmpty()) |
59 | return *m_items.first(); |
60 | else |
61 | return nullptr; |
62 | } |
63 | void setTarget(QObject *target) { m_target = target; } |
64 | void resetTarget() { m_target = nullptr; } |
65 | |
66 | bool isEmpty() const { return m_items.isEmpty(); } |
67 | |
68 | typedef ItemList::iterator iterator; |
69 | iterator begin() { return m_items.begin(); } |
70 | iterator end() { return m_items.end(); } |
71 | |
72 | void grab(QQuickItem *item) { m_items.insert(n: new Item(item)); } |
73 | iterator release(iterator at) { Item *item = *at; at = at.erase(); delete item; return at; } |
74 | |
75 | auto& ignoreList() { return m_ignoreDragItems; } |
76 | |
77 | private: |
78 | |
79 | ItemList m_items; |
80 | QVarLengthArray<QQuickItem *, 4> m_ignoreDragItems; |
81 | QObject *m_target; |
82 | }; |
83 | |
84 | class QQuickDropEventEx : public QDropEvent |
85 | { |
86 | public: |
87 | void setProposedAction(Qt::DropAction action) { m_defaultAction = action; m_dropAction = action; } |
88 | |
89 | static void setProposedAction(QDropEvent *event, Qt::DropAction action) { |
90 | static_cast<QQuickDropEventEx *>(event)->setProposedAction(action); |
91 | } |
92 | |
93 | void copyActions(const QDropEvent &from) { |
94 | m_defaultAction = from.proposedAction(); m_dropAction = from.dropAction(); } |
95 | |
96 | static void copyActions(QDropEvent *to, const QDropEvent &from) { |
97 | static_cast<QQuickDropEventEx *>(to)->copyActions(from); |
98 | } |
99 | }; |
100 | |
101 | class QQuickDragMimeData : public QMimeData |
102 | { |
103 | Q_OBJECT |
104 | public: |
105 | QQuickDragMimeData() |
106 | : m_source(nullptr) |
107 | { |
108 | } |
109 | |
110 | QStringList keys() const { return m_keys; } |
111 | QObject *source() const { return m_source; } |
112 | |
113 | private: |
114 | QObject *m_source; |
115 | Qt::DropActions m_supportedActions; |
116 | QStringList m_keys; |
117 | |
118 | friend class QQuickDragAttached; |
119 | friend class QQuickDragAttachedPrivate; |
120 | }; |
121 | |
122 | class QQuickDragAttached; |
123 | class Q_QUICK_EXPORT QQuickDrag : public QObject |
124 | { |
125 | Q_OBJECT |
126 | |
127 | Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged RESET resetTarget FINAL) |
128 | Q_PROPERTY(Axis axis READ axis WRITE setAxis NOTIFY axisChanged FINAL FINAL) |
129 | Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged FINAL) |
130 | Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged FINAL) |
131 | Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged FINAL) |
132 | Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged FINAL) |
133 | Q_PROPERTY(bool active READ active NOTIFY activeChanged FINAL) |
134 | Q_PROPERTY(bool filterChildren READ filterChildren WRITE setFilterChildren NOTIFY filterChildrenChanged FINAL) |
135 | Q_PROPERTY(bool smoothed READ smoothed WRITE setSmoothed NOTIFY smoothedChanged FINAL) |
136 | // Note, threshold was added in QtQuick 2.2 but REVISION is not supported (or needed) for grouped |
137 | // properties See QTBUG-33179 |
138 | Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged RESET resetThreshold FINAL) |
139 | //### consider drag and drop |
140 | |
141 | QML_NAMED_ELEMENT(Drag) |
142 | QML_ADDED_IN_VERSION(2, 0) |
143 | QML_UNCREATABLE("Drag is only available via attached properties." ) |
144 | QML_ATTACHED(QQuickDragAttached) |
145 | |
146 | public: |
147 | QQuickDrag(QObject *parent=nullptr); |
148 | ~QQuickDrag(); |
149 | |
150 | enum DragType { None, Automatic, Internal }; |
151 | Q_ENUM(DragType) |
152 | |
153 | QQuickItem *target() const; |
154 | void setTarget(QQuickItem *target); |
155 | void resetTarget(); |
156 | |
157 | enum Axis { XAxis=0x01, YAxis=0x02, XAndYAxis=0x03, XandYAxis=XAndYAxis }; |
158 | Q_ENUM(Axis) |
159 | Axis axis() const; |
160 | void setAxis(Axis); |
161 | |
162 | qreal xmin() const; |
163 | void setXmin(qreal); |
164 | qreal xmax() const; |
165 | void setXmax(qreal); |
166 | qreal ymin() const; |
167 | void setYmin(qreal); |
168 | qreal ymax() const; |
169 | void setYmax(qreal); |
170 | |
171 | bool smoothed() const; |
172 | void setSmoothed(bool smooth); |
173 | |
174 | qreal threshold() const; |
175 | void setThreshold(qreal); |
176 | void resetThreshold(); |
177 | |
178 | bool active() const; |
179 | void setActive(bool); |
180 | |
181 | bool filterChildren() const; |
182 | void setFilterChildren(bool); |
183 | |
184 | static QQuickDragAttached *qmlAttachedProperties(QObject *obj); |
185 | |
186 | Q_SIGNALS: |
187 | void targetChanged(); |
188 | void axisChanged(); |
189 | void minimumXChanged(); |
190 | void maximumXChanged(); |
191 | void minimumYChanged(); |
192 | void maximumYChanged(); |
193 | void activeChanged(); |
194 | void filterChildrenChanged(); |
195 | void smoothedChanged(); |
196 | void thresholdChanged(); |
197 | |
198 | private: |
199 | QQuickItem *_target; |
200 | Axis _axis; |
201 | qreal _xmin; |
202 | qreal _xmax; |
203 | qreal _ymin; |
204 | qreal _ymax; |
205 | bool _active : 1; |
206 | bool _filterChildren: 1; |
207 | bool _smoothed : 1; |
208 | qreal _threshold; |
209 | Q_DISABLE_COPY(QQuickDrag) |
210 | }; |
211 | |
212 | class QQuickDragAttachedPrivate; |
213 | class Q_QUICK_EXPORT QQuickDragAttached : public QObject |
214 | { |
215 | Q_OBJECT |
216 | Q_DECLARE_PRIVATE(QQuickDragAttached) |
217 | |
218 | Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged FINAL) |
219 | Q_PROPERTY(QObject *source READ source WRITE setSource NOTIFY sourceChanged RESET resetSource FINAL) |
220 | Q_PROPERTY(QObject *target READ target NOTIFY targetChanged FINAL) |
221 | Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot NOTIFY hotSpotChanged FINAL) |
222 | Q_PROPERTY(QUrl imageSource READ imageSource WRITE setImageSource NOTIFY imageSourceChanged FINAL) |
223 | // imageSourceSize is new in Qt 6.8; revision omitted because of QTBUG-33179 |
224 | Q_PROPERTY(QSize imageSourceSize READ imageSourceSize WRITE setImageSourceSize NOTIFY imageSourceSizeChanged FINAL) |
225 | Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged FINAL) |
226 | Q_PROPERTY(QVariantMap mimeData READ mimeData WRITE setMimeData NOTIFY mimeDataChanged FINAL) |
227 | Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions WRITE setSupportedActions NOTIFY supportedActionsChanged FINAL) |
228 | Q_PROPERTY(Qt::DropAction proposedAction READ proposedAction WRITE setProposedAction NOTIFY proposedActionChanged FINAL) |
229 | Q_PROPERTY(QQuickDrag::DragType dragType READ dragType WRITE setDragType NOTIFY dragTypeChanged FINAL) |
230 | |
231 | QML_ANONYMOUS |
232 | QML_ADDED_IN_VERSION(2, 0) |
233 | |
234 | public: |
235 | QQuickDragAttached(QObject *parent); |
236 | ~QQuickDragAttached(); |
237 | |
238 | bool isActive() const; |
239 | void setActive(bool active); |
240 | |
241 | QObject *source() const; |
242 | void setSource(QObject *item); |
243 | void resetSource(); |
244 | |
245 | QObject *target() const; |
246 | |
247 | QPointF hotSpot() const; |
248 | void setHotSpot(const QPointF &hotSpot); |
249 | |
250 | QUrl imageSource() const; |
251 | void setImageSource(const QUrl &url); |
252 | |
253 | QSize imageSourceSize() const; |
254 | void setImageSourceSize(const QSize &size); |
255 | |
256 | QStringList keys() const; |
257 | void setKeys(const QStringList &keys); |
258 | |
259 | QVariantMap mimeData() const; |
260 | void setMimeData(const QVariantMap &mimeData); |
261 | |
262 | Qt::DropActions supportedActions() const; |
263 | void setSupportedActions(Qt::DropActions actions); |
264 | |
265 | Qt::DropAction proposedAction() const; |
266 | void setProposedAction(Qt::DropAction action); |
267 | |
268 | QQuickDrag::DragType dragType() const; |
269 | void setDragType(QQuickDrag::DragType dragType); |
270 | |
271 | Q_INVOKABLE int drop(); |
272 | |
273 | bool event(QEvent *event) override; |
274 | |
275 | public Q_SLOTS: |
276 | void start(QQmlV4FunctionPtr); |
277 | void startDrag(QQmlV4FunctionPtr); |
278 | void cancel(); |
279 | |
280 | Q_SIGNALS: |
281 | void dragStarted(); |
282 | void dragFinished(Qt::DropAction dropAction); |
283 | |
284 | void activeChanged(); |
285 | void sourceChanged(); |
286 | void targetChanged(); |
287 | void hotSpotChanged(); |
288 | void imageSourceChanged(); |
289 | void imageSourceSizeChanged(); // new in Qt 6.8 |
290 | void keysChanged(); |
291 | void mimeDataChanged(); |
292 | void supportedActionsChanged(); |
293 | void proposedActionChanged(); |
294 | void dragTypeChanged(); |
295 | }; |
296 | |
297 | QT_END_NAMESPACE |
298 | |
299 | #endif |
300 | |