aboutsummaryrefslogtreecommitdiffstats
path: root/src/templates/qquickpopup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/templates/qquickpopup.cpp')
-rw-r--r--src/templates/qquickpopup.cpp938
1 files changed, 923 insertions, 15 deletions
diff --git a/src/templates/qquickpopup.cpp b/src/templates/qquickpopup.cpp
index 87c63f8d..93e5a63a 100644
--- a/src/templates/qquickpopup.cpp
+++ b/src/templates/qquickpopup.cpp
@@ -55,34 +55,400 @@ QT_BEGIN_NAMESPACE
\brief A popup control.
Popup is the base type of popup-like user interface controls.
+
+ \labs
*/
+static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPrivate::Geometry
+ | QQuickItemPrivate::Parent
+ | QQuickItemPrivate::Children;
+
+static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry
+ | QQuickItemPrivate::Parent
+ | QQuickItemPrivate::Destroyed;
+
QQuickPopupPrivate::QQuickPopupPrivate()
: QObjectPrivate()
, focus(false)
, modal(false)
+ , hasTopPadding(false)
+ , hasLeftPadding(false)
+ , hasRightPadding(false)
+ , hasBottomPadding(false)
+ , padding(0)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , contentWidth(0)
+ , contentHeight(0)
+ , parentItem(nullptr)
+ , background(nullptr)
, contentItem(nullptr)
, overlay(nullptr)
, enter(nullptr)
, exit(nullptr)
+ , popupItem(nullptr)
+ , positioner(this)
, transitionManager(this)
{
}
+void QQuickPopupPrivate::init()
+{
+ Q_Q(QQuickPopup);
+ popupItem = new QQuickPopupItem(q);
+ popupItem->setParent(q);
+ q->setParentItem(qobject_cast<QQuickItem *>(parent));
+}
+
void QQuickPopupPrivate::finalizeEnterTransition()
{
if (focus)
- contentItem->setFocus(true);
+ popupItem->setFocus(true);
}
void QQuickPopupPrivate::finalizeExitTransition()
{
Q_Q(QQuickPopup);
overlay = nullptr;
- contentItem->setParentItem(nullptr);
+ positioner.setParentItem(nullptr);
+ popupItem->setParentItem(nullptr);
emit q->visibleChanged();
}
+void QQuickPopupPrivate::resizeBackground()
+{
+ Q_Q(QQuickPopup);
+ if (background) {
+ QQuickItemPrivate *p = QQuickItemPrivate::get(background);
+ if (!p->widthValid && qFuzzyIsNull(background->x())) {
+ background->setWidth(q->width());
+ p->widthValid = false;
+ }
+ if (!p->heightValid && qFuzzyIsNull(background->y())) {
+ background->setHeight(q->height());
+ p->heightValid = false;
+ }
+ }
+}
+
+void QQuickPopupPrivate::resizeContent()
+{
+ Q_Q(QQuickPopup);
+ if (contentItem) {
+ contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding()));
+ contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight()));
+ }
+}
+
+void QQuickPopupPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickPopup);
+ qreal oldPadding = q->topPadding();
+ topPadding = value;
+ hasTopPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ emit q->topPaddingChanged();
+ emit q->availableHeightChanged();
+ q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding),
+ QMarginsF(leftPadding, oldPadding, rightPadding, bottomPadding));
+ }
+}
+
+void QQuickPopupPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickPopup);
+ qreal oldPadding = q->leftPadding();
+ leftPadding = value;
+ hasLeftPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ emit q->leftPaddingChanged();
+ emit q->availableWidthChanged();
+ q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding),
+ QMarginsF(oldPadding, topPadding, rightPadding, bottomPadding));
+ }
+}
+
+void QQuickPopupPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickPopup);
+ qreal oldPadding = q->rightPadding();
+ rightPadding = value;
+ hasRightPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ emit q->rightPaddingChanged();
+ emit q->availableWidthChanged();
+ q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding),
+ QMarginsF(leftPadding, topPadding, oldPadding, bottomPadding));
+ }
+}
+
+void QQuickPopupPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickPopup);
+ qreal oldPadding = q->bottomPadding();
+ bottomPadding = value;
+ hasBottomPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ emit q->bottomPaddingChanged();
+ emit q->availableHeightChanged();
+ q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding),
+ QMarginsF(leftPadding, topPadding, rightPadding, oldPadding));
+ }
+}
+
+class QQuickPopupItemPrivate : public QQuickItemPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickPopupItem)
+
+public:
+ QQuickPopupItemPrivate(QQuickPopup *popup);
+
+ void implicitWidthChanged() override;
+ void implicitHeightChanged() override;
+
+ QQuickPopup *popup;
+};
+
+QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup) : popup(popup)
+{
+}
+
+void QQuickPopupItemPrivate::implicitWidthChanged()
+{
+ emit popup->implicitHeightChanged();
+}
+
+void QQuickPopupItemPrivate::implicitHeightChanged()
+{
+ emit popup->implicitHeightChanged();
+}
+
+QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) :
+ QQuickItem(*(new QQuickPopupItemPrivate(popup)))
+{
+ setAcceptedMouseButtons(Qt::AllButtons);
+}
+
+void QQuickPopupItem::focusInEvent(QFocusEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->focusInEvent(event);
+}
+
+void QQuickPopupItem::focusOutEvent(QFocusEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->focusOutEvent(event);
+}
+
+void QQuickPopupItem::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->keyPressEvent(event);
+}
+
+void QQuickPopupItem::keyReleaseEvent(QKeyEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->keyReleaseEvent(event);
+}
+
+void QQuickPopupItem::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mousePressEvent(event);
+}
+
+void QQuickPopupItem::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseMoveEvent(event);
+}
+
+void QQuickPopupItem::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseReleaseEvent(event);
+}
+
+void QQuickPopupItem::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseDoubleClickEvent(event);
+}
+
+void QQuickPopupItem::mouseUngrabEvent()
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseUngrabEvent();
+}
+
+void QQuickPopupItem::wheelEvent(QWheelEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->wheelEvent(event);
+}
+
+void QQuickPopupItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->geometryChanged(newGeometry, oldGeometry);
+}
+
+QQuickPopupPositioner::QQuickPopupPositioner(QQuickPopupPrivate *popup) :
+ m_x(0),
+ m_y(0),
+ m_parentItem(nullptr),
+ m_popup(popup)
+{
+}
+
+QQuickPopupPositioner::~QQuickPopupPositioner()
+{
+ if (m_parentItem) {
+ QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
+ removeAncestorListeners(m_parentItem->parentItem());
+ }
+}
+
+qreal QQuickPopupPositioner::x() const
+{
+ return m_x;
+}
+
+void QQuickPopupPositioner::setX(qreal x)
+{
+ if (m_x != x) {
+ m_x = x;
+ repositionPopup();
+ }
+}
+
+qreal QQuickPopupPositioner::y() const
+{
+ return m_y;
+}
+
+void QQuickPopupPositioner::setY(qreal y)
+{
+ if (m_y != y) {
+ m_y = y;
+ repositionPopup();
+ }
+}
+
+QQuickItem *QQuickPopupPositioner::parentItem() const
+{
+ return m_parentItem;
+}
+
+void QQuickPopupPositioner::setParentItem(QQuickItem *parent)
+{
+ if (m_parentItem == parent)
+ return;
+
+ if (m_parentItem) {
+ QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
+ removeAncestorListeners(m_parentItem->parentItem());
+ }
+
+ m_parentItem = parent;
+
+ if (!parent)
+ return;
+
+ QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes);
+ addAncestorListeners(parent->parentItem());
+
+ repositionPopup();
+}
+
+void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
+{
+ repositionPopup();
+}
+
+void QQuickPopupPositioner::itemParentChanged(QQuickItem *, QQuickItem *parent)
+{
+ addAncestorListeners(parent);
+}
+
+void QQuickPopupPositioner::itemChildRemoved(QQuickItem *, QQuickItem *child)
+{
+ if (isAncestor(child))
+ removeAncestorListeners(child);
+}
+
+void QQuickPopupPositioner::itemDestroyed(QQuickItem *item)
+{
+ Q_ASSERT(m_parentItem == item);
+
+ m_parentItem = nullptr;
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, ItemChangeTypes);
+ removeAncestorListeners(item->parentItem());
+}
+
+void QQuickPopupPositioner::repositionPopup()
+{
+ QRectF rect(m_x, m_y, m_popup->popupItem->width(), m_popup->popupItem->height());
+ if (m_parentItem) {
+ rect = m_parentItem->mapRectToScene(rect);
+
+ QQuickWindow *window = m_parentItem->window();
+ if (window) {
+ if (rect.top() < 0 || rect.bottom() > window->height()) {
+ // if the popup doesn't fit on the screen, try flipping it around (below <-> above)
+ QRectF flipped = m_parentItem->mapRectToScene(QRectF(m_x, m_parentItem->height() - m_y - rect.height(), rect.width(), rect.height()));
+ if (flipped.y() >= 0 && flipped.bottom() < window->height())
+ rect = flipped;
+ }
+ }
+ }
+
+ m_popup->popupItem->setPosition(rect.topLeft());
+}
+
+void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item)
+{
+ if (item == m_parentItem)
+ return;
+
+ QQuickItem *p = item;
+ while (p) {
+ QQuickItemPrivate::get(p)->removeItemChangeListener(this, AncestorChangeTypes);
+ p = p->parentItem();
+ }
+}
+
+void QQuickPopupPositioner::addAncestorListeners(QQuickItem *item)
+{
+ if (item == m_parentItem)
+ return;
+
+ QQuickItem *p = item;
+ while (p) {
+ QQuickItemPrivate::get(p)->addItemChangeListener(this, AncestorChangeTypes);
+ p = p->parentItem();
+ }
+}
+
+// TODO: use QQuickItem::isAncestorOf() in dev/5.7
+bool QQuickPopupPositioner::isAncestor(QQuickItem *item) const
+{
+ if (!m_parentItem)
+ return false;
+
+ QQuickItem *parent = m_parentItem->parentItem();
+ while (parent) {
+ if (parent == item)
+ return true;
+ parent = parent->parentItem();
+ }
+ return false;
+}
+
QQuickPopupTransitionManager::QQuickPopupTransitionManager(QQuickPopupPrivate *popup)
: QQuickTransitionManager()
, state(Off)
@@ -96,7 +462,7 @@ void QQuickPopupTransitionManager::transitionEnter()
return;
QList<QQuickStateAction> actions;
state = Enter;
- transition(actions, popup->enter, popup->contentItem);
+ transition(actions, popup->enter, popup->popupItem);
}
void QQuickPopupTransitionManager::transitionExit()
@@ -105,7 +471,7 @@ void QQuickPopupTransitionManager::transitionExit()
return;
QList<QQuickStateAction> actions;
state = Exit;
- transition(actions, popup->exit, popup->contentItem);
+ transition(actions, popup->exit, popup->popupItem);
}
void QQuickPopupTransitionManager::finished()
@@ -121,11 +487,21 @@ void QQuickPopupTransitionManager::finished()
QQuickPopup::QQuickPopup(QObject *parent)
: QObject(*(new QQuickPopupPrivate), parent)
{
+ Q_D(QQuickPopup);
+ d->init();
}
QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent)
: QObject(dd, parent)
{
+ Q_D(QQuickPopup);
+ d->init();
+}
+
+QQuickPopup::~QQuickPopup()
+{
+ Q_D(QQuickPopup);
+ d->positioner.setParentItem(nullptr);
}
/*!
@@ -136,13 +512,8 @@ QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent)
void QQuickPopup::open()
{
Q_D(QQuickPopup);
- if (!d->contentItem) {
- qmlInfo(this) << "no popup content to show.";
- return;
- }
if (d->overlay) {
- // FIXME qmlInfo needs to know about QQuickWindow and/or QObject
- static_cast<QDebug>(qmlInfo(this) << "popup already open in window") << d->overlay->window();
+ // popup already open
return;
}
@@ -172,7 +543,11 @@ void QQuickPopup::open()
}
d->overlay = static_cast<QQuickOverlay *>(applicationWindow->overlay());
- d->contentItem->setParentItem(d->overlay);
+ d->popupItem->setParentItem(d->overlay);
+ d->positioner.setParentItem(d->parentItem);
+ // TODO: add Popup::transformOrigin?
+ if (d->contentItem)
+ d->popupItem->setTransformOrigin(d->contentItem->transformOrigin());
emit aboutToShow();
d->transitionManager.transitionEnter();
emit visibleChanged();
@@ -187,17 +562,406 @@ void QQuickPopup::close()
{
Q_D(QQuickPopup);
if (!d->overlay) {
- // TODO This could mean we opened the popup item in a plain QQuickWindow
- qmlInfo(this) << "trying to close non-visible Popup.";
+ // popup already closed
return;
}
- d->contentItem->setFocus(false);
+ d->popupItem->setFocus(false);
emit aboutToHide();
d->transitionManager.transitionExit();
}
/*!
+ \qmlproperty real Qt.labs.controls::Popup::x
+
+ This property holds the x-coordinate of the popup.
+*/
+qreal QQuickPopup::x() const
+{
+ Q_D(const QQuickPopup);
+ return d->positioner.x();
+}
+
+void QQuickPopup::setX(qreal x)
+{
+ Q_D(QQuickPopup);
+ d->positioner.setX(x);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::y
+
+ This property holds the y-coordinate of the popup.
+*/
+qreal QQuickPopup::y() const
+{
+ Q_D(const QQuickPopup);
+ return d->positioner.y();
+}
+
+void QQuickPopup::setY(qreal y)
+{
+ Q_D(QQuickPopup);
+ d->positioner.setY(y);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::width
+
+ This property holds the width of the popup.
+*/
+qreal QQuickPopup::width() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->width();
+}
+
+void QQuickPopup::setWidth(qreal width)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setWidth(width);
+}
+
+void QQuickPopup::resetWidth()
+{
+ Q_D(QQuickPopup);
+ d->popupItem->resetWidth();
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::height
+
+ This property holds the height of the popup.
+*/
+qreal QQuickPopup::height() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->height();
+}
+
+void QQuickPopup::setHeight(qreal height)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setHeight(height);
+}
+
+void QQuickPopup::resetHeight()
+{
+ Q_D(QQuickPopup);
+ d->popupItem->resetHeight();
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::implicitWidth
+
+ This property holds the implicit width of the popup.
+*/
+qreal QQuickPopup::implicitWidth() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->implicitWidth();
+}
+
+void QQuickPopup::setImplicitWidth(qreal width)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setImplicitWidth(width);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::implicitHeight
+
+ This property holds the implicit height of the popup.
+*/
+qreal QQuickPopup::implicitHeight() const
+{
+ Q_D(const QQuickPopup);
+ return d->popupItem->implicitHeight();
+}
+
+void QQuickPopup::setImplicitHeight(qreal height)
+{
+ Q_D(QQuickPopup);
+ d->popupItem->setImplicitHeight(height);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::contentWidth
+
+ This property holds the content width. It is used for calculating the
+ total implicit width of the Popup.
+
+ \note If only a single item is used within the Popup, the implicit width
+ of its contained item is used as the content width.
+*/
+qreal QQuickPopup::contentWidth() const
+{
+ Q_D(const QQuickPopup);
+ return d->contentWidth;
+}
+
+void QQuickPopup::setContentWidth(qreal width)
+{
+ Q_D(QQuickPopup);
+ if (d->contentWidth != width) {
+ d->contentWidth = width;
+ emit contentWidthChanged();
+ }
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::contentHeight
+
+ This property holds the content height. It is used for calculating the
+ total implicit height of the Popup.
+
+ \note If only a single item is used within the Popup, the implicit height
+ of its contained item is used as the content height.
+*/
+qreal QQuickPopup::contentHeight() const
+{
+ Q_D(const QQuickPopup);
+ return d->contentHeight;
+}
+
+void QQuickPopup::setContentHeight(qreal height)
+{
+ Q_D(QQuickPopup);
+ if (d->contentHeight != height) {
+ d->contentHeight = height;
+ emit contentHeightChanged();
+ }
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::availableWidth
+
+ This property holds the width available after deducting horizontal padding.
+
+ \sa padding, leftPadding, rightPadding
+*/
+qreal QQuickPopup::availableWidth() const
+{
+ return qMax<qreal>(0.0, width() - leftPadding() - rightPadding());
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::availableHeight
+
+ This property holds the height available after deducting vertical padding.
+
+ \sa padding, topPadding, bottomPadding
+*/
+qreal QQuickPopup::availableHeight() const
+{
+ return qMax<qreal>(0.0, height() - topPadding() - bottomPadding());
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::padding
+
+ This property holds the default padding.
+
+ \sa availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
+*/
+qreal QQuickPopup::padding() const
+{
+ Q_D(const QQuickPopup);
+ return d->padding;
+}
+
+void QQuickPopup::setPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ if (qFuzzyCompare(d->padding, padding))
+ return;
+ QMarginsF oldPadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
+ d->padding = padding;
+ emit paddingChanged();
+ QMarginsF newPadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
+ if (!qFuzzyCompare(newPadding.top(), oldPadding.top()))
+ emit topPaddingChanged();
+ if (!qFuzzyCompare(newPadding.left(), oldPadding.left()))
+ emit leftPaddingChanged();
+ if (!qFuzzyCompare(newPadding.right(), oldPadding.right()))
+ emit rightPaddingChanged();
+ if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
+ emit bottomPaddingChanged();
+ if (!qFuzzyCompare(newPadding.top(), oldPadding.top()) || !qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
+ emit availableHeightChanged();
+ if (!qFuzzyCompare(newPadding.left(), oldPadding.left()) || !qFuzzyCompare(newPadding.right(), oldPadding.right()))
+ emit availableWidthChanged();
+ paddingChange(newPadding, oldPadding);
+}
+
+void QQuickPopup::resetPadding()
+{
+ setPadding(0);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::topPadding
+
+ This property holds the top padding.
+
+ \sa padding, bottomPadding, availableHeight
+*/
+qreal QQuickPopup::topPadding() const
+{
+ Q_D(const QQuickPopup);
+ if (d->hasTopPadding)
+ return d->topPadding;
+ return d->padding;
+}
+
+void QQuickPopup::setTopPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ d->setTopPadding(padding);
+}
+
+void QQuickPopup::resetTopPadding()
+{
+ Q_D(QQuickPopup);
+ d->setTopPadding(0, true);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::leftPadding
+
+ This property holds the left padding.
+
+ \sa padding, rightPadding, availableWidth
+*/
+qreal QQuickPopup::leftPadding() const
+{
+ Q_D(const QQuickPopup);
+ if (d->hasLeftPadding)
+ return d->leftPadding;
+ return d->padding;
+}
+
+void QQuickPopup::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ d->setLeftPadding(padding);
+}
+
+void QQuickPopup::resetLeftPadding()
+{
+ Q_D(QQuickPopup);
+ d->setLeftPadding(0, true);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::rightPadding
+
+ This property holds the right padding.
+
+ \sa padding, leftPadding, availableWidth
+*/
+qreal QQuickPopup::rightPadding() const
+{
+ Q_D(const QQuickPopup);
+ if (d->hasRightPadding)
+ return d->rightPadding;
+ return d->padding;
+}
+
+void QQuickPopup::setRightPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ d->setRightPadding(padding);
+}
+
+void QQuickPopup::resetRightPadding()
+{
+ Q_D(QQuickPopup);
+ d->setRightPadding(0, true);
+}
+
+/*!
+ \qmlproperty real Qt.labs.controls::Popup::bottomPadding
+
+ This property holds the bottom padding.
+
+ \sa padding, topPadding, availableHeight
+*/
+qreal QQuickPopup::bottomPadding() const
+{
+ Q_D(const QQuickPopup);
+ if (d->hasBottomPadding)
+ return d->bottomPadding;
+ return d->padding;
+}
+
+void QQuickPopup::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickPopup);
+ d->setBottomPadding(padding);
+}
+
+void QQuickPopup::resetBottomPadding()
+{
+ Q_D(QQuickPopup);
+ d->setBottomPadding(0, true);
+}
+
+/*!
+ \qmlproperty Item Qt.labs.popups::Popup::parent
+
+ This property holds the parent item.
+*/
+QQuickItem *QQuickPopup::parentItem() const
+{
+ Q_D(const QQuickPopup);
+ return d->parentItem;
+}
+
+void QQuickPopup::setParentItem(QQuickItem *parent)
+{
+ Q_D(QQuickPopup);
+ if (d->parentItem != parent) {
+ d->parentItem = parent;
+ if (d->positioner.parentItem())
+ d->positioner.setParentItem(parent);
+ emit parentChanged();
+ }
+}
+
+/*!
+ \qmlproperty Item Qt.labs.popups::Popup::background
+
+ This property holds the background item.
+
+ \note If the background item has no explicit size specified, it automatically
+ follows the popup's size. In most cases, there is no need to specify
+ width or height for a background item.
+*/
+QQuickItem *QQuickPopup::background() const
+{
+ Q_D(const QQuickPopup);
+ return d->background;
+}
+
+void QQuickPopup::setBackground(QQuickItem *background)
+{
+ Q_D(QQuickPopup);
+ if (d->background != background) {
+ delete d->background;
+ d->background = background;
+ if (background) {
+ background->setParentItem(d->popupItem);
+ if (qFuzzyIsNull(background->z()))
+ background->setZ(-1);
+ if (isComponentComplete())
+ d->resizeBackground();
+ }
+ emit backgroundChanged();
+ }
+}
+
+/*!
\qmlproperty Item Qt.labs.controls::Popup::contentItem
This property holds the content item of the popup.
@@ -222,15 +986,55 @@ void QQuickPopup::setContentItem(QQuickItem *item)
return;
}
if (d->contentItem != item) {
+ contentItemChange(item, d->contentItem);
delete d->contentItem;
d->contentItem = item;
- if (item)
+ if (item) {
+ item->setParentItem(d->popupItem);
QQuickItemPrivate::get(item)->isTabFence = true;
+ if (isComponentComplete())
+ d->resizeContent();
+ }
emit contentItemChanged();
}
}
/*!
+ \qmlproperty list<Object> Qt.labs.controls::Popup::contentData
+ \default
+
+ This property holds the list of content data.
+
+ \sa Item::data
+*/
+QQmlListProperty<QObject> QQuickPopup::contentData()
+{
+ Q_D(QQuickPopup);
+ return QQmlListProperty<QObject>(d->contentItem, nullptr,
+ QQuickItemPrivate::data_append,
+ QQuickItemPrivate::data_count,
+ QQuickItemPrivate::data_at,
+ QQuickItemPrivate::data_clear);
+}
+
+/*!
+ \qmlproperty list<Item> Qt.labs.controls::Popup::contentChildren
+
+ This property holds the list of content children.
+
+ \sa Item::children
+*/
+QQmlListProperty<QQuickItem> QQuickPopup::contentChildren()
+{
+ Q_D(QQuickPopup);
+ return QQmlListProperty<QQuickItem>(d->contentItem, nullptr,
+ QQuickItemPrivate::children_append,
+ QQuickItemPrivate::children_count,
+ QQuickItemPrivate::children_at,
+ QQuickItemPrivate::children_clear);
+}
+
+/*!
\qmlproperty bool Qt.labs.controls::Popup::focus
This property holds whether the popup has focus.
@@ -281,6 +1085,14 @@ bool QQuickPopup::isVisible() const
return d->overlay != nullptr /*&& !d->transitionManager.isRunning()*/;
}
+void QQuickPopup::setVisible(bool visible)
+{
+ if (visible)
+ open();
+ else
+ close();
+}
+
/*!
\qmlproperty Transition Qt.labs.controls::Popup::enter
@@ -323,6 +1135,102 @@ void QQuickPopup::setExit(QQuickTransition *transition)
emit exitChanged();
}
+void QQuickPopup::classBegin()
+{
+}
+
+void QQuickPopup::componentComplete()
+{
+ Q_D(QQuickPopup);
+ d->complete = true;
+ if (!parentItem())
+ setParentItem(qobject_cast<QQuickItem *>(parent()));
+}
+
+bool QQuickPopup::isComponentComplete() const
+{
+ Q_D(const QQuickPopup);
+ return d->complete;
+}
+
+void QQuickPopup::focusInEvent(QFocusEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::focusOutEvent(QFocusEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::keyPressEvent(QKeyEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::keyReleaseEvent(QKeyEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mousePressEvent(QMouseEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mouseMoveEvent(QMouseEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mouseReleaseEvent(QMouseEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::mouseUngrabEvent()
+{
+}
+
+void QQuickPopup::wheelEvent(QWheelEvent *event)
+{
+ event->accept();
+}
+
+void QQuickPopup::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
+{
+ Q_UNUSED(newItem);
+ Q_UNUSED(oldItem);
+}
+
+void QQuickPopup::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickPopup);
+ d->resizeBackground();
+ d->resizeContent();
+ if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width())) {
+ emit widthChanged();
+ emit availableWidthChanged();
+ }
+ if (!qFuzzyCompare(newGeometry.height(), oldGeometry.height())) {
+ emit heightChanged();
+ emit availableHeightChanged();
+ }
+}
+
+void QQuickPopup::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
+{
+ Q_D(QQuickPopup);
+ Q_UNUSED(newPadding);
+ Q_UNUSED(oldPadding);
+ d->resizeContent();
+}
+
QT_END_NAMESPACE
#include "moc_qquickpopup_p.cpp"