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 QQmlV4Function; |
123 | class QQuickDragAttached; |
124 | class Q_QUICK_PRIVATE_EXPORT QQuickDrag : public QObject |
125 | { |
126 | Q_OBJECT |
127 | |
128 | Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged RESET resetTarget FINAL) |
129 | Q_PROPERTY(Axis axis READ axis WRITE setAxis NOTIFY axisChanged FINAL) |
130 | Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged FINAL) |
131 | Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged FINAL) |
132 | Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged FINAL) |
133 | Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged FINAL) |
134 | Q_PROPERTY(bool active READ active NOTIFY activeChanged FINAL) |
135 | Q_PROPERTY(bool filterChildren READ filterChildren WRITE setFilterChildren NOTIFY filterChildrenChanged FINAL) |
136 | Q_PROPERTY(bool smoothed READ smoothed WRITE setSmoothed NOTIFY smoothedChanged FINAL) |
137 | // Note, threshold was added in QtQuick 2.2 but REVISION is not supported (or needed) for grouped |
138 | // properties See QTBUG-33179 |
139 | Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged RESET resetThreshold FINAL) |
140 | //### consider drag and drop |
141 | |
142 | QML_NAMED_ELEMENT(Drag) |
143 | QML_ADDED_IN_VERSION(2, 0) |
144 | QML_UNCREATABLE("Drag is only available via attached properties." ) |
145 | QML_ATTACHED(QQuickDragAttached) |
146 | |
147 | public: |
148 | QQuickDrag(QObject *parent=nullptr); |
149 | ~QQuickDrag(); |
150 | |
151 | enum DragType { None, Automatic, Internal }; |
152 | Q_ENUM(DragType) |
153 | |
154 | QQuickItem *target() const; |
155 | void setTarget(QQuickItem *target); |
156 | void resetTarget(); |
157 | |
158 | enum Axis { XAxis=0x01, YAxis=0x02, XAndYAxis=0x03, XandYAxis=XAndYAxis }; |
159 | Q_ENUM(Axis) |
160 | Axis axis() const; |
161 | void setAxis(Axis); |
162 | |
163 | qreal xmin() const; |
164 | void setXmin(qreal); |
165 | qreal xmax() const; |
166 | void setXmax(qreal); |
167 | qreal ymin() const; |
168 | void setYmin(qreal); |
169 | qreal ymax() const; |
170 | void setYmax(qreal); |
171 | |
172 | bool smoothed() const; |
173 | void setSmoothed(bool smooth); |
174 | |
175 | qreal threshold() const; |
176 | void setThreshold(qreal); |
177 | void resetThreshold(); |
178 | |
179 | bool active() const; |
180 | void setActive(bool); |
181 | |
182 | bool filterChildren() const; |
183 | void setFilterChildren(bool); |
184 | |
185 | static QQuickDragAttached *qmlAttachedProperties(QObject *obj); |
186 | |
187 | Q_SIGNALS: |
188 | void targetChanged(); |
189 | void axisChanged(); |
190 | void minimumXChanged(); |
191 | void maximumXChanged(); |
192 | void minimumYChanged(); |
193 | void maximumYChanged(); |
194 | void activeChanged(); |
195 | void filterChildrenChanged(); |
196 | void smoothedChanged(); |
197 | void thresholdChanged(); |
198 | |
199 | private: |
200 | QQuickItem *_target; |
201 | Axis _axis; |
202 | qreal _xmin; |
203 | qreal _xmax; |
204 | qreal _ymin; |
205 | qreal _ymax; |
206 | bool _active : 1; |
207 | bool _filterChildren: 1; |
208 | bool _smoothed : 1; |
209 | qreal _threshold; |
210 | Q_DISABLE_COPY(QQuickDrag) |
211 | }; |
212 | |
213 | class QQuickDragAttachedPrivate; |
214 | class Q_QUICK_PRIVATE_EXPORT QQuickDragAttached : public QObject |
215 | { |
216 | Q_OBJECT |
217 | Q_DECLARE_PRIVATE(QQuickDragAttached) |
218 | |
219 | Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged FINAL) |
220 | Q_PROPERTY(QObject *source READ source WRITE setSource NOTIFY sourceChanged RESET resetSource FINAL) |
221 | Q_PROPERTY(QObject *target READ target NOTIFY targetChanged FINAL) |
222 | Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot NOTIFY hotSpotChanged FINAL) |
223 | Q_PROPERTY(QUrl imageSource READ imageSource WRITE setImageSource NOTIFY imageSourceChanged FINAL) |
224 | Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged FINAL) |
225 | Q_PROPERTY(QVariantMap mimeData READ mimeData WRITE setMimeData NOTIFY mimeDataChanged FINAL) |
226 | Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions WRITE setSupportedActions NOTIFY supportedActionsChanged FINAL) |
227 | Q_PROPERTY(Qt::DropAction proposedAction READ proposedAction WRITE setProposedAction NOTIFY proposedActionChanged FINAL) |
228 | Q_PROPERTY(QQuickDrag::DragType dragType READ dragType WRITE setDragType NOTIFY dragTypeChanged FINAL) |
229 | |
230 | QML_ANONYMOUS |
231 | QML_ADDED_IN_VERSION(2, 0) |
232 | |
233 | public: |
234 | QQuickDragAttached(QObject *parent); |
235 | ~QQuickDragAttached(); |
236 | |
237 | bool isActive() const; |
238 | void setActive(bool active); |
239 | |
240 | QObject *source() const; |
241 | void setSource(QObject *item); |
242 | void resetSource(); |
243 | |
244 | QObject *target() const; |
245 | |
246 | QPointF hotSpot() const; |
247 | void setHotSpot(const QPointF &hotSpot); |
248 | |
249 | QUrl imageSource() const; |
250 | void setImageSource(const QUrl &url); |
251 | |
252 | QStringList keys() const; |
253 | void setKeys(const QStringList &keys); |
254 | |
255 | QVariantMap mimeData() const; |
256 | void setMimeData(const QVariantMap &mimeData); |
257 | |
258 | Qt::DropActions supportedActions() const; |
259 | void setSupportedActions(Qt::DropActions actions); |
260 | |
261 | Qt::DropAction proposedAction() const; |
262 | void setProposedAction(Qt::DropAction action); |
263 | |
264 | QQuickDrag::DragType dragType() const; |
265 | void setDragType(QQuickDrag::DragType dragType); |
266 | |
267 | Q_INVOKABLE int drop(); |
268 | |
269 | bool event(QEvent *event) override; |
270 | |
271 | public Q_SLOTS: |
272 | void start(QQmlV4Function *); |
273 | void startDrag(QQmlV4Function *); |
274 | void cancel(); |
275 | |
276 | Q_SIGNALS: |
277 | void dragStarted(); |
278 | void dragFinished(Qt::DropAction dropAction); |
279 | |
280 | void activeChanged(); |
281 | void sourceChanged(); |
282 | void targetChanged(); |
283 | void hotSpotChanged(); |
284 | void imageSourceChanged(); |
285 | void keysChanged(); |
286 | void mimeDataChanged(); |
287 | void supportedActionsChanged(); |
288 | void proposedActionChanged(); |
289 | void dragTypeChanged(); |
290 | }; |
291 | |
292 | QT_END_NAMESPACE |
293 | |
294 | QML_DECLARE_TYPE(QQuickDrag) |
295 | |
296 | #endif |
297 | |