forked from quickshell/quickshell
widgets/wrapper: use bindable properties everywhere
Also fixes changes to margin not updating geometry
This commit is contained in:
parent
8b5b12b722
commit
e135de9ec6
5 changed files with 257 additions and 155 deletions
|
@ -2,21 +2,12 @@
|
|||
|
||||
#include <qobject.h>
|
||||
#include <qquickitem.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
#include "wrapper.hpp"
|
||||
|
||||
namespace qs::widgets {
|
||||
|
||||
MarginWrapperManager::MarginWrapperManager(QObject* parent): WrapperManager(parent) {
|
||||
QObject::connect(
|
||||
this,
|
||||
&WrapperManager::initializedChildChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onChildChanged
|
||||
);
|
||||
|
||||
this->bTopMargin.setBinding([this] {
|
||||
return this->bExtraMargin
|
||||
+ (this->bTopMarginSet.value() ? this->bTopMarginValue : this->bMargin);
|
||||
|
@ -37,13 +28,46 @@ MarginWrapperManager::MarginWrapperManager(QObject* parent): WrapperManager(pare
|
|||
+ (this->bRightMarginSet.value() ? this->bRightMarginValue : this->bMargin);
|
||||
});
|
||||
|
||||
// Coalesces updates via binding infrastructure
|
||||
this->bUpdateWatcher.setBinding([this] {
|
||||
this->bTopMargin.value();
|
||||
this->bBottomMargin.value();
|
||||
this->bLeftMargin.value();
|
||||
this->bRightMargin.value();
|
||||
return 0;
|
||||
this->bChildX.setBinding([this] {
|
||||
if (this->bResizeChild) return this->bLeftMargin.value();
|
||||
|
||||
auto total = this->bLeftMargin + this->bRightMargin;
|
||||
auto mul = total == 0 ? 0.5 : this->bLeftMargin / total;
|
||||
auto margin = this->bWrapperWidth - this->bChildImplicitWidth;
|
||||
return margin * mul;
|
||||
});
|
||||
|
||||
this->bChildY.setBinding([this] {
|
||||
if (this->bResizeChild) return this->bTopMargin.value();
|
||||
|
||||
auto total = this->bTopMargin + this->bBottomMargin;
|
||||
auto mul = total == 0 ? 0.5 : this->bTopMargin / total;
|
||||
auto margin = this->bWrapperHeight - this->bChildImplicitHeight;
|
||||
return margin * mul;
|
||||
});
|
||||
|
||||
this->bChildWidth.setBinding([this] {
|
||||
if (this->bResizeChild) {
|
||||
return this->bWrapperWidth - (this->bLeftMargin + this->bRightMargin);
|
||||
} else {
|
||||
return this->bChildImplicitWidth.value();
|
||||
}
|
||||
});
|
||||
|
||||
this->bChildHeight.setBinding([this] {
|
||||
if (this->bResizeChild) {
|
||||
return this->bWrapperHeight - (this->bTopMargin + this->bBottomMargin);
|
||||
} else {
|
||||
return this->bChildImplicitHeight.value();
|
||||
}
|
||||
});
|
||||
|
||||
this->bWrapperImplicitWidth.setBinding([this] {
|
||||
return this->bChildImplicitWidth.value() + this->bLeftMargin + this->bRightMargin;
|
||||
});
|
||||
|
||||
this->bWrapperImplicitHeight.setBinding([this] {
|
||||
return this->bChildImplicitHeight.value() + this->bTopMargin + this->bBottomMargin;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -51,141 +75,57 @@ void MarginWrapperManager::componentComplete() {
|
|||
this->WrapperManager::componentComplete();
|
||||
|
||||
if (this->mWrapper) {
|
||||
QObject::connect(
|
||||
this->mWrapper,
|
||||
&QQuickItem::widthChanged,
|
||||
this,
|
||||
&MarginWrapperManager::updateChildX
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
this->mWrapper,
|
||||
&QQuickItem::heightChanged,
|
||||
this,
|
||||
&MarginWrapperManager::updateChildY
|
||||
);
|
||||
this->bWrapperWidth.setBinding([this] { return this->mWrapper->bindableWidth().value(); });
|
||||
this->bWrapperHeight.setBinding([this] { return this->mWrapper->bindableHeight().value(); });
|
||||
}
|
||||
|
||||
if (!this->mChild) this->updateGeometry();
|
||||
}
|
||||
|
||||
bool MarginWrapperManager::resizeChild() const { return this->mResizeChild; }
|
||||
|
||||
void MarginWrapperManager::setResizeChild(bool resizeChild) {
|
||||
if (resizeChild == this->mResizeChild) return;
|
||||
this->mResizeChild = resizeChild;
|
||||
this->updateGeometry();
|
||||
emit this->resizeChildChanged();
|
||||
void MarginWrapperManager::disconnectChild() {
|
||||
this->mChild->bindableX().setValue(0);
|
||||
this->mChild->bindableY().setValue(0);
|
||||
this->mChild->bindableWidth().setValue(0);
|
||||
this->mChild->bindableHeight().setValue(0);
|
||||
}
|
||||
|
||||
void MarginWrapperManager::onChildChanged() {
|
||||
void MarginWrapperManager::connectChild() {
|
||||
// QObject::disconnect in MarginWrapper handles disconnecting old item
|
||||
this->mChild->bindableX().setBinding([this] { return this->bChildX.value(); });
|
||||
this->mChild->bindableY().setBinding([this] { return this->bChildY.value(); });
|
||||
this->mChild->bindableWidth().setBinding([this] { return this->bChildWidth.value(); });
|
||||
this->mChild->bindableHeight().setBinding([this] { return this->bChildHeight.value(); });
|
||||
|
||||
if (this->mChild) {
|
||||
QObject::connect(
|
||||
this->mChild,
|
||||
&QQuickItem::implicitWidthChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onChildImplicitWidthChanged
|
||||
);
|
||||
QObject::connect(
|
||||
this->mChild,
|
||||
&QQuickItem::implicitWidthChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onChildImplicitWidthChanged
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
this->mChild,
|
||||
&QQuickItem::implicitHeightChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onChildImplicitHeightChanged
|
||||
);
|
||||
}
|
||||
QObject::connect(
|
||||
this->mChild,
|
||||
&QQuickItem::implicitHeightChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onChildImplicitHeightChanged
|
||||
);
|
||||
|
||||
this->updateGeometry();
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::targetChildWidth() const {
|
||||
auto max = this->mWrapper->width() - (this->bLeftMargin + this->bRightMargin);
|
||||
|
||||
if (this->mResizeChild) return max;
|
||||
else return this->mChild->implicitWidth();
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::targetChildHeight() const {
|
||||
auto max = this->mWrapper->height() - (this->bTopMargin + this->bBottomMargin);
|
||||
|
||||
if (this->mResizeChild) return max;
|
||||
else return this->mChild->implicitHeight();
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::targetChildX() const {
|
||||
if (this->mResizeChild) return this->bLeftMargin;
|
||||
else {
|
||||
auto total = this->bLeftMargin + this->bRightMargin;
|
||||
auto mul = total == 0 ? 0.5 : this->bLeftMargin / total;
|
||||
auto margin = this->mWrapper->width() - this->mChild->implicitWidth();
|
||||
return margin * mul;
|
||||
}
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::targetChildY() const {
|
||||
if (this->mResizeChild) return this->bTopMargin;
|
||||
else {
|
||||
auto total = this->bTopMargin + this->bBottomMargin;
|
||||
auto mul = total == 0 ? 0.5 : this->bTopMargin / total;
|
||||
auto margin = this->mWrapper->height() - this->mChild->implicitHeight();
|
||||
return margin * mul;
|
||||
}
|
||||
}
|
||||
|
||||
void MarginWrapperManager::updateChildX() {
|
||||
if (!this->mChild || !this->mWrapper) return;
|
||||
this->mChild->setX(this->targetChildX());
|
||||
this->mChild->setWidth(this->targetChildWidth());
|
||||
}
|
||||
|
||||
void MarginWrapperManager::updateChildY() {
|
||||
if (!this->mChild || !this->mWrapper) return;
|
||||
this->mChild->setY(this->targetChildY());
|
||||
this->mChild->setHeight(this->targetChildHeight());
|
||||
this->onChildImplicitWidthChanged();
|
||||
this->onChildImplicitHeightChanged();
|
||||
}
|
||||
|
||||
void MarginWrapperManager::onChildImplicitWidthChanged() {
|
||||
if (!this->mChild || !this->mWrapper) return;
|
||||
this->mWrapper->setImplicitWidth(
|
||||
this->mChild->implicitWidth() + this->bLeftMargin + this->bRightMargin
|
||||
);
|
||||
|
||||
// If the implicit width change does not result in an actual width change,
|
||||
// this will not be called anywhere else.
|
||||
this->updateChildX();
|
||||
this->bChildImplicitWidth = this->mChild->implicitWidth();
|
||||
}
|
||||
|
||||
void MarginWrapperManager::onChildImplicitHeightChanged() {
|
||||
if (!this->mChild || !this->mWrapper) return;
|
||||
this->mWrapper->setImplicitHeight(
|
||||
this->mChild->implicitHeight() + this->bTopMargin + this->bBottomMargin
|
||||
);
|
||||
|
||||
// If the implicit height change does not result in an actual height change,
|
||||
// this will not be called anywhere else.
|
||||
this->updateChildY();
|
||||
this->bChildImplicitHeight = this->mChild->implicitHeight();
|
||||
}
|
||||
|
||||
void MarginWrapperManager::updateGeometry() {
|
||||
if (!this->mWrapper) return;
|
||||
void MarginWrapperManager::setWrapperImplicitWidth() {
|
||||
if (this->mWrapper) this->mWrapper->setImplicitWidth(this->bWrapperImplicitWidth);
|
||||
}
|
||||
|
||||
if (this->mChild) {
|
||||
this->mWrapper->setImplicitWidth(
|
||||
this->mChild->implicitWidth() + this->bLeftMargin + this->bRightMargin
|
||||
);
|
||||
this->mWrapper->setImplicitHeight(
|
||||
this->mChild->implicitHeight() + this->bTopMargin + this->bBottomMargin
|
||||
);
|
||||
this->mChild->setX(this->targetChildX());
|
||||
this->mChild->setY(this->targetChildY());
|
||||
this->mChild->setWidth(this->targetChildWidth());
|
||||
this->mChild->setHeight(this->targetChildHeight());
|
||||
} else {
|
||||
this->mWrapper->setImplicitWidth(this->bLeftMargin + this->bRightMargin);
|
||||
this->mWrapper->setImplicitHeight(this->bTopMargin + this->bBottomMargin);
|
||||
}
|
||||
void MarginWrapperManager::setWrapperImplicitHeight() {
|
||||
if (this->mWrapper) this->mWrapper->setImplicitHeight(this->bWrapperImplicitHeight);
|
||||
}
|
||||
|
||||
} // namespace qs::widgets
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue