Honour max-size when docking
Layout will choose a suitable size for the dock widget when addDockWidget() is called
This commit is contained in:
@@ -562,6 +562,11 @@ int Item::minLength(Qt::Orientation o) const
|
||||
return Layouting::length(minSize(), o);
|
||||
}
|
||||
|
||||
int Item::maxLengthHint(Qt::Orientation o) const
|
||||
{
|
||||
return Layouting::length(maxSizeHint(), o);
|
||||
}
|
||||
|
||||
void Item::setLength(int length, Qt::Orientation o)
|
||||
{
|
||||
Q_ASSERT(length > 0);
|
||||
@@ -833,6 +838,8 @@ void Item::onWidgetLayoutRequested()
|
||||
if (w->minSize() != minSize()) {
|
||||
setMinSize(m_guest->minSize());
|
||||
}
|
||||
|
||||
setMaxSizeHint(w->maxSizeHint());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1797,8 +1804,8 @@ QSize ItemContainer::minSize() const
|
||||
|
||||
QSize ItemContainer::maxSizeHint() const
|
||||
{
|
||||
int maxW = 0;
|
||||
int maxH = 0;
|
||||
int maxW = KDDOCKWIDGETS_MAX_WIDTH;
|
||||
int maxH = KDDOCKWIDGETS_MAX_HEIGHT;
|
||||
|
||||
if (!isEmpty()) {
|
||||
const Item::List visibleChildren = this->visibleChildren();
|
||||
@@ -1819,7 +1826,7 @@ QSize ItemContainer::maxSizeHint() const
|
||||
maxW += separatorWaste;
|
||||
}
|
||||
|
||||
return { maxW, maxH };
|
||||
return QSize(maxW, maxH).expandedTo(minSize());
|
||||
}
|
||||
|
||||
void ItemContainer::Private::resizeChildren(QSize oldSize, QSize newSize, SizingInfo::List &childSizes,
|
||||
@@ -2087,7 +2094,7 @@ void ItemContainer::restoreChild(Item *item, NeighbourSqueezeStrategy neighbourS
|
||||
|
||||
const int available = availableOnSide(item, Side1) + availableOnSide(item, Side2) - Item::separatorThickness;
|
||||
|
||||
const int max = available;
|
||||
const int max = qMin(available, item->maxLengthHint(d->m_orientation));
|
||||
const int min = item->minLength(d->m_orientation);
|
||||
const int proposed = Layouting::length(item->size(), d->m_orientation);
|
||||
const int newLength = qBound(min, proposed, max);
|
||||
@@ -2289,7 +2296,7 @@ void ItemContainer::layoutEqually(SizingInfo::List &sizes)
|
||||
|
||||
const int newItemLenght = qBound(size.minLength(d->m_orientation),
|
||||
size.length(d->m_orientation) + suggestedToGive,
|
||||
size.maxLength(d->m_orientation));
|
||||
size.maxLengthHint(d->m_orientation));
|
||||
const int toGive = newItemLenght - size.length(d->m_orientation);
|
||||
|
||||
if (toGive == 0) {
|
||||
|
||||
@@ -138,8 +138,8 @@ struct SizingInfo {
|
||||
return Layouting::length(minSize, o);
|
||||
}
|
||||
|
||||
int maxLength(Qt::Orientation o) const {
|
||||
return Layouting::length(maxSizeHint, o);
|
||||
int maxLengthHint(Qt::Orientation o) const {
|
||||
return qMax(minLength(o), Layouting::length(maxSizeHint, o));
|
||||
}
|
||||
|
||||
int availableLength(Qt::Orientation o) const {
|
||||
@@ -193,7 +193,7 @@ struct SizingInfo {
|
||||
}
|
||||
|
||||
int availableToGrow(Qt::Orientation o) const {
|
||||
return maxLength(o) - length(o);
|
||||
return maxLengthHint(o) - length(o);
|
||||
}
|
||||
|
||||
QVariantMap toVariantMap() const;
|
||||
@@ -294,6 +294,7 @@ public:
|
||||
int refCount() const;
|
||||
|
||||
int minLength(Qt::Orientation) const;
|
||||
int maxLengthHint(Qt::Orientation) const;
|
||||
|
||||
QObject *host() const;
|
||||
Widget *hostWidget() const;
|
||||
|
||||
@@ -69,6 +69,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void setMaxSize(QSize sz)
|
||||
{
|
||||
if (sz != m_maxSize) {
|
||||
m_maxSize = sz;
|
||||
Q_EMIT layoutInvalidated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QSize maxSizeHint() const override {
|
||||
return m_maxSize;
|
||||
}
|
||||
|
||||
void resizeEvent(QResizeEvent *ev) override
|
||||
{
|
||||
QWidget::resizeEvent(ev);
|
||||
@@ -97,6 +110,7 @@ Q_SIGNALS:
|
||||
void layoutInvalidated();
|
||||
private:
|
||||
QSize m_minSize = QSize(200, 200);
|
||||
QSize m_maxSize = QSize(KDDOCKWIDGETS_MAX_WIDTH, KDDOCKWIDGETS_MAX_HEIGHT);
|
||||
};
|
||||
|
||||
static void fatalWarningsMessageHandler(QtMsgType t, const QMessageLogContext &context, const QString &msg)
|
||||
@@ -181,6 +195,7 @@ private Q_SLOTS:
|
||||
void tst_closeAndRestorePreservesPosition();
|
||||
void tst_minSizeChangedBeforeRestore();
|
||||
void tst_separatorMoveCrash();
|
||||
void tst_maxSizeHonoured1();
|
||||
};
|
||||
|
||||
class MyHostWidget : public QWidget
|
||||
@@ -1528,6 +1543,24 @@ void TestMultiSplitter::tst_separatorMoveCrash()
|
||||
c->requestSeparatorMove(separator, available5 + 10);
|
||||
}
|
||||
|
||||
void TestMultiSplitter::tst_maxSizeHonoured1()
|
||||
{
|
||||
// Tests that the suggested rect honours max size when adding an item to a layout.
|
||||
|
||||
auto root = createRoot();
|
||||
auto item1 = createItem();
|
||||
auto item2 = createItem();
|
||||
root->insertItem(item1, Item::Location_OnTop);
|
||||
root->setSize_recursive(QSize(3000, 3000));
|
||||
|
||||
auto guest2 = static_cast<MyGuestWidget*>(item2->guestWidget());
|
||||
const int maxHeight = 250;
|
||||
guest2->setMaxSize(QSize(250, maxHeight));
|
||||
|
||||
root->insertItem(item2, Item::Location_OnBottom);
|
||||
QCOMPARE(item2->height(), maxHeight);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
bool qpaPassed = false;
|
||||
|
||||
@@ -355,6 +355,7 @@ private Q_SLOTS:
|
||||
void tst_lastFloatingPositionIsRestored();
|
||||
void tst_moreTitleBarCornerCases();
|
||||
void tst_maxSizePropagates();
|
||||
void tst_maxSizeHonouredWhenDropped();
|
||||
|
||||
private:
|
||||
std::unique_ptr<MultiSplitter> createMultiSplitterFromSetup(MultiSplitterSetup setup, QHash<QWidget *, Frame *> &frameMap) const;
|
||||
@@ -5332,34 +5333,55 @@ void TestDocks::tst_moreTitleBarCornerCases()
|
||||
|
||||
void TestDocks::tst_maxSizePropagates()
|
||||
{
|
||||
{
|
||||
// Tests that the DockWidget gets the min and max size of its guest widget
|
||||
// Tests that the DockWidget gets the min and max size of its guest widget
|
||||
EnsureTopLevelsDeleted e;
|
||||
auto dock1 = new DockWidget("dock1");
|
||||
|
||||
auto dock1 = new DockWidget("dock1");
|
||||
auto w = new QWidget();
|
||||
w->setMinimumSize(120, 120);
|
||||
w->setMaximumSize(500, 500);
|
||||
dock1->setWidget(w);
|
||||
dock1->show();
|
||||
|
||||
auto w = new QWidget();
|
||||
w->setMinimumSize(120, 120);
|
||||
w->setMaximumSize(500, 500);
|
||||
dock1->setWidget(w);
|
||||
dock1->show();
|
||||
QCOMPARE(Widget_qwidget::widgetMinSize(dock1), Widget_qwidget::widgetMinSize(w));
|
||||
QCOMPARE(dock1->maximumSize(), w->maximumSize());
|
||||
|
||||
QCOMPARE(Widget_qwidget::widgetMinSize(dock1), Widget_qwidget::widgetMinSize(w));
|
||||
QCOMPARE(dock1->maximumSize(), w->maximumSize());
|
||||
w->setMinimumSize(121, 121);
|
||||
w->setMaximumSize(501, 501);
|
||||
|
||||
w->setMinimumSize(121, 121);
|
||||
w->setMaximumSize(501, 501);
|
||||
Testing::waitForEvent(w, QEvent::LayoutRequest);
|
||||
|
||||
Testing::waitForEvent(w, QEvent::LayoutRequest);
|
||||
QCOMPARE(Widget_qwidget::widgetMinSize(dock1), Widget_qwidget::widgetMinSize(w));
|
||||
QCOMPARE(dock1->maximumSize(), w->maximumSize());
|
||||
|
||||
QCOMPARE(Widget_qwidget::widgetMinSize(dock1), Widget_qwidget::widgetMinSize(w));
|
||||
QCOMPARE(dock1->maximumSize(), w->maximumSize());
|
||||
// Now let's see if our Frame also has proper size-constraints
|
||||
Frame *frame = dock1->frame();
|
||||
QCOMPARE(frame->maximumSize().expandedTo(w->maximumSize()), frame->maximumSize());
|
||||
|
||||
// Now let's see if our Frame also has proper size-constraints
|
||||
Frame *frame = dock1->frame();
|
||||
QCOMPARE(frame->maximumSize().expandedTo(w->maximumSize()), frame->maximumSize());
|
||||
delete dock1->window();
|
||||
}
|
||||
|
||||
delete dock1->window();
|
||||
}
|
||||
void TestDocks::tst_maxSizeHonouredWhenDropped()
|
||||
{
|
||||
EnsureTopLevelsDeleted e;
|
||||
auto m1 = createMainWindow();
|
||||
auto dock1 = new DockWidget("dock1");
|
||||
auto dock2 = new DockWidget("dock2");
|
||||
m1->addDockWidget(dock1, Location_OnTop);
|
||||
m1->resize(2000, 2000);
|
||||
|
||||
dock2->setWidget(new QWidget);
|
||||
const int maxWidth = 200;
|
||||
dock2->widget()->setMaximumSize(maxWidth, 200);
|
||||
m1->addDockWidget(dock2, Location_OnLeft);
|
||||
const int droppedWidth = dock2->frame()->width();
|
||||
QVERIFY(droppedWidth < maxWidth + 50); // +50 to cover any margins and waste by QTabWidget
|
||||
|
||||
// Try again, but now dropping a multisplitter
|
||||
dock2->setFloating(true);
|
||||
auto fw = qobject_cast<FloatingWindow*>(dock2->window());
|
||||
m1->dropArea()->drop(fw, Location_OnLeft, nullptr);
|
||||
QCOMPARE(dock2->frame()->width(), droppedWidth);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
Reference in New Issue
Block a user