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 <qobject.h>
 | 
				
			||||||
#include <qquickitem.h>
 | 
					#include <qquickitem.h>
 | 
				
			||||||
#include <qtmetamacros.h>
 | 
					 | 
				
			||||||
#include <qtypes.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "wrapper.hpp"
 | 
					#include "wrapper.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace qs::widgets {
 | 
					namespace qs::widgets {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MarginWrapperManager::MarginWrapperManager(QObject* parent): WrapperManager(parent) {
 | 
					MarginWrapperManager::MarginWrapperManager(QObject* parent): WrapperManager(parent) {
 | 
				
			||||||
	QObject::connect(
 | 
					 | 
				
			||||||
	    this,
 | 
					 | 
				
			||||||
	    &WrapperManager::initializedChildChanged,
 | 
					 | 
				
			||||||
	    this,
 | 
					 | 
				
			||||||
	    &MarginWrapperManager::onChildChanged
 | 
					 | 
				
			||||||
	);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	this->bTopMargin.setBinding([this] {
 | 
						this->bTopMargin.setBinding([this] {
 | 
				
			||||||
		return this->bExtraMargin
 | 
							return this->bExtraMargin
 | 
				
			||||||
		     + (this->bTopMarginSet.value() ? this->bTopMarginValue : this->bMargin);
 | 
							     + (this->bTopMarginSet.value() ? this->bTopMarginValue : this->bMargin);
 | 
				
			||||||
| 
						 | 
					@ -37,13 +28,46 @@ MarginWrapperManager::MarginWrapperManager(QObject* parent): WrapperManager(pare
 | 
				
			||||||
		     + (this->bRightMarginSet.value() ? this->bRightMarginValue : this->bMargin);
 | 
							     + (this->bRightMarginSet.value() ? this->bRightMarginValue : this->bMargin);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Coalesces updates via binding infrastructure
 | 
						this->bChildX.setBinding([this] {
 | 
				
			||||||
	this->bUpdateWatcher.setBinding([this] {
 | 
							if (this->bResizeChild) return this->bLeftMargin.value();
 | 
				
			||||||
		this->bTopMargin.value();
 | 
					
 | 
				
			||||||
		this->bBottomMargin.value();
 | 
							auto total = this->bLeftMargin + this->bRightMargin;
 | 
				
			||||||
		this->bLeftMargin.value();
 | 
							auto mul = total == 0 ? 0.5 : this->bLeftMargin / total;
 | 
				
			||||||
		this->bRightMargin.value();
 | 
							auto margin = this->bWrapperWidth - this->bChildImplicitWidth;
 | 
				
			||||||
		return 0;
 | 
							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,37 +75,25 @@ void MarginWrapperManager::componentComplete() {
 | 
				
			||||||
	this->WrapperManager::componentComplete();
 | 
						this->WrapperManager::componentComplete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->mWrapper) {
 | 
						if (this->mWrapper) {
 | 
				
			||||||
		QObject::connect(
 | 
							this->bWrapperWidth.setBinding([this] { return this->mWrapper->bindableWidth().value(); });
 | 
				
			||||||
		    this->mWrapper,
 | 
							this->bWrapperHeight.setBinding([this] { return this->mWrapper->bindableHeight().value(); });
 | 
				
			||||||
		    &QQuickItem::widthChanged,
 | 
						}
 | 
				
			||||||
		    this,
 | 
					 | 
				
			||||||
		    &MarginWrapperManager::updateChildX
 | 
					 | 
				
			||||||
		);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		QObject::connect(
 | 
					 | 
				
			||||||
		    this->mWrapper,
 | 
					 | 
				
			||||||
		    &QQuickItem::heightChanged,
 | 
					 | 
				
			||||||
		    this,
 | 
					 | 
				
			||||||
		    &MarginWrapperManager::updateChildY
 | 
					 | 
				
			||||||
		);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!this->mChild) this->updateGeometry();
 | 
					void MarginWrapperManager::disconnectChild() {
 | 
				
			||||||
 | 
						this->mChild->bindableX().setValue(0);
 | 
				
			||||||
 | 
						this->mChild->bindableY().setValue(0);
 | 
				
			||||||
 | 
						this->mChild->bindableWidth().setValue(0);
 | 
				
			||||||
 | 
						this->mChild->bindableHeight().setValue(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MarginWrapperManager::resizeChild() const { return this->mResizeChild; }
 | 
					void MarginWrapperManager::connectChild() {
 | 
				
			||||||
 | 
					 | 
				
			||||||
void MarginWrapperManager::setResizeChild(bool resizeChild) {
 | 
					 | 
				
			||||||
	if (resizeChild == this->mResizeChild) return;
 | 
					 | 
				
			||||||
	this->mResizeChild = resizeChild;
 | 
					 | 
				
			||||||
	this->updateGeometry();
 | 
					 | 
				
			||||||
	emit this->resizeChildChanged();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MarginWrapperManager::onChildChanged() {
 | 
					 | 
				
			||||||
	// QObject::disconnect in MarginWrapper handles disconnecting old item
 | 
						// 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(
 | 
						QObject::connect(
 | 
				
			||||||
	    this->mChild,
 | 
						    this->mChild,
 | 
				
			||||||
	    &QQuickItem::implicitWidthChanged,
 | 
						    &QQuickItem::implicitWidthChanged,
 | 
				
			||||||
| 
						 | 
					@ -95,97 +107,25 @@ void MarginWrapperManager::onChildChanged() {
 | 
				
			||||||
	    this,
 | 
						    this,
 | 
				
			||||||
	    &MarginWrapperManager::onChildImplicitHeightChanged
 | 
						    &MarginWrapperManager::onChildImplicitHeightChanged
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->updateGeometry();
 | 
						this->onChildImplicitWidthChanged();
 | 
				
			||||||
}
 | 
						this->onChildImplicitHeightChanged();
 | 
				
			||||||
 | 
					 | 
				
			||||||
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());
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MarginWrapperManager::onChildImplicitWidthChanged() {
 | 
					void MarginWrapperManager::onChildImplicitWidthChanged() {
 | 
				
			||||||
	if (!this->mChild || !this->mWrapper) return;
 | 
						this->bChildImplicitWidth = this->mChild->implicitWidth();
 | 
				
			||||||
	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();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MarginWrapperManager::onChildImplicitHeightChanged() {
 | 
					void MarginWrapperManager::onChildImplicitHeightChanged() {
 | 
				
			||||||
	if (!this->mChild || !this->mWrapper) return;
 | 
						this->bChildImplicitHeight = this->mChild->implicitHeight();
 | 
				
			||||||
	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();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MarginWrapperManager::updateGeometry() {
 | 
					void MarginWrapperManager::setWrapperImplicitWidth() {
 | 
				
			||||||
	if (!this->mWrapper) return;
 | 
						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
 | 
					} // namespace qs::widgets
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@
 | 
				
			||||||
#include <qtmetamacros.h>
 | 
					#include <qtmetamacros.h>
 | 
				
			||||||
#include <qtypes.h>
 | 
					#include <qtypes.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../core/util.hpp"
 | 
					 | 
				
			||||||
#include "wrapper.hpp"
 | 
					#include "wrapper.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace qs::widgets {
 | 
					namespace qs::widgets {
 | 
				
			||||||
| 
						 | 
					@ -69,7 +68,7 @@ class MarginWrapperManager: public WrapperManager {
 | 
				
			||||||
	Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin RESET resetRightMargin NOTIFY rightMarginChanged FINAL);
 | 
						Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin RESET resetRightMargin NOTIFY rightMarginChanged FINAL);
 | 
				
			||||||
	/// Determines if child item should be resized larger than its implicit size if
 | 
						/// Determines if child item should be resized larger than its implicit size if
 | 
				
			||||||
	/// the parent is resized larger than its implicit size. Defaults to false.
 | 
						/// the parent is resized larger than its implicit size. Defaults to false.
 | 
				
			||||||
	Q_PROPERTY(bool resizeChild READ resizeChild WRITE setResizeChild NOTIFY resizeChildChanged FINAL);
 | 
						Q_PROPERTY(bool resizeChild READ default WRITE default BINDABLE bindableResizeChild NOTIFY resizeChildChanged FINAL);
 | 
				
			||||||
	// clang-format on
 | 
						// clang-format on
 | 
				
			||||||
	QML_ELEMENT;
 | 
						QML_ELEMENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,8 +108,7 @@ public:
 | 
				
			||||||
		this->bRightMarginSet = true;
 | 
							this->bRightMarginSet = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] bool resizeChild() const;
 | 
						[[nodiscard]] QBindable<bool> bindableResizeChild() { return &this->bResizeChild; }
 | 
				
			||||||
	void setResizeChild(bool resizeChild);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void marginChanged();
 | 
						void marginChanged();
 | 
				
			||||||
| 
						 | 
					@ -122,42 +120,50 @@ signals:
 | 
				
			||||||
	void resizeChildChanged();
 | 
						void resizeChildChanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
	void onChildChanged();
 | 
					 | 
				
			||||||
	void updateChildX();
 | 
					 | 
				
			||||||
	void updateChildY();
 | 
					 | 
				
			||||||
	void onChildImplicitWidthChanged();
 | 
						void onChildImplicitWidthChanged();
 | 
				
			||||||
	void onChildImplicitHeightChanged();
 | 
						void onChildImplicitHeightChanged();
 | 
				
			||||||
 | 
						void setWrapperImplicitWidth();
 | 
				
			||||||
 | 
						void setWrapperImplicitHeight();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						void disconnectChild() override;
 | 
				
			||||||
 | 
						void connectChild() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void updateGeometry();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] qreal targetChildX() const;
 | 
					 | 
				
			||||||
	[[nodiscard]] qreal targetChildY() const;
 | 
					 | 
				
			||||||
	[[nodiscard]] qreal targetChildWidth() const;
 | 
					 | 
				
			||||||
	[[nodiscard]] qreal targetChildHeight() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool mResizeChild = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// clang-format off
 | 
						// clang-format off
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bResizeChild);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bMargin, &MarginWrapperManager::marginChanged);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bMargin, &MarginWrapperManager::marginChanged);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bExtraMargin, &MarginWrapperManager::baseMarginChanged);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bExtraMargin, &MarginWrapperManager::baseMarginChanged);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bTopMarginValue);
 | 
					 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bBottomMarginValue);
 | 
					 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bLeftMarginValue);
 | 
					 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bRightMarginValue);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bTopMarginSet);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bTopMarginSet);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bBottomMarginSet);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bBottomMarginSet);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bLeftMarginSet);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bLeftMarginSet);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bRightMarginSet);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bRightMarginSet);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bTopMarginValue);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bBottomMarginValue);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bLeftMarginValue);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bRightMarginValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// computed
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bTopMargin, &MarginWrapperManager::topMarginChanged);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bTopMargin, &MarginWrapperManager::topMarginChanged);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bBottomMargin, &MarginWrapperManager::bottomMarginChanged);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bBottomMargin, &MarginWrapperManager::bottomMarginChanged);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bLeftMargin, &MarginWrapperManager::leftMarginChanged);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bLeftMargin, &MarginWrapperManager::leftMarginChanged);
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bRightMargin, &MarginWrapperManager::rightMarginChanged);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bRightMargin, &MarginWrapperManager::rightMarginChanged);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, int, bUpdateWatcher);
 | 
						// bound
 | 
				
			||||||
	QS_BINDING_SUBSCRIBE_METHOD(MarginWrapperManager, bUpdateWatcher, updateGeometry, subscribe);
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bWrapperWidth);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bWrapperHeight);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bChildImplicitWidth);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bChildImplicitHeight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// computed
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bChildX);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bChildY);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bChildWidth);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bChildHeight);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bWrapperImplicitWidth, &MarginWrapperManager::setWrapperImplicitWidth);
 | 
				
			||||||
 | 
						Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bWrapperImplicitHeight, &MarginWrapperManager::setWrapperImplicitHeight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// clang-format on
 | 
						// clang-format on
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										150
									
								
								src/widgets/test/manual/marginwrapper.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								src/widgets/test/manual/marginwrapper.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,150 @@
 | 
				
			||||||
 | 
					import QtQuick
 | 
				
			||||||
 | 
					import QtQuick.Layouts
 | 
				
			||||||
 | 
					import QtQuick.Controls
 | 
				
			||||||
 | 
					import Quickshell
 | 
				
			||||||
 | 
					import Quickshell.Widgets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FloatingWindow {
 | 
				
			||||||
 | 
						color: contentItem.palette.window
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ColumnLayout {
 | 
				
			||||||
 | 
							anchors.fill: parent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Item {
 | 
				
			||||||
 | 
								Layout.fillWidth: true
 | 
				
			||||||
 | 
								Layout.fillHeight: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Rectangle {
 | 
				
			||||||
 | 
									anchors.centerIn: parent
 | 
				
			||||||
 | 
									width: stretchCb.checked ? wrapperWidthSlider.value : implicitWidth
 | 
				
			||||||
 | 
									height: stretchCb.checked ? wrapperHeightSlider.value : implicitHeight
 | 
				
			||||||
 | 
									border.color: "black"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									MarginWrapperManager {
 | 
				
			||||||
 | 
										margin: marginSlider.value
 | 
				
			||||||
 | 
										extraMargin: extraMarginSlider.value
 | 
				
			||||||
 | 
										resizeChild: resizeCb.checked
 | 
				
			||||||
 | 
										topMargin: separateMarginsCb.checked ? topMarginSlider.value : undefined
 | 
				
			||||||
 | 
										bottomMargin: separateMarginsCb.checked ? bottomMarginSlider.value : undefined
 | 
				
			||||||
 | 
										leftMargin: separateMarginsCb.checked ? leftMarginSlider.value : undefined
 | 
				
			||||||
 | 
										rightMargin: separateMarginsCb.checked ? rightMarginSlider.value : undefined
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									Rectangle {
 | 
				
			||||||
 | 
										color: "green"
 | 
				
			||||||
 | 
										implicitWidth: implicitWidthSlider.value
 | 
				
			||||||
 | 
										implicitHeight: implicitHeightSlider.value
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RowLayout {
 | 
				
			||||||
 | 
								Layout.fillWidth: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								CheckBox {
 | 
				
			||||||
 | 
									id: stretchCb
 | 
				
			||||||
 | 
									text: "Stretch"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								CheckBox {
 | 
				
			||||||
 | 
									id: resizeCb
 | 
				
			||||||
 | 
									text: "Resize Child"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								CheckBox {
 | 
				
			||||||
 | 
									id: separateMarginsCb
 | 
				
			||||||
 | 
									text: "Individual Margins"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RowLayout {
 | 
				
			||||||
 | 
								Layout.fillWidth: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Stretch Width" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: wrapperWidthSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: 0; to: 300; value: 200
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Stretch Height" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: wrapperHeightSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: 0; to: 300; value: 200
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RowLayout {
 | 
				
			||||||
 | 
								Layout.fillWidth: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Implicit Width" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: implicitWidthSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: 0; to: 200; value: 100
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Implicit Height" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: implicitHeightSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: 0; to: 200; value: 100
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RowLayout {
 | 
				
			||||||
 | 
								Layout.fillWidth: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Margin" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: marginSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: -100; to: 200; value: 50
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Extra" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: extraMarginSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: -100; to: 200; value: 0
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RowLayout {
 | 
				
			||||||
 | 
								Layout.fillWidth: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Top Margin" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: topMarginSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: -100; to: 200; value: 50
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Bottom Margin" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: bottomMarginSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: -100; to: 200; value: 50
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RowLayout {
 | 
				
			||||||
 | 
								Layout.fillWidth: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Left Margin" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: leftMarginSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: -100; to: 200; value: 50
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Label { text: "Right Margin" }
 | 
				
			||||||
 | 
								Slider {
 | 
				
			||||||
 | 
									id: rightMarginSlider
 | 
				
			||||||
 | 
									Layout.fillWidth: true
 | 
				
			||||||
 | 
									from: -100; to: 200; value: 50
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -61,6 +61,7 @@ void WrapperManager::setChild(QQuickItem* child) {
 | 
				
			||||||
		if (this->mChild->parentItem() == this->mWrapper) {
 | 
							if (this->mChild->parentItem() == this->mWrapper) {
 | 
				
			||||||
			this->mChild->setParentItem(nullptr);
 | 
								this->mChild->setParentItem(nullptr);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							this->disconnectChild();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->mChild = child;
 | 
						this->mChild = child;
 | 
				
			||||||
| 
						 | 
					@ -78,6 +79,8 @@ void WrapperManager::setChild(QQuickItem* child) {
 | 
				
			||||||
		if (auto* wrapper = this->mWrapper) {
 | 
							if (auto* wrapper = this->mWrapper) {
 | 
				
			||||||
			child->setParentItem(wrapper);
 | 
								child->setParentItem(wrapper);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->connectChild();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	emit this->initializedChildChanged();
 | 
						emit this->initializedChildChanged();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,6 +137,9 @@ protected:
 | 
				
			||||||
	void printChildCountWarning() const;
 | 
						void printChildCountWarning() const;
 | 
				
			||||||
	void updateGeometry();
 | 
						void updateGeometry();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void disconnectChild() {};
 | 
				
			||||||
 | 
						virtual void connectChild() {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QQuickItem* mWrapper = nullptr;
 | 
						QQuickItem* mWrapper = nullptr;
 | 
				
			||||||
	QQuickItem* mAssignedWrapper = nullptr;
 | 
						QQuickItem* mAssignedWrapper = nullptr;
 | 
				
			||||||
	QPointer<QQuickItem> mDefaultChild;
 | 
						QPointer<QQuickItem> mDefaultChild;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue