35 static bool intersect_rect(
const QGraphicsItem *item,
const QRectF &exposeRect, Qt::ItemSelectionMode mode,
36 const QTransform &deviceTransform,
const void *intersectData)
38 const QRectF sceneRect = *
static_cast<
const QRectF *>(intersectData);
40 QRectF brect = item->boundingRect();
41 _q_adjustRect(&brect);
47 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
48 if (itemd->itemIsUntransformable()) {
50 const QTransform transform = item->deviceTransform(deviceTransform);
51 QRectF itemRect = (deviceTransform * transform.inverted()).mapRect(sceneRect);
52 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
53 keep = itemRect.contains(brect) && itemRect != brect;
55 keep = itemRect.intersects(brect);
56 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
57 QPainterPath itemPath;
58 itemPath.addRect(itemRect);
59 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
62 Q_ASSERT(!itemd->dirtySceneTransform);
63 const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
64 ? brect.translated(itemd->sceneTransform.dx(),
65 itemd->sceneTransform.dy())
66 : itemd->sceneTransform.mapRect(brect);
67 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
68 keep = sceneRect != brect && sceneRect.contains(itemSceneBoundingRect);
70 keep = sceneRect.intersects(itemSceneBoundingRect);
71 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
72 QPainterPath rectPath;
73 rectPath.addRect(sceneRect);
74 if (itemd->sceneTransformTranslateOnly)
75 rectPath.translate(-itemd->sceneTransform.dx(), -itemd->sceneTransform.dy());
77 rectPath = itemd->sceneTransform.inverted().map(rectPath);
78 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, rectPath, mode);
84 static bool intersect_point(
const QGraphicsItem *item,
const QRectF &exposeRect, Qt::ItemSelectionMode mode,
85 const QTransform &deviceTransform,
const void *intersectData)
87 const QPointF scenePoint = *
static_cast<
const QPointF *>(intersectData);
89 QRectF brect = item->boundingRect();
90 _q_adjustRect(&brect);
96 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
97 if (itemd->itemIsUntransformable()) {
99 const QTransform transform = item->deviceTransform(deviceTransform);
100 QPointF itemPoint = (deviceTransform * transform.inverted()).map(scenePoint);
101 keep = brect.contains(itemPoint);
102 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
103 QPainterPath pointPath;
104 pointPath.addRect(QRectF(itemPoint, QSizeF(1, 1)));
105 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode);
108 Q_ASSERT(!itemd->dirtySceneTransform);
109 QRectF sceneBoundingRect = itemd->sceneTransformTranslateOnly
110 ? brect.translated(itemd->sceneTransform.dx(),
111 itemd->sceneTransform.dy())
112 : itemd->sceneTransform.mapRect(brect);
113 keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1)));
114 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
115 QPointF p = itemd->sceneTransformTranslateOnly
116 ? QPointF(scenePoint.x() - itemd->sceneTransform.dx(),
117 scenePoint.y() - itemd->sceneTransform.dy())
118 : itemd->sceneTransform.inverted().map(scenePoint);
119 keep = item->contains(p);
126 static bool intersect_path(
const QGraphicsItem *item,
const QRectF &exposeRect, Qt::ItemSelectionMode mode,
127 const QTransform &deviceTransform,
const void *intersectData)
129 const QPainterPath scenePath = *
static_cast<
const QPainterPath *>(intersectData);
131 QRectF brect = item->boundingRect();
132 _q_adjustRect(&brect);
135 Q_UNUSED(exposeRect);
138 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
139 if (itemd->itemIsUntransformable()) {
141 const QTransform transform = item->deviceTransform(deviceTransform);
142 QPainterPath itemPath = (deviceTransform * transform.inverted()).map(scenePath);
143 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
144 keep = itemPath.contains(brect);
146 keep = itemPath.intersects(brect);
147 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape))
148 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
150 Q_ASSERT(!itemd->dirtySceneTransform);
151 const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
152 ? brect.translated(itemd->sceneTransform.dx(),
153 itemd->sceneTransform.dy())
154 : itemd->sceneTransform.mapRect(brect);
155 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
156 keep = scenePath.contains(itemSceneBoundingRect);
158 keep = scenePath.intersects(itemSceneBoundingRect);
159 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
160 QPainterPath itemPath = itemd->sceneTransformTranslateOnly
161 ? scenePath.translated(-itemd->sceneTransform.dx(),
162 -itemd->sceneTransform.dy())
163 : itemd->sceneTransform.inverted().map(scenePath);
164 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
193 const QPainterPath &path,
194 Qt::ItemSelectionMode mode)
196 if (item->collidesWithPath(path, mode))
198 if (item->isWidget()) {
200 const QGraphicsWidget *widget =
static_cast<
const QGraphicsWidget *>(item);
201 if (widget->isWindow()) {
202 QRectF frameRect = widget->windowFrameRect();
203 QPainterPath framePath;
204 framePath.addRect(frameRect);
205 bool intersects = path.intersects(frameRect);
206 if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
207 return intersects || path.contains(frameRect.topLeft())
208 || framePath.contains(path.elementAt(0));
209 return !intersects && path.contains(frameRect.topLeft());
221 QList<QGraphicsItem *> *items,
222 const QTransform &viewTransform,
223 Qt::ItemSelectionMode mode,
224 qreal parentOpacity,
const void *intersectData)
const
227 if (!item->d_ptr->visible)
230 const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
231 const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
232 const bool itemHasChildren = !item->d_ptr->children.isEmpty();
233 if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
237 const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
238 const bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform && !itemIsUntransformable;
239 if (wasDirtyParentSceneTransform) {
240 item->d_ptr->updateSceneTransformFromParent();
241 Q_ASSERT(!item->d_ptr->dirtySceneTransform);
244 const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
245 || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape);
246 bool processItem = !itemIsFullyTransparent;
248 processItem = intersect(item, exposeRect, mode, viewTransform, intersectData);
249 if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) {
250 if (wasDirtyParentSceneTransform)
251 item->d_ptr->invalidateChildrenSceneTransform();
257 if (itemHasChildren) {
259 item->d_ptr->ensureSortedChildren();
262 if (itemClipsChildrenToShape && !itemIsUntransformable) {
263 QPainterPath mappedShape = item->d_ptr->sceneTransformTranslateOnly
264 ? item->shape().translated(item->d_ptr->sceneTransform.dx(),
265 item->d_ptr->sceneTransform.dy())
266 : item->d_ptr->sceneTransform.map(item->shape());
267 exposeRect &= mappedShape.controlPointRect();
271 for (i = 0; i < item->d_ptr->children.size(); ++i) {
272 QGraphicsItem *child = item->d_ptr->children.at(i);
273 if (wasDirtyParentSceneTransform)
274 child->d_ptr->dirtySceneTransform = 1;
275 if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
277 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
279 recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
280 mode, opacity, intersectData);
289 if (itemHasChildren) {
290 for (; i < item->d_ptr->children.size(); ++i) {
291 QGraphicsItem *child = item->d_ptr->children.at(i);
292 if (wasDirtyParentSceneTransform)
293 child->d_ptr->dirtySceneTransform = 1;
294 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
296 recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
297 mode, opacity, intersectData);
366QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPointF &pos, Qt::ItemSelectionMode mode,
367 Qt::SortOrder order,
const QTransform &deviceTransform)
const
370 Q_D(
const QGraphicsSceneIndex);
371 QList<QGraphicsItem *> itemList;
372 d->items_helper(QRectF(pos, QSizeF(1, 1)), &QtPrivate::intersect_point, &itemList, deviceTransform, mode, order, &pos);
398QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QRectF &rect, Qt::ItemSelectionMode mode,
399 Qt::SortOrder order,
const QTransform &deviceTransform)
const
401 Q_D(
const QGraphicsSceneIndex);
402 QRectF exposeRect = rect;
403 _q_adjustRect(&exposeRect);
404 QList<QGraphicsItem *> itemList;
405 d->items_helper(exposeRect, &QtPrivate::intersect_rect, &itemList, deviceTransform, mode, order, &rect);
431QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPolygonF &polygon, Qt::ItemSelectionMode mode,
432 Qt::SortOrder order,
const QTransform &deviceTransform)
const
434 Q_D(
const QGraphicsSceneIndex);
435 QList<QGraphicsItem *> itemList;
436 QRectF exposeRect = polygon.boundingRect();
437 _q_adjustRect(&exposeRect);
439 path.addPolygon(polygon);
440 d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
466QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPainterPath &path, Qt::ItemSelectionMode mode,
467 Qt::SortOrder order,
const QTransform &deviceTransform)
const
469 Q_D(
const QGraphicsSceneIndex);
470 QList<QGraphicsItem *> itemList;
471 QRectF exposeRect = path.controlPointRect();
472 _q_adjustRect(&exposeRect);
473 d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
486QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(
const QRectF &rect, Qt::SortOrder order)
const
488 Q_D(
const QGraphicsSceneIndex);
490 QGraphicsScenePrivate *scened = d->scene->d_func();
491 scened->ensureSortedTopLevelItems();
492 if (order == Qt::DescendingOrder) {
493 QList<QGraphicsItem *> sorted;
494 const int numTopLevelItems = scened->topLevelItems.size();
495 sorted.reserve(numTopLevelItems);
496 for (
int i = numTopLevelItems - 1; i >= 0; --i)
497 sorted << scened->topLevelItems.at(i);
500 return scened->topLevelItems;