fix: button row wrong morph calc for fillWidth

This commit is contained in:
2 * r + 2 * t 2026-05-02 21:54:55 +10:00
parent 362863dd74
commit 8d3a915c49
2 changed files with 27 additions and 24 deletions

View file

@ -59,41 +59,51 @@ void ButtonRow::invalidate() {
} }
void ButtonRow::relayout() { void ButtonRow::relayout() {
const auto children = childItems(); const auto allChildren = childItems();
const auto nChildren = children.size();
QList<QQuickItem*> validChildren;
for (auto* const child : allChildren) {
if (child->isVisible() && !child->inherits("QQuickRepeater"))
validChildren.append(child);
}
const auto nChildren = validChildren.size();
const auto totalSpacing = static_cast<qreal>(nChildren - 1) * m_spacing; const auto totalSpacing = static_cast<qreal>(nChildren - 1) * m_spacing;
qreal reservedWidth = 0; qreal reservedWidth = 0;
qreal unreservedWidth = 0;
int fillWidthCount = 0; int fillWidthCount = 0;
qreal maxHeight = 0; qreal maxHeight = 0;
for (auto* const child : children) { for (auto* const child : validChildren) {
if (!child->isVisible())
continue;
maxHeight = qMax(maxHeight, child->implicitHeight()); maxHeight = qMax(maxHeight, child->implicitHeight());
const auto prop = child->property("fillWidth"); const auto prop = child->property("fillWidth");
if (!prop.isValid()) if (!prop.isValid())
continue; continue;
if (prop.toBool()) if (prop.toBool()) {
fillWidthCount++; fillWidthCount++;
else unreservedWidth += child->implicitWidth();
} else {
reservedWidth += child->implicitWidth(); reservedWidth += child->implicitWidth();
}
} }
if (fillWidthCount == 0) if (fillWidthCount == 0)
fillWidthCount = 1; // Avoid divide by 0 fillWidthCount = 1; // Avoid divide by 0
qreal accX = 0;
const auto widthPerItem = (width() - totalSpacing - reservedWidth) / static_cast<qreal>(fillWidthCount); const auto widthPerItem = (width() - totalSpacing - reservedWidth) / static_cast<qreal>(fillWidthCount);
for (int i = 0; i < nChildren; ++i) {
auto* const child = children[i];
if (!child->isVisible())
continue;
auto prevExtraWidth = i > 0 ? getMorphExpansion(children[i - 1]) : 0.0; QList<qreal> baseWidths;
auto nextExtraWidth = i < nChildren - 1 ? getMorphExpansion(children[i + 1]) : 0.0; baseWidths.reserve(nChildren);
for (auto* const child : validChildren)
baseWidths.append(child->property("fillWidth").toBool() ? widthPerItem : child->implicitWidth());
qreal accX = 0;
for (int i = 0; i < nChildren; ++i) {
auto* const child = validChildren[i];
auto prevExtraWidth = i > 0 ? getMorphExpansion(validChildren[i - 1], baseWidths[i - 1]) : 0.0;
auto nextExtraWidth = i < nChildren - 1 ? getMorphExpansion(validChildren[i + 1], baseWidths[i + 1]) : 0.0;
// Items at edges push by full amount, items in middle push by half // Items at edges push by full amount, items in middle push by half
if (i > 1) if (i > 1)
@ -101,9 +111,7 @@ void ButtonRow::relayout() {
if (i < nChildren - 2) if (i < nChildren - 2)
nextExtraWidth /= 2; nextExtraWidth /= 2;
const auto childWidth = child->property("fillWidth").toBool() ? widthPerItem : child->implicitWidth(); child->setWidth(baseWidths[i] + getMorphExpansion(child, baseWidths[i]) - prevExtraWidth - nextExtraWidth);
child->setWidth(childWidth + getMorphExpansion(child, childWidth) - prevExtraWidth - nextExtraWidth);
child->setHeight(maxHeight); child->setHeight(maxHeight);
child->setX(accX); child->setX(accX);
@ -111,14 +119,10 @@ void ButtonRow::relayout() {
accX += child->width() + m_spacing; accX += child->width() + m_spacing;
} }
setImplicitWidth(reservedWidth + totalSpacing); setImplicitWidth(reservedWidth + unreservedWidth + totalSpacing);
setImplicitHeight(maxHeight); setImplicitHeight(maxHeight);
} }
qreal ButtonRow::getMorphExpansion(const QQuickItem* item) {
return getMorphExpansion(item, item->implicitWidth());
}
qreal ButtonRow::getMorphExpansion(const QQuickItem* item, qreal width) { qreal ButtonRow::getMorphExpansion(const QQuickItem* item, qreal width) {
const auto prop = item->property("shapeMorphExpansion"); const auto prop = item->property("shapeMorphExpansion");
return width * (prop.isValid() ? prop.toReal() - 1 : 0.0); return width * (prop.isValid() ? prop.toReal() - 1 : 0.0);

View file

@ -28,7 +28,6 @@ private slots:
private: private:
void relayout(); void relayout();
static qreal getMorphExpansion(const QQuickItem* item);
static qreal getMorphExpansion(const QQuickItem* item, qreal width); static qreal getMorphExpansion(const QQuickItem* item, qreal width);
bool m_dirty; bool m_dirty;