widgets: add ClippingWrapperRectangle

This commit is contained in:
outfoxxed 2024-11-19 02:52:49 -08:00
parent 401ee4cec6
commit 033e810871
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
7 changed files with 63 additions and 4 deletions

View file

@ -12,6 +12,7 @@ qt_add_qml_module(quickshell-widgets
ClippingRectangle.qml
WrapperItem.qml
WrapperRectangle.qml
ClippingWrapperRectangle.qml
)
qt6_add_shaders(quickshell-widgets "widgets-cliprect"

View file

@ -0,0 +1,35 @@
import QtQuick
///! ClippingRectangle that handles sizes and positioning for a single visual child.
/// This component is useful for adding a clipping border or background rectangle to
/// a child item. If you don't need clipping, use @@WrapperRectangle.
///
/// > [!NOTE] ClippingWrapperRectangle is a @@MarginWrapperManager based component.
/// > You should read its documentation as well.
///
/// > [!WARNING] You should not set @@Item.x, @@Item.y, @@Item.width,
/// > @@Item.height or @@Item.anchors on the child item, as they are used
/// > by WrapperItem to position it. Instead set @@Item.implicitWidth and
/// > @@Item.implicitHeight.
ClippingRectangle {
id: root
/// The minimum margin between the child item and the ClippingWrapperRectangle's
/// edges. Defaults to 0.
property /*real*/alias margin: manager.margin
/// If the child item should be resized larger than its implicit size if
/// the WrapperRectangle is resized larger than its implicit size. Defaults to false.
property /*bool*/alias resizeChild: manager.resizeChild
/// See @@WrapperManager.child for details.
property alias child: manager.child
implicitWidth: root.contentItem.implicitWidth + (root.contentInsideBorder ? root.border.width * 2 : 0)
implicitHeight: root.contentItem.implicitHeight + (root.contentInsideBorder ? root.border.width * 2 : 0)
resources: [
MarginWrapperManager {
id: manager
wrapper: root.contentItem
}
]
}

View file

@ -1,5 +1,4 @@
import QtQuick
import Quickshell.Widgets
///! Item that handles sizes and positioning for a single visual child.
/// This component is useful when you need to wrap a single component in

View file

@ -1,9 +1,9 @@
import QtQuick
import Quickshell.Widgets
///! Rectangle that handles sizes and positioning for a single visual child.
/// This component is useful for adding a border or background rectangle to
/// a child item.
/// a child item. If you need to clip the child item to the rectangle's
/// border, see @@ClippingWrapperRectangle.
///
/// > [!NOTE] WrapperRectangle is a @@MarginWrapperManager based component.
/// > You should read its documentation as well.

View file

@ -11,5 +11,6 @@ qml_files = [
"ClippingRectangle.qml",
"WrapperItem.qml",
"WrapperRectangle.qml",
"ClippingWrapperRectangle.qml",
]
-----

View file

@ -11,7 +11,11 @@
namespace qs::widgets {
void WrapperManager::componentComplete() {
this->mWrapper = qobject_cast<QQuickItem*>(this->parent());
if (this->mAssignedWrapper) {
this->mWrapper = this->mAssignedWrapper;
} else {
this->mWrapper = qobject_cast<QQuickItem*>(this->parent());
}
if (!this->mWrapper) {
QString pstr;
@ -118,6 +122,17 @@ void WrapperManager::onChildDestroyed() {
emit this->childChanged();
}
QQuickItem* WrapperManager::wrapper() const { return this->mWrapper; }
void WrapperManager::setWrapper(QQuickItem* wrapper) {
if (this->mWrapper) {
qmlWarning(this) << "Cannot set wrapper after WrapperManager initialization.";
return;
}
this->mAssignedWrapper = wrapper;
}
void WrapperManager::printChildCountWarning() const {
qmlWarning(this->mWrapper) << "Wrapper component cannot have more than one visual child.";
qmlWarning(this->mWrapper) << "Remove all additional children, or pick a specific component "

View file

@ -98,6 +98,9 @@ class WrapperManager
/// When read, `child` will always return the (potentially null) selected child,
/// and not `undefined`.
Q_PROPERTY(QQuickItem* child READ child WRITE setProspectiveChild RESET unsetChild NOTIFY childChanged FINAL);
/// The wrapper managed by this manager. Defaults to the manager's parent.
/// This property may not be changed after Component.onCompleted.
Q_PROPERTY(QQuickItem* wrapper READ wrapper WRITE setWrapper NOTIFY wrapperChanged FINAL);
// clang-format on
QML_ELEMENT;
@ -112,8 +115,12 @@ public:
void setProspectiveChild(QQuickItem* child);
void unsetChild();
[[nodiscard]] QQuickItem* wrapper() const;
void setWrapper(QQuickItem* wrapper);
signals:
void childChanged();
void wrapperChanged();
QSDOC_HIDE void initializedChildChanged();
private slots:
@ -131,6 +138,7 @@ protected:
void updateGeometry();
QQuickItem* mWrapper = nullptr;
QQuickItem* mAssignedWrapper = nullptr;
QPointer<QQuickItem> mDefaultChild;
QQuickItem* mChild = nullptr;
Flags flags;