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);
197 const QPainterPath &path,
198 Qt::ItemSelectionMode mode)
200 if (item->collidesWithPath(path, mode))
202 if (item->isWidget()) {
204 const QGraphicsWidget *widget =
static_cast<
const QGraphicsWidget *>(item);
205 if (widget->isWindow()) {
206 QRectF frameRect = widget->windowFrameRect();
207 QPainterPath framePath;
208 framePath.addRect(frameRect);
209 bool intersects = path.intersects(frameRect);
210 if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
211 return intersects || path.contains(frameRect.topLeft())
212 || framePath.contains(path.elementAt(0));
213 return !intersects && path.contains(frameRect.topLeft());
225 QList<QGraphicsItem *> *items,
226 const QTransform &viewTransform,
227 Qt::ItemSelectionMode mode,
228 qreal parentOpacity,
const void *intersectData)
const
231 if (!item->d_ptr->visible)
234 const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
235 const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
236 const bool itemHasChildren = !item->d_ptr->children.isEmpty();
237 if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
241 const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
242 const bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform && !itemIsUntransformable;
243 if (wasDirtyParentSceneTransform) {
244 item->d_ptr->updateSceneTransformFromParent();
245 Q_ASSERT(!item->d_ptr->dirtySceneTransform);
248 const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
249 || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape);
250 bool processItem = !itemIsFullyTransparent;
252 processItem = intersect(item, exposeRect, mode, viewTransform, intersectData);
253 if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) {
254 if (wasDirtyParentSceneTransform)
255 item->d_ptr->invalidateChildrenSceneTransform();
261 if (itemHasChildren) {
263 item->d_ptr->ensureSortedChildren();
266 if (itemClipsChildrenToShape && !itemIsUntransformable) {
267 QPainterPath mappedShape = item->d_ptr->sceneTransformTranslateOnly
268 ? item->shape().translated(item->d_ptr->sceneTransform.dx(),
269 item->d_ptr->sceneTransform.dy())
270 : item->d_ptr->sceneTransform.map(item->shape());
271 exposeRect &= mappedShape.controlPointRect();
275 for (i = 0; i < item->d_ptr->children.size(); ++i) {
276 QGraphicsItem *child = item->d_ptr->children.at(i);
277 if (wasDirtyParentSceneTransform)
278 child->d_ptr->dirtySceneTransform = 1;
279 if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
281 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
283 recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
284 mode, opacity, intersectData);
293 if (itemHasChildren) {
294 for (; i < item->d_ptr->children.size(); ++i) {
295 QGraphicsItem *child = item->d_ptr->children.at(i);
296 if (wasDirtyParentSceneTransform)
297 child->d_ptr->dirtySceneTransform = 1;
298 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
300 recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
301 mode, opacity, intersectData);
370QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPointF &pos, Qt::ItemSelectionMode mode,
371 Qt::SortOrder order,
const QTransform &deviceTransform)
const
374 Q_D(
const QGraphicsSceneIndex);
375 QList<QGraphicsItem *> itemList;
376 d->items_helper(QRectF(pos, QSizeF(1, 1)), &QtPrivate::intersect_point, &itemList, deviceTransform, mode, order, &pos);
402QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QRectF &rect, Qt::ItemSelectionMode mode,
403 Qt::SortOrder order,
const QTransform &deviceTransform)
const
405 Q_D(
const QGraphicsSceneIndex);
406 QRectF exposeRect = rect;
407 _q_adjustRect(&exposeRect);
408 QList<QGraphicsItem *> itemList;
409 d->items_helper(exposeRect, &QtPrivate::intersect_rect, &itemList, deviceTransform, mode, order, &rect);
435QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPolygonF &polygon, Qt::ItemSelectionMode mode,
436 Qt::SortOrder order,
const QTransform &deviceTransform)
const
438 Q_D(
const QGraphicsSceneIndex);
439 QList<QGraphicsItem *> itemList;
440 QRectF exposeRect = polygon.boundingRect();
441 _q_adjustRect(&exposeRect);
443 path.addPolygon(polygon);
444 d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
470QList<QGraphicsItem *> QGraphicsSceneIndex::items(
const QPainterPath &path, Qt::ItemSelectionMode mode,
471 Qt::SortOrder order,
const QTransform &deviceTransform)
const
473 Q_D(
const QGraphicsSceneIndex);
474 QList<QGraphicsItem *> itemList;
475 QRectF exposeRect = path.controlPointRect();
476 _q_adjustRect(&exposeRect);
477 d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
490QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(
const QRectF &rect, Qt::SortOrder order)
const
492 Q_D(
const QGraphicsSceneIndex);
494 QGraphicsScenePrivate *scened = d->scene->d_func();
495 scened->ensureSortedTopLevelItems();
496 if (order == Qt::DescendingOrder) {
497 QList<QGraphicsItem *> sorted;
498 const int numTopLevelItems = scened->topLevelItems.size();
499 sorted.reserve(numTopLevelItems);
500 for (
int i = numTopLevelItems - 1; i >= 0; --i)
501 sorted << scened->topLevelItems.at(i);
504 return scened->topLevelItems;