widgets/wrapper: support overriding implicit size

This commit is contained in:
outfoxxed 2025-05-24 01:55:55 -07:00
parent e135de9ec6
commit 3cf96ecf97
Signed by untrusted user: outfoxxed
GPG key ID: 4C88A185FB89301E
7 changed files with 146 additions and 26 deletions

View file

@ -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