forked from quickshell/quickshell
		
	widgets/wrapper: support overriding implicit size
This commit is contained in:
		
							parent
							
								
									e135de9ec6
								
							
						
					
					
						commit
						3cf96ecf97
					
				
					 7 changed files with 146 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -41,6 +41,16 @@ ClippingRectangle {
 | 
			
		|||
	/// 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.
 | 
			
		||||
	property /*bool*/alias resizeChild: manager.resizeChild
 | 
			
		||||
	/// Overrides the implicit width of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its left and right margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	property /*real*/alias implicitWidth: manager.implicitWidth
 | 
			
		||||
	/// Overrides the implicit height of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its top and bottom margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	property /*real*/alias implicitHeight: manager.implicitHeight
 | 
			
		||||
	/// See @@WrapperManager.child for details.
 | 
			
		||||
	property alias child: manager.child
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,6 +55,16 @@ Item {
 | 
			
		|||
	/// 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.
 | 
			
		||||
	property /*bool*/alias resizeChild: manager.resizeChild
 | 
			
		||||
	/// Overrides the implicit width of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its left and right margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	property /*real*/alias implicitWidth: manager.implicitWidth
 | 
			
		||||
	/// Overrides the implicit height of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its top and bottom margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	property /*real*/alias implicitHeight: manager.implicitHeight
 | 
			
		||||
	/// See @@WrapperManager.child for details.
 | 
			
		||||
	property /*Item*/alias child: manager.child
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,6 +43,16 @@ MouseArea {
 | 
			
		|||
	/// 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.
 | 
			
		||||
	property /*bool*/alias resizeChild: manager.resizeChild
 | 
			
		||||
	/// Overrides the implicit width of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its left and right margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	property /*real*/alias implicitWidth: manager.implicitWidth
 | 
			
		||||
	/// Overrides the implicit height of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its top and bottom margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	property /*real*/alias implicitHeight: manager.implicitHeight
 | 
			
		||||
	/// See @@WrapperManager.child for details.
 | 
			
		||||
	property /*Item*/alias child: manager.child
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,16 @@ Rectangle {
 | 
			
		|||
	/// 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.
 | 
			
		||||
	property /*bool*/alias resizeChild: manager.resizeChild
 | 
			
		||||
	/// Overrides the implicit width of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its left and right margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	property /*real*/alias implicitWidth: manager.implicitWidth
 | 
			
		||||
	/// Overrides the implicit height of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its top and bottom margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	property /*real*/alias implicitHeight: manager.implicitHeight
 | 
			
		||||
	/// See @@WrapperManager.child for details.
 | 
			
		||||
	property alias child: manager.child
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
 | 
			
		||||
#include <qobject.h>
 | 
			
		||||
#include <qquickitem.h>
 | 
			
		||||
#include <qtmetamacros.h>
 | 
			
		||||
 | 
			
		||||
#include "wrapper.hpp"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,22 +11,26 @@ namespace qs::widgets {
 | 
			
		|||
MarginWrapperManager::MarginWrapperManager(QObject* parent): WrapperManager(parent) {
 | 
			
		||||
	this->bTopMargin.setBinding([this] {
 | 
			
		||||
		return this->bExtraMargin
 | 
			
		||||
		     + (this->bTopMarginSet.value() ? this->bTopMarginValue : this->bMargin);
 | 
			
		||||
		     + (this->bOverrides.value().testFlag(TopMargin) ? this->bTopMarginOverride : this->bMargin
 | 
			
		||||
		     );
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	this->bBottomMargin.setBinding([this] {
 | 
			
		||||
		return this->bExtraMargin
 | 
			
		||||
		     + (this->bBottomMarginSet.value() ? this->bBottomMarginValue : this->bMargin);
 | 
			
		||||
		     + (this->bOverrides.value().testFlag(BottomMargin) ? this->bBottomMarginOverride
 | 
			
		||||
		                                                        : this->bMargin);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	this->bLeftMargin.setBinding([this] {
 | 
			
		||||
		return this->bExtraMargin
 | 
			
		||||
		     + (this->bLeftMarginSet.value() ? this->bLeftMarginValue : this->bMargin);
 | 
			
		||||
		     + (this->bOverrides.value().testFlag(LeftMargin) ? this->bLeftMarginOverride
 | 
			
		||||
		                                                      : this->bMargin);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	this->bRightMargin.setBinding([this] {
 | 
			
		||||
		return this->bExtraMargin
 | 
			
		||||
		     + (this->bRightMarginSet.value() ? this->bRightMarginValue : this->bMargin);
 | 
			
		||||
		     + (this->bOverrides.value().testFlag(RightMargin) ? this->bRightMarginOverride
 | 
			
		||||
		                                                       : this->bMargin);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	this->bChildX.setBinding([this] {
 | 
			
		||||
| 
						 | 
				
			
			@ -63,11 +68,19 @@ MarginWrapperManager::MarginWrapperManager(QObject* parent): WrapperManager(pare
 | 
			
		|||
	});
 | 
			
		||||
 | 
			
		||||
	this->bWrapperImplicitWidth.setBinding([this] {
 | 
			
		||||
		return this->bChildImplicitWidth.value() + this->bLeftMargin + this->bRightMargin;
 | 
			
		||||
		if (this->bOverrides.value().testFlag(ImplicitWidth)) {
 | 
			
		||||
			return this->bImplicitWidthOverride.value();
 | 
			
		||||
		} else {
 | 
			
		||||
			return this->bChildImplicitWidth.value() + this->bLeftMargin + this->bRightMargin;
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	this->bWrapperImplicitHeight.setBinding([this] {
 | 
			
		||||
		return this->bChildImplicitHeight.value() + this->bTopMargin + this->bBottomMargin;
 | 
			
		||||
		if (this->bOverrides.value().testFlag(ImplicitHeight)) {
 | 
			
		||||
			return this->bImplicitHeightOverride.value();
 | 
			
		||||
		} else {
 | 
			
		||||
			return this->bChildImplicitHeight.value() + this->bLeftMargin + this->bRightMargin;
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -122,10 +135,12 @@ void MarginWrapperManager::onChildImplicitHeightChanged() {
 | 
			
		|||
 | 
			
		||||
void MarginWrapperManager::setWrapperImplicitWidth() {
 | 
			
		||||
	if (this->mWrapper) this->mWrapper->setImplicitWidth(this->bWrapperImplicitWidth);
 | 
			
		||||
	emit this->implicitWidthChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MarginWrapperManager::setWrapperImplicitHeight() {
 | 
			
		||||
	if (this->mWrapper) this->mWrapper->setImplicitHeight(this->bWrapperImplicitHeight);
 | 
			
		||||
	emit this->implicitHeightChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace qs::widgets
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <qflags.h>
 | 
			
		||||
#include <qobject.h>
 | 
			
		||||
#include <qproperty.h>
 | 
			
		||||
#include <qqmlintegration.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +70,16 @@ class MarginWrapperManager: public WrapperManager {
 | 
			
		|||
	/// 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.
 | 
			
		||||
	Q_PROPERTY(bool resizeChild READ default WRITE default BINDABLE bindableResizeChild NOTIFY resizeChildChanged FINAL);
 | 
			
		||||
	/// Overrides the implicit width of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its left and right margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth RESET resetImplicitWidth NOTIFY implicitWidthChanged FINAL);
 | 
			
		||||
	/// Overrides the implicit height of the wrapper.
 | 
			
		||||
	///
 | 
			
		||||
	/// Defaults to the implicit width of the content item plus its top and bottom margin,
 | 
			
		||||
	/// and may be reset by assigning `undefined`.
 | 
			
		||||
	Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight RESET resetImplicitHeight NOTIFY implicitHeightChanged FINAL);
 | 
			
		||||
	// clang-format on
 | 
			
		||||
	QML_ELEMENT;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -81,35 +92,61 @@ public:
 | 
			
		|||
	[[nodiscard]] QBindable<qreal> bindableExtraMargin() { return &this->bExtraMargin; }
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] qreal topMargin() const { return this->bTopMargin.value(); }
 | 
			
		||||
	void resetTopMargin() { this->bTopMarginSet = false; }
 | 
			
		||||
	void resetTopMargin() { this->bOverrides = this->bOverrides.value() & ~TopMargin; }
 | 
			
		||||
	void setTopMargin(qreal topMargin) {
 | 
			
		||||
		this->bTopMarginValue = topMargin;
 | 
			
		||||
		this->bTopMarginSet = true;
 | 
			
		||||
		this->bTopMarginOverride = topMargin;
 | 
			
		||||
		this->bOverrides = this->bOverrides.value() | TopMargin;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] qreal bottomMargin() const { return this->bBottomMargin.value(); }
 | 
			
		||||
	void resetBottomMargin() { this->bBottomMarginSet = false; }
 | 
			
		||||
	void resetBottomMargin() { this->bOverrides = this->bOverrides.value() & ~BottomMargin; }
 | 
			
		||||
	void setBottomMargin(qreal bottomMargin) {
 | 
			
		||||
		this->bBottomMarginValue = bottomMargin;
 | 
			
		||||
		this->bBottomMarginSet = true;
 | 
			
		||||
		this->bBottomMarginOverride = bottomMargin;
 | 
			
		||||
		this->bOverrides = this->bOverrides.value() | BottomMargin;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] qreal leftMargin() const { return this->bLeftMargin.value(); }
 | 
			
		||||
	void resetLeftMargin() { this->bLeftMarginSet = false; }
 | 
			
		||||
	void resetLeftMargin() { this->bOverrides = this->bOverrides.value() & ~LeftMargin; }
 | 
			
		||||
	void setLeftMargin(qreal leftMargin) {
 | 
			
		||||
		this->bLeftMarginValue = leftMargin;
 | 
			
		||||
		this->bLeftMarginSet = true;
 | 
			
		||||
		this->bLeftMarginOverride = leftMargin;
 | 
			
		||||
		this->bOverrides = this->bOverrides.value() | LeftMargin;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] qreal rightMargin() const { return this->bRightMargin.value(); }
 | 
			
		||||
	void resetRightMargin() { this->bRightMarginSet = false; }
 | 
			
		||||
	void resetRightMargin() { this->bOverrides = this->bOverrides.value() & ~RightMargin; }
 | 
			
		||||
	void setRightMargin(qreal rightMargin) {
 | 
			
		||||
		this->bRightMarginValue = rightMargin;
 | 
			
		||||
		this->bRightMarginSet = true;
 | 
			
		||||
		this->bRightMarginOverride = rightMargin;
 | 
			
		||||
		this->bOverrides = this->bOverrides.value() | RightMargin;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] QBindable<bool> bindableResizeChild() { return &this->bResizeChild; }
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] qreal implicitWidth() const { return this->bWrapperImplicitWidth.value(); }
 | 
			
		||||
	void resetImplicitWidth() { this->bOverrides = this->bOverrides.value() & ~ImplicitWidth; }
 | 
			
		||||
	void setImplicitWidth(qreal implicitWidth) {
 | 
			
		||||
		this->bImplicitWidthOverride = implicitWidth;
 | 
			
		||||
		this->bOverrides = this->bOverrides.value() | ImplicitWidth;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] qreal implicitHeight() const { return this->bWrapperImplicitHeight.value(); }
 | 
			
		||||
	void resetImplicitHeight() { this->bOverrides = this->bOverrides.value() & ~ImplicitHeight; }
 | 
			
		||||
	void setImplicitHeight(qreal implicitHeight) {
 | 
			
		||||
		this->bImplicitHeightOverride = implicitHeight;
 | 
			
		||||
		this->bOverrides = this->bOverrides.value() | ImplicitHeight;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// has to be public for flag operator definitions
 | 
			
		||||
	enum OverrideFlag : quint8 {
 | 
			
		||||
		ImplicitWidth = 0b1,
 | 
			
		||||
		ImplicitHeight = 0b10,
 | 
			
		||||
		TopMargin = 0b100,
 | 
			
		||||
		BottomMargin = 0b1000,
 | 
			
		||||
		LeftMargin = 0b10000,
 | 
			
		||||
		RightMargin = 0b100000,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Q_DECLARE_FLAGS(OverrideFlags, OverrideFlag);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
	void marginChanged();
 | 
			
		||||
	void baseMarginChanged();
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +155,8 @@ signals:
 | 
			
		|||
	void leftMarginChanged();
 | 
			
		||||
	void rightMarginChanged();
 | 
			
		||||
	void resizeChildChanged();
 | 
			
		||||
	void implicitWidthChanged();
 | 
			
		||||
	void implicitHeightChanged();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	void onChildImplicitWidthChanged();
 | 
			
		||||
| 
						 | 
				
			
			@ -135,14 +174,13 @@ private:
 | 
			
		|||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bMargin, &MarginWrapperManager::marginChanged);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bExtraMargin, &MarginWrapperManager::baseMarginChanged);
 | 
			
		||||
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bTopMarginSet);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bBottomMarginSet);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bLeftMarginSet);
 | 
			
		||||
	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);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, OverrideFlags, bOverrides);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bImplicitWidthOverride);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bImplicitHeightOverride);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bTopMarginOverride);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bBottomMarginOverride);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bLeftMarginOverride);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bRightMarginOverride);
 | 
			
		||||
 | 
			
		||||
	// computed
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bTopMargin, &MarginWrapperManager::topMarginChanged);
 | 
			
		||||
| 
						 | 
				
			
			@ -167,4 +205,6 @@ private:
 | 
			
		|||
	// clang-format on
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Q_DECLARE_OPERATORS_FOR_FLAGS(MarginWrapperManager::OverrideFlags);
 | 
			
		||||
 | 
			
		||||
} // namespace qs::widgets
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,8 @@ FloatingWindow {
 | 
			
		|||
					bottomMargin: separateMarginsCb.checked ? bottomMarginSlider.value : undefined
 | 
			
		||||
					leftMargin: separateMarginsCb.checked ? leftMarginSlider.value : undefined
 | 
			
		||||
					rightMargin: separateMarginsCb.checked ? rightMarginSlider.value : undefined
 | 
			
		||||
					implicitWidth: parentImplicitSizeCb.checked ? parentImplicitWidthSlider.value : undefined
 | 
			
		||||
					implicitHeight: parentImplicitSizeCb.checked ? parentImplicitHeightSlider.value : undefined
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Rectangle {
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +57,11 @@ FloatingWindow {
 | 
			
		|||
				id: separateMarginsCb
 | 
			
		||||
				text: "Individual Margins"
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			CheckBox {
 | 
			
		||||
				id: parentImplicitSizeCb
 | 
			
		||||
				text: "Parent Implicit Size"
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		RowLayout {
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +100,24 @@ FloatingWindow {
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		RowLayout {
 | 
			
		||||
			Layout.fillWidth: true
 | 
			
		||||
 | 
			
		||||
			Label { text: "Parent Implicit Width" }
 | 
			
		||||
			Slider {
 | 
			
		||||
				id: parentImplicitWidthSlider
 | 
			
		||||
				Layout.fillWidth: true
 | 
			
		||||
				from: 0; to: 300; value: 200
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Label { text: "Parent Implicit Height" }
 | 
			
		||||
			Slider {
 | 
			
		||||
				id: parentImplicitHeightSlider
 | 
			
		||||
				Layout.fillWidth: true
 | 
			
		||||
				from: 0; to: 300; value: 200
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		RowLayout {
 | 
			
		||||
			Layout.fillWidth: true
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue