wip
This commit is contained in:
@@ -423,8 +423,9 @@ int Item::separatorThickness()
|
||||
bool Item::checkSanity() const
|
||||
{
|
||||
if (minSize().width() > width() || minSize().height() > height()) {
|
||||
qWarning() << Q_FUNC_INFO << "Size constraints not honoured"
|
||||
qWarning() << Q_FUNC_INFO << "Size constraints not honoured" << this
|
||||
<< "; min=" << minSize() << "; size=" << size();
|
||||
root()->dumpLayout();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -467,6 +468,7 @@ void Item::dumpLayout(int level)
|
||||
: QString();
|
||||
const QString visible = !isVisible() ? QStringLiteral(";hidden;")
|
||||
: QString();
|
||||
|
||||
qDebug().noquote() << indent << "- Widget: " << objectName()
|
||||
<< m_geometry << "r=" << m_geometry.right() << "b=" << m_geometry.bottom()
|
||||
<< visible << beingInserted;
|
||||
@@ -675,6 +677,15 @@ bool ItemContainer::checkSanity() const
|
||||
<< "; got=" << occupied;
|
||||
return false;
|
||||
}
|
||||
|
||||
const QVector<double> percentages = childPercentages();
|
||||
const double totalPercentage = std::accumulate(percentages.begin(), percentages.end(), 0.0);
|
||||
if (!qFuzzyCompare(totalPercentage, 1.0)) {
|
||||
qWarning() << Q_FUNC_INFO << "Percentages don't add up"
|
||||
<< totalPercentage << percentages;
|
||||
const_cast<ItemContainer*>(this)->updateChildPercentages();
|
||||
qWarning() << Q_FUNC_INFO << childPercentages();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -715,7 +726,6 @@ void ItemContainer::removeItem(Item *item, bool hardRemove)
|
||||
{
|
||||
Q_ASSERT(!item->isRoot());
|
||||
if (contains(item)) {
|
||||
m_childPercentages.clear();
|
||||
Item *side1Item = visibleNeighbourFor(item, Side1);
|
||||
Item *side2Item = visibleNeighbourFor(item, Side2);
|
||||
const bool isContainer = item->isContainer();
|
||||
@@ -750,6 +760,7 @@ void ItemContainer::removeItem(Item *item, bool hardRemove)
|
||||
// Neighbours will occupy the space of the deleted item
|
||||
growNeighbours(side1Item, side2Item);
|
||||
Q_EMIT itemsChanged();
|
||||
updateChildPercentages();
|
||||
}
|
||||
} else {
|
||||
// Not ours, ask parent
|
||||
@@ -780,6 +791,7 @@ ItemContainer *ItemContainer::convertChildToContainer(Item *leaf)
|
||||
container->setGeometry(leaf->geometry());
|
||||
container->insertItem(leaf, Location_OnTop);
|
||||
Q_EMIT itemsChanged();
|
||||
updateChildPercentages();
|
||||
|
||||
return container;
|
||||
}
|
||||
@@ -819,6 +831,8 @@ void ItemContainer::insertItem(Item *item, Location loc)
|
||||
// Now we have the correct orientation, we can insert
|
||||
insertItem(item, loc);
|
||||
}
|
||||
|
||||
updateChildPercentages();
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
@@ -1037,14 +1051,14 @@ void ItemContainer::positionItems()
|
||||
|
||||
// If the layout is horizontal, the item will have the height of the container. And vice-versa
|
||||
const int oppositeLength = Layouting::length(size(), oppositeOrientation);
|
||||
item->setLength(oppositeLength, oppositeOrientation);
|
||||
item->setLength_recursive(oppositeLength, oppositeOrientation);
|
||||
|
||||
// Update the pos
|
||||
item->setPos(nextPos, m_orientation);
|
||||
nextPos += item->length(m_orientation) + Item::separatorThickness();
|
||||
}
|
||||
|
||||
m_childPercentages.clear();
|
||||
updateChildPercentages();
|
||||
}
|
||||
|
||||
void ItemContainer::clear()
|
||||
@@ -1170,7 +1184,6 @@ void ItemContainer::insertItem(Item *item, int index, bool growItem)
|
||||
{
|
||||
m_children.insert(index, item);
|
||||
item->setParentContainer(this);
|
||||
m_childPercentages.clear();
|
||||
Q_EMIT itemsChanged();
|
||||
|
||||
if (growItem)
|
||||
@@ -1319,6 +1332,9 @@ QSize ItemContainer::maxSize() const
|
||||
|
||||
void ItemContainer::resize(QSize newSize) // Rename to setSize_recursive
|
||||
{
|
||||
QScopedValueRollback<bool>(m_blockUpdatePercentages, true);
|
||||
checkSanity();
|
||||
|
||||
const QSize minSize = this->minSize();
|
||||
if (newSize.width() < minSize.width() || newSize.height() < minSize.height()) {
|
||||
qWarning() << Q_FUNC_INFO << "New size doesn't respect size constraints";
|
||||
@@ -1332,9 +1348,6 @@ void ItemContainer::resize(QSize newSize) // Rename to setSize_recursive
|
||||
|
||||
const bool lengthChanged = (isVertical() && heightChanged) || (isHorizontal() && widthChanged);
|
||||
|
||||
if (m_childPercentages.isEmpty())
|
||||
updateChildPercentages();
|
||||
|
||||
setSize(newSize);
|
||||
|
||||
if (m_isResizing) {
|
||||
@@ -1346,14 +1359,24 @@ void ItemContainer::resize(QSize newSize) // Rename to setSize_recursive
|
||||
int remaining = totalNewLength;
|
||||
|
||||
int nextPos = 0;
|
||||
for (int i = 0, count = m_children.size(); i < count; ++i) {
|
||||
const QVector<double> childPercentages = this->childPercentages();
|
||||
const Item::List children = visibleChildren();
|
||||
for (int i = 0, count = children.size(); i < count; ++i) {
|
||||
const bool isLast = i == count - 1;
|
||||
|
||||
Item *item = m_children.at(i);
|
||||
const qreal childPercentage = m_childPercentages.at(i);
|
||||
Item *item = children.at(i);
|
||||
const qreal childPercentage = childPercentages.at(i);
|
||||
const int newItemLength = lengthChanged ? (isLast ? remaining
|
||||
: int(childPercentage * totalNewLength))
|
||||
: item->length(m_orientation);
|
||||
|
||||
if (newItemLength <= 0) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid resize. Dumping layout";
|
||||
root()->dumpLayout();
|
||||
Q_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
item->setPos(nextPos, m_orientation);
|
||||
nextPos += newItemLength + separatorThickness();
|
||||
remaining = remaining - newItemLength;
|
||||
@@ -1391,8 +1414,9 @@ void ItemContainer::dumpLayout(int level)
|
||||
: "* Layout: ";
|
||||
|
||||
qDebug().noquote() << indent << typeStr << m_orientation
|
||||
<< m_geometry << "r=" << m_geometry.right() << "b=" << m_geometry.bottom()
|
||||
<< "; this=" << this << beingInserted << visible;
|
||||
<< m_geometry /*<< "r=" << m_geometry.right() << "b=" << m_geometry.bottom()*/
|
||||
<< "; this=" << this << beingInserted << visible
|
||||
<< "; %=" << childPercentages();
|
||||
for (Item *item : qAsConst(m_children)) {
|
||||
item->dumpLayout(level + 1);
|
||||
}
|
||||
@@ -1400,11 +1424,31 @@ void ItemContainer::dumpLayout(int level)
|
||||
|
||||
void ItemContainer::updateChildPercentages()
|
||||
{
|
||||
m_childPercentages.clear();
|
||||
m_childPercentages.reserve(m_children.size());
|
||||
const int available = usableLength();
|
||||
for (Item *item : m_children)
|
||||
m_childPercentages << (1.0 * item->length(m_orientation)) / available;
|
||||
if (m_blockUpdatePercentages)
|
||||
return;
|
||||
|
||||
const int usable = usableLength();
|
||||
for (Item *item : m_children) {
|
||||
if (item->isVisible()) {
|
||||
item->m_sizingInfo.percentageWithinParent = (1.0 * item->length(m_orientation)) / usable;
|
||||
Q_ASSERT(!qFuzzyIsNull(item->m_sizingInfo.percentageWithinParent));
|
||||
} else {
|
||||
item->m_sizingInfo.percentageWithinParent = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVector<double> ItemContainer::childPercentages() const
|
||||
{
|
||||
QVector<double> percentages;
|
||||
percentages.reserve(m_children.size());
|
||||
|
||||
for (Item *item : m_children) {
|
||||
if (item->isVisible())
|
||||
percentages << item->m_sizingInfo.percentageWithinParent;
|
||||
}
|
||||
|
||||
return percentages;
|
||||
}
|
||||
|
||||
void ItemContainer::restorePlaceholder(Item *item)
|
||||
|
||||
@@ -168,6 +168,7 @@ struct SizingInfo {
|
||||
QSize maxSize = QSize(16777215, 16777215); // TODO: Not supported yet
|
||||
QSize proposedSize;
|
||||
bool isBeingInserted = false;
|
||||
double percentageWithinParent = 0.0;
|
||||
};
|
||||
|
||||
class ItemContainer;
|
||||
@@ -394,10 +395,12 @@ Q_SIGNALS:
|
||||
void numVisibleItemsChanged(int);
|
||||
void numItemsChanged();
|
||||
public:
|
||||
QVector<qreal> m_childPercentages;
|
||||
Item::List m_children;
|
||||
bool m_isResizing = false;
|
||||
bool m_isRoot = false;
|
||||
bool m_blockUpdatePercentages = false;
|
||||
private:
|
||||
QVector<double> childPercentages() const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,10 +25,24 @@
|
||||
|
||||
// TODO: namespace
|
||||
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
static int st = Item::separatorThickness();
|
||||
|
||||
static QtMessageHandler s_original = nullptr;
|
||||
static QString s_expectedWarning;
|
||||
|
||||
static void fatalWarningsMessageHandler(QtMsgType t, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
|
||||
s_original(t, context, msg);
|
||||
if (t == QtWarningMsg) {
|
||||
if (s_expectedWarning.isEmpty() ||!msg.contains(s_expectedWarning))
|
||||
qFatal("Got a warning, category=%s", context.category);
|
||||
}
|
||||
}
|
||||
|
||||
static std::unique_ptr<ItemContainer> createRoot()
|
||||
{
|
||||
auto root = new ItemContainer(new QWidget()); // todo WIDGET
|
||||
@@ -63,6 +77,7 @@ class TestMultiSplitter : public QObject
|
||||
public Q_SLOTS:
|
||||
void initTestCase()
|
||||
{
|
||||
s_original = qInstallMessageHandler(fatalWarningsMessageHandler);
|
||||
}
|
||||
|
||||
private Q_SLOTS:
|
||||
@@ -439,6 +454,8 @@ void TestMultiSplitter::tst_resize()
|
||||
|
||||
void TestMultiSplitter::tst_resizeWithConstraints()
|
||||
{
|
||||
s_expectedWarning = QStringLiteral("New size doesn't respect size constraints");
|
||||
|
||||
{
|
||||
// Test that resizing below minSize isn't permitted.
|
||||
|
||||
@@ -471,6 +488,8 @@ void TestMultiSplitter::tst_resizeWithConstraints()
|
||||
|
||||
// TODO: Resize further
|
||||
}
|
||||
|
||||
s_expectedWarning.clear();
|
||||
}
|
||||
|
||||
void TestMultiSplitter::tst_availableSize()
|
||||
|
||||
Reference in New Issue
Block a user