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);
|
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)
|
void Item::setLength(int length, Qt::Orientation o)
|
||||||
{
|
{
|
||||||
Q_ASSERT(length > 0);
|
Q_ASSERT(length > 0);
|
||||||
@@ -833,6 +838,8 @@ void Item::onWidgetLayoutRequested()
|
|||||||
if (w->minSize() != minSize()) {
|
if (w->minSize() != minSize()) {
|
||||||
setMinSize(m_guest->minSize());
|
setMinSize(m_guest->minSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setMaxSizeHint(w->maxSizeHint());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1797,8 +1804,8 @@ QSize ItemContainer::minSize() const
|
|||||||
|
|
||||||
QSize ItemContainer::maxSizeHint() const
|
QSize ItemContainer::maxSizeHint() const
|
||||||
{
|
{
|
||||||
int maxW = 0;
|
int maxW = KDDOCKWIDGETS_MAX_WIDTH;
|
||||||
int maxH = 0;
|
int maxH = KDDOCKWIDGETS_MAX_HEIGHT;
|
||||||
|
|
||||||
if (!isEmpty()) {
|
if (!isEmpty()) {
|
||||||
const Item::List visibleChildren = this->visibleChildren();
|
const Item::List visibleChildren = this->visibleChildren();
|
||||||
@@ -1819,7 +1826,7 @@ QSize ItemContainer::maxSizeHint() const
|
|||||||
maxW += separatorWaste;
|
maxW += separatorWaste;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { maxW, maxH };
|
return QSize(maxW, maxH).expandedTo(minSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemContainer::Private::resizeChildren(QSize oldSize, QSize newSize, SizingInfo::List &childSizes,
|
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 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 min = item->minLength(d->m_orientation);
|
||||||
const int proposed = Layouting::length(item->size(), d->m_orientation);
|
const int proposed = Layouting::length(item->size(), d->m_orientation);
|
||||||
const int newLength = qBound(min, proposed, max);
|
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),
|
const int newItemLenght = qBound(size.minLength(d->m_orientation),
|
||||||
size.length(d->m_orientation) + suggestedToGive,
|
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);
|
const int toGive = newItemLenght - size.length(d->m_orientation);
|
||||||
|
|
||||||
if (toGive == 0) {
|
if (toGive == 0) {
|
||||||
|
|||||||
@@ -138,8 +138,8 @@ struct SizingInfo {
|
|||||||
return Layouting::length(minSize, o);
|
return Layouting::length(minSize, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxLength(Qt::Orientation o) const {
|
int maxLengthHint(Qt::Orientation o) const {
|
||||||
return Layouting::length(maxSizeHint, o);
|
return qMax(minLength(o), Layouting::length(maxSizeHint, o));
|
||||||
}
|
}
|
||||||
|
|
||||||
int availableLength(Qt::Orientation o) const {
|
int availableLength(Qt::Orientation o) const {
|
||||||
@@ -193,7 +193,7 @@ struct SizingInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int availableToGrow(Qt::Orientation o) const {
|
int availableToGrow(Qt::Orientation o) const {
|
||||||
return maxLength(o) - length(o);
|
return maxLengthHint(o) - length(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap toVariantMap() const;
|
QVariantMap toVariantMap() const;
|
||||||
@@ -294,6 +294,7 @@ public:
|
|||||||
int refCount() const;
|
int refCount() const;
|
||||||
|
|
||||||
int minLength(Qt::Orientation) const;
|
int minLength(Qt::Orientation) const;
|
||||||
|
int maxLengthHint(Qt::Orientation) const;
|
||||||
|
|
||||||
QObject *host() const;
|
QObject *host() const;
|
||||||
Widget *hostWidget() 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
|
void resizeEvent(QResizeEvent *ev) override
|
||||||
{
|
{
|
||||||
QWidget::resizeEvent(ev);
|
QWidget::resizeEvent(ev);
|
||||||
@@ -97,6 +110,7 @@ Q_SIGNALS:
|
|||||||
void layoutInvalidated();
|
void layoutInvalidated();
|
||||||
private:
|
private:
|
||||||
QSize m_minSize = QSize(200, 200);
|
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)
|
static void fatalWarningsMessageHandler(QtMsgType t, const QMessageLogContext &context, const QString &msg)
|
||||||
@@ -181,6 +195,7 @@ private Q_SLOTS:
|
|||||||
void tst_closeAndRestorePreservesPosition();
|
void tst_closeAndRestorePreservesPosition();
|
||||||
void tst_minSizeChangedBeforeRestore();
|
void tst_minSizeChangedBeforeRestore();
|
||||||
void tst_separatorMoveCrash();
|
void tst_separatorMoveCrash();
|
||||||
|
void tst_maxSizeHonoured1();
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyHostWidget : public QWidget
|
class MyHostWidget : public QWidget
|
||||||
@@ -1528,6 +1543,24 @@ void TestMultiSplitter::tst_separatorMoveCrash()
|
|||||||
c->requestSeparatorMove(separator, available5 + 10);
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
bool qpaPassed = false;
|
bool qpaPassed = false;
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ private Q_SLOTS:
|
|||||||
void tst_lastFloatingPositionIsRestored();
|
void tst_lastFloatingPositionIsRestored();
|
||||||
void tst_moreTitleBarCornerCases();
|
void tst_moreTitleBarCornerCases();
|
||||||
void tst_maxSizePropagates();
|
void tst_maxSizePropagates();
|
||||||
|
void tst_maxSizeHonouredWhenDropped();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<MultiSplitter> createMultiSplitterFromSetup(MultiSplitterSetup setup, QHash<QWidget *, Frame *> &frameMap) const;
|
std::unique_ptr<MultiSplitter> createMultiSplitterFromSetup(MultiSplitterSetup setup, QHash<QWidget *, Frame *> &frameMap) const;
|
||||||
@@ -5332,34 +5333,55 @@ void TestDocks::tst_moreTitleBarCornerCases()
|
|||||||
|
|
||||||
void TestDocks::tst_maxSizePropagates()
|
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();
|
QCOMPARE(Widget_qwidget::widgetMinSize(dock1), Widget_qwidget::widgetMinSize(w));
|
||||||
w->setMinimumSize(120, 120);
|
QCOMPARE(dock1->maximumSize(), w->maximumSize());
|
||||||
w->setMaximumSize(500, 500);
|
|
||||||
dock1->setWidget(w);
|
|
||||||
dock1->show();
|
|
||||||
|
|
||||||
QCOMPARE(Widget_qwidget::widgetMinSize(dock1), Widget_qwidget::widgetMinSize(w));
|
w->setMinimumSize(121, 121);
|
||||||
QCOMPARE(dock1->maximumSize(), w->maximumSize());
|
w->setMaximumSize(501, 501);
|
||||||
|
|
||||||
w->setMinimumSize(121, 121);
|
Testing::waitForEvent(w, QEvent::LayoutRequest);
|
||||||
w->setMaximumSize(501, 501);
|
|
||||||
|
|
||||||
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));
|
// Now let's see if our Frame also has proper size-constraints
|
||||||
QCOMPARE(dock1->maximumSize(), w->maximumSize());
|
Frame *frame = dock1->frame();
|
||||||
|
QCOMPARE(frame->maximumSize().expandedTo(w->maximumSize()), frame->maximumSize());
|
||||||
|
|
||||||
// Now let's see if our Frame also has proper size-constraints
|
delete dock1->window();
|
||||||
Frame *frame = dock1->frame();
|
}
|
||||||
QCOMPARE(frame->maximumSize().expandedTo(w->maximumSize()), frame->maximumSize());
|
|
||||||
|
|
||||||
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[])
|
int main(int argc, char *argv[])
|
||||||
|
|||||||
Reference in New Issue
Block a user