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.mapRect(brect);
|
||||
keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1)));
|
||||
if (keep) {
|
||||
if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
|
||||
QPointF p = itemd->sceneTransformTranslateOnly
|
||||
? QPointF(scenePoint.x() - itemd->sceneTransform.dx(),
|
||||
scenePoint.y() - itemd->sceneTransform.dy())
|
||||
|
@ -61,6 +61,8 @@ private slots:
|
||||
void movingItems();
|
||||
void connectedToSceneRectChanged();
|
||||
void items();
|
||||
void boundingRectPointIntersection_data();
|
||||
void boundingRectPointIntersection();
|
||||
void removeItems();
|
||||
void clear();
|
||||
|
||||
@ -233,6 +235,56 @@ void tst_QGraphicsSceneIndex::items()
|
||||
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
|
||||
{
|
||||
Q_OBJECT
|
||||
|
Loading…
Reference in New Issue
Block a user