diff --git a/src/private/multisplitter/Item.cpp b/src/private/multisplitter/Item.cpp index 497fa906..2bd1ffdc 100644 --- a/src/private/multisplitter/Item.cpp +++ b/src/private/multisplitter/Item.cpp @@ -50,7 +50,6 @@ QPoint Item::mapToRoot(QPoint p) const QPoint Item::mapFromRoot(QPoint p) const { - ItemContainer *c = parentContainer(); while (c) { p = p - c->pos(); @@ -159,6 +158,11 @@ QSize Item::missingSize() const return missing; } +int Item::missingLength(Qt::Orientation o) const +{ + return Layouting::length(missingSize(), o); +} + bool Item::isBeingInserted() const { return m_sizingInfo.isBeingInserted; @@ -446,11 +450,11 @@ void Item::setGeometry(QRect rect) const QSize minSz = minSize(); if (rect.width() < minSz.width() || rect.height() < minSz.height()) { qWarning() << Q_FUNC_INFO << this << "Constraints not honoured" - << rect.size() << minSz << "dumping layout"; + << rect.size() << minSz << "dumping layout" + << ": parent=" << parentContainer(); root()->dumpLayout(); } - Q_EMIT geometryChanged(); if (oldGeo.x() != x()) @@ -572,21 +576,6 @@ int Item::visibleCount_recursive() const return isVisible() ? 1 : 0; } -int Item::availableOnSide(Side, Qt::Orientation o) const -{ - if (isRoot()) - return 0; - - ItemContainer *container = parentContainer(); - - if (o == container->orientation()) { - - } else { - - } - return 0; -} - ItemContainer::ItemContainer(QWidget *hostWidget, ItemContainer *parent) : Item(true, hostWidget, parent) { @@ -1340,7 +1329,7 @@ QSize ItemContainer::maxSize() const void ItemContainer::resize(QSize newSize) // Rename to setSize_recursive { - QScopedValueRollback(m_blockUpdatePercentages, true); + QScopedValueRollback block(m_blockUpdatePercentages, true); const QSize minSize = this->minSize(); if (newSize.width() < minSize.width() || newSize.height() < minSize.height()) { @@ -1368,7 +1357,9 @@ void ItemContainer::resize(QSize newSize) // Rename to setSize_recursive int nextPos = 0; const QVector childPercentages = this->childPercentages(); const Item::List children = visibleChildren(); - for (int i = 0, count = children.size(); i < count; ++i) { + + const int count = children.size(); + for (int i = 0; i < count; ++i) { const bool isLast = i == count - 1; Item *item = children.at(i); @@ -1803,6 +1794,30 @@ QVector ItemContainer::availableLengthPerNeighbour(Item *item, Side side) c return result; } +SizingInfo::List ItemContainer::sizingInfosPerNeighbour(Item *item, Side side) const +{ + Item::List children = visibleChildren(); + const int indexOfChild = children.indexOf(item); + int start = 0; + int end = 0; + if (side == Side1) { + start = 0; + end = indexOfChild - 1; + } else { + start = indexOfChild + 1; + end = children.size() - 1; + } + + SizingInfo::List result; + result.reserve(end - start + 1); + for (int i = start; i <= end; ++i) { + Item *neighbour = children.at(i); + result << neighbour->m_sizingInfo; + } + + return result; +} + QVector ItemContainer::calculateSqueezes(QVector availabilities, int needed) const { QVector squeezes(availabilities.size(), 0); diff --git a/src/private/multisplitter/Item_p.h b/src/private/multisplitter/Item_p.h index 89c7b51a..3f36496a 100644 --- a/src/private/multisplitter/Item_p.h +++ b/src/private/multisplitter/Item_p.h @@ -164,6 +164,7 @@ inline Side sideForLocation(Location loc) } struct SizingInfo { + typedef QVector List; QSize minSize = QSize(40, 40); // TODO: Hardcoded QSize maxSize = QSize(16777215, 16777215); // TODO: Not supported yet QSize proposedSize; @@ -243,8 +244,8 @@ public: virtual void dumpLayout(int level = 0); void setGeometry(QRect rect); SizingInfo m_sizingInfo; - int availableOnSide(Side, Qt::Orientation) const; QSize missingSize() const; + int missingLength(Qt::Orientation) const; bool isBeingInserted() const; void setBeingInserted(bool); ItemContainer *root() const; @@ -355,9 +356,24 @@ public: void dumpLayout(int level = 0); void updateChildPercentages(); void restorePlaceholder(Item *); + + ///@brief Grows the side1Neighbour to the right and the side2Neighbour to the left + ///So they occupy the empty space that's between them (or bottom/top if Qt::Vertical). + ///This is useful when an Item is removed. Its neighbours will occupy its space. + ///side1Neighbour or side2Neighbour are allowed to be null, in which case the non-null one + ///will occupy the entire space. void growNeighbours(Item *side1Neighbour, Item *side2Neighbour); + + ///@brief grows an item by @p amount. It calculates how much to grow on side1 and on side2 + ///Then calls growItem(item, side1Growth, side2Growth) which will effectively grow it, + ///and shrink the neighbours which are donating the size. void growItem(Item *, int amount, GrowthStrategy); + + ///@brief Grows an item by @p side1Growth on the left and @p side2Growth on the right + ///(or top/bottom if Qt::Vertical). Squeezes the neighbours (not just the immediate ones). + ///at the end positions all items. void growItem(Item *, int side1Growth, int side2Growth); + Item *neighbourFor(const Item *, Side) const; Item *visibleNeighbourFor(const Item *item, Side side) const; QSize availableSize() const; @@ -375,6 +391,7 @@ public: void onChildMinSizeChanged(Item *child); void onChildVisibleChanged(Item *child, bool visible); QVector availableLengthPerNeighbour(Item *item, Side) const; + SizingInfo::List sizingInfosPerNeighbour(Item *item, Side) const; QVector calculateSqueezes(QVector availabilities, int needed) const; QRect suggestedDropRect(QSize minSize, const Item *relativeTo, Location) const; void positionItems(); diff --git a/src/private/multisplitter/tests/tst_multisplitter.cpp b/src/private/multisplitter/tests/tst_multisplitter.cpp index f2cc58d1..d2495077 100644 --- a/src/private/multisplitter/tests/tst_multisplitter.cpp +++ b/src/private/multisplitter/tests/tst_multisplitter.cpp @@ -787,6 +787,8 @@ void TestMultiSplitter::tst_misc1() void TestMultiSplitter::tst_misc2() { // Random test1 + // |5|1|2| + // | |3|4| auto root = createRoot(); auto item1 = createRootWithSingleItem();