1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTestWidgets>
31#include <QtWidgets/qdesktopwidget.h>
32#include <QtWidgets/qgraphicseffect.h>
33#include <QtWidgets/qgraphicsview.h>
34#include <QtWidgets/qgraphicsscene.h>
35#include <QtWidgets/qgraphicsitem.h>
36#include <QtWidgets/qgraphicswidget.h>
37#include <QtWidgets/qstyleoption.h>
38
39#include <private/qgraphicseffect_p.h>
40
41class tst_QGraphicsEffect : public QObject
42{
43 Q_OBJECT
44public slots:
45 void initTestCase();
46
47private slots:
48 void setEnabled();
49 void source();
50 void boundingRectFor();
51 void boundingRect();
52 void boundingRect2();
53 void draw();
54 void opacity();
55 void grayscale();
56 void colorize();
57 void drawPixmapItem();
58 void deviceCoordinateTranslateCaching();
59 void inheritOpacity();
60 void dropShadowClipping();
61 void childrenVisibilityShouldInvalidateCache();
62 void prepareGeometryChangeInvalidateCache();
63 void itemHasNoContents();
64};
65
66void tst_QGraphicsEffect::initTestCase()
67{}
68
69class CustomItem : public QGraphicsRectItem
70{
71public:
72 CustomItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = 0)
73 : QGraphicsRectItem(x, y, width, height, parent), numRepaints(0),
74 m_painter(0), m_styleOption(0)
75 {}
76
77 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
78 {
79 m_painter = painter;
80 m_styleOption = option;
81 ++numRepaints;
82 QGraphicsRectItem::paint(painter, option, widget);
83 }
84
85 void reset()
86 {
87 numRepaints = 0;
88 m_painter = 0;
89 m_styleOption = 0;
90 }
91
92 int numRepaints;
93 QPainter *m_painter;
94 const QStyleOption *m_styleOption;
95};
96
97class CustomEffect : public QGraphicsEffect
98{
99public:
100 CustomEffect()
101 : QGraphicsEffect(), numRepaints(0), m_margin(10),
102 doNothingInDraw(false), m_painter(0), m_styleOption(0), m_source(0), m_opacity(1.0)
103 {}
104
105 QRectF boundingRectFor(const QRectF &rect) const
106 { return rect.adjusted(-m_margin, -m_margin, m_margin, m_margin); }
107
108 void reset()
109 {
110 numRepaints = 0;
111 m_sourceChangedFlags = QGraphicsEffect::ChangeFlags();
112 m_painter = 0;
113 m_styleOption = 0;
114 m_source = 0;
115 m_opacity = 1.0;
116 }
117
118 void setMargin(int margin)
119 {
120 m_margin = margin;
121 updateBoundingRect();
122 }
123
124 int margin() const
125 { return m_margin; }
126
127 void draw(QPainter *painter)
128 {
129 ++numRepaints;
130 if (doNothingInDraw)
131 return;
132 m_source = source();
133 m_painter = painter;
134 m_styleOption = source()->styleOption();
135 m_opacity = painter->opacity();
136 drawSource(painter);
137 }
138
139 void sourceChanged(QGraphicsEffect::ChangeFlags flags)
140 { m_sourceChangedFlags |= flags; }
141
142 int numRepaints;
143 int m_margin;
144 QGraphicsEffect::ChangeFlags m_sourceChangedFlags;
145 bool doNothingInDraw;
146 QPainter *m_painter;
147 const QStyleOption *m_styleOption;
148 QGraphicsEffectSource *m_source;
149 qreal m_opacity;
150};
151
152void tst_QGraphicsEffect::setEnabled()
153{
154 CustomEffect effect;
155 QVERIFY(effect.isEnabled());
156
157 effect.setEnabled(false);
158 QVERIFY(!effect.isEnabled());
159}
160
161void tst_QGraphicsEffect::source()
162{
163 QPointer<CustomEffect> effect = new CustomEffect;
164 QVERIFY(!effect->source());
165 QVERIFY(!effect->m_sourceChangedFlags);
166
167 // Install effect on QGraphicsItem.
168 QGraphicsItem *item = new QGraphicsRectItem(0, 0, 10, 10);
169 item->setGraphicsEffect(effect);
170 QVERIFY(effect->source());
171 QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
172 QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceAttached);
173 effect->reset();
174
175 // Make sure disabling/enabling the effect doesn't change the source.
176 effect->setEnabled(false);
177 QVERIFY(effect->source());
178 QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
179 QVERIFY(!effect->m_sourceChangedFlags);
180 effect->reset();
181
182 effect->setEnabled(true);
183 QVERIFY(effect->source());
184 QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
185 QVERIFY(!effect->m_sourceChangedFlags);
186 effect->reset();
187
188 // Uninstall effect on QGraphicsItem.
189 effect->reset();
190 item->setGraphicsEffect(0);
191 QVERIFY(!effect);
192 effect = new CustomEffect;
193
194 // The item takes ownership and should delete the effect when destroyed.
195 item->setGraphicsEffect(effect);
196 QPointer<QGraphicsEffectSource> source = effect->source();
197 QVERIFY(source);
198 QCOMPARE(source->graphicsItem(), (const QGraphicsItem*)item);
199 delete item;
200 QVERIFY(!effect);
201 QVERIFY(!source);
202}
203
204void tst_QGraphicsEffect::boundingRectFor()
205{
206 CustomEffect effect;
207 int margin = effect.margin();
208 const QRectF source(0, 0, 100, 100);
209 QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
210
211 effect.setMargin(margin = 20);
212 QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
213}
214
215void tst_QGraphicsEffect::boundingRect()
216{
217 // No source; empty bounding rect.
218 CustomEffect *effect = new CustomEffect;
219 QCOMPARE(effect->boundingRect(), QRectF());
220
221 // Install effect on QGraphicsItem.
222 QRectF itemRect(0, 0, 100, 100);
223 QGraphicsRectItem *item = new QGraphicsRectItem;
224 item->setPen(QPen(Qt::black, 0));
225 item->setRect(itemRect);
226 item->setGraphicsEffect(effect);
227 int margin = effect->margin();
228 QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
229 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
230
231 // Make sure disabling/enabling the effect doesn't change the bounding rect.
232 effect->setEnabled(false);
233 QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
234 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
235 effect->setEnabled(true);
236 QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
237 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
238
239 // Change effect margins.
240 effect->setMargin(margin = 20);
241 QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
242 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
243
244 // Uninstall effect on QGraphicsItem.
245 QPointer<CustomEffect> ptr = effect;
246 item->setGraphicsEffect(0);
247 QVERIFY(!ptr);
248
249 delete item;
250}
251
252void tst_QGraphicsEffect::boundingRect2()
253{
254 CustomEffect *effect = new CustomEffect;
255 QGraphicsRectItem *root = new QGraphicsRectItem;
256 root->setPen(QPen(Qt::black, 0));
257 root->setGraphicsEffect(effect);
258
259 QGraphicsRectItem *child = new QGraphicsRectItem;
260 QRectF childRect(0, 0, 100, 100);
261 child->setPen(QPen(Qt::black, 0));
262 child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
263 child->setRect(childRect);
264 child->setParentItem(root);
265
266 QGraphicsRectItem *grandChild = new QGraphicsRectItem;
267 QRectF grandChildRect(0, 0, 200, 200);
268 grandChild->setPen(QPen(Qt::black, 0));
269 grandChild->setRect(grandChildRect);
270 grandChild->setParentItem(child);
271
272 // Make sure the effect's bounding rect is clipped to the child's bounding rect.
273 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
274
275 // Disable ItemClipsChildrenToShape; effect's bounding rect is no longer clipped.
276 child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
277 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
278
279 // Add root item to a scene, do the same tests as above. Results should be the same.
280 QGraphicsScene scene;
281 scene.addItem(root);
282
283 child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
284 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
285
286 child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
287 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
288
289 // Now add the scene to a view, results should be the same.
290 QGraphicsView view(&scene);
291
292 child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
293 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
294
295 child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
296 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
297
298 CustomEffect *childEffect = new CustomEffect;
299 child->setGraphicsEffect(childEffect);
300 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childEffect->boundingRectFor(childRect | grandChildRect)));
301
302 child->setGraphicsEffect(0);
303 QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
304}
305
306void tst_QGraphicsEffect::draw()
307{
308 QGraphicsScene scene;
309 CustomItem *item = new CustomItem(0, 0, 100, 100);
310 scene.addItem(item);
311
312 QGraphicsView view(&scene);
313 view.show();
314 QVERIFY(QTest::qWaitForWindowActive(&view));
315 QTRY_VERIFY(item->numRepaints > 0);
316 QCoreApplication::processEvents(); // Process all queued paint events
317 item->reset();
318
319 // Make sure installing the effect triggers a repaint.
320 CustomEffect *effect = new CustomEffect;
321 item->setGraphicsEffect(effect);
322 QTRY_COMPARE(effect->numRepaints, 1);
323 QTRY_COMPARE(item->numRepaints, 1);
324
325 // Make sure QPainter* and QStyleOptionGraphicsItem* stays persistent
326 // during QGraphicsEffect::draw/QGraphicsItem::paint.
327 QVERIFY(effect->m_painter);
328 QCOMPARE(effect->m_painter, item->m_painter);
329 QCOMPARE(effect->m_styleOption, item->m_styleOption);
330 // Make sure QGraphicsEffect::source is persistent.
331 QCOMPARE(effect->m_source, effect->source());
332 effect->reset();
333 item->reset();
334
335 // Make sure updating the source triggers a repaint.
336 item->update();
337 QTRY_COMPARE(effect->numRepaints, 1);
338 QTRY_COMPARE(item->numRepaints, 1);
339 QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceInvalidated);
340 effect->reset();
341 item->reset();
342
343 // Make sure changing the effect's bounding rect triggers a repaint.
344 effect->setMargin(20);
345 QTRY_COMPARE(effect->numRepaints, 1);
346 QTRY_COMPARE(item->numRepaints, 1);
347 effect->reset();
348 item->reset();
349
350 // Make sure change the item's bounding rect triggers a repaint.
351 item->setRect(0, 0, 50, 50);
352 QTRY_COMPARE(effect->numRepaints, 1);
353 QTRY_COMPARE(item->numRepaints, 1);
354 QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceBoundingRectChanged);
355 effect->reset();
356 item->reset();
357
358 // Make sure the effect is the one to issue a repaint of the item.
359 effect->doNothingInDraw = true;
360 item->update();
361 QTRY_COMPARE(effect->numRepaints, 1);
362 QCOMPARE(item->numRepaints, 0);
363 effect->doNothingInDraw = false;
364 effect->reset();
365 item->reset();
366
367 // Make sure we update the source when disabling/enabling the effect.
368 effect->setEnabled(false);
369 QTRY_COMPARE(item->numRepaints, 1);
370 QCOMPARE(effect->numRepaints, 0);
371 effect->reset();
372 item->reset();
373
374 effect->setEnabled(true);
375 QTRY_COMPARE(effect->numRepaints, 1);
376 QTRY_COMPARE(item->numRepaints, 1);
377 effect->reset();
378 item->reset();
379
380 // Effect is already enabled; nothing should happen.
381 effect->setEnabled(true);
382 QTest::qWait(50);
383 QCOMPARE(effect->numRepaints, 0);
384 QCOMPARE(item->numRepaints, 0);
385
386 // Make sure uninstalling an effect triggers a repaint.
387 QPointer<CustomEffect> ptr = effect;
388 item->setGraphicsEffect(0);
389 QVERIFY(!ptr);
390 QTRY_COMPARE(item->numRepaints, 1);
391}
392
393void tst_QGraphicsEffect::opacity()
394{
395 // Make sure the painter's opacity is correct in QGraphicsEffect::draw.
396 QGraphicsScene scene;
397 CustomItem *item = new CustomItem(0, 0, 100, 100);
398 item->setOpacity(0.5);
399 CustomEffect *effect = new CustomEffect;
400 item->setGraphicsEffect(effect);
401 scene.addItem(item);
402
403 QGraphicsView view(&scene);
404 view.show();
405 QVERIFY(QTest::qWaitForWindowExposed(&view));
406 QTRY_VERIFY(effect->numRepaints > 0);
407 QCOMPARE(effect->m_opacity, qreal(0.5));
408}
409
410void tst_QGraphicsEffect::grayscale()
411{
412 if (qApp->desktop()->depth() < 24)
413 QSKIP("Test only works on 32 bit displays");
414
415 QGraphicsScene scene(0, 0, 100, 100);
416
417 QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
418 item->setPen(Qt::NoPen);
419 item->setBrush(QColor(122, 193, 66)); // Qt light green
420
421 QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
422 effect->setColor(Qt::black);
423 item->setGraphicsEffect(effect);
424
425 QPainter painter;
426 QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
427
428 image.fill(0);
429 painter.begin(&image);
430 painter.setRenderHint(QPainter::Antialiasing);
431 scene.render(&painter);
432 painter.end();
433
434 QCOMPARE(image.pixel(10, 10), qRgb(148, 148, 148));
435
436 effect->setStrength(0.5);
437
438 image.fill(0);
439 painter.begin(&image);
440 painter.setRenderHint(QPainter::Antialiasing);
441 scene.render(&painter);
442 painter.end();
443
444 QCOMPARE(image.pixel(10, 10), qRgb(135, 171, 107));
445
446 effect->setStrength(0.0);
447
448 image.fill(0);
449 painter.begin(&image);
450 painter.setRenderHint(QPainter::Antialiasing);
451 scene.render(&painter);
452 painter.end();
453
454 QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
455}
456
457void tst_QGraphicsEffect::colorize()
458{
459 if (qApp->desktop()->depth() < 24)
460 QSKIP("Test only works on 32 bit displays");
461
462 QGraphicsScene scene(0, 0, 100, 100);
463
464 QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
465 item->setPen(Qt::NoPen);
466 item->setBrush(QColor(122, 193, 66)); // Qt light green
467
468 QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
469 effect->setColor(QColor(102, 153, 51)); // Qt dark green
470 item->setGraphicsEffect(effect);
471
472 QPainter painter;
473 QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
474
475 image.fill(0);
476 painter.begin(&image);
477 painter.setRenderHint(QPainter::Antialiasing);
478 scene.render(&painter);
479 painter.end();
480
481 QCOMPARE(image.pixel(10, 10), qRgb(191, 212, 169));
482
483 effect->setStrength(0.5);
484
485 image.fill(0);
486 painter.begin(&image);
487 painter.setRenderHint(QPainter::Antialiasing);
488 scene.render(&painter);
489 painter.end();
490
491 QCOMPARE(image.pixel(10, 10), qRgb(156, 203, 117));
492
493 effect->setStrength(0.0);
494
495 image.fill(0);
496 painter.begin(&image);
497 painter.setRenderHint(QPainter::Antialiasing);
498 scene.render(&painter);
499 painter.end();
500
501 QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
502}
503
504class PixmapItemEffect : public QGraphicsEffect
505{
506public:
507 PixmapItemEffect(const QPixmap &source)
508 : QGraphicsEffect()
509 , pixmap(source)
510 , repaints(0)
511 {}
512
513 QRectF boundingRectFor(const QRectF &rect) const
514 { return rect; }
515
516 void draw(QPainter *painter)
517 {
518 QCOMPARE(sourcePixmap(Qt::LogicalCoordinates).handle(), pixmap.handle());
519 QVERIFY((painter->worldTransform().type() <= QTransform::TxTranslate) == (sourcePixmap(Qt::DeviceCoordinates).handle() == pixmap.handle()));
520
521 ++repaints;
522 }
523 QPixmap pixmap;
524 int repaints;
525};
526
527void tst_QGraphicsEffect::drawPixmapItem()
528{
529 QImage image(32, 32, QImage::Format_RGB32);
530 QPainter p(&image);
531 p.fillRect(0, 0, 32, 16, Qt::blue);
532 p.fillRect(0, 16, 32, 16, Qt::red);
533 p.end();
534
535 QGraphicsScene scene;
536 QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
537 scene.addItem(item);
538
539 PixmapItemEffect *effect = new PixmapItemEffect(item->pixmap());
540 item->setGraphicsEffect(effect);
541
542 QGraphicsView view(&scene);
543 view.show();
544 QVERIFY(QTest::qWaitForWindowExposed(&view));
545 QTRY_VERIFY(effect->repaints >= 1);
546
547 item->setTransform(QTransform().rotate(180), true);
548
549 QTRY_VERIFY(effect->repaints >= 2);
550}
551
552class DeviceEffect : public QGraphicsEffect
553{
554public:
555 QRectF boundingRectFor(const QRectF &rect) const
556 { return rect; }
557
558 void draw(QPainter *painter)
559 {
560 QPoint offset;
561 QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, QGraphicsEffect::NoPad);
562
563 if (pixmap.isNull())
564 return;
565
566 painter->save();
567 painter->setWorldTransform(QTransform());
568 painter->drawPixmap(offset, pixmap);
569 painter->restore();
570 }
571};
572
573void tst_QGraphicsEffect::deviceCoordinateTranslateCaching()
574{
575 QGraphicsScene scene;
576 CustomItem *item = new CustomItem(0, 0, 10, 10);
577 scene.addItem(item);
578 scene.setSceneRect(0, 0, 50, 0);
579
580 item->setGraphicsEffect(new DeviceEffect);
581 item->setPen(Qt::NoPen);
582 item->setBrush(Qt::red);
583
584 QGraphicsView view(&scene);
585 view.show();
586 QVERIFY(QTest::qWaitForWindowExposed(&view));
587
588 QTRY_VERIFY(item->numRepaints >= 1);
589 int numRepaints = item->numRepaints;
590
591 item->setTransform(QTransform::fromTranslate(10, 0), true);
592
593 QTRY_COMPARE(item->numRepaints, numRepaints);
594}
595
596void tst_QGraphicsEffect::inheritOpacity()
597{
598 QGraphicsScene scene;
599 QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 10, 10);
600 CustomItem *item = new CustomItem(0, 0, 10, 10, rectItem);
601
602 scene.addItem(rectItem);
603
604 item->setGraphicsEffect(new DeviceEffect);
605 item->setPen(Qt::NoPen);
606 item->setBrush(Qt::red);
607
608 rectItem->setOpacity(0.5);
609
610 QGraphicsView view(&scene);
611 view.show();
612 QVERIFY(QTest::qWaitForWindowExposed(&view));
613
614 QTRY_VERIFY(item->numRepaints >= 1);
615
616 int numRepaints = item->numRepaints;
617
618 rectItem->setOpacity(1);
619
620 // item should have been rerendered due to opacity changing
621 QTRY_VERIFY(item->numRepaints > numRepaints);
622}
623
624void tst_QGraphicsEffect::dropShadowClipping()
625{
626 QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
627 img.fill(0xffffffff);
628
629 QGraphicsScene scene;
630 QGraphicsRectItem *item = new QGraphicsRectItem(-5, -500, 10, 1000);
631 item->setGraphicsEffect(new QGraphicsDropShadowEffect);
632 item->setPen(Qt::NoPen);
633 item->setBrush(Qt::red);
634
635 scene.addItem(item);
636
637 QPainter p(&img);
638 scene.render(&p, img.rect(), QRect(-64, -64, 128, 128));
639 p.end();
640
641 for (int y = 1; y < img.height(); ++y)
642 for (int x = 0; x < img.width(); ++x)
643 QCOMPARE(img.pixel(x, y), img.pixel(x, y-1));
644}
645
646class MyGraphicsItem : public QGraphicsWidget
647{
648public:
649 MyGraphicsItem(QGraphicsItem *parent = 0) :
650 QGraphicsWidget(parent), nbPaint(0)
651 {}
652 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
653 {
654 nbPaint++;
655 QGraphicsWidget::paint(painter, option, widget);
656 }
657 int nbPaint;
658};
659
660void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache()
661{
662 QGraphicsScene scene;
663 MyGraphicsItem parent;
664 parent.resize(200, 200);
665 QGraphicsWidget child(&parent);
666 child.resize(200, 200);
667 child.setVisible(false);
668 scene.addItem(&parent);
669 QGraphicsView view(&scene);
670 view.show();
671 QApplication::setActiveWindow(&view);
672 QVERIFY(QTest::qWaitForWindowActive(&view));
673 QTRY_VERIFY(parent.nbPaint >= 1);
674 //we set an effect on the parent
675 parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent));
676 //flush the events
677 QApplication::processEvents();
678 //new effect applied->repaint
679 QVERIFY(parent.nbPaint >= 2);
680 child.setVisible(true);
681 //flush the events
682 QApplication::processEvents();
683 //a new child appears we need to redraw the effect.
684 QVERIFY(parent.nbPaint >= 3);
685}
686
687void tst_QGraphicsEffect::prepareGeometryChangeInvalidateCache()
688{
689 MyGraphicsItem *item = new MyGraphicsItem;
690 item->resize(200, 200);
691
692 QGraphicsScene scene;
693 scene.addItem(item);
694
695 QGraphicsView view(&scene);
696 view.show();
697 qApp->setActiveWindow(&view);
698 QVERIFY(QTest::qWaitForWindowActive(&view));
699 QTRY_VERIFY(item->nbPaint >= 1);
700
701 item->nbPaint = 0;
702 item->setGraphicsEffect(new QGraphicsDropShadowEffect);
703 QTRY_COMPARE(item->nbPaint, 1);
704
705 item->nbPaint = 0;
706 item->resize(300, 300);
707 QTRY_COMPARE(item->nbPaint, 1);
708
709 item->nbPaint = 0;
710 item->setPos(item->pos() + QPointF(10, 10));
711 QTest::qWait(50);
712 QCOMPARE(item->nbPaint, 0);
713}
714
715void tst_QGraphicsEffect::itemHasNoContents()
716{
717 QGraphicsRectItem *parent = new QGraphicsRectItem;
718 parent->setFlag(QGraphicsItem::ItemHasNoContents);
719
720 MyGraphicsItem *child = new MyGraphicsItem;
721 child->setParentItem(parent);
722 child->resize(200, 200);
723
724 QGraphicsScene scene;
725 scene.addItem(parent);
726
727 QGraphicsView view(&scene);
728 view.show();
729 qApp->setActiveWindow(&view);
730 QVERIFY(QTest::qWaitForWindowActive(&view));
731 QTRY_VERIFY(child->nbPaint >= 1);
732
733 CustomEffect *effect = new CustomEffect;
734 parent->setGraphicsEffect(effect);
735 QTRY_VERIFY(effect->numRepaints >= 1);
736
737 for (int i = 0; i < 3; ++i) {
738 effect->reset();
739 effect->update();
740 QTRY_VERIFY(effect->numRepaints >= 1);
741 }
742}
743
744QTEST_MAIN(tst_QGraphicsEffect)
745#include "tst_qgraphicseffect.moc"
746
747