forked from quickshell/quickshell
widgets: add wrapper components and managers
This commit is contained in:
parent
79fca3cab8
commit
401ee4cec6
8 changed files with 578 additions and 0 deletions
|
@ -1,5 +1,7 @@
|
|||
qt_add_library(quickshell-widgets STATIC
|
||||
cliprect.cpp
|
||||
wrapper.cpp
|
||||
marginwrapper.cpp
|
||||
)
|
||||
|
||||
qt_add_qml_module(quickshell-widgets
|
||||
|
@ -8,6 +10,8 @@ qt_add_qml_module(quickshell-widgets
|
|||
QML_FILES
|
||||
IconImage.qml
|
||||
ClippingRectangle.qml
|
||||
WrapperItem.qml
|
||||
WrapperRectangle.qml
|
||||
)
|
||||
|
||||
qt6_add_shaders(quickshell-widgets "widgets-cliprect"
|
||||
|
|
44
src/widgets/WrapperItem.qml
Normal file
44
src/widgets/WrapperItem.qml
Normal file
|
@ -0,0 +1,44 @@
|
|||
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
|
||||
/// an item, or give a single component a margin. See [QtQuick.Layouts]
|
||||
/// for positioning multiple items.
|
||||
///
|
||||
/// > [!NOTE] WrapperItem is a @@MarginWrapperManager based component.
|
||||
/// > You should read its documentation as well.
|
||||
///
|
||||
/// ### Example: Adding a margin to an item
|
||||
/// The snippet below adds a 10px margin to all sides of the @@QtQuick.Text item.
|
||||
///
|
||||
/// ```qml
|
||||
/// WrapperItem {
|
||||
/// margin: 10
|
||||
///
|
||||
/// @@QtQuick.Text { text: "Hello!" }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// > [!NOTE] The child item can be specified by writing it inline in the wrapper,
|
||||
/// > as in the example above, or by using the @@child property. See
|
||||
/// > @@WrapperManager.child for details.
|
||||
///
|
||||
/// > [!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.
|
||||
///
|
||||
/// [QtQuick.Layouts]: https://doc.qt.io/qt-6/qtquicklayouts-index.html
|
||||
Item {
|
||||
/// The minimum margin between the child item and the WrapperItem'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 WrapperItem is resized larger than its implicit size. Defaults to false.
|
||||
property /*bool*/alias resizeChild: manager.resizeChild
|
||||
/// See @@WrapperManager.child for details.
|
||||
property /*Item*/alias child: manager.child
|
||||
|
||||
MarginWrapperManager { id: manager }
|
||||
}
|
35
src/widgets/WrapperRectangle.qml
Normal file
35
src/widgets/WrapperRectangle.qml
Normal file
|
@ -0,0 +1,35 @@
|
|||
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.
|
||||
///
|
||||
/// > [!NOTE] WrapperRectangle 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.
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
/// If true (default), the rectangle's border width will be added
|
||||
/// to the margin.
|
||||
property bool contentInsideBorder: true
|
||||
/// The minimum margin between the child item and the WrapperRectangle's
|
||||
/// edges. If @@contentInsideBorder is true, this excludes the border,
|
||||
/// otherwise it includes it. Defaults to 0.
|
||||
property real margin: 0
|
||||
/// 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
|
||||
|
||||
MarginWrapperManager {
|
||||
id: manager
|
||||
margin: (root.contentInsideBorder ? root.border.width : 0) + root.margin
|
||||
}
|
||||
}
|
146
src/widgets/marginwrapper.cpp
Normal file
146
src/widgets/marginwrapper.cpp
Normal file
|
@ -0,0 +1,146 @@
|
|||
#include "marginwrapper.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
#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
|
||||
);
|
||||
}
|
||||
|
||||
void MarginWrapperManager::componentComplete() {
|
||||
if (this->mWrapper) {
|
||||
QObject::connect(
|
||||
this->mWrapper,
|
||||
&QQuickItem::widthChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onWrapperWidthChanged
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
this->mWrapper,
|
||||
&QQuickItem::heightChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onWrapperHeightChanged
|
||||
);
|
||||
}
|
||||
|
||||
this->WrapperManager::componentComplete();
|
||||
|
||||
if (!this->mChild) this->updateGeometry();
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::margin() const { return this->mMargin; }
|
||||
|
||||
void MarginWrapperManager::setMargin(qreal margin) {
|
||||
if (margin == this->mMargin) return;
|
||||
this->mMargin = margin;
|
||||
this->updateGeometry();
|
||||
emit this->marginChanged();
|
||||
}
|
||||
|
||||
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::onChildChanged() {
|
||||
// QObject::disconnect in MarginWrapper handles disconnecting old item
|
||||
|
||||
if (this->mChild) {
|
||||
QObject::connect(
|
||||
this->mChild,
|
||||
&QQuickItem::implicitWidthChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onChildImplicitWidthChanged
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
this->mChild,
|
||||
&QQuickItem::implicitHeightChanged,
|
||||
this,
|
||||
&MarginWrapperManager::onChildImplicitHeightChanged
|
||||
);
|
||||
}
|
||||
|
||||
this->updateGeometry();
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::targetChildWidth() const {
|
||||
auto max = this->mWrapper->width() - this->mMargin * 2;
|
||||
|
||||
if (this->mResizeChild) return max;
|
||||
else return std::min(this->mChild->implicitWidth(), max);
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::targetChildHeight() const {
|
||||
auto max = this->mWrapper->height() - this->mMargin * 2;
|
||||
|
||||
if (this->mResizeChild) return max;
|
||||
else return std::min(this->mChild->implicitHeight(), max);
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::targetChildX() const {
|
||||
if (this->mResizeChild) return this->mMargin;
|
||||
else return this->mWrapper->width() / 2 - this->mChild->implicitWidth() / 2;
|
||||
}
|
||||
|
||||
qreal MarginWrapperManager::targetChildY() const {
|
||||
if (this->mResizeChild) return this->mMargin;
|
||||
else return this->mWrapper->height() / 2 - this->mChild->implicitHeight() / 2;
|
||||
}
|
||||
|
||||
void MarginWrapperManager::onWrapperWidthChanged() {
|
||||
if (!this->mChild || !this->mWrapper) return;
|
||||
this->mChild->setX(this->targetChildX());
|
||||
this->mChild->setWidth(this->targetChildWidth());
|
||||
}
|
||||
|
||||
void MarginWrapperManager::onWrapperHeightChanged() {
|
||||
if (!this->mChild || !this->mWrapper) return;
|
||||
this->mChild->setY(this->targetChildY());
|
||||
this->mChild->setHeight(this->targetChildHeight());
|
||||
}
|
||||
|
||||
void MarginWrapperManager::onChildImplicitWidthChanged() {
|
||||
if (!this->mChild || !this->mWrapper) return;
|
||||
this->mWrapper->setImplicitWidth(this->mChild->implicitWidth() + this->mMargin * 2);
|
||||
}
|
||||
|
||||
void MarginWrapperManager::onChildImplicitHeightChanged() {
|
||||
if (!this->mChild || !this->mWrapper) return;
|
||||
this->mWrapper->setImplicitHeight(this->mChild->implicitHeight() + this->mMargin * 2);
|
||||
}
|
||||
|
||||
void MarginWrapperManager::updateGeometry() {
|
||||
if (!this->mWrapper) return;
|
||||
|
||||
if (this->mChild) {
|
||||
this->mWrapper->setImplicitWidth(this->mChild->implicitWidth() + this->mMargin * 2);
|
||||
this->mWrapper->setImplicitHeight(this->mChild->implicitHeight() + this->mMargin * 2);
|
||||
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->mMargin * 2);
|
||||
this->mWrapper->setImplicitHeight(this->mMargin * 2);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace qs::widgets
|
75
src/widgets/marginwrapper.hpp
Normal file
75
src/widgets/marginwrapper.hpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#pragma once
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
#include "wrapper.hpp"
|
||||
|
||||
namespace qs::widgets {
|
||||
|
||||
///! Helper object for applying sizes and margins to a single child item.
|
||||
/// > [!NOTE] MarginWrapperManager is an extension of @@WrapperManager.
|
||||
/// > You should read its documentation to understand wrapper types.
|
||||
///
|
||||
/// MarginWrapperManager can be used to apply margins to a child item,
|
||||
/// in addition to handling the size / implicit size relationship
|
||||
/// between the parent and the child. @@WrapperItem and @@WrapperRectangle
|
||||
/// exist for Item and Rectangle implementations respectively.
|
||||
///
|
||||
/// > [!WARNING] MarginWrapperManager based types set the child item's
|
||||
/// > @@QtQuick.Item.x, @@QtQuick.Item.y, @@QtQuick.Item.width, @@QtQuick.Item.height
|
||||
/// > or @@QtQuick.Item.anchors properties. Do not set them yourself,
|
||||
/// > instead set @@Item.implicitWidth and @@Item.implicitHeight.
|
||||
///
|
||||
/// ### Implementing a margin wrapper type
|
||||
/// Follow the directions in @@WrapperManager$'s documentation, and or
|
||||
/// alias the @@margin property if you wish to expose it.
|
||||
class MarginWrapperManager: public WrapperManager {
|
||||
Q_OBJECT;
|
||||
// clang-format off
|
||||
/// The minimum margin between the child item and the parent item's edges.
|
||||
/// Defaults to 0.
|
||||
Q_PROPERTY(qreal margin READ margin WRITE setMargin NOTIFY marginChanged FINAL);
|
||||
/// If the 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 resizeChild WRITE setResizeChild NOTIFY resizeChildChanged FINAL);
|
||||
// clang-format on
|
||||
QML_ELEMENT;
|
||||
|
||||
public:
|
||||
explicit MarginWrapperManager(QObject* parent = nullptr);
|
||||
|
||||
void componentComplete() override;
|
||||
|
||||
[[nodiscard]] qreal margin() const;
|
||||
void setMargin(qreal margin);
|
||||
|
||||
[[nodiscard]] bool resizeChild() const;
|
||||
void setResizeChild(bool resizeChild);
|
||||
|
||||
signals:
|
||||
void marginChanged();
|
||||
void resizeChildChanged();
|
||||
|
||||
private slots:
|
||||
void onChildChanged();
|
||||
void onWrapperWidthChanged();
|
||||
void onWrapperHeightChanged();
|
||||
void onChildImplicitWidthChanged();
|
||||
void onChildImplicitHeightChanged();
|
||||
|
||||
private:
|
||||
void updateGeometry();
|
||||
|
||||
[[nodiscard]] qreal targetChildX() const;
|
||||
[[nodiscard]] qreal targetChildY() const;
|
||||
[[nodiscard]] qreal targetChildWidth() const;
|
||||
[[nodiscard]] qreal targetChildHeight() const;
|
||||
|
||||
qreal mMargin = 0;
|
||||
bool mResizeChild = false;
|
||||
};
|
||||
|
||||
} // namespace qs::widgets
|
|
@ -1,7 +1,15 @@
|
|||
name = "Quickshell.Widgets"
|
||||
description = "Bundled widgets"
|
||||
|
||||
headers = [
|
||||
"wrapper.hpp",
|
||||
"marginwrapper.hpp",
|
||||
]
|
||||
|
||||
qml_files = [
|
||||
"IconImage.qml",
|
||||
"ClippingRectangle.qml",
|
||||
"WrapperItem.qml",
|
||||
"WrapperRectangle.qml",
|
||||
]
|
||||
-----
|
||||
|
|
127
src/widgets/wrapper.cpp
Normal file
127
src/widgets/wrapper.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
#include "wrapper.hpp"
|
||||
|
||||
#include <QtQml/qqmlinfo.h>
|
||||
#include <QtQml/qqmllist.h>
|
||||
#include <qlogging.h>
|
||||
#include <qnamespace.h>
|
||||
#include <qobject.h>
|
||||
#include <qquickitem.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
namespace qs::widgets {
|
||||
|
||||
void WrapperManager::componentComplete() {
|
||||
this->mWrapper = qobject_cast<QQuickItem*>(this->parent());
|
||||
|
||||
if (!this->mWrapper) {
|
||||
QString pstr;
|
||||
QDebug(&pstr) << this->parent();
|
||||
|
||||
qmlWarning(this) << "Parent of WrapperManager is not a QQuickItem. Parent: " << pstr;
|
||||
return;
|
||||
}
|
||||
|
||||
QQuickItem* child = this->mChild;
|
||||
this->mChild = nullptr; // avoids checks for the old item in setChild.
|
||||
|
||||
const auto& childItems = this->mWrapper->childItems();
|
||||
|
||||
if (childItems.length() == 1) {
|
||||
this->mDefaultChild = childItems.first();
|
||||
} else if (childItems.length() != 0) {
|
||||
this->flags.setFlag(WrapperManager::HasMultipleChildren);
|
||||
|
||||
if (!child && !this->flags.testFlags(WrapperManager::NullChild)) {
|
||||
this->printChildCountWarning();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* item: childItems) {
|
||||
if (item != child) item->setParentItem(nullptr);
|
||||
}
|
||||
|
||||
if (child && !this->flags.testFlag(WrapperManager::NullChild)) {
|
||||
this->setChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
QQuickItem* WrapperManager::child() const { return this->mChild; }
|
||||
|
||||
void WrapperManager::setChild(QQuickItem* child) {
|
||||
if (child && child == this->mChild) return;
|
||||
|
||||
if (this->mChild != nullptr) {
|
||||
QObject::disconnect(this->mChild, nullptr, this, nullptr);
|
||||
|
||||
if (this->mChild->parentItem() == this->mWrapper) {
|
||||
this->mChild->setParentItem(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
this->mChild = child;
|
||||
this->flags.setFlag(WrapperManager::NullChild, child == nullptr);
|
||||
|
||||
if (child) {
|
||||
QObject::connect(
|
||||
child,
|
||||
&QObject::destroyed,
|
||||
this,
|
||||
&WrapperManager::onChildDestroyed,
|
||||
Qt::UniqueConnection
|
||||
);
|
||||
|
||||
if (auto* wrapper = this->mWrapper) {
|
||||
child->setParentItem(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
emit this->initializedChildChanged();
|
||||
emit this->childChanged();
|
||||
}
|
||||
|
||||
void WrapperManager::setProspectiveChild(QQuickItem* child) {
|
||||
if (child && child == this->mChild) return;
|
||||
|
||||
if (!this->mWrapper) {
|
||||
if (this->mChild) {
|
||||
QObject::disconnect(this->mChild, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
this->mChild = child;
|
||||
this->flags.setFlag(WrapperManager::NullChild, child == nullptr);
|
||||
|
||||
if (child) {
|
||||
QObject::connect(child, &QObject::destroyed, this, &WrapperManager::onChildDestroyed);
|
||||
}
|
||||
} else {
|
||||
this->setChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
void WrapperManager::unsetChild() {
|
||||
if (!this->mWrapper) {
|
||||
this->setProspectiveChild(nullptr);
|
||||
} else {
|
||||
this->setChild(this->mDefaultChild);
|
||||
|
||||
if (!this->mDefaultChild && this->flags.testFlag(WrapperManager::HasMultipleChildren)) {
|
||||
this->printChildCountWarning();
|
||||
}
|
||||
}
|
||||
|
||||
this->flags.setFlag(WrapperManager::NullChild, false);
|
||||
}
|
||||
|
||||
void WrapperManager::onChildDestroyed() {
|
||||
this->mChild = nullptr;
|
||||
this->unsetChild();
|
||||
emit this->childChanged();
|
||||
}
|
||||
|
||||
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 "
|
||||
"to wrap using the child property.";
|
||||
}
|
||||
|
||||
} // namespace qs::widgets
|
139
src/widgets/wrapper.hpp
Normal file
139
src/widgets/wrapper.hpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
#pragma once
|
||||
|
||||
#include <qflags.h>
|
||||
#include <qobject.h>
|
||||
#include <qpointer.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qqmllist.h>
|
||||
#include <qqmlparserstatus.h>
|
||||
#include <qquickitem.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
#include "../core/doc.hpp"
|
||||
|
||||
namespace qs::widgets {
|
||||
|
||||
///! Helper object for creating components with a single visual child.
|
||||
/// WrapperManager determines which child of an Item should be its visual
|
||||
/// child, and exposes it for further operations. See @@MarginWrapperManager
|
||||
/// for a subclass that implements automatic sizing and margins.
|
||||
///
|
||||
/// ### Using wrapper types
|
||||
/// WrapperManager based types have a single visual child item.
|
||||
/// You can specify the child item using the default property, or by
|
||||
/// setting the @@child property. You must use the @@child property if
|
||||
/// the widget has more than one @@QtQuick.Item based child.
|
||||
///
|
||||
/// #### Example using the default property
|
||||
/// ```qml
|
||||
/// WrapperWidget { // a widget that uses WrapperManager
|
||||
/// // Putting the item inline uses the default property of WrapperWidget.
|
||||
/// @@QtQuick.Text { text: "Hello" }
|
||||
///
|
||||
/// // Scope does not extend Item, so it can be placed in the
|
||||
/// // default property without issue.
|
||||
/// @@Quickshell.Scope {}
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// #### Example using the child property
|
||||
/// ```qml
|
||||
/// WrapperWidget {
|
||||
/// @@QtQuick.Text {
|
||||
/// id: text
|
||||
/// text: "Hello"
|
||||
/// }
|
||||
///
|
||||
/// @@QtQuick.Text {
|
||||
/// id: otherText
|
||||
/// text: "Other Text"
|
||||
/// }
|
||||
///
|
||||
/// // Both text and otherText extend Item, so one must be specified.
|
||||
/// child: text
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// See @@child for more details on how the child property can be used.
|
||||
///
|
||||
/// ### Implementing wrapper types
|
||||
/// In addition to the bundled wrapper types, you can make your own using
|
||||
/// WrapperManager. To implement a wrapper, create a WrapperManager inside
|
||||
/// your wrapper component 's default property, then alias a new property
|
||||
/// to the WrapperManager's @@child property.
|
||||
///
|
||||
/// #### Example
|
||||
/// ```qml
|
||||
/// Item { // your wrapper component
|
||||
/// WrapperManager { id: wrapperManager }
|
||||
///
|
||||
/// // Allows consumers of your wrapper component to use the child property.
|
||||
/// property alias child: wrapperManager.child
|
||||
///
|
||||
/// // The rest of your component logic. You can use
|
||||
/// // `wrapperManager.child` or `this.child` to refer to the selected child.
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ### See also
|
||||
/// - @@WrapperItem - A @@MarginWrapperManager based component that sizes itself
|
||||
/// to its child.
|
||||
/// - @@WrapperRectangle - A @@MarginWrapperManager based component that sizes
|
||||
/// itself to its child, and provides an option to use its border as an inset.
|
||||
class WrapperManager
|
||||
: public QObject
|
||||
, public QQmlParserStatus {
|
||||
Q_OBJECT;
|
||||
// clang-format off
|
||||
/// The wrapper component's selected child.
|
||||
///
|
||||
/// Setting this property override's WrapperManager's default selection,
|
||||
/// and resolve ambiguity when more than one visual child is present.
|
||||
/// The property can additionally be defined inline or reference a component
|
||||
/// that is not already a child of the wrapper, in which case it will be
|
||||
/// reparented to the wrapper. Setting child to `null` will select no child,
|
||||
/// and `undefined` will restore the default child.
|
||||
///
|
||||
/// 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);
|
||||
// clang-format on
|
||||
QML_ELEMENT;
|
||||
|
||||
public:
|
||||
explicit WrapperManager(QObject* parent = nullptr): QObject(parent) {}
|
||||
|
||||
void classBegin() override {}
|
||||
void componentComplete() override;
|
||||
|
||||
[[nodiscard]] QQuickItem* child() const;
|
||||
void setChild(QQuickItem* child);
|
||||
void setProspectiveChild(QQuickItem* child);
|
||||
void unsetChild();
|
||||
|
||||
signals:
|
||||
void childChanged();
|
||||
QSDOC_HIDE void initializedChildChanged();
|
||||
|
||||
private slots:
|
||||
void onChildDestroyed();
|
||||
|
||||
protected:
|
||||
enum Flag : quint8 {
|
||||
NoFlags = 0x0,
|
||||
NullChild = 0x1,
|
||||
HasMultipleChildren = 0x2,
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag);
|
||||
|
||||
void printChildCountWarning() const;
|
||||
void updateGeometry();
|
||||
|
||||
QQuickItem* mWrapper = nullptr;
|
||||
QPointer<QQuickItem> mDefaultChild;
|
||||
QQuickItem* mChild = nullptr;
|
||||
Flags flags;
|
||||
};
|
||||
|
||||
} // namespace qs::widgets
|
Loading…
Add table
Add a link
Reference in a new issue