Make *ItemBoundingRect modes work with custom shapes.
Currently, calling QGraphicsScene::items(QPointF(0, 0), Qt::IntersectsItemBoundingRect) or QGraphicsScene::items(QPointF(0, 0), Qt::ContainsItemBoundingRect) will exclude items whose shape does not contain QPointF(0, 0). This is because QGraphicsSceneIndexPointIntersector::intersect() also checks if the point is contained within the shape, instead of just checking if it is contained within the bounding rect. Task-number: QTBUG-19036 Change-Id: Ie701af2a5694d40cf9b3c9c19adbb09a53a4e398 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Andreas Aardal Hanssen <andreas@hanssen.name>
This commit is contained in:
parent
9b8b6c7db8
commit
5ec344cc77
@ -151,7 +151,7 @@ public:
|
|||||||
itemd->sceneTransform.dy())
|
itemd->sceneTransform.dy())
|
||||||
: itemd->sceneTransform.mapRect(brect);
|
: itemd->sceneTransform.mapRect(brect);
|
||||||
keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1)));
|
keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1)));
|
||||||
if (keep) {
|
if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
|
||||||
QPointF p = itemd->sceneTransformTranslateOnly
|
QPointF p = itemd->sceneTransformTranslateOnly
|
||||||
? QPointF(scenePoint.x() - itemd->sceneTransform.dx(),
|
? QPointF(scenePoint.x() - itemd->sceneTransform.dx(),
|
||||||
scenePoint.y() - itemd->sceneTransform.dy())
|
scenePoint.y() - itemd->sceneTransform.dy())
|
||||||
|
@ -61,6 +61,8 @@ private slots:
|
|||||||
void movingItems();
|
void movingItems();
|
||||||
void connectedToSceneRectChanged();
|
void connectedToSceneRectChanged();
|
||||||
void items();
|
void items();
|
||||||
|
void boundingRectPointIntersection_data();
|
||||||
|
void boundingRectPointIntersection();
|
||||||
void removeItems();
|
void removeItems();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
@ -233,6 +235,56 @@ void tst_QGraphicsSceneIndex::items()
|
|||||||
QCOMPARE(scene.items().size(), 3);
|
QCOMPARE(scene.items().size(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CustomShapeItem : public QGraphicsItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CustomShapeItem(const QPainterPath &shape) : QGraphicsItem(0), mShape(shape) {}
|
||||||
|
|
||||||
|
QPainterPath shape() const { return mShape; }
|
||||||
|
QRectF boundingRect() const { return mShape.boundingRect(); }
|
||||||
|
void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) {}
|
||||||
|
private:
|
||||||
|
QPainterPath mShape;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Qt::ItemSelectionMode)
|
||||||
|
Q_DECLARE_METATYPE(QPainterPath)
|
||||||
|
|
||||||
|
void tst_QGraphicsSceneIndex::boundingRectPointIntersection_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QPainterPath>("itemShape");
|
||||||
|
QTest::addColumn<Qt::ItemSelectionMode>("mode");
|
||||||
|
|
||||||
|
QTest::newRow("zero shape - intersects rect") << QPainterPath() << Qt::IntersectsItemBoundingRect;
|
||||||
|
QTest::newRow("zero shape - contains rect") << QPainterPath() << Qt::ContainsItemBoundingRect;
|
||||||
|
|
||||||
|
QPainterPath triangle;
|
||||||
|
triangle.moveTo(50, 0);
|
||||||
|
triangle.lineTo(0, 50);
|
||||||
|
triangle.lineTo(100, 50);
|
||||||
|
triangle.lineTo(50, 0);
|
||||||
|
QTest::newRow("triangle shape - intersects rect") << triangle << Qt::IntersectsItemBoundingRect;
|
||||||
|
QTest::newRow("triangle shape - contains rect") << triangle << Qt::ContainsItemBoundingRect;
|
||||||
|
|
||||||
|
QPainterPath rect;
|
||||||
|
rect.addRect(QRectF(0, 0, 100, 100));
|
||||||
|
QTest::newRow("rectangle shape - intersects rect") << rect << Qt::IntersectsItemBoundingRect;
|
||||||
|
QTest::newRow("rectangle shape - contains rect") << rect << Qt::ContainsItemBoundingRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QGraphicsSceneIndex::boundingRectPointIntersection()
|
||||||
|
{
|
||||||
|
QFETCH(QPainterPath, itemShape);
|
||||||
|
QFETCH(Qt::ItemSelectionMode, mode);
|
||||||
|
|
||||||
|
QGraphicsScene scene;
|
||||||
|
CustomShapeItem *item = new CustomShapeItem(itemShape);
|
||||||
|
scene.addItem(item);
|
||||||
|
QList<QGraphicsItem*> items = scene.items(QPointF(0, 0), mode, Qt::AscendingOrder);
|
||||||
|
QVERIFY(!items.isEmpty());
|
||||||
|
QCOMPARE(items.first(), item);
|
||||||
|
}
|
||||||
|
|
||||||
class RectWidget : public QGraphicsWidget
|
class RectWidget : public QGraphicsWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Loading…
Reference in New Issue
Block a user