summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Arve Saether <[email protected]>2014-10-20 15:40:18 +0200
committerJan Arve Sæther <[email protected]>2014-10-23 07:17:50 +0200
commitbf200fc948d89e1a735a8bcca879654028f944d2 (patch)
tree2696c1a5314d722100a28f1b44ff54aa5f1e803e
parente5c1572e7eafbce26ca5835c7fe1682bfb69d92b (diff)
Adjust the layout if a QGraphicsWidget is explicitly hidden
Since layout items can now be hidden, this also makes sure we respect the QSizePolicy::retainSizeWhenHidden Task-number: QTBUG-20132 Change-Id: Iab59fc9b61d4ca1bb2208c479a027da6eb0283a9 Reviewed-by: Paul Olav Tvete <[email protected]>
-rw-r--r--src/gui/util/qgridlayoutengine.cpp2
-rw-r--r--src/gui/util/qgridlayoutengine_p.h1
-rw-r--r--src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp20
-rw-r--r--src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h4
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.cpp4
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp89
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp25
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp36
8 files changed, 180 insertions, 1 deletions
diff --git a/src/gui/util/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp
index ed15e460f36..65f2297fcef 100644
--- a/src/gui/util/qgridlayoutengine.cpp
+++ b/src/gui/util/qgridlayoutengine.cpp
@@ -1289,7 +1289,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData,
if (rowIsIdenticalToPrevious && item != itemAt(row - 1, column, orientation))
rowIsIdenticalToPrevious = false;
- if (item)
+ if (item && !item->isIgnored())
rowIsEmpty = false;
}
diff --git a/src/gui/util/qgridlayoutengine_p.h b/src/gui/util/qgridlayoutengine_p.h
index bf34e816b53..b75312bfe8d 100644
--- a/src/gui/util/qgridlayoutengine_p.h
+++ b/src/gui/util/qgridlayoutengine_p.h
@@ -295,6 +295,7 @@ public:
virtual QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const = 0;
virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const = 0;
+ virtual bool isIgnored() const { return false; }
virtual void setGeometry(const QRectF &rect) = 0;
/*
diff --git a/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp b/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp
index 3d9c5d6de5e..c9b2ecd62c5 100644
--- a/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp
+++ b/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp
@@ -38,9 +38,29 @@
#include "qgraphicslayoutitem_p.h"
#include "qgraphicslayout_p.h"
#include "qgraphicswidget.h"
+#include <private/qgraphicswidget_p.h>
QT_BEGIN_NAMESPACE
+bool QGraphicsGridLayoutEngineItem::isHidden() const
+{
+ if (QGraphicsItem *item = q_layoutItem->graphicsItem())
+ return QGraphicsItemPrivate::get(item)->explicitlyHidden;
+ return false;
+}
+
+/*!
+ \internal
+
+ If this returns true, the layout will arrange just as if the item was never added to the layout.
+ (Note that this shouldn't lead to a "double spacing" where the item was hidden)
+ ### Qt6: Move to QGraphicsLayoutItem and make virtual
+*/
+bool QGraphicsGridLayoutEngineItem::isIgnored() const
+{
+ return isHidden() && !q_layoutItem->sizePolicy().retainSizeWhenHidden();
+}
+
/*
returns \c true if the size policy returns \c true for either hasHeightForWidth()
or hasWidthForHeight()
diff --git a/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h b/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h
index 4d6bdfce0a9..07486514f8d 100644
--- a/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h
+++ b/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h
@@ -82,6 +82,10 @@ public:
return q_layoutItem->effectiveSizeHint(which, constraint);
}
+ bool isHidden() const;
+
+ virtual bool isIgnored() const Q_DECL_OVERRIDE;
+
virtual void setGeometry(const QRectF &rect) Q_DECL_OVERRIDE
{
q_layoutItem->setGeometry(rect);
diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp
index 4a9c3b098eb..5bd563e535b 100644
--- a/src/widgets/graphicsview/qgraphicswidget.cpp
+++ b/src/widgets/graphicsview/qgraphicswidget.cpp
@@ -1137,6 +1137,10 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &
setAttribute(Qt::WA_Resized, false);
}
}
+
+ // layout size hint only changes if an item changes from/to explicitly hidden state
+ if (value.toBool() || d->explicitlyHidden)
+ updateGeometry();
break;
case ItemVisibleHasChanged:
if (!value.toBool()) {
diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
index c90c431d8b7..3b55fcd5fc9 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
@@ -124,6 +124,7 @@ private slots:
void heightForWidthWithSpanning();
void stretchAndHeightForWidth();
void testDefaultAlignment();
+ void hiddenItems();
};
class RectWidget : public QGraphicsWidget
@@ -3485,6 +3486,94 @@ void tst_QGraphicsGridLayout::testDefaultAlignment()
QCOMPARE(w->geometry(), QRectF(0,0,50,50));
QCOMPARE(w2->geometry(), QRectF(0,50,100,100));
}
+
+static RectWidget *addWidget(QGraphicsGridLayout *grid, int row, int column)
+{
+ RectWidget *w = new RectWidget;
+ w->setPreferredSize(20, 20);
+ grid->addItem(w, row, column);
+ return w;
+}
+
+static void setVisible(bool visible, QGraphicsWidget **widgets)
+{
+ for (int i = 0; i < 3; ++i)
+ if (widgets[i]) widgets[i]->setVisible(visible);
+}
+
+static void setRetainSizeWhenHidden(bool retainSize, QGraphicsWidget **widgets)
+{
+ QSizePolicy sp = widgets[0]->sizePolicy();
+ sp.setRetainSizeWhenHidden(retainSize);
+ for (int i = 0; i < 3; ++i)
+ if (widgets[i]) widgets[i]->setSizePolicy(sp);
+}
+
+void tst_QGraphicsGridLayout::hiddenItems()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QGraphicsGridLayout *layout = new QGraphicsGridLayout(widget);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(2);
+
+ // Create a 3x3 layout
+ addWidget(layout, 0, 0);
+ RectWidget *w01 = addWidget(layout, 0, 1);
+ addWidget(layout, 0, 2);
+ RectWidget *w10 = addWidget(layout, 1, 0);
+ RectWidget *w11 = addWidget(layout, 1, 1);
+ RectWidget *w12 = addWidget(layout, 1, 2);
+ addWidget(layout, 2, 0);
+ RectWidget *w21 = addWidget(layout, 2, 1);
+ addWidget(layout, 2, 2);
+
+ QGraphicsWidget *middleColumn[] = {w01, w11, w21 };
+ QGraphicsWidget *topTwoOfMiddleColumn[] = {w01, w11, 0 };
+
+ // hide and show middle column
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+ setVisible(false, middleColumn); // hide middle column
+ QCOMPARE(layout->preferredWidth(), qreal(42));
+ setVisible(true, middleColumn); // show middle column
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+ setRetainSizeWhenHidden(true, middleColumn);
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+ setVisible(false, middleColumn); // hide middle column
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+ setRetainSizeWhenHidden(false, middleColumn);
+ QCOMPARE(layout->preferredWidth(), qreal(42));
+ setVisible(true, middleColumn);
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+
+ // Hide only two items, => column should not collapse
+ setVisible(false, topTwoOfMiddleColumn);
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+
+
+ QGraphicsWidget *middleRow[] = {w10, w11, w12 };
+ QGraphicsWidget *leftMostTwoOfMiddleRow[] = {w10, w11, 0 };
+
+ // hide and show middle row
+ QCOMPARE(layout->preferredHeight(), qreal(64));
+ setVisible(false, middleRow);
+ QCOMPARE(layout->preferredHeight(), qreal(42));
+ setVisible(true, middleRow);
+ QCOMPARE(layout->preferredHeight(), qreal(64));
+ setRetainSizeWhenHidden(true, middleColumn);
+ QCOMPARE(layout->preferredHeight(), qreal(64));
+ setVisible(false, middleRow);
+ QCOMPARE(layout->preferredHeight(), qreal(64));
+ setRetainSizeWhenHidden(false, middleRow);
+ QCOMPARE(layout->preferredHeight(), qreal(42));
+ setVisible(true, middleRow);
+ QCOMPARE(layout->preferredHeight(), qreal(64));
+
+ // Hide only two items => row should not collapse
+ setVisible(false, leftMostTwoOfMiddleRow);
+ QCOMPARE(layout->preferredHeight(), qreal(64));
+
+}
+
QTEST_MAIN(tst_QGraphicsGridLayout)
#include "tst_qgraphicsgridlayout.moc"
diff --git a/tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp
index d35667f2150..107e3eb48ab 100644
--- a/tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp
@@ -50,6 +50,7 @@ private slots:
void compressLayoutRequest();
void automaticReparenting();
void verifyActivate();
+ void sizeHintOfHiddenLayout();
void invalidate();
void constructors();
void alternativeLayoutItems();
@@ -279,6 +280,30 @@ void tst_QGraphicsLayout::verifyActivate()
}
+
+void tst_QGraphicsLayout::sizeHintOfHiddenLayout()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+
+ QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
+ scene.addItem(window);
+ TestLayout *lout = new TestLayout(window);
+ lout->setContentsMargins(1,2,2,1);
+ QGraphicsWidget *w = new QGraphicsWidget;
+ w->setPreferredSize(20, 20);
+ w->setMaximumSize(50, 50);
+ lout->addItem(w);
+ window->setLayout(lout);
+
+ for (int pass = 0; pass < 3; ++pass) {
+ QCOMPARE(lout->sizeHint(Qt::MinimumSize), QSizeF(3,3));
+ QCOMPARE(lout->sizeHint(Qt::PreferredSize), QSizeF(23,23));
+ QCOMPARE(lout->sizeHint(Qt::MaximumSize), QSizeF(53,53));
+ window->setVisible(pass % 2);
+ }
+}
+
static void clearAllCounters(TestGraphicsWidget *widget)
{
if (!widget)
diff --git a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
index 7147bb8cce3..1513abf0b18 100644
--- a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
@@ -103,6 +103,7 @@ private slots:
void testOffByOneInLargerLayout();
void testDefaultAlignment();
void combineSizePolicies();
+ void hiddenItems();
// Task specific tests
void task218400_insertStretchCrash();
@@ -1721,6 +1722,41 @@ void tst_QGraphicsLinearLayout::combineSizePolicies()
QCOMPARE(layout->maximumHeight(), qreal(200));
}
+void tst_QGraphicsLinearLayout::hiddenItems()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, widget);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(2);
+
+ RectWidget *w1 = new RectWidget;
+ w1->setPreferredSize(QSizeF(20, 20));
+ layout->addItem(w1);
+
+ RectWidget *w2 = new RectWidget;
+ w2->setPreferredSize(QSizeF(20, 20));
+ layout->addItem(w2);
+
+ RectWidget *w3 = new RectWidget;
+ w3->setPreferredSize(QSizeF(20, 20));
+ layout->addItem(w3);
+
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+ w2->hide();
+ QCOMPARE(layout->preferredWidth(), qreal(42));
+ w2->show();
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+ QSizePolicy sp = w2->sizePolicy();
+ sp.setRetainSizeWhenHidden(true);
+ w2->setSizePolicy(sp);
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+ w2->hide();
+ QCOMPARE(layout->preferredWidth(), qreal(64));
+ sp.setRetainSizeWhenHidden(false);
+ w2->setSizePolicy(sp);
+ QCOMPARE(layout->preferredWidth(), qreal(42));
+}
+
QTEST_MAIN(tst_QGraphicsLinearLayout)
#include "tst_qgraphicslinearlayout.moc"