Merge lp:~dandrader/ubuntu/trusty/qtdeclarative-opensource-src/backport_fix_qtbug_32004 into lp:ubuntu/trusty/qtdeclarative-opensource-src
- Trusty (14.04)
- backport_fix_qtbug_32004
- Merge into trusty
Proposed by
Daniel d'Andrada
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 11 | ||||
Proposed branch: | lp:~dandrader/ubuntu/trusty/qtdeclarative-opensource-src/backport_fix_qtbug_32004 | ||||
Merge into: | lp:ubuntu/trusty/qtdeclarative-opensource-src | ||||
Diff against target: |
13126 lines (+12814/-138) 11 files modified
.pc/applied-patches (+1/-0) .pc/fix_qtbug_32004.patch/src/quick/items/qquickitem.cpp (+7219/-0) .pc/fix_qtbug_32004.patch/src/quick/items/qquickitem_p.h (+918/-0) .pc/fix_qtbug_32004.patch/src/quick/items/qquickwindow.cpp (+2819/-0) .pc/fix_qtbug_32004.patch/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp (+1212/-0) debian/patches/fix_qtbug_32004.patch (+459/-0) debian/patches/series (+1/-0) src/quick/items/qquickitem.cpp (+72/-104) src/quick/items/qquickitem_p.h (+0/-10) src/quick/items/qquickwindow.cpp (+16/-24) tests/auto/quick/qquickwindow/tst_qquickwindow.cpp (+97/-0) |
||||
To merge this branch: | bzr merge lp:~dandrader/ubuntu/trusty/qtdeclarative-opensource-src/backport_fix_qtbug_32004 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu branches | Pending | ||
Review via email: mp+195761@code.launchpad.net |
Commit message
Backport fix for QTBUG-32004 which is slated for Qt 5.3
Description of the change
To post a comment you must log in.
Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote : | # |
Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote : | # |
I've now upload powers so I will be working on testing this backport to 5.0.2.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.pc/applied-patches' |
2 | --- .pc/applied-patches 2013-10-08 13:20:40 +0000 |
3 | +++ .pc/applied-patches 2013-11-19 12:08:13 +0000 |
4 | @@ -10,3 +10,4 @@ |
5 | qtquick_delegate_creation_range_itemviews.patch |
6 | qml_type_loading.patch |
7 | fix_1236765.patch |
8 | +fix_qtbug_32004.patch |
9 | |
10 | === added directory '.pc/fix_qtbug_32004.patch' |
11 | === added file '.pc/fix_qtbug_32004.patch/.timestamp' |
12 | === added directory '.pc/fix_qtbug_32004.patch/src' |
13 | === added directory '.pc/fix_qtbug_32004.patch/src/quick' |
14 | === added directory '.pc/fix_qtbug_32004.patch/src/quick/items' |
15 | === added file '.pc/fix_qtbug_32004.patch/src/quick/items/qquickitem.cpp' |
16 | --- .pc/fix_qtbug_32004.patch/src/quick/items/qquickitem.cpp 1970-01-01 00:00:00 +0000 |
17 | +++ .pc/fix_qtbug_32004.patch/src/quick/items/qquickitem.cpp 2013-11-19 12:08:13 +0000 |
18 | @@ -0,0 +1,7219 @@ |
19 | +/**************************************************************************** |
20 | +** |
21 | +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). |
22 | +** Contact: http://www.qt-project.org/legal |
23 | +** |
24 | +** This file is part of the QtQml module of the Qt Toolkit. |
25 | +** |
26 | +** $QT_BEGIN_LICENSE:LGPL$ |
27 | +** Commercial License Usage |
28 | +** Licensees holding valid commercial Qt licenses may use this file in |
29 | +** accordance with the commercial license agreement provided with the |
30 | +** Software or, alternatively, in accordance with the terms contained in |
31 | +** a written agreement between you and Digia. For licensing terms and |
32 | +** conditions see http://qt.digia.com/licensing. For further information |
33 | +** use the contact form at http://qt.digia.com/contact-us. |
34 | +** |
35 | +** GNU Lesser General Public License Usage |
36 | +** Alternatively, this file may be used under the terms of the GNU Lesser |
37 | +** General Public License version 2.1 as published by the Free Software |
38 | +** Foundation and appearing in the file LICENSE.LGPL included in the |
39 | +** packaging of this file. Please review the following information to |
40 | +** ensure the GNU Lesser General Public License version 2.1 requirements |
41 | +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
42 | +** |
43 | +** In addition, as a special exception, Digia gives you certain additional |
44 | +** rights. These rights are described in the Digia Qt LGPL Exception |
45 | +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
46 | +** |
47 | +** GNU General Public License Usage |
48 | +** Alternatively, this file may be used under the terms of the GNU |
49 | +** General Public License version 3.0 as published by the Free Software |
50 | +** Foundation and appearing in the file LICENSE.GPL included in the |
51 | +** packaging of this file. Please review the following information to |
52 | +** ensure the GNU General Public License version 3.0 requirements will be |
53 | +** met: http://www.gnu.org/copyleft/gpl.html. |
54 | +** |
55 | +** |
56 | +** $QT_END_LICENSE$ |
57 | +** |
58 | +****************************************************************************/ |
59 | + |
60 | +#include "qquickitem.h" |
61 | + |
62 | +#include "qquickwindow.h" |
63 | +#include <QtQml/qjsengine.h> |
64 | +#include "qquickwindow_p.h" |
65 | + |
66 | +#include "qquickevents_p_p.h" |
67 | +#include "qquickscreen_p.h" |
68 | + |
69 | +#include <QtQml/qqmlengine.h> |
70 | +#include <QtQml/qqmlcomponent.h> |
71 | +#include <QtQml/qqmlinfo.h> |
72 | +#include <QtGui/qpen.h> |
73 | +#include <QtGui/qguiapplication.h> |
74 | +#include <QtGui/private/qguiapplication_p.h> |
75 | +#include <QtGui/qinputmethod.h> |
76 | +#include <QtCore/qdebug.h> |
77 | +#include <QtCore/qcoreevent.h> |
78 | +#include <QtCore/qnumeric.h> |
79 | + |
80 | +#include <private/qqmlglobal_p.h> |
81 | +#include <private/qqmlengine_p.h> |
82 | +#include <QtQuick/private/qquickstategroup_p.h> |
83 | +#include <private/qqmlopenmetaobject_p.h> |
84 | +#include <QtQuick/private/qquickstate_p.h> |
85 | +#include <private/qquickitem_p.h> |
86 | +#include <private/qqmlaccessors_p.h> |
87 | +#include <QtQuick/private/qquickaccessibleattached_p.h> |
88 | + |
89 | +#ifndef QT_NO_CURSOR |
90 | +# include <QtGui/qcursor.h> |
91 | +#endif |
92 | + |
93 | +#include <float.h> |
94 | + |
95 | +// XXX todo Check that elements that create items handle memory correctly after visual ownership change |
96 | + |
97 | +QT_BEGIN_NAMESPACE |
98 | + |
99 | +#ifdef FOCUS_DEBUG |
100 | +void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1); |
101 | +void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth) |
102 | +{ |
103 | + qWarning() |
104 | + << QByteArray(depth, '\t').constData() |
105 | + << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ') |
106 | + << item->hasFocus() |
107 | + << item->hasActiveFocus() |
108 | + << item->isFocusScope() |
109 | + << item; |
110 | + foreach (QQuickItem *child, item->childItems()) { |
111 | + printFocusTree( |
112 | + child, |
113 | + item->isFocusScope() || !scope ? item : scope, |
114 | + item->isFocusScope() || !scope ? depth + 1 : depth); |
115 | + } |
116 | +} |
117 | +#endif |
118 | + |
119 | +static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n) |
120 | +{ |
121 | + QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o)); |
122 | + *n = &d->parentNotifier; |
123 | +} |
124 | + |
125 | +QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem) |
126 | +QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x) |
127 | +QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y) |
128 | +QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width) |
129 | +QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height) |
130 | + |
131 | +static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier }; |
132 | +static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 }; |
133 | +static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 }; |
134 | +static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 }; |
135 | +static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 }; |
136 | + |
137 | +QML_DECLARE_PROPERTIES(QQuickItem) { |
138 | + { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent }, |
139 | + { QML_PROPERTY_NAME(x), 0, &QQuickItem_x }, |
140 | + { QML_PROPERTY_NAME(y), 0, &QQuickItem_y }, |
141 | + { QML_PROPERTY_NAME(width), 0, &QQuickItem_width }, |
142 | + { QML_PROPERTY_NAME(height), 0, &QQuickItem_height } |
143 | +}; |
144 | + |
145 | +void QQuickItemPrivate::registerAccessorProperties() |
146 | +{ |
147 | + QML_DEFINE_PROPERTIES(QQuickItem); |
148 | +} |
149 | + |
150 | +/*! |
151 | + \qmltype Transform |
152 | + \instantiates QQuickTransform |
153 | + \inqmlmodule QtQuick 2 |
154 | + \ingroup qtquick-visual-transforms |
155 | + \brief For specifying advanced transformations on Items |
156 | + |
157 | + The Transform type is a base type which cannot be instantiated directly. |
158 | + The following concrete Transform types are available: |
159 | + |
160 | + \list |
161 | + \li \l Rotation |
162 | + \li \l Scale |
163 | + \li \l Translate |
164 | + \endlist |
165 | + |
166 | + The Transform types let you create and control advanced transformations that can be configured |
167 | + independently using specialized properties. |
168 | + |
169 | + You can assign any number of Transforms to an \l Item. Each Transform is applied in order, |
170 | + one at a time. |
171 | +*/ |
172 | +QQuickTransformPrivate::QQuickTransformPrivate() |
173 | +{ |
174 | +} |
175 | + |
176 | +QQuickTransform::QQuickTransform(QObject *parent) |
177 | +: QObject(*(new QQuickTransformPrivate), parent) |
178 | +{ |
179 | +} |
180 | + |
181 | +QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent) |
182 | +: QObject(dd, parent) |
183 | +{ |
184 | +} |
185 | + |
186 | +QQuickTransform::~QQuickTransform() |
187 | +{ |
188 | + Q_D(QQuickTransform); |
189 | + for (int ii = 0; ii < d->items.count(); ++ii) { |
190 | + QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii)); |
191 | + p->transforms.removeOne(this); |
192 | + p->dirty(QQuickItemPrivate::Transform); |
193 | + } |
194 | +} |
195 | + |
196 | +void QQuickTransform::update() |
197 | +{ |
198 | + Q_D(QQuickTransform); |
199 | + for (int ii = 0; ii < d->items.count(); ++ii) { |
200 | + QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii)); |
201 | + p->dirty(QQuickItemPrivate::Transform); |
202 | + } |
203 | +} |
204 | + |
205 | +QQuickContents::QQuickContents(QQuickItem *item) |
206 | +: m_item(item), m_x(0), m_y(0), m_width(0), m_height(0) |
207 | +{ |
208 | +} |
209 | + |
210 | +QQuickContents::~QQuickContents() |
211 | +{ |
212 | + QList<QQuickItem *> children = m_item->childItems(); |
213 | + for (int i = 0; i < children.count(); ++i) { |
214 | + QQuickItem *child = children.at(i); |
215 | + QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed); |
216 | + } |
217 | +} |
218 | + |
219 | +bool QQuickContents::calcHeight(QQuickItem *changed) |
220 | +{ |
221 | + qreal oldy = m_y; |
222 | + qreal oldheight = m_height; |
223 | + |
224 | + if (changed) { |
225 | + qreal top = oldy; |
226 | + qreal bottom = oldy + oldheight; |
227 | + qreal y = changed->y(); |
228 | + if (y + changed->height() > bottom) |
229 | + bottom = y + changed->height(); |
230 | + if (y < top) |
231 | + top = y; |
232 | + m_y = top; |
233 | + m_height = bottom - top; |
234 | + } else { |
235 | + qreal top = FLT_MAX; |
236 | + qreal bottom = 0; |
237 | + QList<QQuickItem *> children = m_item->childItems(); |
238 | + for (int i = 0; i < children.count(); ++i) { |
239 | + QQuickItem *child = children.at(i); |
240 | + qreal y = child->y(); |
241 | + if (y + child->height() > bottom) |
242 | + bottom = y + child->height(); |
243 | + if (y < top) |
244 | + top = y; |
245 | + } |
246 | + if (!children.isEmpty()) |
247 | + m_y = top; |
248 | + m_height = qMax(bottom - top, qreal(0.0)); |
249 | + } |
250 | + |
251 | + return (m_height != oldheight || m_y != oldy); |
252 | +} |
253 | + |
254 | +bool QQuickContents::calcWidth(QQuickItem *changed) |
255 | +{ |
256 | + qreal oldx = m_x; |
257 | + qreal oldwidth = m_width; |
258 | + |
259 | + if (changed) { |
260 | + qreal left = oldx; |
261 | + qreal right = oldx + oldwidth; |
262 | + qreal x = changed->x(); |
263 | + if (x + changed->width() > right) |
264 | + right = x + changed->width(); |
265 | + if (x < left) |
266 | + left = x; |
267 | + m_x = left; |
268 | + m_width = right - left; |
269 | + } else { |
270 | + qreal left = FLT_MAX; |
271 | + qreal right = 0; |
272 | + QList<QQuickItem *> children = m_item->childItems(); |
273 | + for (int i = 0; i < children.count(); ++i) { |
274 | + QQuickItem *child = children.at(i); |
275 | + qreal x = child->x(); |
276 | + if (x + child->width() > right) |
277 | + right = x + child->width(); |
278 | + if (x < left) |
279 | + left = x; |
280 | + } |
281 | + if (!children.isEmpty()) |
282 | + m_x = left; |
283 | + m_width = qMax(right - left, qreal(0.0)); |
284 | + } |
285 | + |
286 | + return (m_width != oldwidth || m_x != oldx); |
287 | +} |
288 | + |
289 | +void QQuickContents::complete() |
290 | +{ |
291 | + QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children); |
292 | + |
293 | + QList<QQuickItem *> children = m_item->childItems(); |
294 | + for (int i = 0; i < children.count(); ++i) { |
295 | + QQuickItem *child = children.at(i); |
296 | + QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed); |
297 | + //###what about changes to visibility? |
298 | + } |
299 | + calcGeometry(); |
300 | +} |
301 | + |
302 | +void QQuickContents::updateRect() |
303 | +{ |
304 | + QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF()); |
305 | +} |
306 | + |
307 | +void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry) |
308 | +{ |
309 | + Q_UNUSED(changed) |
310 | + bool wChanged = false; |
311 | + bool hChanged = false; |
312 | + //### we can only pass changed if the left edge has moved left, or the right edge has moved right |
313 | + if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x()) |
314 | + wChanged = calcWidth(/*changed*/); |
315 | + if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y()) |
316 | + hChanged = calcHeight(/*changed*/); |
317 | + if (wChanged || hChanged) |
318 | + updateRect(); |
319 | +} |
320 | + |
321 | +void QQuickContents::itemDestroyed(QQuickItem *item) |
322 | +{ |
323 | + if (item) |
324 | + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed); |
325 | + calcGeometry(); |
326 | +} |
327 | + |
328 | +void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item) |
329 | +{ |
330 | + if (item) |
331 | + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed); |
332 | + calcGeometry(); |
333 | +} |
334 | + |
335 | +void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item) |
336 | +{ |
337 | + if (item) |
338 | + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed); |
339 | + calcGeometry(item); |
340 | +} |
341 | + |
342 | +QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item) |
343 | +: m_processPost(false), m_next(0) |
344 | +{ |
345 | + QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0; |
346 | + if (p) { |
347 | + m_next = p->extra.value().keyHandler; |
348 | + p->extra->keyHandler = this; |
349 | + } |
350 | +} |
351 | + |
352 | +QQuickItemKeyFilter::~QQuickItemKeyFilter() |
353 | +{ |
354 | +} |
355 | + |
356 | +void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post) |
357 | +{ |
358 | + if (m_next) m_next->keyPressed(event, post); |
359 | +} |
360 | + |
361 | +void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post) |
362 | +{ |
363 | + if (m_next) m_next->keyReleased(event, post); |
364 | +} |
365 | + |
366 | +#ifndef QT_NO_IM |
367 | +void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post) |
368 | +{ |
369 | + if (m_next) |
370 | + m_next->inputMethodEvent(event, post); |
371 | + else |
372 | + event->ignore(); |
373 | +} |
374 | + |
375 | +QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const |
376 | +{ |
377 | + if (m_next) return m_next->inputMethodQuery(query); |
378 | + return QVariant(); |
379 | +} |
380 | +#endif // QT_NO_IM |
381 | + |
382 | +void QQuickItemKeyFilter::componentComplete() |
383 | +{ |
384 | + if (m_next) m_next->componentComplete(); |
385 | +} |
386 | +/*! |
387 | + \qmltype KeyNavigation |
388 | + \instantiates QQuickKeyNavigationAttached |
389 | + \inqmlmodule QtQuick 2 |
390 | + \ingroup qtquick-input |
391 | + \brief Supports key navigation by arrow keys |
392 | + |
393 | + Key-based user interfaces commonly allow the use of arrow keys to navigate between |
394 | + focusable items. The KeyNavigation attached property enables this behavior by providing a |
395 | + convenient way to specify the item that should gain focus when an arrow or tab key is pressed. |
396 | + |
397 | + The following example provides key navigation for a 2x2 grid of items: |
398 | + |
399 | + \snippet qml/keynavigation.qml 0 |
400 | + |
401 | + The top-left item initially receives focus by setting \l {Item::}{focus} to |
402 | + \c true. When an arrow key is pressed, the focus will move to the |
403 | + appropriate item, as defined by the value that has been set for |
404 | + the KeyNavigation \l left, \l right, \l up or \l down properties. |
405 | + |
406 | + Note that if a KeyNavigation attached property receives the key press and release |
407 | + events for a requested arrow or tab key, the event is accepted and does not |
408 | + propagate any further. |
409 | + |
410 | + By default, KeyNavigation receives key events after the item to which it is attached. |
411 | + If the item accepts the key event, the KeyNavigation attached property will not |
412 | + receive an event for that key. Setting the \l priority property to |
413 | + \c KeyNavigation.BeforeItem allows the event to be used for key navigation |
414 | + before the item, rather than after. |
415 | + |
416 | + If item to which the focus is switching is not enabled or visible, an attempt will |
417 | + be made to skip this item and focus on the next. This is possible if there are |
418 | + a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled |
419 | + or visible, they will also be skipped. |
420 | + |
421 | + KeyNavigation will implicitly set the other direction to return focus to this item. So if you set |
422 | + \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this |
423 | + item. However, if that item's KeyNavigation has had right explicitly set then no change will occur. |
424 | + This means that the above example could have been written, with the same behaviour, without specifying |
425 | + KeyNavigation.right or KeyNavigation.down for any of the items. |
426 | + |
427 | + \sa {Keys}{Keys attached property} |
428 | +*/ |
429 | + |
430 | +/*! |
431 | + \qmlproperty Item QtQuick2::KeyNavigation::left |
432 | + \qmlproperty Item QtQuick2::KeyNavigation::right |
433 | + \qmlproperty Item QtQuick2::KeyNavigation::up |
434 | + \qmlproperty Item QtQuick2::KeyNavigation::down |
435 | + |
436 | + These properties hold the item to assign focus to |
437 | + when the left, right, up or down cursor keys |
438 | + are pressed. |
439 | +*/ |
440 | + |
441 | +/*! |
442 | + \qmlproperty Item QtQuick2::KeyNavigation::tab |
443 | + \qmlproperty Item QtQuick2::KeyNavigation::backtab |
444 | + |
445 | + These properties hold the item to assign focus to |
446 | + when the Tab key or Shift+Tab key combination (Backtab) are pressed. |
447 | +*/ |
448 | + |
449 | +QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent) |
450 | +: QObject(*(new QQuickKeyNavigationAttachedPrivate), parent), |
451 | + QQuickItemKeyFilter(qmlobject_cast<QQuickItem*>(parent)) |
452 | +{ |
453 | + m_processPost = true; |
454 | +} |
455 | + |
456 | +QQuickKeyNavigationAttached * |
457 | +QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj) |
458 | +{ |
459 | + return new QQuickKeyNavigationAttached(obj); |
460 | +} |
461 | + |
462 | +QQuickItem *QQuickKeyNavigationAttached::left() const |
463 | +{ |
464 | + Q_D(const QQuickKeyNavigationAttached); |
465 | + return d->left; |
466 | +} |
467 | + |
468 | +void QQuickKeyNavigationAttached::setLeft(QQuickItem *i) |
469 | +{ |
470 | + Q_D(QQuickKeyNavigationAttached); |
471 | + if (d->left == i) |
472 | + return; |
473 | + d->left = i; |
474 | + d->leftSet = true; |
475 | + QQuickKeyNavigationAttached* other = |
476 | + qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i)); |
477 | + if (other && !other->d_func()->rightSet){ |
478 | + other->d_func()->right = qobject_cast<QQuickItem*>(parent()); |
479 | + emit other->rightChanged(); |
480 | + } |
481 | + emit leftChanged(); |
482 | +} |
483 | + |
484 | +QQuickItem *QQuickKeyNavigationAttached::right() const |
485 | +{ |
486 | + Q_D(const QQuickKeyNavigationAttached); |
487 | + return d->right; |
488 | +} |
489 | + |
490 | +void QQuickKeyNavigationAttached::setRight(QQuickItem *i) |
491 | +{ |
492 | + Q_D(QQuickKeyNavigationAttached); |
493 | + if (d->right == i) |
494 | + return; |
495 | + d->right = i; |
496 | + d->rightSet = true; |
497 | + QQuickKeyNavigationAttached* other = |
498 | + qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i)); |
499 | + if (other && !other->d_func()->leftSet){ |
500 | + other->d_func()->left = qobject_cast<QQuickItem*>(parent()); |
501 | + emit other->leftChanged(); |
502 | + } |
503 | + emit rightChanged(); |
504 | +} |
505 | + |
506 | +QQuickItem *QQuickKeyNavigationAttached::up() const |
507 | +{ |
508 | + Q_D(const QQuickKeyNavigationAttached); |
509 | + return d->up; |
510 | +} |
511 | + |
512 | +void QQuickKeyNavigationAttached::setUp(QQuickItem *i) |
513 | +{ |
514 | + Q_D(QQuickKeyNavigationAttached); |
515 | + if (d->up == i) |
516 | + return; |
517 | + d->up = i; |
518 | + d->upSet = true; |
519 | + QQuickKeyNavigationAttached* other = |
520 | + qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i)); |
521 | + if (other && !other->d_func()->downSet){ |
522 | + other->d_func()->down = qobject_cast<QQuickItem*>(parent()); |
523 | + emit other->downChanged(); |
524 | + } |
525 | + emit upChanged(); |
526 | +} |
527 | + |
528 | +QQuickItem *QQuickKeyNavigationAttached::down() const |
529 | +{ |
530 | + Q_D(const QQuickKeyNavigationAttached); |
531 | + return d->down; |
532 | +} |
533 | + |
534 | +void QQuickKeyNavigationAttached::setDown(QQuickItem *i) |
535 | +{ |
536 | + Q_D(QQuickKeyNavigationAttached); |
537 | + if (d->down == i) |
538 | + return; |
539 | + d->down = i; |
540 | + d->downSet = true; |
541 | + QQuickKeyNavigationAttached* other = |
542 | + qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i)); |
543 | + if (other && !other->d_func()->upSet) { |
544 | + other->d_func()->up = qobject_cast<QQuickItem*>(parent()); |
545 | + emit other->upChanged(); |
546 | + } |
547 | + emit downChanged(); |
548 | +} |
549 | + |
550 | +QQuickItem *QQuickKeyNavigationAttached::tab() const |
551 | +{ |
552 | + Q_D(const QQuickKeyNavigationAttached); |
553 | + return d->tab; |
554 | +} |
555 | + |
556 | +void QQuickKeyNavigationAttached::setTab(QQuickItem *i) |
557 | +{ |
558 | + Q_D(QQuickKeyNavigationAttached); |
559 | + if (d->tab == i) |
560 | + return; |
561 | + d->tab = i; |
562 | + d->tabSet = true; |
563 | + QQuickKeyNavigationAttached* other = |
564 | + qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i)); |
565 | + if (other && !other->d_func()->backtabSet) { |
566 | + other->d_func()->backtab = qobject_cast<QQuickItem*>(parent()); |
567 | + emit other->backtabChanged(); |
568 | + } |
569 | + emit tabChanged(); |
570 | +} |
571 | + |
572 | +QQuickItem *QQuickKeyNavigationAttached::backtab() const |
573 | +{ |
574 | + Q_D(const QQuickKeyNavigationAttached); |
575 | + return d->backtab; |
576 | +} |
577 | + |
578 | +void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i) |
579 | +{ |
580 | + Q_D(QQuickKeyNavigationAttached); |
581 | + if (d->backtab == i) |
582 | + return; |
583 | + d->backtab = i; |
584 | + d->backtabSet = true; |
585 | + QQuickKeyNavigationAttached* other = |
586 | + qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i)); |
587 | + if (other && !other->d_func()->tabSet) { |
588 | + other->d_func()->tab = qobject_cast<QQuickItem*>(parent()); |
589 | + emit other->tabChanged(); |
590 | + } |
591 | + emit backtabChanged(); |
592 | +} |
593 | + |
594 | +/*! |
595 | + \qmlproperty enumeration QtQuick2::KeyNavigation::priority |
596 | + |
597 | + This property determines whether the keys are processed before |
598 | + or after the attached item's own key handling. |
599 | + |
600 | + \list |
601 | + \li KeyNavigation.BeforeItem - process the key events before normal |
602 | + item key processing. If the event is used for key navigation, it will be accepted and will not |
603 | + be passed on to the item. |
604 | + \li KeyNavigation.AfterItem (default) - process the key events after normal item key |
605 | + handling. If the item accepts the key event it will not be |
606 | + handled by the KeyNavigation attached property handler. |
607 | + \endlist |
608 | +*/ |
609 | +QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const |
610 | +{ |
611 | + return m_processPost ? AfterItem : BeforeItem; |
612 | +} |
613 | + |
614 | +void QQuickKeyNavigationAttached::setPriority(Priority order) |
615 | +{ |
616 | + bool processPost = order == AfterItem; |
617 | + if (processPost != m_processPost) { |
618 | + m_processPost = processPost; |
619 | + emit priorityChanged(); |
620 | + } |
621 | +} |
622 | + |
623 | +void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post) |
624 | +{ |
625 | + Q_D(QQuickKeyNavigationAttached); |
626 | + event->ignore(); |
627 | + |
628 | + if (post != m_processPost) { |
629 | + QQuickItemKeyFilter::keyPressed(event, post); |
630 | + return; |
631 | + } |
632 | + |
633 | + bool mirror = false; |
634 | + switch (event->key()) { |
635 | + case Qt::Key_Left: { |
636 | + if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent())) |
637 | + mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror; |
638 | + QQuickItem* leftItem = mirror ? d->right : d->left; |
639 | + if (leftItem) { |
640 | + setFocusNavigation(leftItem, mirror ? "right" : "left"); |
641 | + event->accept(); |
642 | + } |
643 | + break; |
644 | + } |
645 | + case Qt::Key_Right: { |
646 | + if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent())) |
647 | + mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror; |
648 | + QQuickItem* rightItem = mirror ? d->left : d->right; |
649 | + if (rightItem) { |
650 | + setFocusNavigation(rightItem, mirror ? "left" : "right"); |
651 | + event->accept(); |
652 | + } |
653 | + break; |
654 | + } |
655 | + case Qt::Key_Up: |
656 | + if (d->up) { |
657 | + setFocusNavigation(d->up, "up"); |
658 | + event->accept(); |
659 | + } |
660 | + break; |
661 | + case Qt::Key_Down: |
662 | + if (d->down) { |
663 | + setFocusNavigation(d->down, "down"); |
664 | + event->accept(); |
665 | + } |
666 | + break; |
667 | + case Qt::Key_Tab: |
668 | + if (d->tab) { |
669 | + setFocusNavigation(d->tab, "tab"); |
670 | + event->accept(); |
671 | + } |
672 | + break; |
673 | + case Qt::Key_Backtab: |
674 | + if (d->backtab) { |
675 | + setFocusNavigation(d->backtab, "backtab"); |
676 | + event->accept(); |
677 | + } |
678 | + break; |
679 | + default: |
680 | + break; |
681 | + } |
682 | + |
683 | + if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post); |
684 | +} |
685 | + |
686 | +void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post) |
687 | +{ |
688 | + Q_D(QQuickKeyNavigationAttached); |
689 | + event->ignore(); |
690 | + |
691 | + if (post != m_processPost) { |
692 | + QQuickItemKeyFilter::keyReleased(event, post); |
693 | + return; |
694 | + } |
695 | + |
696 | + bool mirror = false; |
697 | + switch (event->key()) { |
698 | + case Qt::Key_Left: |
699 | + if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent())) |
700 | + mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror; |
701 | + if (mirror ? d->right : d->left) |
702 | + event->accept(); |
703 | + break; |
704 | + case Qt::Key_Right: |
705 | + if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent())) |
706 | + mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror; |
707 | + if (mirror ? d->left : d->right) |
708 | + event->accept(); |
709 | + break; |
710 | + case Qt::Key_Up: |
711 | + if (d->up) { |
712 | + event->accept(); |
713 | + } |
714 | + break; |
715 | + case Qt::Key_Down: |
716 | + if (d->down) { |
717 | + event->accept(); |
718 | + } |
719 | + break; |
720 | + case Qt::Key_Tab: |
721 | + if (d->tab) { |
722 | + event->accept(); |
723 | + } |
724 | + break; |
725 | + case Qt::Key_Backtab: |
726 | + if (d->backtab) { |
727 | + event->accept(); |
728 | + } |
729 | + break; |
730 | + default: |
731 | + break; |
732 | + } |
733 | + |
734 | + if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post); |
735 | +} |
736 | + |
737 | +void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir) |
738 | +{ |
739 | + QQuickItem *initialItem = currentItem; |
740 | + bool isNextItem = false; |
741 | + do { |
742 | + isNextItem = false; |
743 | + if (currentItem->isVisible() && currentItem->isEnabled()) { |
744 | + currentItem->setFocus(true); |
745 | + } else { |
746 | + QObject *attached = |
747 | + qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false); |
748 | + if (attached) { |
749 | + QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir)); |
750 | + if (tempItem) { |
751 | + currentItem = tempItem; |
752 | + isNextItem = true; |
753 | + } |
754 | + } |
755 | + } |
756 | + } |
757 | + while (currentItem != initialItem && isNextItem); |
758 | +} |
759 | + |
760 | +const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = { |
761 | + { Qt::Key_Left, "leftPressed" }, |
762 | + { Qt::Key_Right, "rightPressed" }, |
763 | + { Qt::Key_Up, "upPressed" }, |
764 | + { Qt::Key_Down, "downPressed" }, |
765 | + { Qt::Key_Tab, "tabPressed" }, |
766 | + { Qt::Key_Backtab, "backtabPressed" }, |
767 | + { Qt::Key_Asterisk, "asteriskPressed" }, |
768 | + { Qt::Key_NumberSign, "numberSignPressed" }, |
769 | + { Qt::Key_Escape, "escapePressed" }, |
770 | + { Qt::Key_Return, "returnPressed" }, |
771 | + { Qt::Key_Enter, "enterPressed" }, |
772 | + { Qt::Key_Delete, "deletePressed" }, |
773 | + { Qt::Key_Space, "spacePressed" }, |
774 | + { Qt::Key_Back, "backPressed" }, |
775 | + { Qt::Key_Cancel, "cancelPressed" }, |
776 | + { Qt::Key_Select, "selectPressed" }, |
777 | + { Qt::Key_Yes, "yesPressed" }, |
778 | + { Qt::Key_No, "noPressed" }, |
779 | + { Qt::Key_Context1, "context1Pressed" }, |
780 | + { Qt::Key_Context2, "context2Pressed" }, |
781 | + { Qt::Key_Context3, "context3Pressed" }, |
782 | + { Qt::Key_Context4, "context4Pressed" }, |
783 | + { Qt::Key_Call, "callPressed" }, |
784 | + { Qt::Key_Hangup, "hangupPressed" }, |
785 | + { Qt::Key_Flip, "flipPressed" }, |
786 | + { Qt::Key_Menu, "menuPressed" }, |
787 | + { Qt::Key_VolumeUp, "volumeUpPressed" }, |
788 | + { Qt::Key_VolumeDown, "volumeDownPressed" }, |
789 | + { 0, 0 } |
790 | +}; |
791 | + |
792 | +bool QQuickKeysAttached::isConnected(const char *signalName) |
793 | +{ |
794 | + Q_D(QQuickKeysAttached); |
795 | + int signal_index = d->signalIndex(signalName); |
796 | + return d->isSignalConnected(signal_index); |
797 | +} |
798 | + |
799 | +/*! |
800 | + \qmltype Keys |
801 | + \instantiates QQuickKeysAttached |
802 | + \inqmlmodule QtQuick 2 |
803 | + \ingroup qtquick-input |
804 | + \brief Provides key handling to Items |
805 | + |
806 | + All visual primitives support key handling via the Keys |
807 | + attached property. Keys can be handled via the onPressed |
808 | + and onReleased signal properties. |
809 | + |
810 | + The signal properties have a \l KeyEvent parameter, named |
811 | + \e event which contains details of the event. If a key is |
812 | + handled \e event.accepted should be set to true to prevent the |
813 | + event from propagating up the item hierarchy. |
814 | + |
815 | + \section1 Example Usage |
816 | + |
817 | + The following example shows how the general onPressed handler can |
818 | + be used to test for a certain key; in this case, the left cursor |
819 | + key: |
820 | + |
821 | + \snippet qml/keys/keys-pressed.qml key item |
822 | + |
823 | + Some keys may alternatively be handled via specific signal properties, |
824 | + for example \e onSelectPressed. These handlers automatically set |
825 | + \e event.accepted to true. |
826 | + |
827 | + \snippet qml/keys/keys-handler.qml key item |
828 | + |
829 | + See \l{Qt::Key}{Qt.Key} for the list of keyboard codes. |
830 | + |
831 | + \section1 Key Handling Priorities |
832 | + |
833 | + The Keys attached property can be configured to handle key events |
834 | + before or after the item it is attached to. This makes it possible |
835 | + to intercept events in order to override an item's default behavior, |
836 | + or act as a fallback for keys not handled by the item. |
837 | + |
838 | + If \l priority is Keys.BeforeItem (default) the order of key event processing is: |
839 | + |
840 | + \list 1 |
841 | + \li Items specified in \c forwardTo |
842 | + \li specific key handlers, e.g. onReturnPressed |
843 | + \li onKeyPress, onKeyRelease handlers |
844 | + \li Item specific key handling, e.g. TextInput key handling |
845 | + \li parent item |
846 | + \endlist |
847 | + |
848 | + If priority is Keys.AfterItem the order of key event processing is: |
849 | + |
850 | + \list 1 |
851 | + \li Item specific key handling, e.g. TextInput key handling |
852 | + \li Items specified in \c forwardTo |
853 | + \li specific key handlers, e.g. onReturnPressed |
854 | + \li onKeyPress, onKeyRelease handlers |
855 | + \li parent item |
856 | + \endlist |
857 | + |
858 | + If the event is accepted during any of the above steps, key |
859 | + propagation stops. |
860 | + |
861 | + \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property} |
862 | +*/ |
863 | + |
864 | +/*! |
865 | + \qmlproperty bool QtQuick2::Keys::enabled |
866 | + |
867 | + This flags enables key handling if true (default); otherwise |
868 | + no key handlers will be called. |
869 | +*/ |
870 | + |
871 | +/*! |
872 | + \qmlproperty enumeration QtQuick2::Keys::priority |
873 | + |
874 | + This property determines whether the keys are processed before |
875 | + or after the attached item's own key handling. |
876 | + |
877 | + \list |
878 | + \li Keys.BeforeItem (default) - process the key events before normal |
879 | + item key processing. If the event is accepted it will not |
880 | + be passed on to the item. |
881 | + \li Keys.AfterItem - process the key events after normal item key |
882 | + handling. If the item accepts the key event it will not be |
883 | + handled by the Keys attached property handler. |
884 | + \endlist |
885 | +*/ |
886 | + |
887 | +/*! |
888 | + \qmlproperty list<Object> QtQuick2::Keys::forwardTo |
889 | + |
890 | + This property provides a way to forward key presses, key releases, and keyboard input |
891 | + coming from input methods to other items. This can be useful when you want |
892 | + one item to handle some keys (e.g. the up and down arrow keys), and another item to |
893 | + handle other keys (e.g. the left and right arrow keys). Once an item that has been |
894 | + forwarded keys accepts the event it is no longer forwarded to items later in the |
895 | + list. |
896 | + |
897 | + This example forwards key events to two lists: |
898 | + \qml |
899 | + Item { |
900 | + ListView { |
901 | + id: list1 |
902 | + // ... |
903 | + } |
904 | + ListView { |
905 | + id: list2 |
906 | + // ... |
907 | + } |
908 | + Keys.forwardTo: [list1, list2] |
909 | + focus: true |
910 | + } |
911 | + \endqml |
912 | +*/ |
913 | + |
914 | +/*! |
915 | + \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event) |
916 | + |
917 | + This handler is called when a key has been pressed. The \a event |
918 | + parameter provides information about the event. |
919 | +*/ |
920 | + |
921 | +/*! |
922 | + \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event) |
923 | + |
924 | + This handler is called when a key has been released. The \a event |
925 | + parameter provides information about the event. |
926 | +*/ |
927 | + |
928 | +/*! |
929 | + \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event) |
930 | + |
931 | + This handler is called when the digit '0' has been pressed. The \a event |
932 | + parameter provides information about the event. |
933 | +*/ |
934 | + |
935 | +/*! |
936 | + \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event) |
937 | + |
938 | + This handler is called when the digit '1' has been pressed. The \a event |
939 | + parameter provides information about the event. |
940 | +*/ |
941 | + |
942 | +/*! |
943 | + \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event) |
944 | + |
945 | + This handler is called when the digit '2' has been pressed. The \a event |
946 | + parameter provides information about the event. |
947 | +*/ |
948 | + |
949 | +/*! |
950 | + \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event) |
951 | + |
952 | + This handler is called when the digit '3' has been pressed. The \a event |
953 | + parameter provides information about the event. |
954 | +*/ |
955 | + |
956 | +/*! |
957 | + \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event) |
958 | + |
959 | + This handler is called when the digit '4' has been pressed. The \a event |
960 | + parameter provides information about the event. |
961 | +*/ |
962 | + |
963 | +/*! |
964 | + \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event) |
965 | + |
966 | + This handler is called when the digit '5' has been pressed. The \a event |
967 | + parameter provides information about the event. |
968 | +*/ |
969 | + |
970 | +/*! |
971 | + \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event) |
972 | + |
973 | + This handler is called when the digit '6' has been pressed. The \a event |
974 | + parameter provides information about the event. |
975 | +*/ |
976 | + |
977 | +/*! |
978 | + \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event) |
979 | + |
980 | + This handler is called when the digit '7' has been pressed. The \a event |
981 | + parameter provides information about the event. |
982 | +*/ |
983 | + |
984 | +/*! |
985 | + \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event) |
986 | + |
987 | + This handler is called when the digit '8' has been pressed. The \a event |
988 | + parameter provides information about the event. |
989 | +*/ |
990 | + |
991 | +/*! |
992 | + \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event) |
993 | + |
994 | + This handler is called when the digit '9' has been pressed. The \a event |
995 | + parameter provides information about the event. |
996 | +*/ |
997 | + |
998 | +/*! |
999 | + \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event) |
1000 | + |
1001 | + This handler is called when the Left arrow has been pressed. The \a event |
1002 | + parameter provides information about the event. |
1003 | +*/ |
1004 | + |
1005 | +/*! |
1006 | + \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event) |
1007 | + |
1008 | + This handler is called when the Right arrow has been pressed. The \a event |
1009 | + parameter provides information about the event. |
1010 | +*/ |
1011 | + |
1012 | +/*! |
1013 | + \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event) |
1014 | + |
1015 | + This handler is called when the Up arrow has been pressed. The \a event |
1016 | + parameter provides information about the event. |
1017 | +*/ |
1018 | + |
1019 | +/*! |
1020 | + \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event) |
1021 | + |
1022 | + This handler is called when the Down arrow has been pressed. The \a event |
1023 | + parameter provides information about the event. |
1024 | +*/ |
1025 | + |
1026 | +/*! |
1027 | + \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event) |
1028 | + |
1029 | + This handler is called when the Tab key has been pressed. The \a event |
1030 | + parameter provides information about the event. |
1031 | +*/ |
1032 | + |
1033 | +/*! |
1034 | + \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event) |
1035 | + |
1036 | + This handler is called when the Shift+Tab key combination (Backtab) has |
1037 | + been pressed. The \a event parameter provides information about the event. |
1038 | +*/ |
1039 | + |
1040 | +/*! |
1041 | + \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event) |
1042 | + |
1043 | + This handler is called when the Asterisk '*' has been pressed. The \a event |
1044 | + parameter provides information about the event. |
1045 | +*/ |
1046 | + |
1047 | +/*! |
1048 | + \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event) |
1049 | + |
1050 | + This handler is called when the Escape key has been pressed. The \a event |
1051 | + parameter provides information about the event. |
1052 | +*/ |
1053 | + |
1054 | +/*! |
1055 | + \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event) |
1056 | + |
1057 | + This handler is called when the Return key has been pressed. The \a event |
1058 | + parameter provides information about the event. |
1059 | +*/ |
1060 | + |
1061 | +/*! |
1062 | + \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event) |
1063 | + |
1064 | + This handler is called when the Enter key has been pressed. The \a event |
1065 | + parameter provides information about the event. |
1066 | +*/ |
1067 | + |
1068 | +/*! |
1069 | + \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event) |
1070 | + |
1071 | + This handler is called when the Delete key has been pressed. The \a event |
1072 | + parameter provides information about the event. |
1073 | +*/ |
1074 | + |
1075 | +/*! |
1076 | + \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event) |
1077 | + |
1078 | + This handler is called when the Space key has been pressed. The \a event |
1079 | + parameter provides information about the event. |
1080 | +*/ |
1081 | + |
1082 | +/*! |
1083 | + \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event) |
1084 | + |
1085 | + This handler is called when the Back key has been pressed. The \a event |
1086 | + parameter provides information about the event. |
1087 | +*/ |
1088 | + |
1089 | +/*! |
1090 | + \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event) |
1091 | + |
1092 | + This handler is called when the Cancel key has been pressed. The \a event |
1093 | + parameter provides information about the event. |
1094 | +*/ |
1095 | + |
1096 | +/*! |
1097 | + \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event) |
1098 | + |
1099 | + This handler is called when the Select key has been pressed. The \a event |
1100 | + parameter provides information about the event. |
1101 | +*/ |
1102 | + |
1103 | +/*! |
1104 | + \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event) |
1105 | + |
1106 | + This handler is called when the Yes key has been pressed. The \a event |
1107 | + parameter provides information about the event. |
1108 | +*/ |
1109 | + |
1110 | +/*! |
1111 | + \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event) |
1112 | + |
1113 | + This handler is called when the No key has been pressed. The \a event |
1114 | + parameter provides information about the event. |
1115 | +*/ |
1116 | + |
1117 | +/*! |
1118 | + \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event) |
1119 | + |
1120 | + This handler is called when the Context1 key has been pressed. The \a event |
1121 | + parameter provides information about the event. |
1122 | +*/ |
1123 | + |
1124 | +/*! |
1125 | + \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event) |
1126 | + |
1127 | + This handler is called when the Context2 key has been pressed. The \a event |
1128 | + parameter provides information about the event. |
1129 | +*/ |
1130 | + |
1131 | +/*! |
1132 | + \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event) |
1133 | + |
1134 | + This handler is called when the Context3 key has been pressed. The \a event |
1135 | + parameter provides information about the event. |
1136 | +*/ |
1137 | + |
1138 | +/*! |
1139 | + \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event) |
1140 | + |
1141 | + This handler is called when the Context4 key has been pressed. The \a event |
1142 | + parameter provides information about the event. |
1143 | +*/ |
1144 | + |
1145 | +/*! |
1146 | + \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event) |
1147 | + |
1148 | + This handler is called when the Call key has been pressed. The \a event |
1149 | + parameter provides information about the event. |
1150 | +*/ |
1151 | + |
1152 | +/*! |
1153 | + \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event) |
1154 | + |
1155 | + This handler is called when the Hangup key has been pressed. The \a event |
1156 | + parameter provides information about the event. |
1157 | +*/ |
1158 | + |
1159 | +/*! |
1160 | + \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event) |
1161 | + |
1162 | + This handler is called when the Flip key has been pressed. The \a event |
1163 | + parameter provides information about the event. |
1164 | +*/ |
1165 | + |
1166 | +/*! |
1167 | + \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event) |
1168 | + |
1169 | + This handler is called when the Menu key has been pressed. The \a event |
1170 | + parameter provides information about the event. |
1171 | +*/ |
1172 | + |
1173 | +/*! |
1174 | + \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event) |
1175 | + |
1176 | + This handler is called when the VolumeUp key has been pressed. The \a event |
1177 | + parameter provides information about the event. |
1178 | +*/ |
1179 | + |
1180 | +/*! |
1181 | + \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event) |
1182 | + |
1183 | + This handler is called when the VolumeDown key has been pressed. The \a event |
1184 | + parameter provides information about the event. |
1185 | +*/ |
1186 | + |
1187 | +QQuickKeysAttached::QQuickKeysAttached(QObject *parent) |
1188 | +: QObject(*(new QQuickKeysAttachedPrivate), parent), |
1189 | + QQuickItemKeyFilter(qmlobject_cast<QQuickItem*>(parent)) |
1190 | +{ |
1191 | + Q_D(QQuickKeysAttached); |
1192 | + m_processPost = false; |
1193 | + d->item = qmlobject_cast<QQuickItem*>(parent); |
1194 | +} |
1195 | + |
1196 | +QQuickKeysAttached::~QQuickKeysAttached() |
1197 | +{ |
1198 | +} |
1199 | + |
1200 | +QQuickKeysAttached::Priority QQuickKeysAttached::priority() const |
1201 | +{ |
1202 | + return m_processPost ? AfterItem : BeforeItem; |
1203 | +} |
1204 | + |
1205 | +void QQuickKeysAttached::setPriority(Priority order) |
1206 | +{ |
1207 | + bool processPost = order == AfterItem; |
1208 | + if (processPost != m_processPost) { |
1209 | + m_processPost = processPost; |
1210 | + emit priorityChanged(); |
1211 | + } |
1212 | +} |
1213 | + |
1214 | +void QQuickKeysAttached::componentComplete() |
1215 | +{ |
1216 | + Q_D(QQuickKeysAttached); |
1217 | +#ifndef QT_NO_IM |
1218 | + if (d->item) { |
1219 | + for (int ii = 0; ii < d->targets.count(); ++ii) { |
1220 | + QQuickItem *targetItem = d->targets.at(ii); |
1221 | + if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) { |
1222 | + d->item->setFlag(QQuickItem::ItemAcceptsInputMethod); |
1223 | + break; |
1224 | + } |
1225 | + } |
1226 | + } |
1227 | +#endif |
1228 | +} |
1229 | + |
1230 | +void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post) |
1231 | +{ |
1232 | + Q_D(QQuickKeysAttached); |
1233 | + if (post != m_processPost || !d->enabled || d->inPress) { |
1234 | + event->ignore(); |
1235 | + QQuickItemKeyFilter::keyPressed(event, post); |
1236 | + return; |
1237 | + } |
1238 | + |
1239 | + // first process forwards |
1240 | + if (d->item && d->item->window()) { |
1241 | + d->inPress = true; |
1242 | + for (int ii = 0; ii < d->targets.count(); ++ii) { |
1243 | + QQuickItem *i = d->targets.at(ii); |
1244 | + if (i && i->isVisible()) { |
1245 | + d->item->window()->sendEvent(i, event); |
1246 | + if (event->isAccepted()) { |
1247 | + d->inPress = false; |
1248 | + return; |
1249 | + } |
1250 | + } |
1251 | + } |
1252 | + d->inPress = false; |
1253 | + } |
1254 | + |
1255 | + QQuickKeyEvent ke(*event); |
1256 | + QByteArray keySignal = keyToSignal(event->key()); |
1257 | + if (!keySignal.isEmpty()) { |
1258 | + keySignal += "(QQuickKeyEvent*)"; |
1259 | + if (isConnected(keySignal)) { |
1260 | + // If we specifically handle a key then default to accepted |
1261 | + ke.setAccepted(true); |
1262 | + int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal); |
1263 | + metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke)); |
1264 | + } |
1265 | + } |
1266 | + if (!ke.isAccepted()) |
1267 | + emit pressed(&ke); |
1268 | + event->setAccepted(ke.isAccepted()); |
1269 | + |
1270 | + if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post); |
1271 | +} |
1272 | + |
1273 | +void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post) |
1274 | +{ |
1275 | + Q_D(QQuickKeysAttached); |
1276 | + if (post != m_processPost || !d->enabled || d->inRelease) { |
1277 | + event->ignore(); |
1278 | + QQuickItemKeyFilter::keyReleased(event, post); |
1279 | + return; |
1280 | + } |
1281 | + |
1282 | + if (d->item && d->item->window()) { |
1283 | + d->inRelease = true; |
1284 | + for (int ii = 0; ii < d->targets.count(); ++ii) { |
1285 | + QQuickItem *i = d->targets.at(ii); |
1286 | + if (i && i->isVisible()) { |
1287 | + d->item->window()->sendEvent(i, event); |
1288 | + if (event->isAccepted()) { |
1289 | + d->inRelease = false; |
1290 | + return; |
1291 | + } |
1292 | + } |
1293 | + } |
1294 | + d->inRelease = false; |
1295 | + } |
1296 | + |
1297 | + QQuickKeyEvent ke(*event); |
1298 | + emit released(&ke); |
1299 | + event->setAccepted(ke.isAccepted()); |
1300 | + |
1301 | + if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post); |
1302 | +} |
1303 | + |
1304 | +#ifndef QT_NO_IM |
1305 | +void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post) |
1306 | +{ |
1307 | + Q_D(QQuickKeysAttached); |
1308 | + if (post == m_processPost && d->item && !d->inIM && d->item->window()) { |
1309 | + d->inIM = true; |
1310 | + for (int ii = 0; ii < d->targets.count(); ++ii) { |
1311 | + QQuickItem *i = d->targets.at(ii); |
1312 | + if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) { |
1313 | + d->item->window()->sendEvent(i, event); |
1314 | + if (event->isAccepted()) { |
1315 | + d->imeItem = i; |
1316 | + d->inIM = false; |
1317 | + return; |
1318 | + } |
1319 | + } |
1320 | + } |
1321 | + d->inIM = false; |
1322 | + } |
1323 | + QQuickItemKeyFilter::inputMethodEvent(event, post); |
1324 | +} |
1325 | + |
1326 | +QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const |
1327 | +{ |
1328 | + Q_D(const QQuickKeysAttached); |
1329 | + if (d->item) { |
1330 | + for (int ii = 0; ii < d->targets.count(); ++ii) { |
1331 | + QQuickItem *i = d->targets.at(ii); |
1332 | + if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) { |
1333 | + //### how robust is i == d->imeItem check? |
1334 | + QVariant v = i->inputMethodQuery(query); |
1335 | + if (v.userType() == QVariant::RectF) |
1336 | + v = d->item->mapRectFromItem(i, v.toRectF()); //### cost? |
1337 | + return v; |
1338 | + } |
1339 | + } |
1340 | + } |
1341 | + return QQuickItemKeyFilter::inputMethodQuery(query); |
1342 | +} |
1343 | +#endif // QT_NO_IM |
1344 | + |
1345 | +QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj) |
1346 | +{ |
1347 | + return new QQuickKeysAttached(obj); |
1348 | +} |
1349 | + |
1350 | +/*! |
1351 | + \qmltype LayoutMirroring |
1352 | + \instantiates QQuickLayoutMirroringAttached |
1353 | + \inqmlmodule QtQuick 2 |
1354 | + \ingroup qtquick-positioners |
1355 | + \ingroup qml-utility-elements |
1356 | + \brief Property used to mirror layout behavior |
1357 | + |
1358 | + The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors}, |
1359 | + \l{Item Layouts}{positioner} types (such as \l Row and \l Grid) |
1360 | + and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left |
1361 | + anchors become right anchors, and positioner types like \l Grid and \l Row reverse the |
1362 | + horizontal layout of child items. |
1363 | + |
1364 | + Mirroring is enabled for an item by setting the \l enabled property to true. By default, this |
1365 | + only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring |
1366 | + behavior to all child items as well. If the \c LayoutMirroring attached property has not been defined |
1367 | + for an item, mirroring is not enabled. |
1368 | + |
1369 | + The following example shows mirroring in action. The \l Row below is specified as being anchored |
1370 | + to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally |
1371 | + reversed and it is now anchored to the right. Also, since items in a \l Row are positioned |
1372 | + from left to right by default, they are now positioned from right to left instead, as demonstrated |
1373 | + by the numbering and opacity of the items: |
1374 | + |
1375 | + \snippet qml/layoutmirroring.qml 0 |
1376 | + |
1377 | + \image layoutmirroring.png |
1378 | + |
1379 | + Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left |
1380 | + layout versions of an application to target different language areas. The \l childrenInherit |
1381 | + property allows layout mirroring to be applied without manually setting layout configurations |
1382 | + for every item in an application. Keep in mind, however, that mirroring does not affect any |
1383 | + positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with |
1384 | + mirroring enabled, it will often be necessary to apply some layout fixes to support the |
1385 | + desired layout direction. Also, it may be necessary to disable the mirroring of individual |
1386 | + child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if |
1387 | + mirroring is not the desired behavior, or if the child item already implements mirroring in |
1388 | + some custom way. |
1389 | + |
1390 | + See \l {Right-to-left User Interfaces} for further details on using \c LayoutMirroring and |
1391 | + other related features to implement right-to-left support for an application. |
1392 | +*/ |
1393 | + |
1394 | +/*! |
1395 | + \qmlproperty bool QtQuick2::LayoutMirroring::enabled |
1396 | + |
1397 | + This property holds whether the item's layout is mirrored horizontally. Setting this to true |
1398 | + horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right, |
1399 | + and right anchors become left. For \l{Item Layouts}{positioner} types |
1400 | + (such as \l Row and \l Grid) and view types (such as \l {GridView}{GridView} and \l {ListView}{ListView}) |
1401 | + this also mirrors the horizontal layout direction of the item. |
1402 | + |
1403 | + The default value is false. |
1404 | +*/ |
1405 | + |
1406 | +/*! |
1407 | + \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit |
1408 | + |
1409 | + This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item |
1410 | + is inherited by its children. |
1411 | + |
1412 | + The default value is false. |
1413 | +*/ |
1414 | + |
1415 | + |
1416 | +QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0) |
1417 | +{ |
1418 | + if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) { |
1419 | + itemPrivate = QQuickItemPrivate::get(item); |
1420 | + itemPrivate->extra.value().layoutDirectionAttached = this; |
1421 | + } else |
1422 | + qmlInfo(parent) << tr("LayoutDirection attached property only works with Items"); |
1423 | +} |
1424 | + |
1425 | +QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object) |
1426 | +{ |
1427 | + return new QQuickLayoutMirroringAttached(object); |
1428 | +} |
1429 | + |
1430 | +bool QQuickLayoutMirroringAttached::enabled() const |
1431 | +{ |
1432 | + return itemPrivate ? itemPrivate->effectiveLayoutMirror : false; |
1433 | +} |
1434 | + |
1435 | +void QQuickLayoutMirroringAttached::setEnabled(bool enabled) |
1436 | +{ |
1437 | + if (!itemPrivate) |
1438 | + return; |
1439 | + |
1440 | + itemPrivate->isMirrorImplicit = false; |
1441 | + if (enabled != itemPrivate->effectiveLayoutMirror) { |
1442 | + itemPrivate->setLayoutMirror(enabled); |
1443 | + if (itemPrivate->inheritMirrorFromItem) |
1444 | + itemPrivate->resolveLayoutMirror(); |
1445 | + } |
1446 | +} |
1447 | + |
1448 | +void QQuickLayoutMirroringAttached::resetEnabled() |
1449 | +{ |
1450 | + if (itemPrivate && !itemPrivate->isMirrorImplicit) { |
1451 | + itemPrivate->isMirrorImplicit = true; |
1452 | + itemPrivate->resolveLayoutMirror(); |
1453 | + } |
1454 | +} |
1455 | + |
1456 | +bool QQuickLayoutMirroringAttached::childrenInherit() const |
1457 | +{ |
1458 | + return itemPrivate ? itemPrivate->inheritMirrorFromItem : false; |
1459 | +} |
1460 | + |
1461 | +void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) { |
1462 | + if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) { |
1463 | + itemPrivate->inheritMirrorFromItem = childrenInherit; |
1464 | + itemPrivate->resolveLayoutMirror(); |
1465 | + childrenInheritChanged(); |
1466 | + } |
1467 | +} |
1468 | + |
1469 | +void QQuickItemPrivate::resolveLayoutMirror() |
1470 | +{ |
1471 | + Q_Q(QQuickItem); |
1472 | + if (QQuickItem *parentItem = q->parentItem()) { |
1473 | + QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem); |
1474 | + setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent); |
1475 | + } else { |
1476 | + setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem); |
1477 | + } |
1478 | +} |
1479 | + |
1480 | +void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit) |
1481 | +{ |
1482 | + inherit = inherit || inheritMirrorFromItem; |
1483 | + if (!isMirrorImplicit && inheritMirrorFromItem) |
1484 | + mirror = effectiveLayoutMirror; |
1485 | + if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent) |
1486 | + return; |
1487 | + |
1488 | + inheritMirrorFromParent = inherit; |
1489 | + inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false; |
1490 | + |
1491 | + if (isMirrorImplicit) |
1492 | + setLayoutMirror(inherit ? inheritedLayoutMirror : false); |
1493 | + for (int i = 0; i < childItems.count(); ++i) { |
1494 | + if (QQuickItem *child = qmlobject_cast<QQuickItem *>(childItems.at(i))) { |
1495 | + QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); |
1496 | + childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent); |
1497 | + } |
1498 | + } |
1499 | +} |
1500 | + |
1501 | +void QQuickItemPrivate::setLayoutMirror(bool mirror) |
1502 | +{ |
1503 | + if (mirror != effectiveLayoutMirror) { |
1504 | + effectiveLayoutMirror = mirror; |
1505 | + if (_anchors) { |
1506 | + QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors); |
1507 | + anchor_d->fillChanged(); |
1508 | + anchor_d->centerInChanged(); |
1509 | + anchor_d->updateHorizontalAnchors(); |
1510 | + } |
1511 | + mirrorChange(); |
1512 | + if (extra.isAllocated() && extra->layoutDirectionAttached) { |
1513 | + emit extra->layoutDirectionAttached->enabledChanged(); |
1514 | + } |
1515 | + } |
1516 | +} |
1517 | + |
1518 | +void QQuickItemPrivate::setAccessibleFlagAndListener() |
1519 | +{ |
1520 | + Q_Q(QQuickItem); |
1521 | + QQuickItem *item = q; |
1522 | + while (item) { |
1523 | + if (item->d_func()->isAccessible) |
1524 | + break; // already set - grandparents should have the flag set as well. |
1525 | + |
1526 | + item->d_func()->isAccessible = true; |
1527 | + item = item->d_func()->parentItem; |
1528 | + } |
1529 | +} |
1530 | + |
1531 | +void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) |
1532 | +{ |
1533 | + Q_Q(QQuickItem); |
1534 | + Q_ASSERT(scope); |
1535 | + |
1536 | + QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope); |
1537 | + |
1538 | + QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem; |
1539 | + // Correct focus chain in scope |
1540 | + if (oldSubFocusItem) { |
1541 | + QQuickItem *sfi = scopePrivate->subFocusItem->parentItem(); |
1542 | + while (sfi && sfi != scope) { |
1543 | + QQuickItemPrivate::get(sfi)->subFocusItem = 0; |
1544 | + sfi = sfi->parentItem(); |
1545 | + } |
1546 | + } |
1547 | + |
1548 | + if (focus) { |
1549 | + scopePrivate->subFocusItem = q; |
1550 | + QQuickItem *sfi = scopePrivate->subFocusItem->parentItem(); |
1551 | + while (sfi && sfi != scope) { |
1552 | + QQuickItemPrivate::get(sfi)->subFocusItem = q; |
1553 | + sfi = sfi->parentItem(); |
1554 | + } |
1555 | + } else { |
1556 | + scopePrivate->subFocusItem = 0; |
1557 | + } |
1558 | +} |
1559 | + |
1560 | +/*! |
1561 | + \class QQuickItem |
1562 | + \brief The QQuickItem class provides the most basic of all visual items in QtQuick. |
1563 | + \inmodule QtQuick |
1564 | + |
1565 | + All visual items in Qt Quick inherit from QQuickItem. Although a QQuickItem |
1566 | + instance has no visual appearance, it defines all the attributes that are |
1567 | + common across visual items, such as x and y position, width and height, |
1568 | + \l {Positioning with Anchors}{anchoring} and key handling support. |
1569 | + |
1570 | + You can subclass QQuickItem to provide your own custom visual item |
1571 | + that inherits these features. |
1572 | + |
1573 | + \section1 Custom Scene Graph Items |
1574 | + |
1575 | + All visual QML items are rendered using the scene graph, a |
1576 | + low-level, high-performance rendering stack, closely tied to |
1577 | + OpenGL. It is possible for subclasses of QQuickItem to add their |
1578 | + own custom content into the scene graph by setting the |
1579 | + QQuickItem::ItemHasContents flag and reimplementing the |
1580 | + QQuickItem::updatePaintNode() function. |
1581 | + |
1582 | + \warning It is crucial that OpenGL operations and interaction with |
1583 | + the scene graph happens exclusively on the rendering thread, |
1584 | + primarily during the updatePaintNode() call. The best rule of |
1585 | + thumb is to only use classes with the "QSG" prefix inside the |
1586 | + QQuickItem::updatePaintNode() function. |
1587 | + |
1588 | + To read more about how the scene graph rendering works, see |
1589 | + \l{Scene Graph and Rendering} |
1590 | + |
1591 | + \section1 Custom QPainter Items |
1592 | + |
1593 | + The QQuickItem provides a subclass, QQuickPaintedItem, which |
1594 | + allows the users to render content using QPainter. |
1595 | + |
1596 | + \warning Using QQuickPaintedItem uses an indirect 2D surface to |
1597 | + render its content, either using software rasterization or using |
1598 | + an OpenGL framebuffer object (FBO), so the rendering is a two-step |
1599 | + operation. First rasterize the surface, then draw the |
1600 | + surface. Using scene graph API directly is always significantly |
1601 | + faster. |
1602 | + |
1603 | + \sa QQuickWindow, QQuickPaintedItem |
1604 | +*/ |
1605 | + |
1606 | +/*! |
1607 | + \qmltype Item |
1608 | + \instantiates QQuickItem |
1609 | + \inherits QtObject |
1610 | + \inqmlmodule QtQuick 2 |
1611 | + \ingroup qtquick-visual |
1612 | + \brief A basic visual QML type |
1613 | + |
1614 | + The Item type is the base type for all visual items in Qt Quick. |
1615 | + |
1616 | + All visual items in Qt Quick inherit from Item. Although an Item |
1617 | + object has no visual appearance, it defines all the attributes that are |
1618 | + common across visual items, such as x and y position, width and height, |
1619 | + \l {Positioning with Anchors}{anchoring} and key handling support. |
1620 | + |
1621 | + The Item type can be useful for grouping several items under a single |
1622 | + root visual item. For example: |
1623 | + |
1624 | + \qml |
1625 | + import QtQuick 2.0 |
1626 | + |
1627 | + Item { |
1628 | + Image { |
1629 | + source: "tile.png" |
1630 | + } |
1631 | + Image { |
1632 | + x: 80 |
1633 | + width: 100 |
1634 | + height: 100 |
1635 | + source: "tile.png" |
1636 | + } |
1637 | + Image { |
1638 | + x: 190 |
1639 | + width: 100 |
1640 | + height: 100 |
1641 | + fillMode: Image.Tile |
1642 | + source: "tile.png" |
1643 | + } |
1644 | + } |
1645 | + \endqml |
1646 | + |
1647 | + |
1648 | + \section2 Key Handling |
1649 | + |
1650 | + Key handling is available to all Item-based visual types via the \l Keys |
1651 | + attached property. The \e Keys attached property provides basic handlers |
1652 | + such as \l {Keys::}{onPressed} and \l {Keys}{::onReleased}, as well as |
1653 | + handlers for specific keys, such as \l {Keys::}{onSpacePressed}. The |
1654 | + example below assigns \l {Keyboard Focus in Qt Quick}{keyboard focus} to |
1655 | + the item and handles the left key via the general \e onPressed handler |
1656 | + and the return key via the onReturnPressed handler: |
1657 | + |
1658 | + \qml |
1659 | + import QtQuick 2.0 |
1660 | + |
1661 | + Item { |
1662 | + focus: true |
1663 | + Keys.onPressed: { |
1664 | + if (event.key == Qt.Key_Left) { |
1665 | + console.log("move left"); |
1666 | + event.accepted = true; |
1667 | + } |
1668 | + } |
1669 | + Keys.onReturnPressed: console.log("Pressed return"); |
1670 | + } |
1671 | + \endqml |
1672 | + |
1673 | + See the \l Keys attached property for detailed documentation. |
1674 | + |
1675 | + \section2 Layout Mirroring |
1676 | + |
1677 | + Item layouts can be mirrored using the \l LayoutMirroring attached |
1678 | + property. This causes \l{anchors.top}{anchors} to be horizontally |
1679 | + reversed, and also causes items that lay out or position their children |
1680 | + (such as ListView or \l Row) to horizontally reverse the direction of |
1681 | + their layouts. |
1682 | + |
1683 | + See LayoutMirroring for more details. |
1684 | +*/ |
1685 | + |
1686 | +/*! |
1687 | + \enum QQuickItem::Flag |
1688 | + |
1689 | + This enum type is used to specify various item properties. |
1690 | + |
1691 | + \value ItemClipsChildrenToShape Indicates this item should visually clip |
1692 | + its children so that they are rendered only within the boundaries of this |
1693 | + item. |
1694 | + \value ItemAcceptsInputMethod Indicates the item supports text input |
1695 | + methods. |
1696 | + \value ItemIsFocusScope Indicates the item is a focus scope. See |
1697 | + \l {Keyboard Focus in Qt Quick} for more information. |
1698 | + \value ItemHasContents Indicates the item has visual content and should be |
1699 | + rendered by the scene graph. |
1700 | + \value ItemAcceptsDrops Indicates the item accepts drag and drop events. |
1701 | + |
1702 | + \sa setFlag(), setFlags(), flags() |
1703 | +*/ |
1704 | + |
1705 | +/*! |
1706 | + \enum QQuickItem::ItemChange |
1707 | + \brief Used in conjunction with QQuickItem::itemChange() to notify |
1708 | + the item about certain types of changes. |
1709 | + |
1710 | + \value ItemChildAddedChange A child was added. ItemChangeData::item contains |
1711 | + the added child. |
1712 | + |
1713 | + \value ItemChildRemovedChange A child was removed. ItemChangeData::item |
1714 | + contains the removed child. |
1715 | + |
1716 | + \value ItemSceneChange The item was added to or removed from a scene. The |
1717 | + QQuickWindow rendering the scene is specified in using ItemChangeData::window. |
1718 | + The window parameter is null when the item is removed from a scene. |
1719 | + |
1720 | + \value ItemVisibleHasChanged The item's visibility has changed. |
1721 | + ItemChangeData::boolValue contains the new visibility. |
1722 | + |
1723 | + \value ItemParentHasChanged The item's parent has changed. |
1724 | + ItemChangeData::item contains the new parent. |
1725 | + |
1726 | + \value ItemOpacityHasChanged The item's opacity has changed. |
1727 | + ItemChangeData::realValue contains the new opacity. |
1728 | + |
1729 | + \value ItemActiveFocusHasChanged The item's focus has changed. |
1730 | + ItemChangeData::boolValue contains whether the item has focus or not. |
1731 | + |
1732 | + \value ItemRotationHasChanged The item's rotation has changed. |
1733 | + ItemChangeData::realValue contains the new rotation. |
1734 | +*/ |
1735 | + |
1736 | +/*! |
1737 | + \class QQuickItem::ItemChangeData |
1738 | + \inmodule QtQuick |
1739 | + \brief Adds supplimentary information to the QQuickItem::itemChange() |
1740 | + function. |
1741 | + |
1742 | + The meaning of each member of this class is defined by the change type. |
1743 | + |
1744 | + \sa QQuickItem::ItemChange |
1745 | +*/ |
1746 | + |
1747 | +/*! |
1748 | + \fn QQuickItem::ItemChangeData::ItemChangeData(QQuickItem *) |
1749 | + \internal |
1750 | + */ |
1751 | + |
1752 | +/*! |
1753 | + \fn QQuickItem::ItemChangeData::ItemChangeData(QQuickWindow *) |
1754 | + \internal |
1755 | + */ |
1756 | + |
1757 | +/*! |
1758 | + \fn QQuickItem::ItemChangeData::ItemChangeData(qreal) |
1759 | + \internal |
1760 | + */ |
1761 | + |
1762 | +/*! |
1763 | + \fn QQuickItem::ItemChangeData::ItemChangeData(bool) |
1764 | + \internal |
1765 | + */ |
1766 | + |
1767 | +/*! |
1768 | + \variable QQuickItem::ItemChangeData::realValue |
1769 | + Contains supplimentary information to the QQuickItem::itemChange() function. |
1770 | + \sa QQuickItem::ItemChange |
1771 | + */ |
1772 | + |
1773 | +/*! |
1774 | + \variable QQuickItem::ItemChangeData::boolValue |
1775 | + Contains supplimentary information to the QQuickItem::itemChange() function. |
1776 | + \sa QQuickItem::ItemChange |
1777 | + */ |
1778 | + |
1779 | +/*! |
1780 | + \variable QQuickItem::ItemChangeData::item |
1781 | + Contains supplimentary information to the QQuickItem::itemChange() function. |
1782 | + \sa QQuickItem::ItemChange |
1783 | + */ |
1784 | + |
1785 | +/*! |
1786 | + \variable QQuickItem::ItemChangeData::window |
1787 | + Contains supplimentary information to the QQuickItem::itemChange() function. |
1788 | + \sa QQuickItem::ItemChange |
1789 | + */ |
1790 | + |
1791 | +/*! |
1792 | + \enum QQuickItem::TransformOrigin |
1793 | + |
1794 | + Controls the point about which simple transforms like scale apply. |
1795 | + |
1796 | + \value TopLeft The top-left corner of the item. |
1797 | + \value Top The center point of the top of the item. |
1798 | + \value TopRight The top-right corner of the item. |
1799 | + \value Left The left most point of the vertical middle. |
1800 | + \value Center The center of the item. |
1801 | + \value Right The right most point of the vertical middle. |
1802 | + \value BottomLeft The bottom-left corner of the item. |
1803 | + \value Bottom The center point of the bottom of the item. |
1804 | + \value BottomRight The bottom-right corner of the item. |
1805 | + |
1806 | + \sa transformOrigin |
1807 | +*/ |
1808 | + |
1809 | +/*! |
1810 | + \fn void QQuickItem::childrenRectChanged(const QRectF &) |
1811 | + \internal |
1812 | +*/ |
1813 | + |
1814 | +/*! |
1815 | + \fn void QQuickItem::baselineOffsetChanged(qreal) |
1816 | + \internal |
1817 | +*/ |
1818 | + |
1819 | +/*! |
1820 | + \fn void QQuickItem::stateChanged(const QString &state) |
1821 | + \internal |
1822 | +*/ |
1823 | + |
1824 | +/*! |
1825 | + \fn void QQuickItem::parentChanged(QQuickItem *) |
1826 | + \internal |
1827 | +*/ |
1828 | + |
1829 | +/*! |
1830 | + \fn void QQuickItem::smoothChanged(bool) |
1831 | + \internal |
1832 | +*/ |
1833 | + |
1834 | +/*! |
1835 | + \fn void QQuickItem::antialiasingChanged(bool) |
1836 | + \internal |
1837 | +*/ |
1838 | + |
1839 | +/*! |
1840 | + \fn void QQuickItem::clipChanged(bool) |
1841 | + \internal |
1842 | +*/ |
1843 | + |
1844 | +/*! |
1845 | + \fn void QQuickItem::transformOriginChanged(TransformOrigin) |
1846 | + \internal |
1847 | +*/ |
1848 | + |
1849 | +/*! |
1850 | + \fn void QQuickItem::focusChanged(bool) |
1851 | + \internal |
1852 | +*/ |
1853 | + |
1854 | +/*! |
1855 | + \fn void QQuickItem::activeFocusChanged(bool) |
1856 | + \internal |
1857 | +*/ |
1858 | + |
1859 | +/*! |
1860 | + \fn void QQuickItem::childrenChanged() |
1861 | + \internal |
1862 | +*/ |
1863 | + |
1864 | +/*! |
1865 | + \fn void QQuickItem::opacityChanged() |
1866 | + \internal |
1867 | +*/ |
1868 | + |
1869 | +/*! |
1870 | + \fn void QQuickItem::enabledChanged() |
1871 | + \internal |
1872 | +*/ |
1873 | + |
1874 | +/*! |
1875 | + \fn void QQuickItem::visibleChanged() |
1876 | + \internal |
1877 | +*/ |
1878 | + |
1879 | +/*! |
1880 | + \fn void QQuickItem::visibleChildrenChanged() |
1881 | + \internal |
1882 | +*/ |
1883 | + |
1884 | +/*! |
1885 | + \fn void QQuickItem::rotationChanged() |
1886 | + \internal |
1887 | +*/ |
1888 | + |
1889 | +/*! |
1890 | + \fn void QQuickItem::scaleChanged() |
1891 | + \internal |
1892 | +*/ |
1893 | + |
1894 | +/*! |
1895 | + \fn void QQuickItem::xChanged() |
1896 | + \internal |
1897 | +*/ |
1898 | + |
1899 | +/*! |
1900 | + \fn void QQuickItem::yChanged() |
1901 | + \internal |
1902 | +*/ |
1903 | + |
1904 | +/*! |
1905 | + \fn void QQuickItem::widthChanged() |
1906 | + \internal |
1907 | +*/ |
1908 | + |
1909 | +/*! |
1910 | + \fn void QQuickItem::heightChanged() |
1911 | + \internal |
1912 | +*/ |
1913 | + |
1914 | +/*! |
1915 | + \fn void QQuickItem::zChanged() |
1916 | + \internal |
1917 | +*/ |
1918 | + |
1919 | +/*! |
1920 | + \fn void QQuickItem::implicitWidthChanged() |
1921 | + \internal |
1922 | +*/ |
1923 | + |
1924 | +/*! |
1925 | + \fn void QQuickItem::implicitHeightChanged() |
1926 | + \internal |
1927 | +*/ |
1928 | + |
1929 | +/*! |
1930 | + \fn QQuickItem::QQuickItem(QQuickItem *parent) |
1931 | + |
1932 | + Constructs a QQuickItem with the given \a parent. |
1933 | +*/ |
1934 | +QQuickItem::QQuickItem(QQuickItem* parent) |
1935 | +: QObject(*(new QQuickItemPrivate), parent) |
1936 | +{ |
1937 | + Q_D(QQuickItem); |
1938 | + d->init(parent); |
1939 | +} |
1940 | + |
1941 | +/*! \internal |
1942 | +*/ |
1943 | +QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent) |
1944 | +: QObject(dd, parent) |
1945 | +{ |
1946 | + Q_D(QQuickItem); |
1947 | + d->init(parent); |
1948 | +} |
1949 | + |
1950 | +#ifndef QT_NO_DEBUG |
1951 | +static int qt_item_count = 0; |
1952 | + |
1953 | +static void qt_print_item_count() |
1954 | +{ |
1955 | + qDebug("Number of leaked items: %i", qt_item_count); |
1956 | + qt_item_count = -1; |
1957 | +} |
1958 | +#endif |
1959 | + |
1960 | +/*! |
1961 | + Destroys the QQuickItem. |
1962 | +*/ |
1963 | +QQuickItem::~QQuickItem() |
1964 | +{ |
1965 | +#ifndef QT_NO_DEBUG |
1966 | + --qt_item_count; |
1967 | + if (qt_item_count < 0) |
1968 | + qDebug("Item destroyed after qt_print_item_count() was called."); |
1969 | +#endif |
1970 | + |
1971 | + Q_D(QQuickItem); |
1972 | + |
1973 | + if (d->windowRefCount > 1) |
1974 | + d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow(). |
1975 | + if (d->parentItem) |
1976 | + setParentItem(0); |
1977 | + else if (d->window) |
1978 | + d->derefWindow(); |
1979 | + |
1980 | + // XXX todo - optimize |
1981 | + while (!d->childItems.isEmpty()) |
1982 | + d->childItems.first()->setParentItem(0); |
1983 | + |
1984 | + for (int ii = 0; ii < d->changeListeners.count(); ++ii) { |
1985 | + QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate(); |
1986 | + if (anchor) |
1987 | + anchor->clearItem(this); |
1988 | + } |
1989 | + |
1990 | + /* |
1991 | + update item anchors that depended on us unless they are our child (and will also be destroyed), |
1992 | + or our sibling, and our parent is also being destroyed. |
1993 | + */ |
1994 | + for (int ii = 0; ii < d->changeListeners.count(); ++ii) { |
1995 | + QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate(); |
1996 | + if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this) |
1997 | + anchor->update(); |
1998 | + } |
1999 | + |
2000 | + for (int ii = 0; ii < d->changeListeners.count(); ++ii) { |
2001 | + const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii); |
2002 | + if (change.types & QQuickItemPrivate::Destroyed) |
2003 | + change.listener->itemDestroyed(this); |
2004 | + } |
2005 | + |
2006 | + d->changeListeners.clear(); |
2007 | + |
2008 | + if (d->extra.isAllocated()) { |
2009 | + delete d->extra->contents; d->extra->contents = 0; |
2010 | + delete d->extra->layer; d->extra->layer = 0; |
2011 | + } |
2012 | + |
2013 | + delete d->_anchors; d->_anchors = 0; |
2014 | + delete d->_stateGroup; d->_stateGroup = 0; |
2015 | +} |
2016 | + |
2017 | +/*! |
2018 | + \qmlproperty Item QtQuick2::Item::parent |
2019 | + This property holds the visual parent of the item. |
2020 | + |
2021 | + \note The concept of the \e {visual parent} differs from that of the |
2022 | + \e {QObject parent}. An item's visual parent may not necessarily be the |
2023 | + same as its object parent. See \l {Concepts - Visual Parent in Qt Quick} |
2024 | + for more details. |
2025 | +*/ |
2026 | +/*! |
2027 | + \property QQuickItem::parent |
2028 | + This property holds the visual parent of the item. |
2029 | + |
2030 | + \note The concept of the \e {visual parent} differs from that of the |
2031 | + \e {QObject parent}. An item's visual parent may not necessarily be the |
2032 | + same as its object parent. See \l {Concepts - Visual Parent in Qt Quick} |
2033 | + for more details. |
2034 | +*/ |
2035 | +QQuickItem *QQuickItem::parentItem() const |
2036 | +{ |
2037 | + Q_D(const QQuickItem); |
2038 | + return d->parentItem; |
2039 | +} |
2040 | + |
2041 | +void QQuickItem::setParentItem(QQuickItem *parentItem) |
2042 | +{ |
2043 | + Q_D(QQuickItem); |
2044 | + if (parentItem == d->parentItem) |
2045 | + return; |
2046 | + |
2047 | + if (parentItem) { |
2048 | + QQuickItem *itemAncestor = parentItem->parentItem(); |
2049 | + while (itemAncestor != 0) { |
2050 | + if (itemAncestor == this) { |
2051 | + qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree."); |
2052 | + return; |
2053 | + } |
2054 | + itemAncestor = itemAncestor->parentItem(); |
2055 | + } |
2056 | + } |
2057 | + |
2058 | + d->removeFromDirtyList(); |
2059 | + |
2060 | + QQuickItem *oldParentItem = d->parentItem; |
2061 | + QQuickItem *scopeFocusedItem = 0; |
2062 | + |
2063 | + if (oldParentItem) { |
2064 | + QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem); |
2065 | + |
2066 | + QQuickItem *scopeItem = 0; |
2067 | + |
2068 | + if (hasFocus()) |
2069 | + scopeFocusedItem = this; |
2070 | + else if (!isFocusScope() && d->subFocusItem) |
2071 | + scopeFocusedItem = d->subFocusItem; |
2072 | + |
2073 | + if (scopeFocusedItem) { |
2074 | + scopeItem = oldParentItem; |
2075 | + while (!scopeItem->isFocusScope() && scopeItem->parentItem()) |
2076 | + scopeItem = scopeItem->parentItem(); |
2077 | + if (d->window) { |
2078 | + QQuickWindowPrivate::get(d->window)->clearFocusInScope(scopeItem, scopeFocusedItem, |
2079 | + QQuickWindowPrivate::DontChangeFocusProperty); |
2080 | + if (scopeFocusedItem != this) |
2081 | + QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true); |
2082 | + } else { |
2083 | + QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false); |
2084 | + } |
2085 | + } |
2086 | + |
2087 | + const bool wasVisible = isVisible(); |
2088 | + op->removeChild(this); |
2089 | + if (wasVisible) { |
2090 | + emit oldParentItem->visibleChildrenChanged(); |
2091 | + } |
2092 | + } else if (d->window) { |
2093 | + QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this); |
2094 | + } |
2095 | + |
2096 | + QQuickWindow *oldParentWindow = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->window : 0; |
2097 | + QQuickWindow *parentWindow = parentItem ? QQuickItemPrivate::get(parentItem)->window : 0; |
2098 | + if (oldParentWindow == parentWindow) { |
2099 | + // Avoid freeing and reallocating resources if the window stays the same. |
2100 | + d->parentItem = parentItem; |
2101 | + } else { |
2102 | + if (oldParentWindow) |
2103 | + d->derefWindow(); |
2104 | + d->parentItem = parentItem; |
2105 | + if (parentWindow) |
2106 | + d->refWindow(parentWindow); |
2107 | + } |
2108 | + |
2109 | + d->dirty(QQuickItemPrivate::ParentChanged); |
2110 | + |
2111 | + if (d->parentItem) |
2112 | + QQuickItemPrivate::get(d->parentItem)->addChild(this); |
2113 | + else if (d->window) |
2114 | + QQuickWindowPrivate::get(d->window)->parentlessItems.insert(this); |
2115 | + |
2116 | + d->setEffectiveVisibleRecur(d->calcEffectiveVisible()); |
2117 | + d->setEffectiveEnableRecur(0, d->calcEffectiveEnable()); |
2118 | + |
2119 | + if (d->parentItem) { |
2120 | + if (!scopeFocusedItem) { |
2121 | + if (hasFocus()) |
2122 | + scopeFocusedItem = this; |
2123 | + else if (!isFocusScope() && d->subFocusItem) |
2124 | + scopeFocusedItem = d->subFocusItem; |
2125 | + } |
2126 | + |
2127 | + if (scopeFocusedItem) { |
2128 | + // We need to test whether this item becomes scope focused |
2129 | + QQuickItem *scopeItem = d->parentItem; |
2130 | + while (!scopeItem->isFocusScope() && scopeItem->parentItem()) |
2131 | + scopeItem = scopeItem->parentItem(); |
2132 | + |
2133 | + if (QQuickItemPrivate::get(scopeItem)->subFocusItem |
2134 | + || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) { |
2135 | + if (scopeFocusedItem != this) |
2136 | + QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false); |
2137 | + QQuickItemPrivate::get(scopeFocusedItem)->focus = false; |
2138 | + emit scopeFocusedItem->focusChanged(false); |
2139 | + } else { |
2140 | + if (d->window) { |
2141 | + QQuickWindowPrivate::get(d->window)->setFocusInScope(scopeItem, scopeFocusedItem, |
2142 | + QQuickWindowPrivate::DontChangeFocusProperty); |
2143 | + } else { |
2144 | + QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true); |
2145 | + } |
2146 | + } |
2147 | + } |
2148 | + } |
2149 | + |
2150 | + d->resolveLayoutMirror(); |
2151 | + |
2152 | + d->itemChange(ItemParentHasChanged, d->parentItem); |
2153 | + |
2154 | + d->parentNotifier.notify(); |
2155 | + if (d->isAccessible && d->parentItem) { |
2156 | + d->parentItem->d_func()->setAccessibleFlagAndListener(); |
2157 | + } |
2158 | + |
2159 | + emit parentChanged(d->parentItem); |
2160 | + if (isVisible() && d->parentItem) |
2161 | + emit d->parentItem->visibleChildrenChanged(); |
2162 | +} |
2163 | + |
2164 | +/*! |
2165 | + Moves the specified \a sibling item to the index before this item |
2166 | + within the visual stacking order. |
2167 | + |
2168 | + The given \a sibling must be a sibling of this item; that is, they must |
2169 | + have the same immediate \l parent. |
2170 | + |
2171 | + \sa {Concepts - Visual Parent in Qt Quick} |
2172 | +*/ |
2173 | +void QQuickItem::stackBefore(const QQuickItem *sibling) |
2174 | +{ |
2175 | + Q_D(QQuickItem); |
2176 | + if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) { |
2177 | + qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling); |
2178 | + return; |
2179 | + } |
2180 | + |
2181 | + QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem); |
2182 | + |
2183 | + int myIndex = parentPrivate->childItems.lastIndexOf(this); |
2184 | + int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling)); |
2185 | + |
2186 | + Q_ASSERT(myIndex != -1 && siblingIndex != -1); |
2187 | + |
2188 | + if (myIndex == siblingIndex - 1) |
2189 | + return; |
2190 | + |
2191 | + parentPrivate->childItems.move(myIndex, myIndex < siblingIndex ? siblingIndex - 1 : siblingIndex); |
2192 | + |
2193 | + parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged); |
2194 | + parentPrivate->markSortedChildrenDirty(this); |
2195 | + |
2196 | + for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii) |
2197 | + QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged(); |
2198 | +} |
2199 | + |
2200 | +/*! |
2201 | + Moves the specified \a sibling item to the index after this item |
2202 | + within the visual stacking order. |
2203 | + |
2204 | + The given \a sibling must be a sibling of this item; that is, they must |
2205 | + have the same immediate \l parent. |
2206 | + |
2207 | + \sa {Concepts - Visual Parent in Qt Quick} |
2208 | +*/ |
2209 | +void QQuickItem::stackAfter(const QQuickItem *sibling) |
2210 | +{ |
2211 | + Q_D(QQuickItem); |
2212 | + if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) { |
2213 | + qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling); |
2214 | + return; |
2215 | + } |
2216 | + |
2217 | + QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem); |
2218 | + |
2219 | + int myIndex = parentPrivate->childItems.lastIndexOf(this); |
2220 | + int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling)); |
2221 | + |
2222 | + Q_ASSERT(myIndex != -1 && siblingIndex != -1); |
2223 | + |
2224 | + if (myIndex == siblingIndex + 1) |
2225 | + return; |
2226 | + |
2227 | + parentPrivate->childItems.move(myIndex, myIndex > siblingIndex ? siblingIndex + 1 : siblingIndex); |
2228 | + |
2229 | + parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged); |
2230 | + parentPrivate->markSortedChildrenDirty(this); |
2231 | + |
2232 | + for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii) |
2233 | + QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged(); |
2234 | +} |
2235 | + |
2236 | +/*! |
2237 | + Returns the window in which this item is rendered. |
2238 | + |
2239 | + The item does not have a window until it has been assigned into a scene. To |
2240 | + get notification about this, reimplement the itemChange() function and |
2241 | + listen for the ItemSceneChange change. The itemChange() function is called |
2242 | + both when the item is entered into a scene and when it is removed from a scene. |
2243 | + */ |
2244 | +QQuickWindow *QQuickItem::window() const |
2245 | +{ |
2246 | + Q_D(const QQuickItem); |
2247 | + return d->window; |
2248 | +} |
2249 | + |
2250 | +static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs) |
2251 | +{ |
2252 | + return lhs->z() < rhs->z(); |
2253 | +} |
2254 | + |
2255 | +QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const |
2256 | +{ |
2257 | + if (sortedChildItems) |
2258 | + return *sortedChildItems; |
2259 | + |
2260 | + // If none of the items have set Z then the paint order list is the same as |
2261 | + // the childItems list. This is by far the most common case. |
2262 | + bool haveZ = false; |
2263 | + for (int i = 0; i < childItems.count(); ++i) { |
2264 | + if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) { |
2265 | + haveZ = true; |
2266 | + break; |
2267 | + } |
2268 | + } |
2269 | + if (haveZ) { |
2270 | + sortedChildItems = new QList<QQuickItem*>(childItems); |
2271 | + qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort); |
2272 | + return *sortedChildItems; |
2273 | + } |
2274 | + |
2275 | + sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems); |
2276 | + |
2277 | + return childItems; |
2278 | +} |
2279 | + |
2280 | +void QQuickItemPrivate::addChild(QQuickItem *child) |
2281 | +{ |
2282 | + Q_Q(QQuickItem); |
2283 | + |
2284 | + Q_ASSERT(!childItems.contains(child)); |
2285 | + |
2286 | + childItems.append(child); |
2287 | + |
2288 | +#ifndef QT_NO_CURSOR |
2289 | + QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); |
2290 | + if (childPrivate->extra.isAllocated()) |
2291 | + incrementCursorCount(childPrivate->extra.value().numItemsWithCursor); |
2292 | +#endif |
2293 | + |
2294 | + markSortedChildrenDirty(child); |
2295 | + dirty(QQuickItemPrivate::ChildrenChanged); |
2296 | + |
2297 | + itemChange(QQuickItem::ItemChildAddedChange, child); |
2298 | + |
2299 | + emit q->childrenChanged(); |
2300 | +} |
2301 | + |
2302 | +void QQuickItemPrivate::removeChild(QQuickItem *child) |
2303 | +{ |
2304 | + Q_Q(QQuickItem); |
2305 | + |
2306 | + Q_ASSERT(child); |
2307 | + Q_ASSERT(childItems.contains(child)); |
2308 | + childItems.removeOne(child); |
2309 | + Q_ASSERT(!childItems.contains(child)); |
2310 | + |
2311 | +#ifndef QT_NO_CURSOR |
2312 | + QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); |
2313 | + if (childPrivate->extra.isAllocated()) |
2314 | + incrementCursorCount(-childPrivate->extra.value().numItemsWithCursor); |
2315 | +#endif |
2316 | + |
2317 | + markSortedChildrenDirty(child); |
2318 | + dirty(QQuickItemPrivate::ChildrenChanged); |
2319 | + |
2320 | + itemChange(QQuickItem::ItemChildRemovedChange, child); |
2321 | + |
2322 | + emit q->childrenChanged(); |
2323 | +} |
2324 | + |
2325 | +void QQuickItemPrivate::refWindow(QQuickWindow *c) |
2326 | +{ |
2327 | + // An item needs a window if it is referenced by another item which has a window. |
2328 | + // Typically the item is referenced by a parent, but can also be referenced by a |
2329 | + // ShaderEffect or ShaderEffectSource. 'windowRefCount' counts how many items with |
2330 | + // a window is referencing this item. When the reference count goes from zero to one, |
2331 | + // or one to zero, the window of this item is updated and propagated to the children. |
2332 | + // As long as the reference count stays above zero, the window is unchanged. |
2333 | + // refWindow() increments the reference count. |
2334 | + // derefWindow() decrements the reference count. |
2335 | + |
2336 | + Q_Q(QQuickItem); |
2337 | + Q_ASSERT((window != 0) == (windowRefCount > 0)); |
2338 | + Q_ASSERT(c); |
2339 | + if (++windowRefCount > 1) { |
2340 | + if (c != window) |
2341 | + qWarning("QQuickItem: Cannot use same item on different windows at the same time."); |
2342 | + return; // Window already set. |
2343 | + } |
2344 | + |
2345 | + Q_ASSERT(window == 0); |
2346 | + window = c; |
2347 | + |
2348 | + if (polishScheduled) |
2349 | + QQuickWindowPrivate::get(window)->itemsToPolish.insert(q); |
2350 | + |
2351 | + if (!parentItem) |
2352 | + QQuickWindowPrivate::get(window)->parentlessItems.insert(q); |
2353 | + |
2354 | + for (int ii = 0; ii < childItems.count(); ++ii) { |
2355 | + QQuickItem *child = childItems.at(ii); |
2356 | + QQuickItemPrivate::get(child)->refWindow(c); |
2357 | + } |
2358 | + |
2359 | + dirty(Window); |
2360 | + |
2361 | + if (extra.isAllocated() && extra->screenAttached) |
2362 | + extra->screenAttached->windowChanged(c); |
2363 | + itemChange(QQuickItem::ItemSceneChange, c); |
2364 | +} |
2365 | + |
2366 | +void QQuickItemPrivate::derefWindow() |
2367 | +{ |
2368 | + Q_Q(QQuickItem); |
2369 | + Q_ASSERT((window != 0) == (windowRefCount > 0)); |
2370 | + |
2371 | + if (!window) |
2372 | + return; // This can happen when destroying recursive shader effect sources. |
2373 | + |
2374 | + if (--windowRefCount > 0) |
2375 | + return; // There are still other references, so don't set window to null yet. |
2376 | + |
2377 | + q->releaseResources(); |
2378 | + removeFromDirtyList(); |
2379 | + QQuickWindowPrivate *c = QQuickWindowPrivate::get(window); |
2380 | + if (polishScheduled) |
2381 | + c->itemsToPolish.remove(q); |
2382 | + QMutableHashIterator<int, QQuickItem *> itemTouchMapIt(c->itemForTouchPointId); |
2383 | + while (itemTouchMapIt.hasNext()) { |
2384 | + if (itemTouchMapIt.next().value() == q) |
2385 | + itemTouchMapIt.remove(); |
2386 | + } |
2387 | + if (c->mouseGrabberItem == q) |
2388 | + c->mouseGrabberItem = 0; |
2389 | +#ifndef QT_NO_CURSOR |
2390 | + if (c->cursorItem == q) |
2391 | + c->cursorItem = 0; |
2392 | +#endif |
2393 | + if ( hoverEnabled ) |
2394 | + c->hoverItems.removeAll(q); |
2395 | + if (itemNodeInstance) |
2396 | + c->cleanup(itemNodeInstance); |
2397 | + if (!parentItem) |
2398 | + c->parentlessItems.remove(q); |
2399 | + |
2400 | + window = 0; |
2401 | + |
2402 | + itemNodeInstance = 0; |
2403 | + |
2404 | + if (extra.isAllocated()) { |
2405 | + extra->opacityNode = 0; |
2406 | + extra->clipNode = 0; |
2407 | + extra->rootNode = 0; |
2408 | + extra->beforePaintNode = 0; |
2409 | + } |
2410 | + |
2411 | + groupNode = 0; |
2412 | + paintNode = 0; |
2413 | + |
2414 | + for (int ii = 0; ii < childItems.count(); ++ii) { |
2415 | + QQuickItem *child = childItems.at(ii); |
2416 | + QQuickItemPrivate::get(child)->derefWindow(); |
2417 | + } |
2418 | + |
2419 | + dirty(Window); |
2420 | + |
2421 | + if (extra.isAllocated() && extra->screenAttached) |
2422 | + extra->screenAttached->windowChanged(0); |
2423 | + itemChange(QQuickItem::ItemSceneChange, (QQuickWindow *)0); |
2424 | +} |
2425 | + |
2426 | + |
2427 | +/*! |
2428 | +Returns a transform that maps points from window space into item space. |
2429 | +*/ |
2430 | +QTransform QQuickItemPrivate::windowToItemTransform() const |
2431 | +{ |
2432 | + // XXX todo - optimize |
2433 | + return itemToWindowTransform().inverted(); |
2434 | +} |
2435 | + |
2436 | +/*! |
2437 | +Returns a transform that maps points from item space into window space. |
2438 | +*/ |
2439 | +QTransform QQuickItemPrivate::itemToWindowTransform() const |
2440 | +{ |
2441 | + // XXX todo |
2442 | + QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToWindowTransform():QTransform(); |
2443 | + itemToParentTransform(rv); |
2444 | + return rv; |
2445 | +} |
2446 | + |
2447 | +/*! |
2448 | +Motifies \a t with this items local transform relative to its parent. |
2449 | +*/ |
2450 | +void QQuickItemPrivate::itemToParentTransform(QTransform &t) const |
2451 | +{ |
2452 | + if (x || y) |
2453 | + t.translate(x, y); |
2454 | + |
2455 | + if (!transforms.isEmpty()) { |
2456 | + QMatrix4x4 m(t); |
2457 | + for (int ii = transforms.count() - 1; ii >= 0; --ii) |
2458 | + transforms.at(ii)->applyTo(&m); |
2459 | + t = m.toTransform(); |
2460 | + } |
2461 | + |
2462 | + if (scale() != 1. || rotation() != 0.) { |
2463 | + QPointF tp = computeTransformOrigin(); |
2464 | + t.translate(tp.x(), tp.y()); |
2465 | + t.scale(scale(), scale()); |
2466 | + t.rotate(rotation()); |
2467 | + t.translate(-tp.x(), -tp.y()); |
2468 | + } |
2469 | +} |
2470 | + |
2471 | +/*! |
2472 | + Returns true if construction of the QML component is complete; otherwise |
2473 | + returns false. |
2474 | + |
2475 | + It is often desirable to delay some processing until the component is |
2476 | + completed. |
2477 | + |
2478 | + \sa componentComplete() |
2479 | +*/ |
2480 | +bool QQuickItem::isComponentComplete() const |
2481 | +{ |
2482 | + Q_D(const QQuickItem); |
2483 | + return d->componentComplete; |
2484 | +} |
2485 | + |
2486 | +QQuickItemPrivate::QQuickItemPrivate() |
2487 | + : _anchors(0) |
2488 | + , _stateGroup(0) |
2489 | + , flags(0) |
2490 | + , widthValid(false) |
2491 | + , heightValid(false) |
2492 | + , baselineOffsetValid(false) |
2493 | + , componentComplete(true) |
2494 | + , keepMouse(false) |
2495 | + , keepTouch(false) |
2496 | + , hoverEnabled(false) |
2497 | + , smooth(true) |
2498 | + , antialiasing(false) |
2499 | + , focus(false) |
2500 | + , activeFocus(false) |
2501 | + , notifiedFocus(false) |
2502 | + , notifiedActiveFocus(false) |
2503 | + , filtersChildMouseEvents(false) |
2504 | + , explicitVisible(true) |
2505 | + , effectiveVisible(true) |
2506 | + , explicitEnable(true) |
2507 | + , effectiveEnable(true) |
2508 | + , polishScheduled(false) |
2509 | + , inheritedLayoutMirror(false) |
2510 | + , effectiveLayoutMirror(false) |
2511 | + , isMirrorImplicit(true) |
2512 | + , inheritMirrorFromParent(false) |
2513 | + , inheritMirrorFromItem(false) |
2514 | + , isAccessible(false) |
2515 | + , culled(false) |
2516 | + , hasCursor(false) |
2517 | + , dirtyAttributes(0) |
2518 | + , nextDirtyItem(0) |
2519 | + , prevDirtyItem(0) |
2520 | + , window(0) |
2521 | + , windowRefCount(0) |
2522 | + , parentItem(0) |
2523 | + , sortedChildItems(&childItems) |
2524 | + , subFocusItem(0) |
2525 | + , x(0) |
2526 | + , y(0) |
2527 | + , width(0) |
2528 | + , height(0) |
2529 | + , implicitWidth(0) |
2530 | + , implicitHeight(0) |
2531 | + , baselineOffset(0) |
2532 | + , itemNodeInstance(0) |
2533 | + , groupNode(0) |
2534 | + , paintNode(0) |
2535 | +{ |
2536 | +} |
2537 | + |
2538 | +QQuickItemPrivate::~QQuickItemPrivate() |
2539 | +{ |
2540 | + if (sortedChildItems != &childItems) |
2541 | + delete sortedChildItems; |
2542 | +} |
2543 | + |
2544 | +void QQuickItemPrivate::init(QQuickItem *parent) |
2545 | +{ |
2546 | +#ifndef QT_NO_DEBUG |
2547 | + ++qt_item_count; |
2548 | + static bool atexit_registered = false; |
2549 | + if (!atexit_registered) { |
2550 | + atexit(qt_print_item_count); |
2551 | + atexit_registered = true; |
2552 | + } |
2553 | +#endif |
2554 | + |
2555 | + Q_Q(QQuickItem); |
2556 | + |
2557 | + registerAccessorProperties(); |
2558 | + |
2559 | + baselineOffsetValid = false; |
2560 | + |
2561 | + if (parent) { |
2562 | + q->setParentItem(parent); |
2563 | + QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent); |
2564 | + setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent); |
2565 | + } |
2566 | +} |
2567 | + |
2568 | +void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o) |
2569 | +{ |
2570 | + if (!o) |
2571 | + return; |
2572 | + |
2573 | + QQuickItem *that = static_cast<QQuickItem *>(prop->object); |
2574 | + |
2575 | + if (QQuickItem *item = qmlobject_cast<QQuickItem *>(o)) { |
2576 | + item->setParentItem(that); |
2577 | + } else { |
2578 | + if (o->inherits("QGraphicsItem")) |
2579 | + qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className()); |
2580 | + |
2581 | + // XXX todo - do we really want this behavior? |
2582 | + o->setParent(that); |
2583 | + } |
2584 | +} |
2585 | + |
2586 | +/*! |
2587 | + \qmlproperty list<Object> QtQuick2::Item::data |
2588 | + \default |
2589 | + |
2590 | + The data property allows you to freely mix visual children and resources |
2591 | + in an item. If you assign a visual item to the data list it becomes |
2592 | + a child and if you assign any other object type, it is added as a resource. |
2593 | + |
2594 | + So you can write: |
2595 | + \qml |
2596 | + Item { |
2597 | + Text {} |
2598 | + Rectangle {} |
2599 | + Timer {} |
2600 | + } |
2601 | + \endqml |
2602 | + |
2603 | + instead of: |
2604 | + \qml |
2605 | + Item { |
2606 | + children: [ |
2607 | + Text {}, |
2608 | + Rectangle {} |
2609 | + ] |
2610 | + resources: [ |
2611 | + Timer {} |
2612 | + ] |
2613 | + } |
2614 | + \endqml |
2615 | + |
2616 | + It should not generally be necessary to refer to the \c data property, |
2617 | + as it is the default property for Item and thus all child items are |
2618 | + automatically assigned to this property. |
2619 | + */ |
2620 | + |
2621 | +int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *property) |
2622 | +{ |
2623 | + QQuickItem *item = static_cast<QQuickItem*>(property->object); |
2624 | + QQuickItemPrivate *privateItem = QQuickItemPrivate::get(item); |
2625 | + QQmlListProperty<QObject> resourcesProperty = privateItem->resources(); |
2626 | + QQmlListProperty<QQuickItem> childrenProperty = privateItem->children(); |
2627 | + |
2628 | + return resources_count(&resourcesProperty) + children_count(&childrenProperty); |
2629 | +} |
2630 | + |
2631 | +QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *property, int i) |
2632 | +{ |
2633 | + QQuickItem *item = static_cast<QQuickItem*>(property->object); |
2634 | + QQuickItemPrivate *privateItem = QQuickItemPrivate::get(item); |
2635 | + QQmlListProperty<QObject> resourcesProperty = privateItem->resources(); |
2636 | + QQmlListProperty<QQuickItem> childrenProperty = privateItem->children(); |
2637 | + |
2638 | + int resourcesCount = resources_count(&resourcesProperty); |
2639 | + if (i < resourcesCount) |
2640 | + return resources_at(&resourcesProperty, i); |
2641 | + const int j = i - resourcesCount; |
2642 | + if (j < children_count(&childrenProperty)) |
2643 | + return children_at(&childrenProperty, j); |
2644 | + return 0; |
2645 | +} |
2646 | + |
2647 | +void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *property) |
2648 | +{ |
2649 | + QQuickItem *item = static_cast<QQuickItem*>(property->object); |
2650 | + QQuickItemPrivate *privateItem = QQuickItemPrivate::get(item); |
2651 | + QQmlListProperty<QObject> resourcesProperty = privateItem->resources(); |
2652 | + QQmlListProperty<QQuickItem> childrenProperty = privateItem->children(); |
2653 | + |
2654 | + resources_clear(&resourcesProperty); |
2655 | + children_clear(&childrenProperty); |
2656 | +} |
2657 | + |
2658 | +QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index) |
2659 | +{ |
2660 | + const QObjectList children = prop->object->children(); |
2661 | + if (index < children.count()) |
2662 | + return children.at(index); |
2663 | + else |
2664 | + return 0; |
2665 | +} |
2666 | + |
2667 | +void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o) |
2668 | +{ |
2669 | + // XXX todo - do we really want this behavior? |
2670 | + o->setParent(prop->object); |
2671 | +} |
2672 | + |
2673 | +int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop) |
2674 | +{ |
2675 | + return prop->object->children().count(); |
2676 | +} |
2677 | + |
2678 | +void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop) |
2679 | +{ |
2680 | + // XXX todo - do we really want this behavior? |
2681 | + const QObjectList children = prop->object->children(); |
2682 | + for (int index = 0; index < children.count(); index++) |
2683 | + children.at(index)->setParent(0); |
2684 | +} |
2685 | + |
2686 | +QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index) |
2687 | +{ |
2688 | + QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object)); |
2689 | + if (index >= p->childItems.count() || index < 0) |
2690 | + return 0; |
2691 | + else |
2692 | + return p->childItems.at(index); |
2693 | +} |
2694 | + |
2695 | +void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o) |
2696 | +{ |
2697 | + if (!o) |
2698 | + return; |
2699 | + |
2700 | + QQuickItem *that = static_cast<QQuickItem *>(prop->object); |
2701 | + if (o->parentItem() == that) |
2702 | + o->setParentItem(0); |
2703 | + |
2704 | + o->setParentItem(that); |
2705 | +} |
2706 | + |
2707 | +int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop) |
2708 | +{ |
2709 | + QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object)); |
2710 | + return p->childItems.count(); |
2711 | +} |
2712 | + |
2713 | +void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop) |
2714 | +{ |
2715 | + QQuickItem *that = static_cast<QQuickItem *>(prop->object); |
2716 | + QQuickItemPrivate *p = QQuickItemPrivate::get(that); |
2717 | + while (!p->childItems.isEmpty()) |
2718 | + p->childItems.at(0)->setParentItem(0); |
2719 | +} |
2720 | + |
2721 | +int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop) |
2722 | +{ |
2723 | + QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object)); |
2724 | + int visibleCount = 0; |
2725 | + int c = p->childItems.count(); |
2726 | + while (c--) { |
2727 | + if (p->childItems.at(c)->isVisible()) visibleCount++; |
2728 | + } |
2729 | + |
2730 | + return visibleCount; |
2731 | +} |
2732 | + |
2733 | +QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index) |
2734 | +{ |
2735 | + QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object)); |
2736 | + const int childCount = p->childItems.count(); |
2737 | + if (index >= childCount || index < 0) |
2738 | + return 0; |
2739 | + |
2740 | + int visibleCount = -1; |
2741 | + for (int i = 0; i < childCount; i++) { |
2742 | + if (p->childItems.at(i)->isVisible()) visibleCount++; |
2743 | + if (visibleCount == index) return p->childItems.at(i); |
2744 | + } |
2745 | + return 0; |
2746 | +} |
2747 | + |
2748 | +int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop) |
2749 | +{ |
2750 | + QQuickItem *that = static_cast<QQuickItem *>(prop->object); |
2751 | + QQuickItemPrivate *p = QQuickItemPrivate::get(that); |
2752 | + |
2753 | + return p->transforms.count(); |
2754 | +} |
2755 | + |
2756 | +void QQuickTransform::appendToItem(QQuickItem *item) |
2757 | +{ |
2758 | + Q_D(QQuickTransform); |
2759 | + if (!item) |
2760 | + return; |
2761 | + |
2762 | + QQuickItemPrivate *p = QQuickItemPrivate::get(item); |
2763 | + |
2764 | + if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) { |
2765 | + p->transforms.removeOne(this); |
2766 | + p->transforms.append(this); |
2767 | + } else { |
2768 | + p->transforms.append(this); |
2769 | + d->items.append(item); |
2770 | + } |
2771 | + |
2772 | + p->dirty(QQuickItemPrivate::Transform); |
2773 | +} |
2774 | + |
2775 | +void QQuickTransform::prependToItem(QQuickItem *item) |
2776 | +{ |
2777 | + Q_D(QQuickTransform); |
2778 | + if (!item) |
2779 | + return; |
2780 | + |
2781 | + QQuickItemPrivate *p = QQuickItemPrivate::get(item); |
2782 | + |
2783 | + if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) { |
2784 | + p->transforms.removeOne(this); |
2785 | + p->transforms.prepend(this); |
2786 | + } else { |
2787 | + p->transforms.prepend(this); |
2788 | + d->items.append(item); |
2789 | + } |
2790 | + |
2791 | + p->dirty(QQuickItemPrivate::Transform); |
2792 | +} |
2793 | + |
2794 | +void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform) |
2795 | +{ |
2796 | + if (!transform) |
2797 | + return; |
2798 | + |
2799 | + QQuickItem *that = static_cast<QQuickItem *>(prop->object); |
2800 | + transform->appendToItem(that); |
2801 | +} |
2802 | + |
2803 | +QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx) |
2804 | +{ |
2805 | + QQuickItem *that = static_cast<QQuickItem *>(prop->object); |
2806 | + QQuickItemPrivate *p = QQuickItemPrivate::get(that); |
2807 | + |
2808 | + if (idx < 0 || idx >= p->transforms.count()) |
2809 | + return 0; |
2810 | + else |
2811 | + return p->transforms.at(idx); |
2812 | +} |
2813 | + |
2814 | +void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop) |
2815 | +{ |
2816 | + QQuickItem *that = static_cast<QQuickItem *>(prop->object); |
2817 | + QQuickItemPrivate *p = QQuickItemPrivate::get(that); |
2818 | + |
2819 | + for (int ii = 0; ii < p->transforms.count(); ++ii) { |
2820 | + QQuickTransform *t = p->transforms.at(ii); |
2821 | + QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t); |
2822 | + tp->items.removeOne(that); |
2823 | + } |
2824 | + |
2825 | + p->transforms.clear(); |
2826 | + |
2827 | + p->dirty(QQuickItemPrivate::Transform); |
2828 | +} |
2829 | + |
2830 | +/*! |
2831 | + \qmlproperty AnchorLine QtQuick2::Item::anchors.top |
2832 | + \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom |
2833 | + \qmlproperty AnchorLine QtQuick2::Item::anchors.left |
2834 | + \qmlproperty AnchorLine QtQuick2::Item::anchors.right |
2835 | + \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter |
2836 | + \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter |
2837 | + \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline |
2838 | + |
2839 | + \qmlproperty Item QtQuick2::Item::anchors.fill |
2840 | + \qmlproperty Item QtQuick2::Item::anchors.centerIn |
2841 | + |
2842 | + \qmlproperty real QtQuick2::Item::anchors.margins |
2843 | + \qmlproperty real QtQuick2::Item::anchors.topMargin |
2844 | + \qmlproperty real QtQuick2::Item::anchors.bottomMargin |
2845 | + \qmlproperty real QtQuick2::Item::anchors.leftMargin |
2846 | + \qmlproperty real QtQuick2::Item::anchors.rightMargin |
2847 | + \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset |
2848 | + \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset |
2849 | + \qmlproperty real QtQuick2::Item::anchors.baselineOffset |
2850 | + |
2851 | + \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered |
2852 | + |
2853 | + Anchors provide a way to position an item by specifying its |
2854 | + relationship with other items. |
2855 | + |
2856 | + Margins apply to top, bottom, left, right, and fill anchors. |
2857 | + The \c anchors.margins property can be used to set all of the various margins at once, to the same value. |
2858 | + It will not override a specific margin that has been previously set; to clear an explicit margin |
2859 | + set it's value to \c undefined. |
2860 | + Note that margins are anchor-specific and are not applied if an item does not |
2861 | + use anchors. |
2862 | + |
2863 | + Offsets apply for horizontal center, vertical center, and baseline anchors. |
2864 | + |
2865 | + \table |
2866 | + \row |
2867 | + \li \image declarative-anchors_example.png |
2868 | + \li Text anchored to Image, horizontally centered and vertically below, with a margin. |
2869 | + \qml |
2870 | + Item { |
2871 | + Image { |
2872 | + id: pic |
2873 | + // ... |
2874 | + } |
2875 | + Text { |
2876 | + id: label |
2877 | + anchors.horizontalCenter: pic.horizontalCenter |
2878 | + anchors.top: pic.bottom |
2879 | + anchors.topMargin: 5 |
2880 | + // ... |
2881 | + } |
2882 | + } |
2883 | + \endqml |
2884 | + \row |
2885 | + \li \image declarative-anchors_example2.png |
2886 | + \li |
2887 | + Left of Text anchored to right of Image, with a margin. The y |
2888 | + property of both defaults to 0. |
2889 | + |
2890 | + \qml |
2891 | + Item { |
2892 | + Image { |
2893 | + id: pic |
2894 | + // ... |
2895 | + } |
2896 | + Text { |
2897 | + id: label |
2898 | + anchors.left: pic.right |
2899 | + anchors.leftMargin: 5 |
2900 | + // ... |
2901 | + } |
2902 | + } |
2903 | + \endqml |
2904 | + \endtable |
2905 | + |
2906 | + \c anchors.fill provides a convenient way for one item to have the |
2907 | + same geometry as another item, and is equivalent to connecting all |
2908 | + four directional anchors. |
2909 | + |
2910 | + To clear an anchor value, set it to \c undefined. |
2911 | + |
2912 | + \c anchors.alignWhenCentered (default true) forces centered anchors to align to a |
2913 | + whole pixel, i.e. if the item being centered has an odd width/height the item |
2914 | + will be positioned on a whole pixel rather than being placed on a half-pixel. |
2915 | + This ensures the item is painted crisply. There are cases where this is not |
2916 | + desirable, for example when rotating the item jitters may be apparent as the |
2917 | + center is rounded. |
2918 | + |
2919 | + \note You can only anchor an item to siblings or a parent. |
2920 | + |
2921 | + For more information see \l {anchor-layout}{Anchor Layouts}. |
2922 | +*/ |
2923 | +QQuickAnchors *QQuickItemPrivate::anchors() const |
2924 | +{ |
2925 | + if (!_anchors) { |
2926 | + Q_Q(const QQuickItem); |
2927 | + _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q)); |
2928 | + if (!componentComplete) |
2929 | + _anchors->classBegin(); |
2930 | + } |
2931 | + return _anchors; |
2932 | +} |
2933 | + |
2934 | +void QQuickItemPrivate::siblingOrderChanged() |
2935 | +{ |
2936 | + Q_Q(QQuickItem); |
2937 | + for (int ii = 0; ii < changeListeners.count(); ++ii) { |
2938 | + const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii); |
2939 | + if (change.types & QQuickItemPrivate::SiblingOrder) { |
2940 | + change.listener->itemSiblingOrderChanged(q); |
2941 | + } |
2942 | + } |
2943 | +} |
2944 | + |
2945 | +QQmlListProperty<QObject> QQuickItemPrivate::data() |
2946 | +{ |
2947 | + return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append, |
2948 | + QQuickItemPrivate::data_count, |
2949 | + QQuickItemPrivate::data_at, |
2950 | + QQuickItemPrivate::data_clear); |
2951 | +} |
2952 | + |
2953 | +/*! |
2954 | + \qmlproperty real QtQuick2::Item::childrenRect.x |
2955 | + \qmlproperty real QtQuick2::Item::childrenRect.y |
2956 | + \qmlproperty real QtQuick2::Item::childrenRect.width |
2957 | + \qmlproperty real QtQuick2::Item::childrenRect.height |
2958 | + |
2959 | + This property holds the collective position and size of the item's |
2960 | + children. |
2961 | + |
2962 | + This property is useful if you need to access the collective geometry |
2963 | + of an item's children in order to correctly size the item. |
2964 | +*/ |
2965 | +/*! |
2966 | + \property QQuickItem::childrenRect |
2967 | + |
2968 | + This property holds the collective position and size of the item's |
2969 | + children. |
2970 | + |
2971 | + This property is useful if you need to access the collective geometry |
2972 | + of an item's children in order to correctly size the item. |
2973 | +*/ |
2974 | +QRectF QQuickItem::childrenRect() |
2975 | +{ |
2976 | + Q_D(QQuickItem); |
2977 | + if (!d->extra.isAllocated() || !d->extra->contents) { |
2978 | + d->extra.value().contents = new QQuickContents(this); |
2979 | + if (d->componentComplete) |
2980 | + d->extra->contents->complete(); |
2981 | + } |
2982 | + return d->extra->contents->rectF(); |
2983 | +} |
2984 | + |
2985 | +/*! |
2986 | + Returns the children of this item. |
2987 | + */ |
2988 | +QList<QQuickItem *> QQuickItem::childItems() const |
2989 | +{ |
2990 | + Q_D(const QQuickItem); |
2991 | + return d->childItems; |
2992 | +} |
2993 | + |
2994 | +/*! |
2995 | + \qmlproperty bool QtQuick2::Item::clip |
2996 | + This property holds whether clipping is enabled. The default clip value is \c false. |
2997 | + |
2998 | + If clipping is enabled, an item will clip its own painting, as well |
2999 | + as the painting of its children, to its bounding rectangle. |
3000 | + |
3001 | + Non-rectangular clipping regions are not supported for performance reasons. |
3002 | +*/ |
3003 | +/*! |
3004 | + \property QQuickItem::clip |
3005 | + This property holds whether clipping is enabled. The default clip value is \c false. |
3006 | + |
3007 | + If clipping is enabled, an item will clip its own painting, as well |
3008 | + as the painting of its children, to its bounding rectangle. If you set |
3009 | + clipping during an item's paint operation, remember to re-set it to |
3010 | + prevent clipping the rest of your scene. |
3011 | + |
3012 | + Non-rectangular clipping regions are not supported for performance reasons. |
3013 | +*/ |
3014 | +bool QQuickItem::clip() const |
3015 | +{ |
3016 | + return flags() & ItemClipsChildrenToShape; |
3017 | +} |
3018 | + |
3019 | +void QQuickItem::setClip(bool c) |
3020 | +{ |
3021 | + if (clip() == c) |
3022 | + return; |
3023 | + |
3024 | + setFlag(ItemClipsChildrenToShape, c); |
3025 | + |
3026 | + emit clipChanged(c); |
3027 | +} |
3028 | + |
3029 | + |
3030 | +/*! |
3031 | + This function is called to handle this item's changes in |
3032 | + geometry from \a oldGeometry to \a newGeometry. If the two |
3033 | + geometries are the same, it doesn't do anything. |
3034 | + |
3035 | + Derived classes must call the base class method within their implementation. |
3036 | + */ |
3037 | +void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) |
3038 | +{ |
3039 | + Q_D(QQuickItem); |
3040 | + |
3041 | + if (d->_anchors) |
3042 | + QQuickAnchorsPrivate::get(d->_anchors)->updateMe(); |
3043 | + |
3044 | + bool xChange = (newGeometry.x() != oldGeometry.x()); |
3045 | + bool yChange = (newGeometry.y() != oldGeometry.y()); |
3046 | + bool widthChange = (newGeometry.width() != oldGeometry.width()); |
3047 | + bool heightChange = (newGeometry.height() != oldGeometry.height()); |
3048 | + |
3049 | + for (int ii = 0; ii < d->changeListeners.count(); ++ii) { |
3050 | + const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii); |
3051 | + if (change.types & QQuickItemPrivate::Geometry) { |
3052 | + if (change.gTypes == QQuickItemPrivate::GeometryChange) { |
3053 | + change.listener->itemGeometryChanged(this, newGeometry, oldGeometry); |
3054 | + } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) || |
3055 | + (yChange && (change.gTypes & QQuickItemPrivate::YChange)) || |
3056 | + (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) || |
3057 | + (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) { |
3058 | + change.listener->itemGeometryChanged(this, newGeometry, oldGeometry); |
3059 | + } |
3060 | + } |
3061 | + } |
3062 | + |
3063 | + if (xChange) |
3064 | + emit xChanged(); |
3065 | + if (yChange) |
3066 | + emit yChanged(); |
3067 | + if (widthChange) |
3068 | + emit widthChanged(); |
3069 | + if (heightChange) |
3070 | + emit heightChanged(); |
3071 | +} |
3072 | + |
3073 | +/*! |
3074 | + Called on the render thread when it is time to sync the state |
3075 | + of the item with the scene graph. |
3076 | + |
3077 | + The function is called as a result of QQuickItem::update(), if |
3078 | + the user has set the QQuickItem::ItemHasContents flag on the item. |
3079 | + |
3080 | + The function should return the root of the scene graph subtree for |
3081 | + this item. Most implementations will return a single |
3082 | + QSGGeometryNode containing the visual representation of this item. |
3083 | + \a oldNode is the node that was returned the last time the |
3084 | + function was called. \a updatePaintNodeData provides a pointer to |
3085 | + the QSGTransformNode associated with this QQuickItem. |
3086 | + |
3087 | + \code |
3088 | + QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) |
3089 | + { |
3090 | + QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node); |
3091 | + if (!n) { |
3092 | + n = new QSGSimpleRectNode(); |
3093 | + n->setColor(Qt::red); |
3094 | + } |
3095 | + n->setRect(boundingRect()); |
3096 | + return n; |
3097 | + } |
3098 | + \endcode |
3099 | + |
3100 | + The main thread is blocked while this function is executed so it is safe to read |
3101 | + values from the QQuickItem instance and other objects in the main thread. |
3102 | + |
3103 | + If no call to QQuickItem::updatePaintNode() result in actual scene graph |
3104 | + changes, like QSGNode::markDirty() or adding and removing nodes, then |
3105 | + the underlying implementation may decide to not render the scene again as |
3106 | + the visual outcome is identical. |
3107 | + |
3108 | + \warning It is crucial that OpenGL operations and interaction with |
3109 | + the scene graph happens exclusively on the render thread, |
3110 | + primarily during the QQuickItem::updatePaintNode() call. The best |
3111 | + rule of thumb is to only use classes with the "QSG" prefix inside |
3112 | + the QQuickItem::updatePaintNode() function. |
3113 | + |
3114 | + \warning This function is called on the render thread. This means any |
3115 | + QObjects or thread local storage that is created will have affinity to the |
3116 | + render thread, so apply caution when doing anything other than rendering |
3117 | + in this function. Similarily for signals, these will be emitted on the render |
3118 | + thread and will thus often be delivered via queued connections. |
3119 | + |
3120 | + \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry, |
3121 | + QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty() |
3122 | + */ |
3123 | + |
3124 | +QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) |
3125 | +{ |
3126 | + Q_UNUSED(updatePaintNodeData) |
3127 | + delete oldNode; |
3128 | + return 0; |
3129 | +} |
3130 | + |
3131 | +/*! |
3132 | + This function is called when the item's scene graph resources are no longer needed. |
3133 | + It allows items to free its resources, for instance textures, that are not owned by scene graph |
3134 | + nodes. Note that scene graph nodes are managed by QQuickWindow and should not be deleted by |
3135 | + this function. Scene graph resources are no longer needed when the parent is set to null and |
3136 | + the item is not used by any \l ShaderEffect or \l ShaderEffectSource. |
3137 | + |
3138 | + This function is called from the main thread. Therefore, resources used by the scene graph |
3139 | + should not be deleted directly, but by calling \l QObject::deleteLater(). |
3140 | + |
3141 | + \note The item destructor still needs to free its scene graph resources if not already done. |
3142 | + */ |
3143 | + |
3144 | +void QQuickItem::releaseResources() |
3145 | +{ |
3146 | +} |
3147 | + |
3148 | +QSGTransformNode *QQuickItemPrivate::createTransformNode() |
3149 | +{ |
3150 | + return new QSGTransformNode; |
3151 | +} |
3152 | + |
3153 | +/*! |
3154 | + This function should perform any layout as required for this item. |
3155 | + |
3156 | + When polish() is called, the scene graph schedules a polish event for this |
3157 | + item. When the scene graph is ready to render this item, it calls |
3158 | + updatePolish() to do any item layout as required before it renders the |
3159 | + next frame. |
3160 | + */ |
3161 | +void QQuickItem::updatePolish() |
3162 | +{ |
3163 | +} |
3164 | + |
3165 | +void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types) |
3166 | +{ |
3167 | + changeListeners.append(ChangeListener(listener, types)); |
3168 | +} |
3169 | + |
3170 | +void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types) |
3171 | +{ |
3172 | + ChangeListener change(listener, types); |
3173 | + changeListeners.removeOne(change); |
3174 | +} |
3175 | + |
3176 | +void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types) |
3177 | +{ |
3178 | + ChangeListener change(listener, types); |
3179 | + int index = changeListeners.find(change); |
3180 | + if (index > -1) |
3181 | + changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes |
3182 | + else |
3183 | + changeListeners.append(change); |
3184 | +} |
3185 | + |
3186 | +void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, |
3187 | + GeometryChangeTypes types) |
3188 | +{ |
3189 | + ChangeListener change(listener, types); |
3190 | + if (types == NoChange) { |
3191 | + changeListeners.removeOne(change); |
3192 | + } else { |
3193 | + int index = changeListeners.find(change); |
3194 | + if (index > -1) |
3195 | + changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes |
3196 | + } |
3197 | +} |
3198 | + |
3199 | +/*! |
3200 | + This event handler can be reimplemented in a subclass to receive key |
3201 | + press events for an item. The event information is provided by the |
3202 | + \a event parameter. |
3203 | + */ |
3204 | +void QQuickItem::keyPressEvent(QKeyEvent *event) |
3205 | +{ |
3206 | + event->ignore(); |
3207 | +} |
3208 | + |
3209 | +/*! |
3210 | + This event handler can be reimplemented in a subclass to receive key |
3211 | + release events for an item. The event information is provided by the |
3212 | + \a event parameter. |
3213 | + */ |
3214 | +void QQuickItem::keyReleaseEvent(QKeyEvent *event) |
3215 | +{ |
3216 | + event->ignore(); |
3217 | +} |
3218 | + |
3219 | +#ifndef QT_NO_IM |
3220 | +/*! |
3221 | + This event handler can be reimplemented in a subclass to receive input |
3222 | + method events for an item. The event information is provided by the |
3223 | + \a event parameter. |
3224 | + */ |
3225 | +void QQuickItem::inputMethodEvent(QInputMethodEvent *event) |
3226 | +{ |
3227 | + event->ignore(); |
3228 | +} |
3229 | +#endif // QT_NO_IM |
3230 | + |
3231 | +/*! |
3232 | + This event handler can be reimplemented in a subclass to receive focus-in |
3233 | + events for an item. The event information is provided by the |
3234 | + \a event parameter. |
3235 | + */ |
3236 | +void QQuickItem::focusInEvent(QFocusEvent * /*event*/) |
3237 | +{ |
3238 | +#ifndef QT_NO_ACCESSIBILITY |
3239 | + if (QAccessible::isActive()) { |
3240 | + if (QObject *acc = QQuickAccessibleAttached::findAccessible(this)) { |
3241 | + QAccessibleEvent ev(acc, QAccessible::Focus); |
3242 | + QAccessible::updateAccessibility(&ev); |
3243 | + } |
3244 | + } |
3245 | +#endif |
3246 | +} |
3247 | + |
3248 | +/*! |
3249 | + This event handler can be reimplemented in a subclass to receive focus-out |
3250 | + events for an item. The event information is provided by the |
3251 | + \a event parameter. |
3252 | + */ |
3253 | +void QQuickItem::focusOutEvent(QFocusEvent * /*event*/) |
3254 | +{ |
3255 | +} |
3256 | + |
3257 | +/*! |
3258 | + This event handler can be reimplemented in a subclass to receive mouse |
3259 | + press events for an item. The event information is provided by the |
3260 | + \a event parameter. |
3261 | + */ |
3262 | +void QQuickItem::mousePressEvent(QMouseEvent *event) |
3263 | +{ |
3264 | + event->ignore(); |
3265 | +} |
3266 | + |
3267 | +/*! |
3268 | + This event handler can be reimplemented in a subclass to receive mouse |
3269 | + move events for an item. The event information is provided by the |
3270 | + \a event parameter. |
3271 | + */ |
3272 | +void QQuickItem::mouseMoveEvent(QMouseEvent *event) |
3273 | +{ |
3274 | + event->ignore(); |
3275 | +} |
3276 | + |
3277 | +/*! |
3278 | + This event handler can be reimplemented in a subclass to receive mouse |
3279 | + release events for an item. The event information is provided by the |
3280 | + \a event parameter. |
3281 | + */ |
3282 | +void QQuickItem::mouseReleaseEvent(QMouseEvent *event) |
3283 | +{ |
3284 | + event->ignore(); |
3285 | +} |
3286 | + |
3287 | +/*! |
3288 | + This event handler can be reimplemented in a subclass to receive mouse |
3289 | + double-click events for an item. The event information is provided by the |
3290 | + \a event parameter. |
3291 | + */ |
3292 | +void QQuickItem::mouseDoubleClickEvent(QMouseEvent *) |
3293 | +{ |
3294 | +} |
3295 | + |
3296 | +/*! |
3297 | + This event handler can be reimplemented in a subclass to be notified |
3298 | + when a mouse ungrab event has occurred on this item. |
3299 | + |
3300 | + \sa ungrabMouse() |
3301 | + */ |
3302 | +void QQuickItem::mouseUngrabEvent() |
3303 | +{ |
3304 | + // XXX todo |
3305 | +} |
3306 | + |
3307 | +/*! |
3308 | + This event handler can be reimplemented in a subclass to be notified |
3309 | + when a touch ungrab event has occurred on this item. |
3310 | + */ |
3311 | +void QQuickItem::touchUngrabEvent() |
3312 | +{ |
3313 | + // XXX todo |
3314 | +} |
3315 | + |
3316 | +#ifndef QT_NO_WHEELEVENT |
3317 | +/*! |
3318 | + This event handler can be reimplemented in a subclass to receive |
3319 | + wheel events for an item. The event information is provided by the |
3320 | + \a event parameter. |
3321 | + */ |
3322 | +void QQuickItem::wheelEvent(QWheelEvent *event) |
3323 | +{ |
3324 | + event->ignore(); |
3325 | +} |
3326 | +#endif |
3327 | + |
3328 | +/*! |
3329 | + This event handler can be reimplemented in a subclass to receive touch |
3330 | + events for an item. The event information is provided by the |
3331 | + \a event parameter. |
3332 | + */ |
3333 | +void QQuickItem::touchEvent(QTouchEvent *event) |
3334 | +{ |
3335 | + event->ignore(); |
3336 | +} |
3337 | + |
3338 | +/*! |
3339 | + This event handler can be reimplemented in a subclass to receive hover-enter |
3340 | + events for an item. The event information is provided by the |
3341 | + \a event parameter. |
3342 | + |
3343 | + Hover events are only provided if acceptHoverEvents() is true. |
3344 | + */ |
3345 | +void QQuickItem::hoverEnterEvent(QHoverEvent *event) |
3346 | +{ |
3347 | + Q_UNUSED(event); |
3348 | +} |
3349 | + |
3350 | +/*! |
3351 | + This event handler can be reimplemented in a subclass to receive hover-move |
3352 | + events for an item. The event information is provided by the |
3353 | + \a event parameter. |
3354 | + |
3355 | + Hover events are only provided if acceptHoverEvents() is true. |
3356 | + */ |
3357 | +void QQuickItem::hoverMoveEvent(QHoverEvent *event) |
3358 | +{ |
3359 | + Q_UNUSED(event); |
3360 | +} |
3361 | + |
3362 | +/*! |
3363 | + This event handler can be reimplemented in a subclass to receive hover-leave |
3364 | + events for an item. The event information is provided by the |
3365 | + \a event parameter. |
3366 | + |
3367 | + Hover events are only provided if acceptHoverEvents() is true. |
3368 | + */ |
3369 | +void QQuickItem::hoverLeaveEvent(QHoverEvent *event) |
3370 | +{ |
3371 | + Q_UNUSED(event); |
3372 | +} |
3373 | + |
3374 | +#ifndef QT_NO_DRAGANDDROP |
3375 | +/*! |
3376 | + This event handler can be reimplemented in a subclass to receive drag-enter |
3377 | + events for an item. The event information is provided by the |
3378 | + \a event parameter. |
3379 | + |
3380 | + Drag and drop events are only provided if the ItemAcceptsDrops flag |
3381 | + has been set for this item. |
3382 | + |
3383 | + \sa Drag, {Drag and Drop} |
3384 | + */ |
3385 | +void QQuickItem::dragEnterEvent(QDragEnterEvent *event) |
3386 | +{ |
3387 | + Q_UNUSED(event); |
3388 | +} |
3389 | + |
3390 | +/*! |
3391 | + This event handler can be reimplemented in a subclass to receive drag-move |
3392 | + events for an item. The event information is provided by the |
3393 | + \a event parameter. |
3394 | + |
3395 | + Drag and drop events are only provided if the ItemAcceptsDrops flag |
3396 | + has been set for this item. |
3397 | + |
3398 | + \sa Drag, {Drag and Drop} |
3399 | + */ |
3400 | +void QQuickItem::dragMoveEvent(QDragMoveEvent *event) |
3401 | +{ |
3402 | + Q_UNUSED(event); |
3403 | +} |
3404 | + |
3405 | +/*! |
3406 | + This event handler can be reimplemented in a subclass to receive drag-leave |
3407 | + events for an item. The event information is provided by the |
3408 | + \a event parameter. |
3409 | + |
3410 | + Drag and drop events are only provided if the ItemAcceptsDrops flag |
3411 | + has been set for this item. |
3412 | + |
3413 | + \sa Drag, {Drag and Drop} |
3414 | + */ |
3415 | +void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event) |
3416 | +{ |
3417 | + Q_UNUSED(event); |
3418 | +} |
3419 | + |
3420 | +/*! |
3421 | + This event handler can be reimplemented in a subclass to receive drop |
3422 | + events for an item. The event information is provided by the |
3423 | + \a event parameter. |
3424 | + |
3425 | + Drag and drop events are only provided if the ItemAcceptsDrops flag |
3426 | + has been set for this item. |
3427 | + |
3428 | + \sa Drag, {Drag and Drop} |
3429 | + */ |
3430 | +void QQuickItem::dropEvent(QDropEvent *event) |
3431 | +{ |
3432 | + Q_UNUSED(event); |
3433 | +} |
3434 | +#endif // QT_NO_DRAGANDDROP |
3435 | + |
3436 | +/*! |
3437 | + Reimplement this method to filter the mouse events that are received by |
3438 | + this item's children. |
3439 | + |
3440 | + This method will only be called if filtersChildMouseEvents() is true. |
3441 | + |
3442 | + Return true if the specified \a event should not be passed onto the |
3443 | + specified child \a item, and false otherwise. |
3444 | + |
3445 | + \sa setFiltersChildMouseEvents() |
3446 | + */ |
3447 | +bool QQuickItem::childMouseEventFilter(QQuickItem *item, QEvent *event) |
3448 | +{ |
3449 | + Q_UNUSED(item); |
3450 | + Q_UNUSED(event); |
3451 | + return false; |
3452 | +} |
3453 | + |
3454 | +/*! |
3455 | + \internal |
3456 | + */ |
3457 | +void QQuickItem::windowDeactivateEvent() |
3458 | +{ |
3459 | + foreach (QQuickItem* item, childItems()) { |
3460 | + item->windowDeactivateEvent(); |
3461 | + } |
3462 | +} |
3463 | + |
3464 | +#ifndef QT_NO_IM |
3465 | +/*! |
3466 | + This method is only relevant for input items. |
3467 | + |
3468 | + If this item is an input item, this method should be reimplemented to |
3469 | + return the relevant input method flags for the given \a query. |
3470 | + |
3471 | + \sa QWidget::inputMethodQuery() |
3472 | + */ |
3473 | +QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const |
3474 | +{ |
3475 | + Q_D(const QQuickItem); |
3476 | + QVariant v; |
3477 | + |
3478 | + switch (query) { |
3479 | + case Qt::ImEnabled: |
3480 | + v = (bool)(flags() & ItemAcceptsInputMethod); |
3481 | + break; |
3482 | + case Qt::ImHints: |
3483 | + case Qt::ImCursorRectangle: |
3484 | + case Qt::ImFont: |
3485 | + case Qt::ImCursorPosition: |
3486 | + case Qt::ImSurroundingText: |
3487 | + case Qt::ImCurrentSelection: |
3488 | + case Qt::ImMaximumTextLength: |
3489 | + case Qt::ImAnchorPosition: |
3490 | + case Qt::ImPreferredLanguage: |
3491 | + if (d->extra.isAllocated() && d->extra->keyHandler) |
3492 | + v = d->extra->keyHandler->inputMethodQuery(query); |
3493 | + default: |
3494 | + break; |
3495 | + } |
3496 | + |
3497 | + return v; |
3498 | +} |
3499 | +#endif // QT_NO_IM |
3500 | + |
3501 | +QQuickAnchorLine QQuickItemPrivate::left() const |
3502 | +{ |
3503 | + Q_Q(const QQuickItem); |
3504 | + return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left); |
3505 | +} |
3506 | + |
3507 | +QQuickAnchorLine QQuickItemPrivate::right() const |
3508 | +{ |
3509 | + Q_Q(const QQuickItem); |
3510 | + return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right); |
3511 | +} |
3512 | + |
3513 | +QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const |
3514 | +{ |
3515 | + Q_Q(const QQuickItem); |
3516 | + return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter); |
3517 | +} |
3518 | + |
3519 | +QQuickAnchorLine QQuickItemPrivate::top() const |
3520 | +{ |
3521 | + Q_Q(const QQuickItem); |
3522 | + return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top); |
3523 | +} |
3524 | + |
3525 | +QQuickAnchorLine QQuickItemPrivate::bottom() const |
3526 | +{ |
3527 | + Q_Q(const QQuickItem); |
3528 | + return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom); |
3529 | +} |
3530 | + |
3531 | +QQuickAnchorLine QQuickItemPrivate::verticalCenter() const |
3532 | +{ |
3533 | + Q_Q(const QQuickItem); |
3534 | + return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter); |
3535 | +} |
3536 | + |
3537 | +QQuickAnchorLine QQuickItemPrivate::baseline() const |
3538 | +{ |
3539 | + Q_Q(const QQuickItem); |
3540 | + return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline); |
3541 | +} |
3542 | + |
3543 | +/*! |
3544 | + \qmlproperty int QtQuick2::Item::baselineOffset |
3545 | + |
3546 | + Specifies the position of the item's baseline in local coordinates. |
3547 | + |
3548 | + The baseline of a \l Text item is the imaginary line on which the text |
3549 | + sits. Controls containing text usually set their baseline to the |
3550 | + baseline of their text. |
3551 | + |
3552 | + For non-text items, a default baseline offset of 0 is used. |
3553 | +*/ |
3554 | +/*! |
3555 | + \property QQuickItem::baselineOffset |
3556 | + |
3557 | + Specifies the position of the item's baseline in local coordinates. |
3558 | + |
3559 | + The baseline of a \l Text item is the imaginary line on which the text |
3560 | + sits. Controls containing text usually set their baseline to the |
3561 | + baseline of their text. |
3562 | + |
3563 | + For non-text items, a default baseline offset of 0 is used. |
3564 | +*/ |
3565 | +qreal QQuickItem::baselineOffset() const |
3566 | +{ |
3567 | + Q_D(const QQuickItem); |
3568 | + if (d->baselineOffsetValid) { |
3569 | + return d->baselineOffset; |
3570 | + } else { |
3571 | + return 0.0; |
3572 | + } |
3573 | +} |
3574 | + |
3575 | +void QQuickItem::setBaselineOffset(qreal offset) |
3576 | +{ |
3577 | + Q_D(QQuickItem); |
3578 | + if (offset == d->baselineOffset) |
3579 | + return; |
3580 | + |
3581 | + d->baselineOffset = offset; |
3582 | + d->baselineOffsetValid = true; |
3583 | + |
3584 | + for (int ii = 0; ii < d->changeListeners.count(); ++ii) { |
3585 | + const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii); |
3586 | + if (change.types & QQuickItemPrivate::Geometry) { |
3587 | + QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); |
3588 | + if (anchor) |
3589 | + anchor->updateVerticalAnchors(); |
3590 | + } |
3591 | + } |
3592 | + |
3593 | + if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor)) |
3594 | + QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors(); |
3595 | + |
3596 | + emit baselineOffsetChanged(offset); |
3597 | +} |
3598 | + |
3599 | + |
3600 | +/*! |
3601 | + * Schedules a call to updatePaintNode() for this item. |
3602 | + * |
3603 | + * The call to QQuickItem::updatePaintNode() will always happen if the |
3604 | + * item is showing in a QQuickWindow. |
3605 | + * |
3606 | + * Only items which specifies QQuickItem::ItemHasContents are allowed |
3607 | + * to call QQuickItem::update(). |
3608 | + */ |
3609 | +void QQuickItem::update() |
3610 | +{ |
3611 | + Q_D(QQuickItem); |
3612 | + Q_ASSERT(flags() & ItemHasContents); |
3613 | + d->dirty(QQuickItemPrivate::Content); |
3614 | +} |
3615 | + |
3616 | +/*! |
3617 | + Schedules a polish event for this item. |
3618 | + |
3619 | + When the scene graph processes the request, it will call updatePolish() |
3620 | + on this item. |
3621 | + */ |
3622 | +void QQuickItem::polish() |
3623 | +{ |
3624 | + Q_D(QQuickItem); |
3625 | + if (!d->polishScheduled) { |
3626 | + d->polishScheduled = true; |
3627 | + if (d->window) { |
3628 | + QQuickWindowPrivate *p = QQuickWindowPrivate::get(d->window); |
3629 | + bool maybeupdate = p->itemsToPolish.isEmpty(); |
3630 | + p->itemsToPolish.insert(this); |
3631 | + if (maybeupdate) d->window->maybeUpdate(); |
3632 | + } |
3633 | + } |
3634 | +} |
3635 | + |
3636 | +/*! |
3637 | + \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y) |
3638 | + \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height) |
3639 | + |
3640 | + Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a |
3641 | + item's coordinate system, to this item's coordinate system, and returns an object with \c x and |
3642 | + \c y (and optionally \c width and \c height) properties matching the mapped coordinate. |
3643 | + |
3644 | + If \a item is a \c null value, this maps the point or rect from the coordinate system of |
3645 | + the root QML view. |
3646 | +*/ |
3647 | +/*! |
3648 | + \internal |
3649 | + */ |
3650 | +void QQuickItem::mapFromItem(QQmlV8Function *args) const |
3651 | +{ |
3652 | + if (args->Length() != 0) { |
3653 | + v8::Local<v8::Value> item = (*args)[0]; |
3654 | + QV8Engine *engine = args->engine(); |
3655 | + |
3656 | + QQuickItem *itemObj = 0; |
3657 | + if (!item->IsNull()) |
3658 | + itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item)); |
3659 | + |
3660 | + if (!itemObj && !item->IsNull()) { |
3661 | + qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString()) |
3662 | + << "\" which is neither null nor an Item"; |
3663 | + return; |
3664 | + } |
3665 | + |
3666 | + v8::Local<v8::Object> rv = v8::Object::New(); |
3667 | + args->returnValue(rv); |
3668 | + |
3669 | + qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0; |
3670 | + qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0; |
3671 | + |
3672 | + if (args->Length() > 3) { |
3673 | + qreal w = (*args)[3]->NumberValue(); |
3674 | + qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0; |
3675 | + |
3676 | + QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h)); |
3677 | + |
3678 | + rv->Set(v8::String::New("x"), v8::Number::New(r.x())); |
3679 | + rv->Set(v8::String::New("y"), v8::Number::New(r.y())); |
3680 | + rv->Set(v8::String::New("width"), v8::Number::New(r.width())); |
3681 | + rv->Set(v8::String::New("height"), v8::Number::New(r.height())); |
3682 | + } else { |
3683 | + QPointF p = mapFromItem(itemObj, QPointF(x, y)); |
3684 | + |
3685 | + rv->Set(v8::String::New("x"), v8::Number::New(p.x())); |
3686 | + rv->Set(v8::String::New("y"), v8::Number::New(p.y())); |
3687 | + } |
3688 | + } |
3689 | +} |
3690 | + |
3691 | +/*! |
3692 | + \internal |
3693 | + */ |
3694 | +QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const |
3695 | +{ |
3696 | + Q_D(const QQuickItem); |
3697 | + |
3698 | + // XXX todo - we need to be able to handle common parents better and detect |
3699 | + // invalid cases |
3700 | + if (ok) *ok = true; |
3701 | + |
3702 | + QTransform t = d->itemToWindowTransform(); |
3703 | + if (other) t *= QQuickItemPrivate::get(other)->windowToItemTransform(); |
3704 | + |
3705 | + return t; |
3706 | +} |
3707 | + |
3708 | +/*! |
3709 | + \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y) |
3710 | + \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height) |
3711 | + |
3712 | + Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this |
3713 | + item's coordinate system, to \a item's coordinate system, and returns an object with \c x and |
3714 | + \c y (and optionally \c width and \c height) properties matching the mapped coordinate. |
3715 | + |
3716 | + If \a item is a \c null value, this maps the point or rect to the coordinate system of the |
3717 | + root QML view. |
3718 | +*/ |
3719 | +/*! |
3720 | + \internal |
3721 | + */ |
3722 | +void QQuickItem::mapToItem(QQmlV8Function *args) const |
3723 | +{ |
3724 | + if (args->Length() != 0) { |
3725 | + v8::Local<v8::Value> item = (*args)[0]; |
3726 | + QV8Engine *engine = args->engine(); |
3727 | + |
3728 | + QQuickItem *itemObj = 0; |
3729 | + if (!item->IsNull()) |
3730 | + itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item)); |
3731 | + |
3732 | + if (!itemObj && !item->IsNull()) { |
3733 | + qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString()) |
3734 | + << "\" which is neither null nor an Item"; |
3735 | + return; |
3736 | + } |
3737 | + |
3738 | + v8::Local<v8::Object> rv = v8::Object::New(); |
3739 | + args->returnValue(rv); |
3740 | + |
3741 | + qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0; |
3742 | + qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0; |
3743 | + |
3744 | + if (args->Length() > 3) { |
3745 | + qreal w = (*args)[3]->NumberValue(); |
3746 | + qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0; |
3747 | + |
3748 | + QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h)); |
3749 | + |
3750 | + rv->Set(v8::String::New("x"), v8::Number::New(r.x())); |
3751 | + rv->Set(v8::String::New("y"), v8::Number::New(r.y())); |
3752 | + rv->Set(v8::String::New("width"), v8::Number::New(r.width())); |
3753 | + rv->Set(v8::String::New("height"), v8::Number::New(r.height())); |
3754 | + } else { |
3755 | + QPointF p = mapToItem(itemObj, QPointF(x, y)); |
3756 | + |
3757 | + rv->Set(v8::String::New("x"), v8::Number::New(p.x())); |
3758 | + rv->Set(v8::String::New("y"), v8::Number::New(p.y())); |
3759 | + } |
3760 | + } |
3761 | +} |
3762 | + |
3763 | +/*! |
3764 | + \qmlmethod QtQuick2::Item::forceActiveFocus() |
3765 | + |
3766 | + Forces active focus on the item. |
3767 | + |
3768 | + This method sets focus on the item and ensures that all ancestor |
3769 | + FocusScope objects in the object hierarchy are also given \l focus. |
3770 | + |
3771 | + \sa activeFocus |
3772 | +*/ |
3773 | +/*! |
3774 | + Forces active focus on the item. |
3775 | + |
3776 | + This method sets focus on the item and ensures that all ancestor |
3777 | + FocusScope objects in the object hierarchy are also given \l focus. |
3778 | + |
3779 | + \sa activeFocus |
3780 | +*/ |
3781 | +void QQuickItem::forceActiveFocus() |
3782 | +{ |
3783 | + setFocus(true); |
3784 | + QQuickItem *parent = parentItem(); |
3785 | + while (parent) { |
3786 | + if (parent->flags() & QQuickItem::ItemIsFocusScope) { |
3787 | + parent->setFocus(true); |
3788 | + } |
3789 | + parent = parent->parentItem(); |
3790 | + } |
3791 | +} |
3792 | + |
3793 | +/*! |
3794 | + \qmlmethod QtQuick2::Item::childAt(real x, real y) |
3795 | + |
3796 | + Returns the first visible child item found at point (\a x, \a y) within |
3797 | + the coordinate system of this item. |
3798 | + |
3799 | + Returns \c null if there is no such item. |
3800 | +*/ |
3801 | +/*! |
3802 | + Returns the first visible child item found at point (\a x, \a y) within |
3803 | + the coordinate system of this item. |
3804 | + |
3805 | + Returns 0 if there is no such item. |
3806 | +*/ |
3807 | +QQuickItem *QQuickItem::childAt(qreal x, qreal y) const |
3808 | +{ |
3809 | + // XXX todo - should this include transform etc.? |
3810 | + const QList<QQuickItem *> children = childItems(); |
3811 | + for (int i = children.count()-1; i >= 0; --i) { |
3812 | + QQuickItem *child = children.at(i); |
3813 | + if (child->isVisible() && child->x() <= x |
3814 | + && child->x() + child->width() >= x |
3815 | + && child->y() <= y |
3816 | + && child->y() + child->height() >= y) |
3817 | + return child; |
3818 | + } |
3819 | + return 0; |
3820 | +} |
3821 | + |
3822 | +QQmlListProperty<QObject> QQuickItemPrivate::resources() |
3823 | +{ |
3824 | + return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append, |
3825 | + QQuickItemPrivate::resources_count, |
3826 | + QQuickItemPrivate::resources_at, |
3827 | + QQuickItemPrivate::resources_clear); |
3828 | +} |
3829 | + |
3830 | +/*! |
3831 | + \qmlproperty list<Item> QtQuick2::Item::children |
3832 | + \qmlproperty list<Object> QtQuick2::Item::resources |
3833 | + |
3834 | + The children property contains the list of visual children of this item. |
3835 | + The resources property contains non-visual resources that you want to |
3836 | + reference by name. |
3837 | + |
3838 | + It is not generally necessary to refer to these properties when adding |
3839 | + child items or resources, as the default \l data property will |
3840 | + automatically assign child objects to the \c children and \c resources |
3841 | + properties as appropriate. See the \l data documentation for details. |
3842 | +*/ |
3843 | +/*! |
3844 | + \property QQuickItem::children |
3845 | + \internal |
3846 | +*/ |
3847 | +QQmlListProperty<QQuickItem> QQuickItemPrivate::children() |
3848 | +{ |
3849 | + return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append, |
3850 | + QQuickItemPrivate::children_count, |
3851 | + QQuickItemPrivate::children_at, |
3852 | + QQuickItemPrivate::children_clear); |
3853 | + |
3854 | +} |
3855 | + |
3856 | +/*! |
3857 | + \qmlproperty real QtQuick2::Item::visibleChildren |
3858 | + This read-only property lists all of the item's children that are currently visible. |
3859 | + Note that a child's visibility may have changed explicitly, or because the visibility |
3860 | + of this (it's parent) item or another grandparent changed. |
3861 | +*/ |
3862 | +/*! |
3863 | + \property QQuickItem::visibleChildren |
3864 | + \internal |
3865 | +*/ |
3866 | +QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren() |
3867 | +{ |
3868 | + return QQmlListProperty<QQuickItem>(q_func(), |
3869 | + 0, |
3870 | + QQuickItemPrivate::visibleChildren_count, |
3871 | + QQuickItemPrivate::visibleChildren_at); |
3872 | + |
3873 | +} |
3874 | + |
3875 | +/*! |
3876 | + \qmlproperty list<State> QtQuick2::Item::states |
3877 | + |
3878 | + This property holds the list of possible states for this item. To change |
3879 | + the state of this item, set the \l state property to one of these states, |
3880 | + or set the \l state property to an empty string to revert the item to its |
3881 | + default state. |
3882 | + |
3883 | + This property is specified as a list of \l State objects. For example, |
3884 | + below is an item with "red_color" and "blue_color" states: |
3885 | + |
3886 | + \qml |
3887 | + import QtQuick 2.0 |
3888 | + |
3889 | + Rectangle { |
3890 | + id: root |
3891 | + width: 100; height: 100 |
3892 | + |
3893 | + states: [ |
3894 | + State { |
3895 | + name: "red_color" |
3896 | + PropertyChanges { target: root; color: "red" } |
3897 | + }, |
3898 | + State { |
3899 | + name: "blue_color" |
3900 | + PropertyChanges { target: root; color: "blue" } |
3901 | + } |
3902 | + ] |
3903 | + } |
3904 | + \endqml |
3905 | + |
3906 | + See \l{Qt Quick States} and \l{Animation and Transitions in Qt Quick} for |
3907 | + more details on using states and transitions. |
3908 | + |
3909 | + \sa transitions |
3910 | +*/ |
3911 | +/*! |
3912 | + \property QQuickItem::states |
3913 | + \internal |
3914 | + */ |
3915 | +QQmlListProperty<QQuickState> QQuickItemPrivate::states() |
3916 | +{ |
3917 | + return _states()->statesProperty(); |
3918 | +} |
3919 | + |
3920 | +/*! |
3921 | + \qmlproperty list<Transition> QtQuick2::Item::transitions |
3922 | + |
3923 | + This property holds the list of transitions for this item. These define the |
3924 | + transitions to be applied to the item whenever it changes its \l state. |
3925 | + |
3926 | + This property is specified as a list of \l Transition objects. For example: |
3927 | + |
3928 | + \qml |
3929 | + import QtQuick 2.0 |
3930 | + |
3931 | + Item { |
3932 | + transitions: [ |
3933 | + Transition { |
3934 | + //... |
3935 | + }, |
3936 | + Transition { |
3937 | + //... |
3938 | + } |
3939 | + ] |
3940 | + } |
3941 | + \endqml |
3942 | + |
3943 | + See \l{Qt Quick States} and \l{Animation and Transitions in Qt Quick} for |
3944 | + more details on using states and transitions. |
3945 | + |
3946 | + \sa states |
3947 | +*/ |
3948 | +/*! |
3949 | + \property QQuickItem::transitions |
3950 | + \internal |
3951 | + */ |
3952 | +QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions() |
3953 | +{ |
3954 | + return _states()->transitionsProperty(); |
3955 | +} |
3956 | + |
3957 | +QString QQuickItemPrivate::state() const |
3958 | +{ |
3959 | + if (!_stateGroup) |
3960 | + return QString(); |
3961 | + else |
3962 | + return _stateGroup->state(); |
3963 | +} |
3964 | + |
3965 | +void QQuickItemPrivate::setState(const QString &state) |
3966 | +{ |
3967 | + _states()->setState(state); |
3968 | +} |
3969 | + |
3970 | +/*! |
3971 | + \qmlproperty string QtQuick2::Item::state |
3972 | + |
3973 | + This property holds the name of the current state of the item. |
3974 | + |
3975 | + If the item is in its default state — that is, no explicit state has been |
3976 | + set — then this property holds an empty string. Likewise, you can return |
3977 | + an item to its default state by setting this property to an empty string. |
3978 | + |
3979 | + \sa {Qt Quick States} |
3980 | +*/ |
3981 | +/*! |
3982 | + \property QQuickItem::state |
3983 | + |
3984 | + This property holds the name of the current state of the item. |
3985 | + |
3986 | + If the item is in its default state — that is, no explicit state has been |
3987 | + set — then this property holds an empty string. Likewise, you can return |
3988 | + an item to its default state by setting this property to an empty string. |
3989 | + |
3990 | + \sa {Qt Quick States} |
3991 | +*/ |
3992 | +QString QQuickItem::state() const |
3993 | +{ |
3994 | + Q_D(const QQuickItem); |
3995 | + return d->state(); |
3996 | +} |
3997 | + |
3998 | +void QQuickItem::setState(const QString &state) |
3999 | +{ |
4000 | + Q_D(QQuickItem); |
4001 | + d->setState(state); |
4002 | +} |
4003 | + |
4004 | +/*! |
4005 | + \qmlproperty list<Transform> QtQuick2::Item::transform |
4006 | + This property holds the list of transformations to apply. |
4007 | + |
4008 | + For more information see \l Transform. |
4009 | +*/ |
4010 | +/*! |
4011 | + \property QQuickItem::transform |
4012 | + \internal |
4013 | + */ |
4014 | +/*! |
4015 | + \internal |
4016 | + */ |
4017 | +QQmlListProperty<QQuickTransform> QQuickItem::transform() |
4018 | +{ |
4019 | + return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append, |
4020 | + QQuickItemPrivate::transform_count, |
4021 | + QQuickItemPrivate::transform_at, |
4022 | + QQuickItemPrivate::transform_clear); |
4023 | +} |
4024 | + |
4025 | +/*! |
4026 | + \reimp |
4027 | + Derived classes should call the base class method before adding their own action to |
4028 | + perform at classBegin. |
4029 | +*/ |
4030 | +void QQuickItem::classBegin() |
4031 | +{ |
4032 | + Q_D(QQuickItem); |
4033 | + d->componentComplete = false; |
4034 | + if (d->_stateGroup) |
4035 | + d->_stateGroup->classBegin(); |
4036 | + if (d->_anchors) |
4037 | + d->_anchors->classBegin(); |
4038 | + if (d->extra.isAllocated() && d->extra->layer) |
4039 | + d->extra->layer->classBegin(); |
4040 | +} |
4041 | + |
4042 | +/*! |
4043 | + \reimp |
4044 | + Derived classes should call the base class method before adding their own actions to |
4045 | + perform at componentComplete. |
4046 | +*/ |
4047 | +void QQuickItem::componentComplete() |
4048 | +{ |
4049 | + Q_D(QQuickItem); |
4050 | + d->componentComplete = true; |
4051 | + if (d->_stateGroup) |
4052 | + d->_stateGroup->componentComplete(); |
4053 | + if (d->_anchors) { |
4054 | + d->_anchors->componentComplete(); |
4055 | + QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete(); |
4056 | + } |
4057 | + |
4058 | + if (d->extra.isAllocated() && d->extra->layer) |
4059 | + d->extra->layer->componentComplete(); |
4060 | + |
4061 | + if (d->extra.isAllocated() && d->extra->keyHandler) |
4062 | + d->extra->keyHandler->componentComplete(); |
4063 | + |
4064 | + if (d->extra.isAllocated() && d->extra->contents) |
4065 | + d->extra->contents->complete(); |
4066 | + |
4067 | + if (d->window && d->dirtyAttributes) { |
4068 | + d->addToDirtyList(); |
4069 | + QQuickWindowPrivate::get(d->window)->dirtyItem(this); |
4070 | + } |
4071 | +} |
4072 | + |
4073 | +QQuickStateGroup *QQuickItemPrivate::_states() |
4074 | +{ |
4075 | + Q_Q(QQuickItem); |
4076 | + if (!_stateGroup) { |
4077 | + _stateGroup = new QQuickStateGroup; |
4078 | + if (!componentComplete) |
4079 | + _stateGroup->classBegin(); |
4080 | + qmlobject_connect(_stateGroup, QQuickStateGroup, SIGNAL(stateChanged(QString)), |
4081 | + q, QQuickItem, SIGNAL(stateChanged(QString))) |
4082 | + } |
4083 | + |
4084 | + return _stateGroup; |
4085 | +} |
4086 | + |
4087 | +QPointF QQuickItemPrivate::computeTransformOrigin() const |
4088 | +{ |
4089 | + switch (origin()) { |
4090 | + default: |
4091 | + case QQuickItem::TopLeft: |
4092 | + return QPointF(0, 0); |
4093 | + case QQuickItem::Top: |
4094 | + return QPointF(width / 2., 0); |
4095 | + case QQuickItem::TopRight: |
4096 | + return QPointF(width, 0); |
4097 | + case QQuickItem::Left: |
4098 | + return QPointF(0, height / 2.); |
4099 | + case QQuickItem::Center: |
4100 | + return QPointF(width / 2., height / 2.); |
4101 | + case QQuickItem::Right: |
4102 | + return QPointF(width, height / 2.); |
4103 | + case QQuickItem::BottomLeft: |
4104 | + return QPointF(0, height); |
4105 | + case QQuickItem::Bottom: |
4106 | + return QPointF(width / 2., height); |
4107 | + case QQuickItem::BottomRight: |
4108 | + return QPointF(width, height); |
4109 | + } |
4110 | +} |
4111 | + |
4112 | +void QQuickItemPrivate::transformChanged() |
4113 | +{ |
4114 | + if (extra.isAllocated() && extra->layer) |
4115 | + extra->layer->updateMatrix(); |
4116 | +} |
4117 | + |
4118 | +void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e) |
4119 | +{ |
4120 | + Q_Q(QQuickItem); |
4121 | + |
4122 | + Q_ASSERT(e->isAccepted()); |
4123 | + if (extra.isAllocated() && extra->keyHandler) { |
4124 | + if (e->type() == QEvent::KeyPress) |
4125 | + extra->keyHandler->keyPressed(e, false); |
4126 | + else |
4127 | + extra->keyHandler->keyReleased(e, false); |
4128 | + |
4129 | + if (e->isAccepted()) |
4130 | + return; |
4131 | + else |
4132 | + e->accept(); |
4133 | + } |
4134 | + |
4135 | + if (e->type() == QEvent::KeyPress) |
4136 | + q->keyPressEvent(e); |
4137 | + else |
4138 | + q->keyReleaseEvent(e); |
4139 | + |
4140 | + if (e->isAccepted()) |
4141 | + return; |
4142 | + |
4143 | + if (extra.isAllocated() && extra->keyHandler) { |
4144 | + e->accept(); |
4145 | + |
4146 | + if (e->type() == QEvent::KeyPress) |
4147 | + extra->keyHandler->keyPressed(e, true); |
4148 | + else |
4149 | + extra->keyHandler->keyReleased(e, true); |
4150 | + } |
4151 | +} |
4152 | + |
4153 | +#ifndef QT_NO_IM |
4154 | +void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e) |
4155 | +{ |
4156 | + Q_Q(QQuickItem); |
4157 | + |
4158 | + Q_ASSERT(e->isAccepted()); |
4159 | + if (extra.isAllocated() && extra->keyHandler) { |
4160 | + extra->keyHandler->inputMethodEvent(e, false); |
4161 | + |
4162 | + if (e->isAccepted()) |
4163 | + return; |
4164 | + else |
4165 | + e->accept(); |
4166 | + } |
4167 | + |
4168 | + q->inputMethodEvent(e); |
4169 | + |
4170 | + if (e->isAccepted()) |
4171 | + return; |
4172 | + |
4173 | + if (extra.isAllocated() && extra->keyHandler) { |
4174 | + e->accept(); |
4175 | + |
4176 | + extra->keyHandler->inputMethodEvent(e, true); |
4177 | + } |
4178 | +} |
4179 | +#endif // QT_NO_IM |
4180 | + |
4181 | +void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e) |
4182 | +{ |
4183 | + Q_Q(QQuickItem); |
4184 | + |
4185 | + if (e->type() == QEvent::FocusIn) { |
4186 | + q->focusInEvent(e); |
4187 | + } else { |
4188 | + q->focusOutEvent(e); |
4189 | + } |
4190 | +} |
4191 | + |
4192 | +void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e) |
4193 | +{ |
4194 | + Q_Q(QQuickItem); |
4195 | + |
4196 | + Q_ASSERT(e->isAccepted()); |
4197 | + |
4198 | + switch (e->type()) { |
4199 | + default: |
4200 | + Q_ASSERT(!"Unknown event type"); |
4201 | + case QEvent::MouseMove: |
4202 | + q->mouseMoveEvent(e); |
4203 | + break; |
4204 | + case QEvent::MouseButtonPress: |
4205 | + q->mousePressEvent(e); |
4206 | + break; |
4207 | + case QEvent::MouseButtonRelease: |
4208 | + q->mouseReleaseEvent(e); |
4209 | + break; |
4210 | + case QEvent::MouseButtonDblClick: |
4211 | + q->mouseDoubleClickEvent(e); |
4212 | + break; |
4213 | + } |
4214 | +} |
4215 | + |
4216 | +#ifndef QT_NO_WHEELEVENT |
4217 | +void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e) |
4218 | +{ |
4219 | + Q_Q(QQuickItem); |
4220 | + q->wheelEvent(e); |
4221 | +} |
4222 | +#endif |
4223 | + |
4224 | +void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e) |
4225 | +{ |
4226 | + Q_Q(QQuickItem); |
4227 | + q->touchEvent(e); |
4228 | +} |
4229 | + |
4230 | +void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e) |
4231 | +{ |
4232 | + Q_Q(QQuickItem); |
4233 | + switch (e->type()) { |
4234 | + default: |
4235 | + Q_ASSERT(!"Unknown event type"); |
4236 | + case QEvent::HoverEnter: |
4237 | + q->hoverEnterEvent(e); |
4238 | + break; |
4239 | + case QEvent::HoverLeave: |
4240 | + q->hoverLeaveEvent(e); |
4241 | + break; |
4242 | + case QEvent::HoverMove: |
4243 | + q->hoverMoveEvent(e); |
4244 | + break; |
4245 | + } |
4246 | +} |
4247 | + |
4248 | +#ifndef QT_NO_DRAGANDDROP |
4249 | +void QQuickItemPrivate::deliverDragEvent(QEvent *e) |
4250 | +{ |
4251 | + Q_Q(QQuickItem); |
4252 | + switch (e->type()) { |
4253 | + default: |
4254 | + Q_ASSERT(!"Unknown event type"); |
4255 | + case QEvent::DragEnter: |
4256 | + q->dragEnterEvent(static_cast<QDragEnterEvent *>(e)); |
4257 | + break; |
4258 | + case QEvent::DragLeave: |
4259 | + q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e)); |
4260 | + break; |
4261 | + case QEvent::DragMove: |
4262 | + q->dragMoveEvent(static_cast<QDragMoveEvent *>(e)); |
4263 | + break; |
4264 | + case QEvent::Drop: |
4265 | + q->dropEvent(static_cast<QDropEvent *>(e)); |
4266 | + break; |
4267 | + } |
4268 | +} |
4269 | +#endif // QT_NO_DRAGANDDROP |
4270 | + |
4271 | +/*! |
4272 | + Called when \a change occurs for this item. |
4273 | + |
4274 | + \a value contains extra information relating to the change, when |
4275 | + applicable. |
4276 | + */ |
4277 | +void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value) |
4278 | +{ |
4279 | + Q_UNUSED(change); |
4280 | + Q_UNUSED(value); |
4281 | +} |
4282 | + |
4283 | +#ifndef QT_NO_IM |
4284 | +/*! |
4285 | + Notify input method on updated query values if needed. \a queries indicates |
4286 | + the changed attributes. |
4287 | +*/ |
4288 | +void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries) |
4289 | +{ |
4290 | + if (hasActiveFocus()) |
4291 | + qApp->inputMethod()->update(queries); |
4292 | +} |
4293 | +#endif // QT_NO_IM |
4294 | + |
4295 | +/*! \internal */ |
4296 | +// XXX todo - do we want/need this anymore? |
4297 | +QRectF QQuickItem::boundingRect() const |
4298 | +{ |
4299 | + Q_D(const QQuickItem); |
4300 | + return QRectF(0, 0, d->width, d->height); |
4301 | +} |
4302 | + |
4303 | +/*! \internal */ |
4304 | +QRectF QQuickItem::clipRect() const |
4305 | +{ |
4306 | + Q_D(const QQuickItem); |
4307 | + return QRectF(0, 0, d->width, d->height); |
4308 | +} |
4309 | + |
4310 | +/*! |
4311 | + \qmlproperty enumeration QtQuick2::Item::transformOrigin |
4312 | + This property holds the origin point around which scale and rotation transform. |
4313 | + |
4314 | + Nine transform origins are available, as shown in the image below. |
4315 | + The default transform origin is \c Item.Center. |
4316 | + |
4317 | + \image declarative-transformorigin.png |
4318 | + |
4319 | + This example rotates an image around its bottom-right corner. |
4320 | + \qml |
4321 | + Image { |
4322 | + source: "myimage.png" |
4323 | + transformOrigin: Item.BottomRight |
4324 | + rotation: 45 |
4325 | + } |
4326 | + \endqml |
4327 | + |
4328 | + To set an arbitrary transform origin point use the \l Scale or \l Rotation |
4329 | + transform types with \l transform. |
4330 | +*/ |
4331 | +/*! |
4332 | + \property QQuickItem::transformOrigin |
4333 | + This property holds the origin point around which scale and rotation transform. |
4334 | + |
4335 | + Nine transform origins are available, as shown in the image below. |
4336 | + The default transform origin is \c Item.Center. |
4337 | + |
4338 | + \image declarative-transformorigin.png |
4339 | +*/ |
4340 | +QQuickItem::TransformOrigin QQuickItem::transformOrigin() const |
4341 | +{ |
4342 | + Q_D(const QQuickItem); |
4343 | + return d->origin(); |
4344 | +} |
4345 | + |
4346 | +void QQuickItem::setTransformOrigin(TransformOrigin origin) |
4347 | +{ |
4348 | + Q_D(QQuickItem); |
4349 | + if (origin == d->origin()) |
4350 | + return; |
4351 | + |
4352 | + d->extra.value().origin = origin; |
4353 | + d->dirty(QQuickItemPrivate::TransformOrigin); |
4354 | + |
4355 | + emit transformOriginChanged(d->origin()); |
4356 | +} |
4357 | + |
4358 | +/*! |
4359 | + \property QQuickItem::transformOriginPoint |
4360 | + \internal |
4361 | + */ |
4362 | +/*! |
4363 | + \internal |
4364 | + */ |
4365 | +QPointF QQuickItem::transformOriginPoint() const |
4366 | +{ |
4367 | + Q_D(const QQuickItem); |
4368 | + if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull()) |
4369 | + return d->extra->userTransformOriginPoint; |
4370 | + return d->computeTransformOrigin(); |
4371 | +} |
4372 | + |
4373 | +/*! |
4374 | + \internal |
4375 | + */ |
4376 | +void QQuickItem::setTransformOriginPoint(const QPointF &point) |
4377 | +{ |
4378 | + Q_D(QQuickItem); |
4379 | + if (d->extra.value().userTransformOriginPoint == point) |
4380 | + return; |
4381 | + |
4382 | + d->extra->userTransformOriginPoint = point; |
4383 | + d->dirty(QQuickItemPrivate::TransformOrigin); |
4384 | +} |
4385 | + |
4386 | +/*! |
4387 | + \qmlproperty real QtQuick2::Item::z |
4388 | + |
4389 | + Sets the stacking order of sibling items. By default the stacking order is 0. |
4390 | + |
4391 | + Items with a higher stacking value are drawn on top of siblings with a |
4392 | + lower stacking order. Items with the same stacking value are drawn |
4393 | + bottom up in the order they appear. Items with a negative stacking |
4394 | + value are drawn under their parent's content. |
4395 | + |
4396 | + The following example shows the various effects of stacking order. |
4397 | + |
4398 | + \table |
4399 | + \row |
4400 | + \li \image declarative-item_stacking1.png |
4401 | + \li Same \c z - later children above earlier children: |
4402 | + \qml |
4403 | + Item { |
4404 | + Rectangle { |
4405 | + color: "red" |
4406 | + width: 100; height: 100 |
4407 | + } |
4408 | + Rectangle { |
4409 | + color: "blue" |
4410 | + x: 50; y: 50; width: 100; height: 100 |
4411 | + } |
4412 | + } |
4413 | + \endqml |
4414 | + \row |
4415 | + \li \image declarative-item_stacking2.png |
4416 | + \li Higher \c z on top: |
4417 | + \qml |
4418 | + Item { |
4419 | + Rectangle { |
4420 | + z: 1 |
4421 | + color: "red" |
4422 | + width: 100; height: 100 |
4423 | + } |
4424 | + Rectangle { |
4425 | + color: "blue" |
4426 | + x: 50; y: 50; width: 100; height: 100 |
4427 | + } |
4428 | + } |
4429 | + \endqml |
4430 | + \row |
4431 | + \li \image declarative-item_stacking3.png |
4432 | + \li Same \c z - children above parents: |
4433 | + \qml |
4434 | + Item { |
4435 | + Rectangle { |
4436 | + color: "red" |
4437 | + width: 100; height: 100 |
4438 | + Rectangle { |
4439 | + color: "blue" |
4440 | + x: 50; y: 50; width: 100; height: 100 |
4441 | + } |
4442 | + } |
4443 | + } |
4444 | + \endqml |
4445 | + \row |
4446 | + \li \image declarative-item_stacking4.png |
4447 | + \li Lower \c z below: |
4448 | + \qml |
4449 | + Item { |
4450 | + Rectangle { |
4451 | + color: "red" |
4452 | + width: 100; height: 100 |
4453 | + Rectangle { |
4454 | + z: -1 |
4455 | + color: "blue" |
4456 | + x: 50; y: 50; width: 100; height: 100 |
4457 | + } |
4458 | + } |
4459 | + } |
4460 | + \endqml |
4461 | + \endtable |
4462 | + */ |
4463 | +/*! |
4464 | + \property QQuickItem::z |
4465 | + |
4466 | + Sets the stacking order of sibling items. By default the stacking order is 0. |
4467 | + |
4468 | + Items with a higher stacking value are drawn on top of siblings with a |
4469 | + lower stacking order. Items with the same stacking value are drawn |
4470 | + bottom up in the order they appear. Items with a negative stacking |
4471 | + value are drawn under their parent's content. |
4472 | + |
4473 | + The following example shows the various effects of stacking order. |
4474 | + |
4475 | + \table |
4476 | + \row |
4477 | + \li \image declarative-item_stacking1.png |
4478 | + \li Same \c z - later children above earlier children: |
4479 | + \qml |
4480 | + Item { |
4481 | + Rectangle { |
4482 | + color: "red" |
4483 | + width: 100; height: 100 |
4484 | + } |
4485 | + Rectangle { |
4486 | + color: "blue" |
4487 | + x: 50; y: 50; width: 100; height: 100 |
4488 | + } |
4489 | + } |
4490 | + \endqml |
4491 | + \row |
4492 | + \li \image declarative-item_stacking2.png |
4493 | + \li Higher \c z on top: |
4494 | + \qml |
4495 | + Item { |
4496 | + Rectangle { |
4497 | + z: 1 |
4498 | + color: "red" |
4499 | + width: 100; height: 100 |
4500 | + } |
4501 | + Rectangle { |
4502 | + color: "blue" |
4503 | + x: 50; y: 50; width: 100; height: 100 |
4504 | + } |
4505 | + } |
4506 | + \endqml |
4507 | + \row |
4508 | + \li \image declarative-item_stacking3.png |
4509 | + \li Same \c z - children above parents: |
4510 | + \qml |
4511 | + Item { |
4512 | + Rectangle { |
4513 | + color: "red" |
4514 | + width: 100; height: 100 |
4515 | + Rectangle { |
4516 | + color: "blue" |
4517 | + x: 50; y: 50; width: 100; height: 100 |
4518 | + } |
4519 | + } |
4520 | + } |
4521 | + \endqml |
4522 | + \row |
4523 | + \li \image declarative-item_stacking4.png |
4524 | + \li Lower \c z below: |
4525 | + \qml |
4526 | + Item { |
4527 | + Rectangle { |
4528 | + color: "red" |
4529 | + width: 100; height: 100 |
4530 | + Rectangle { |
4531 | + z: -1 |
4532 | + color: "blue" |
4533 | + x: 50; y: 50; width: 100; height: 100 |
4534 | + } |
4535 | + } |
4536 | + } |
4537 | + \endqml |
4538 | + \endtable |
4539 | + */ |
4540 | +qreal QQuickItem::z() const |
4541 | +{ |
4542 | + Q_D(const QQuickItem); |
4543 | + return d->z(); |
4544 | +} |
4545 | + |
4546 | +void QQuickItem::setZ(qreal v) |
4547 | +{ |
4548 | + Q_D(QQuickItem); |
4549 | + if (d->z() == v) |
4550 | + return; |
4551 | + |
4552 | + d->extra.value().z = v; |
4553 | + |
4554 | + d->dirty(QQuickItemPrivate::ZValue); |
4555 | + if (d->parentItem) { |
4556 | + QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged); |
4557 | + QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this); |
4558 | + } |
4559 | + |
4560 | + emit zChanged(); |
4561 | + |
4562 | + if (d->extra.isAllocated() && d->extra->layer) |
4563 | + d->extra->layer->updateZ(); |
4564 | +} |
4565 | + |
4566 | +/*! |
4567 | + \qmlproperty real QtQuick2::Item::rotation |
4568 | + This property holds the rotation of the item in degrees clockwise around |
4569 | + its transformOrigin. |
4570 | + |
4571 | + The default value is 0 degrees (that is, no rotation). |
4572 | + |
4573 | + \table |
4574 | + \row |
4575 | + \li \image declarative-rotation.png |
4576 | + \li |
4577 | + \qml |
4578 | + Rectangle { |
4579 | + color: "blue" |
4580 | + width: 100; height: 100 |
4581 | + Rectangle { |
4582 | + color: "red" |
4583 | + x: 25; y: 25; width: 50; height: 50 |
4584 | + rotation: 30 |
4585 | + } |
4586 | + } |
4587 | + \endqml |
4588 | + \endtable |
4589 | + |
4590 | + \sa transform, Rotation |
4591 | +*/ |
4592 | +/*! |
4593 | + \property QQuickItem::rotation |
4594 | + This property holds the rotation of the item in degrees clockwise around |
4595 | + its transformOrigin. |
4596 | + |
4597 | + The default value is 0 degrees (that is, no rotation). |
4598 | + |
4599 | + \table |
4600 | + \row |
4601 | + \li \image declarative-rotation.png |
4602 | + \li |
4603 | + \qml |
4604 | + Rectangle { |
4605 | + color: "blue" |
4606 | + width: 100; height: 100 |
4607 | + Rectangle { |
4608 | + color: "red" |
4609 | + x: 25; y: 25; width: 50; height: 50 |
4610 | + rotation: 30 |
4611 | + } |
4612 | + } |
4613 | + \endqml |
4614 | + \endtable |
4615 | + |
4616 | + \sa transform, Rotation |
4617 | + */ |
4618 | +qreal QQuickItem::rotation() const |
4619 | +{ |
4620 | + Q_D(const QQuickItem); |
4621 | + return d->rotation(); |
4622 | +} |
4623 | + |
4624 | +void QQuickItem::setRotation(qreal r) |
4625 | +{ |
4626 | + Q_D(QQuickItem); |
4627 | + if (d->rotation() == r) |
4628 | + return; |
4629 | + |
4630 | + d->extra.value().rotation = r; |
4631 | + |
4632 | + d->dirty(QQuickItemPrivate::BasicTransform); |
4633 | + |
4634 | + d->itemChange(ItemRotationHasChanged, r); |
4635 | + |
4636 | + emit rotationChanged(); |
4637 | +} |
4638 | + |
4639 | +/*! |
4640 | + \qmlproperty real QtQuick2::Item::scale |
4641 | + This property holds the scale factor for this item. |
4642 | + |
4643 | + A scale of less than 1.0 causes the item to be rendered at a smaller |
4644 | + size, and a scale greater than 1.0 renders the item at a larger size. |
4645 | + A negative scale causes the item to be mirrored when rendered. |
4646 | + |
4647 | + The default value is 1.0. |
4648 | + |
4649 | + Scaling is applied from the transformOrigin. |
4650 | + |
4651 | + \table |
4652 | + \row |
4653 | + \li \image declarative-scale.png |
4654 | + \li |
4655 | + \qml |
4656 | + import QtQuick 2.0 |
4657 | + |
4658 | + Rectangle { |
4659 | + color: "blue" |
4660 | + width: 100; height: 100 |
4661 | + |
4662 | + Rectangle { |
4663 | + color: "green" |
4664 | + width: 25; height: 25 |
4665 | + } |
4666 | + |
4667 | + Rectangle { |
4668 | + color: "red" |
4669 | + x: 25; y: 25; width: 50; height: 50 |
4670 | + scale: 1.4 |
4671 | + } |
4672 | + } |
4673 | + \endqml |
4674 | + \endtable |
4675 | + |
4676 | + \sa transform, Scale |
4677 | +*/ |
4678 | +/*! |
4679 | + \property QQuickItem::scale |
4680 | + This property holds the scale factor for this item. |
4681 | + |
4682 | + A scale of less than 1.0 causes the item to be rendered at a smaller |
4683 | + size, and a scale greater than 1.0 renders the item at a larger size. |
4684 | + A negative scale causes the item to be mirrored when rendered. |
4685 | + |
4686 | + The default value is 1.0. |
4687 | + |
4688 | + Scaling is applied from the transformOrigin. |
4689 | + |
4690 | + \table |
4691 | + \row |
4692 | + \li \image declarative-scale.png |
4693 | + \li |
4694 | + \qml |
4695 | + import QtQuick 2.0 |
4696 | + |
4697 | + Rectangle { |
4698 | + color: "blue" |
4699 | + width: 100; height: 100 |
4700 | + |
4701 | + Rectangle { |
4702 | + color: "green" |
4703 | + width: 25; height: 25 |
4704 | + } |
4705 | + |
4706 | + Rectangle { |
4707 | + color: "red" |
4708 | + x: 25; y: 25; width: 50; height: 50 |
4709 | + scale: 1.4 |
4710 | + } |
4711 | + } |
4712 | + \endqml |
4713 | + \endtable |
4714 | + |
4715 | + \sa transform, Scale |
4716 | + */ |
4717 | +qreal QQuickItem::scale() const |
4718 | +{ |
4719 | + Q_D(const QQuickItem); |
4720 | + return d->scale(); |
4721 | +} |
4722 | + |
4723 | +void QQuickItem::setScale(qreal s) |
4724 | +{ |
4725 | + Q_D(QQuickItem); |
4726 | + if (d->scale() == s) |
4727 | + return; |
4728 | + |
4729 | + d->extra.value().scale = s; |
4730 | + |
4731 | + d->dirty(QQuickItemPrivate::BasicTransform); |
4732 | + |
4733 | + emit scaleChanged(); |
4734 | +} |
4735 | + |
4736 | +/*! |
4737 | + \qmlproperty real QtQuick2::Item::opacity |
4738 | + |
4739 | + This property holds the opacity of the item. Opacity is specified as a |
4740 | + number between 0.0 (fully transparent) and 1.0 (fully opaque). The default |
4741 | + value is 1.0. |
4742 | + |
4743 | + When this property is set, the specified opacity is also applied |
4744 | + individually to child items. This may have an unintended effect in some |
4745 | + circumstances. For example in the second set of rectangles below, the red |
4746 | + rectangle has specified an opacity of 0.5, which affects the opacity of |
4747 | + its blue child rectangle even though the child has not specified an opacity. |
4748 | + |
4749 | + \table |
4750 | + \row |
4751 | + \li \image declarative-item_opacity1.png |
4752 | + \li |
4753 | + \qml |
4754 | + Item { |
4755 | + Rectangle { |
4756 | + color: "red" |
4757 | + width: 100; height: 100 |
4758 | + Rectangle { |
4759 | + color: "blue" |
4760 | + x: 50; y: 50; width: 100; height: 100 |
4761 | + } |
4762 | + } |
4763 | + } |
4764 | + \endqml |
4765 | + \row |
4766 | + \li \image declarative-item_opacity2.png |
4767 | + \li |
4768 | + \qml |
4769 | + Item { |
4770 | + Rectangle { |
4771 | + opacity: 0.5 |
4772 | + color: "red" |
4773 | + width: 100; height: 100 |
4774 | + Rectangle { |
4775 | + color: "blue" |
4776 | + x: 50; y: 50; width: 100; height: 100 |
4777 | + } |
4778 | + } |
4779 | + } |
4780 | + \endqml |
4781 | + \endtable |
4782 | + |
4783 | + Changing an item's opacity does not affect whether the item receives user |
4784 | + input events. (In contrast, setting \l visible property to \c false stops |
4785 | + mouse events, and setting the \l enabled property to \c false stops mouse |
4786 | + and keyboard events, and also removes active focus from the item.) |
4787 | + |
4788 | + \sa visible |
4789 | +*/ |
4790 | +/*! |
4791 | + \property QQuickItem::opacity |
4792 | + |
4793 | + This property holds the opacity of the item. Opacity is specified as a |
4794 | + number between 0.0 (fully transparent) and 1.0 (fully opaque). The default |
4795 | + value is 1.0. |
4796 | + |
4797 | + When this property is set, the specified opacity is also applied |
4798 | + individually to child items. This may have an unintended effect in some |
4799 | + circumstances. For example in the second set of rectangles below, the red |
4800 | + rectangle has specified an opacity of 0.5, which affects the opacity of |
4801 | + its blue child rectangle even though the child has not specified an opacity. |
4802 | + |
4803 | + \table |
4804 | + \row |
4805 | + \li \image declarative-item_opacity1.png |
4806 | + \li |
4807 | + \qml |
4808 | + Item { |
4809 | + Rectangle { |
4810 | + color: "red" |
4811 | + width: 100; height: 100 |
4812 | + Rectangle { |
4813 | + color: "blue" |
4814 | + x: 50; y: 50; width: 100; height: 100 |
4815 | + } |
4816 | + } |
4817 | + } |
4818 | + \endqml |
4819 | + \row |
4820 | + \li \image declarative-item_opacity2.png |
4821 | + \li |
4822 | + \qml |
4823 | + Item { |
4824 | + Rectangle { |
4825 | + opacity: 0.5 |
4826 | + color: "red" |
4827 | + width: 100; height: 100 |
4828 | + Rectangle { |
4829 | + color: "blue" |
4830 | + x: 50; y: 50; width: 100; height: 100 |
4831 | + } |
4832 | + } |
4833 | + } |
4834 | + \endqml |
4835 | + \endtable |
4836 | + |
4837 | + Changing an item's opacity does not affect whether the item receives user |
4838 | + input events. (In contrast, setting \l visible property to \c false stops |
4839 | + mouse events, and setting the \l enabled property to \c false stops mouse |
4840 | + and keyboard events, and also removes active focus from the item.) |
4841 | + |
4842 | + \sa visible |
4843 | +*/ |
4844 | +qreal QQuickItem::opacity() const |
4845 | +{ |
4846 | + Q_D(const QQuickItem); |
4847 | + return d->opacity(); |
4848 | +} |
4849 | + |
4850 | +void QQuickItem::setOpacity(qreal o) |
4851 | +{ |
4852 | + Q_D(QQuickItem); |
4853 | + if (d->opacity() == o) |
4854 | + return; |
4855 | + |
4856 | + d->extra.value().opacity = o; |
4857 | + |
4858 | + d->dirty(QQuickItemPrivate::OpacityValue); |
4859 | + |
4860 | + d->itemChange(ItemOpacityHasChanged, o); |
4861 | + |
4862 | + emit opacityChanged(); |
4863 | +} |
4864 | + |
4865 | +/*! |
4866 | + \qmlproperty bool QtQuick2::Item::visible |
4867 | + |
4868 | + This property holds whether the item is visible. By default this is true. |
4869 | + |
4870 | + Setting this property directly affects the \c visible value of child |
4871 | + items. When set to \c false, the \c visible values of all child items also |
4872 | + become \c false. When set to \c true, the \c visible values of child items |
4873 | + are returned to \c true, unless they have explicitly been set to \c false. |
4874 | + |
4875 | + (Because of this flow-on behavior, using the \c visible property may not |
4876 | + have the intended effect if a property binding should only respond to |
4877 | + explicit property changes. In such cases it may be better to use the |
4878 | + \l opacity property instead.) |
4879 | + |
4880 | + If this property is set to \c false, the item will no longer receive mouse |
4881 | + events, but will continue to receive key events and will retain the keyboard |
4882 | + \l focus if it has been set. (In contrast, setting the \l enabled property |
4883 | + to \c false stops both mouse and keyboard events, and also removes focus |
4884 | + from the item.) |
4885 | + |
4886 | + \note This property's value is only affected by changes to this property or |
4887 | + the parent's \c visible property. It does not change, for example, if this |
4888 | + item moves off-screen, or if the \l opacity changes to 0. |
4889 | + |
4890 | + \sa opacity, enabled |
4891 | +*/ |
4892 | +/*! |
4893 | + \property QQuickItem::visible |
4894 | + |
4895 | + This property holds whether the item is visible. By default this is true. |
4896 | + |
4897 | + Setting this property directly affects the \c visible value of child |
4898 | + items. When set to \c false, the \c visible values of all child items also |
4899 | + become \c false. When set to \c true, the \c visible values of child items |
4900 | + are returned to \c true, unless they have explicitly been set to \c false. |
4901 | + |
4902 | + (Because of this flow-on behavior, using the \c visible property may not |
4903 | + have the intended effect if a property binding should only respond to |
4904 | + explicit property changes. In such cases it may be better to use the |
4905 | + \l opacity property instead.) |
4906 | + |
4907 | + If this property is set to \c false, the item will no longer receive mouse |
4908 | + events, but will continue to receive key events and will retain the keyboard |
4909 | + \l focus if it has been set. (In contrast, setting the \l enabled property |
4910 | + to \c false stops both mouse and keyboard events, and also removes focus |
4911 | + from the item.) |
4912 | + |
4913 | + \note This property's value is only affected by changes to this property or |
4914 | + the parent's \c visible property. It does not change, for example, if this |
4915 | + item moves off-screen, or if the \l opacity changes to 0. |
4916 | + |
4917 | + \sa opacity, enabled |
4918 | +*/ |
4919 | +bool QQuickItem::isVisible() const |
4920 | +{ |
4921 | + Q_D(const QQuickItem); |
4922 | + return d->effectiveVisible; |
4923 | +} |
4924 | + |
4925 | +void QQuickItem::setVisible(bool v) |
4926 | +{ |
4927 | + Q_D(QQuickItem); |
4928 | + if (v == d->explicitVisible) |
4929 | + return; |
4930 | + |
4931 | + d->explicitVisible = v; |
4932 | + if (!v) |
4933 | + d->dirty(QQuickItemPrivate::Visible); |
4934 | + |
4935 | + const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible()); |
4936 | + if (childVisibilityChanged && d->parentItem) |
4937 | + emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this! |
4938 | +} |
4939 | + |
4940 | +/*! |
4941 | + \qmlproperty bool QtQuick2::Item::enabled |
4942 | + |
4943 | + This property holds whether the item receives mouse and keyboard events. |
4944 | + By default this is true. |
4945 | + |
4946 | + Setting this property directly affects the \c enabled value of child |
4947 | + items. When set to \c false, the \c enabled values of all child items also |
4948 | + become \c false. When set to \c true, the \c enabled values of child items |
4949 | + are returned to \c true, unless they have explicitly been set to \c false. |
4950 | + |
4951 | + Setting this property to \c false automatically causes \l activeFocus to be |
4952 | + set to \c false, and this item will longer receive keyboard events. |
4953 | + |
4954 | + \sa visible |
4955 | +*/ |
4956 | +/*! |
4957 | + \property QQuickItem::enabled |
4958 | + |
4959 | + This property holds whether the item receives mouse and keyboard events. |
4960 | + By default this is true. |
4961 | + |
4962 | + Setting this property directly affects the \c enabled value of child |
4963 | + items. When set to \c false, the \c enabled values of all child items also |
4964 | + become \c false. When set to \c true, the \c enabled values of child items |
4965 | + are returned to \c true, unless they have explicitly been set to \c false. |
4966 | + |
4967 | + Setting this property to \c false automatically causes \l activeFocus to be |
4968 | + set to \c false, and this item will longer receive keyboard events. |
4969 | + |
4970 | + \sa visible |
4971 | +*/ |
4972 | +bool QQuickItem::isEnabled() const |
4973 | +{ |
4974 | + Q_D(const QQuickItem); |
4975 | + return d->effectiveEnable; |
4976 | +} |
4977 | + |
4978 | +void QQuickItem::setEnabled(bool e) |
4979 | +{ |
4980 | + Q_D(QQuickItem); |
4981 | + if (e == d->explicitEnable) |
4982 | + return; |
4983 | + |
4984 | + d->explicitEnable = e; |
4985 | + |
4986 | + QQuickItem *scope = parentItem(); |
4987 | + while (scope && !scope->isFocusScope()) |
4988 | + scope = scope->parentItem(); |
4989 | + |
4990 | + d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable()); |
4991 | +} |
4992 | + |
4993 | +bool QQuickItemPrivate::calcEffectiveVisible() const |
4994 | +{ |
4995 | + // XXX todo - Should the effective visible of an element with no parent just be the current |
4996 | + // effective visible? This would prevent pointless re-processing in the case of an element |
4997 | + // moving to/from a no-parent situation, but it is different from what graphics view does. |
4998 | + return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible); |
4999 | +} |
5000 | + |
The diff has been truncated for viewing.
For getting sponsored, the process would be to have this updated Qt version tested so that the "-autopilot" AP tests from http:// reports. qa.ubuntu. com/smokeng/ trusty/ touch/mako/ 24:20131119: 20131111. 1/5037/ are run to ensure there are no regressions. Some of the AP tests come from packages and some from click (https:/ /wiki.ubuntu. com/Touch/ Testing# Running_ Click_tests).