33 static bool intersect_rect(
const QGraphicsItem *item,
const QRectF &exposeRect, Qt::ItemSelectionMode mode,
34 const QTransform &deviceTransform,
const void *intersectData)
36 const QRectF sceneRect = *
static_cast<
const QRectF *>(intersectData);
38 QRectF brect = item->boundingRect();
39 _q_adjustRect(&brect);
45 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
46 if (itemd->itemIsUntransformable()) {
48 const QTransform transform = item->deviceTransform(deviceTransform);
49 QRectF itemRect = (deviceTransform * transform.inverted()).mapRect(sceneRect);
50 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
51 keep = itemRect.contains(brect) && itemRect != brect;
53 keep = itemRect.intersects(brect);
54 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
55 QPainterPath itemPath;
56 itemPath.addRect(itemRect);
57 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
60 Q_ASSERT(!itemd->dirtySceneTransform);
61 const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
62 ? brect.translated(itemd->sceneTransform.dx(),
63 itemd->sceneTransform.dy())
64 : itemd->sceneTransform.mapRect(brect);
65 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
66 keep = sceneRect != brect && sceneRect.contains(itemSceneBoundingRect);
68 keep = sceneRect.intersects(itemSceneBoundingRect);
69 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
70 QPainterPath rectPath;
71 rectPath.addRect(sceneRect);
72 if (itemd->sceneTransformTranslateOnly)
73 rectPath.translate(-itemd->sceneTransform.dx(), -itemd->sceneTransform.dy());
75 rectPath = itemd->sceneTransform.inverted().map(rectPath);
76 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, rectPath, mode);
82 static bool intersect_point(
const QGraphicsItem *item,
const QRectF &exposeRect, Qt::ItemSelectionMode mode,
83 const QTransform &deviceTransform,
const void *intersectData)
85 const QPointF scenePoint = *
static_cast<
const QPointF *>(intersectData);
87 QRectF brect = item->boundingRect();
88 _q_adjustRect(&brect);
94 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
95 if (itemd->itemIsUntransformable()) {
97 const QTransform transform = item->deviceTransform(deviceTransform);
98 QPointF itemPoint = (deviceTransform * transform.inverted()).map(scenePoint);
99 keep = brect.contains(itemPoint);
100 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
101 QPainterPath pointPath;
102 pointPath.addRect(QRectF(itemPoint, QSizeF(1, 1)));
103 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode);
106 Q_ASSERT(!itemd->dirtySceneTransform);
107 QRectF sceneBoundingRect = itemd->sceneTransformTranslateOnly
108 ? brect.translated(itemd->sceneTransform.dx(),
109 itemd->sceneTransform.dy())
110 : itemd->sceneTransform.mapRect(brect);
111 keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1)));
112 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
113 QPointF p = itemd->sceneTransformTranslateOnly
114 ? QPointF(scenePoint.x() - itemd->sceneTransform.dx(),
115 scenePoint.y() - itemd->sceneTransform.dy())
116 : itemd->sceneTransform.inverted().map(scenePoint);
117 keep = item->contains(p);
124 static bool intersect_path(
const QGraphicsItem *item,
const QRectF &exposeRect, Qt::ItemSelectionMode mode,
125 const QTransform &deviceTransform,
const void *intersectData)
127 const QPainterPath scenePath = *
static_cast<
const QPainterPath *>(intersectData);
129 QRectF brect = item->boundingRect();
130 _q_adjustRect(&brect);
133 Q_UNUSED(exposeRect);
136 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
137 if (itemd->itemIsUntransformable()) {
139 const QTransform transform = item->deviceTransform(deviceTransform);
140 QPainterPath itemPath = (deviceTransform * transform.inverted()).map(scenePath);
141 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
142 keep = itemPath.contains(brect);
144 keep = itemPath.intersects(brect);
145 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape))
146 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
148 Q_ASSERT(!itemd->dirtySceneTransform);
149 const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
150 ? brect.translated(itemd->sceneTransform.dx(),
151 itemd->sceneTransform.dy())
152 : itemd->sceneTransform.mapRect(brect);
153 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
154 keep = scenePath.contains(itemSceneBoundingRect);
156 keep = scenePath.intersects(itemSceneBoundingRect);
157 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
158 QPainterPath itemPath = itemd->sceneTransformTranslateOnly
159 ? scenePath.translated(-itemd->sceneTransform.dx(),
160 -itemd->sceneTransform.dy())
161 : itemd->sceneTransform.inverted().map(scenePath);
162 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
191 const QPainterPath &path,
192 Qt::ItemSelectionMode mode)
194 if (item->collidesWithPath(path, mode))
196 if (item->isWidget()) {
198 const QGraphicsWidget *widget =
static_cast<
const QGraphicsWidget *>(item);
199 if (widget->isWindow()) {
200 QRectF frameRect = widget->windowFrameRect();
201 QPainterPath framePath;
202 framePath.addRect(frameRect);
203 bool intersects = path.intersects(frameRect);
204 if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
205 return intersects || path.contains(frameRect.topLeft())
206 || framePath.contains(path.elementAt(0));
207 return !intersects && path.contains(frameRect.topLeft());
219 QList<QGraphicsItem *> *items,
220 const QTransform &viewTransform,
221 Qt::ItemSelectionMode mode,
222 qreal parentOpacity,
const void *intersectData)
const
225 if (!item->d_ptr->visible)
228 const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
229 const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
230 const bool itemHasChildren = !item->d_ptr->children.isEmpty();
231 if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
235 const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
236 const bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform && !itemIsUntransformable;
237 if (wasDirtyParentSceneTransform) {
238 item->d_ptr->updateSceneTransformFromParent();
239 Q_ASSERT(!item->d_ptr->dirtySceneTransform);
242 const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
243 || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape);
244 bool processItem = !itemIsFullyTransparent;
246 processItem = intersect(item, exposeRect, mode, viewTransform, intersectData);
247 if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) {
248 if (wasDirtyParentSceneTransform)
249 item->d_ptr->invalidateChildrenSceneTransform();
255 if (itemHasChildren) {
257 item->d_ptr->ensureSortedChildren();
260 if (itemClipsChildrenToShape && !itemIsUntransformable) {
261 QPainterPath mappedShape = item->d_ptr->sceneTransformTranslateOnly
262 ? item->shape().translated(item->d_ptr->sceneTransform.dx(),
263 item->d_ptr->sceneTransform.dy())
264 : item->d_ptr->sceneTransform.map(item->shape());
265 exposeRect &= mappedShape.controlPointRect();
269 for (i = 0; i < item->d_ptr->children.size(); ++i) {
270 QGraphicsItem *child = item->d_ptr->children.at(i);
271 if (wasDirtyParentSceneTransform)
272 child->d_ptr->dirtySceneTransform = 1;
273 if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
275 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
277 recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
278 mode, opacity, intersectData);
287 if (itemHasChildren) {
288 for (; i < item->d_ptr->children.size(); ++i) {
289 QGraphicsItem *child = item->d_ptr->children.at(i);
290 if (wasDirtyParentSceneTransform)
291 child->d_ptr->dirtySceneTransform = 1;
292 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
294 recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
295 mode, opacity, intersectData);
364QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPointF &pos, Qt::ItemSelectionMode mode,
365 Qt::SortOrder order,
const QTransform &deviceTransform)
const
368 Q_D(
const QGraphicsSceneIndex);
369 QList<QGraphicsItem *> itemList;
370 d->items_helper(QRectF(pos, QSizeF(1, 1)), &QtPrivate::intersect_point, &itemList, deviceTransform, mode, order, &pos);
396QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QRectF &rect, Qt::ItemSelectionMode mode,
397 Qt::SortOrder order,
const QTransform &deviceTransform)
const
399 Q_D(
const QGraphicsSceneIndex);
400 QRectF exposeRect = rect;
401 _q_adjustRect(&exposeRect);
402 QList<QGraphicsItem *> itemList;
403 d->items_helper(exposeRect, &QtPrivate::intersect_rect, &itemList, deviceTransform, mode, order, &rect);
429QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPolygonF &polygon, Qt::ItemSelectionMode mode,
430 Qt::SortOrder order,
const QTransform &deviceTransform)
const
432 Q_D(
const QGraphicsSceneIndex);
433 QList<QGraphicsItem *> itemList;
434 QRectF exposeRect = polygon.boundingRect();
435 _q_adjustRect(&exposeRect);
437 path.addPolygon(polygon);
438 d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
464QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPainterPath &path, Qt::ItemSelectionMode mode,
465 Qt::SortOrder order,
const QTransform &deviceTransform)
const
467 Q_D(
const QGraphicsSceneIndex);
468 QList<QGraphicsItem *> itemList;
469 QRectF exposeRect = path.controlPointRect();
470 _q_adjustRect(&exposeRect);
471 d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
484QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(
const QRectF &rect, Qt::SortOrder order)
const
486 Q_D(
const QGraphicsSceneIndex);
488 QGraphicsScenePrivate *scened = d->scene->d_func();
489 scened->ensureSortedTopLevelItems();
490 if (order == Qt::DescendingOrder) {
491 QList<QGraphicsItem *> sorted;
492 const int numTopLevelItems = scened->topLevelItems.size();
493 sorted.reserve(numTopLevelItems);
494 for (
int i = numTopLevelItems - 1; i >= 0; --i)
495 sorted << scened->topLevelItems.at(i);
498 return scened->topLevelItems;