aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickstackview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickstackview.cpp')
-rw-r--r--src/quicktemplates2/qquickstackview.cpp121
1 files changed, 89 insertions, 32 deletions
diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp
index a7853df7..a9922704 100644
--- a/src/quicktemplates2/qquickstackview.cpp
+++ b/src/quicktemplates2/qquickstackview.cpp
@@ -36,6 +36,8 @@
#include "qquickstackview_p.h"
#include "qquickstackview_p_p.h"
+#include "qquickstackelement_p_p.h"
+#include "qquickstacktransition_p_p.h"
#include <QtQml/qjsvalue.h>
#include <QtQml/qqmlengine.h>
@@ -109,7 +111,7 @@ QT_BEGIN_NAMESPACE
Using StackView in an application is as simple as adding it as a child to
a Window. The stack is usually anchored to the edges of the window, except
at the top or bottom where it might be anchored to a status bar, or some
- other similar UI component. The stack can then be used by invoking its
+ other similar UI component. The stack can then be used by invoking its
navigation methods. The first item to show in the StackView is the one
that was assigned to \l initialItem, or the topmost item if \l initialItem
is not set.
@@ -295,8 +297,8 @@ QT_BEGIN_NAMESPACE
\sa {Customizing StackView}, {Navigation Controls}, {Container Controls}
*/
-QQuickStackView::QQuickStackView(QQuickItem *parent) :
- QQuickControl(*(new QQuickStackViewPrivate), parent)
+QQuickStackView::QQuickStackView(QQuickItem *parent)
+ : QQuickControl(*(new QQuickStackViewPrivate), parent)
{
setFlag(ItemIsFocusScope);
}
@@ -308,13 +310,14 @@ QQuickStackView::~QQuickStackView()
d->transitioner->setChangeListener(nullptr);
delete d->transitioner;
}
- qDeleteAll(d->removals);
+ qDeleteAll(d->removing);
+ qDeleteAll(d->removed);
qDeleteAll(d->elements);
}
-QQuickStackAttached *QQuickStackView::qmlAttachedProperties(QObject *object)
+QQuickStackViewAttached *QQuickStackView::qmlAttachedProperties(QObject *object)
{
- return new QQuickStackAttached(object);
+ return new QQuickStackViewAttached(object);
}
/*!
@@ -472,7 +475,7 @@ void QQuickStackView::push(QQmlV4Function *args)
{
Q_D(QQuickStackView);
if (args->length() <= 0) {
- qmlInfo(this) << "push: missing arguments";
+ qmlWarning(this) << "push: missing arguments";
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -496,7 +499,7 @@ void QQuickStackView::push(QQmlV4Function *args)
}
if (elements.isEmpty()) {
- qmlInfo(this) << "push: nothing to push";
+ qmlWarning(this) << "push: nothing to push";
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -511,7 +514,7 @@ void QQuickStackView::push(QQmlV4Function *args)
d->startTransition(QQuickStackTransition::pushEnter(operation, enter, this),
QQuickStackTransition::pushExit(operation, exit, this),
operation == Immediate);
- d->setCurrentItem(enter->item);
+ d->setCurrentItem(enter);
}
if (d->currentItem) {
@@ -557,7 +560,7 @@ void QQuickStackView::pop(QQmlV4Function *args)
int argc = args->length();
if (d->elements.count() <= 1 || argc > 2) {
if (argc > 2)
- qmlInfo(this) << "pop: too many arguments";
+ qmlWarning(this) << "pop: too many arguments";
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -577,7 +580,7 @@ void QQuickStackView::pop(QQmlV4Function *args)
enter = d->findElement(item);
if (!enter) {
if (item != d->currentItem)
- qmlInfo(this) << "pop: unknown argument: " << value->toQString(); // TODO: safe?
+ qmlWarning(this) << "pop: unknown argument: " << value->toQString(); // TODO: safe?
args->setReturnValue(QV4::Encode::null());
d->elements.push(exit); // restore
return;
@@ -597,13 +600,14 @@ void QQuickStackView::pop(QQmlV4Function *args)
if (d->popElements(enter)) {
if (exit) {
exit->removal = true;
+ d->removing.insert(exit);
previousItem = exit->item;
}
emit depthChanged();
d->startTransition(QQuickStackTransition::popExit(operation, exit, this),
QQuickStackTransition::popEnter(operation, enter, this),
operation == Immediate);
- d->setCurrentItem(enter->item);
+ d->setCurrentItem(enter);
}
if (previousItem) {
@@ -705,7 +709,7 @@ void QQuickStackView::replace(QQmlV4Function *args)
{
Q_D(QQuickStackView);
if (args->length() <= 0) {
- qmlInfo(this) << "replace: missing arguments";
+ qmlWarning(this) << "replace: missing arguments";
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -727,7 +731,7 @@ void QQuickStackView::replace(QQmlV4Function *args)
QList<QQuickStackElement *> elements = d->parseElements(args, target ? 1 : 0);
if (elements.isEmpty()) {
- qmlInfo(this) << "replace: nothing to push";
+ qmlWarning(this) << "replace: nothing to push";
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -740,13 +744,15 @@ void QQuickStackView::replace(QQmlV4Function *args)
if (exit != target ? d->replaceElements(target, elements) : d->pushElements(elements)) {
if (depth != d->elements.count())
emit depthChanged();
- if (exit)
+ if (exit) {
exit->removal = true;
+ d->removing.insert(exit);
+ }
QQuickStackElement *enter = d->elements.top();
d->startTransition(QQuickStackTransition::replaceExit(operation, exit, this),
QQuickStackTransition::replaceEnter(operation, enter, this),
operation == Immediate);
- d->setCurrentItem(enter->item);
+ d->setCurrentItem(enter);
}
if (d->currentItem) {
@@ -969,7 +975,7 @@ void QQuickStackView::componentComplete()
element = QQuickStackElement::fromString(d->initialItem.toString(), this);
if (d->pushElement(element)) {
emit depthChanged();
- d->setCurrentItem(element->item);
+ d->setCurrentItem(element);
element->setStatus(QQuickStackView::Active);
}
}
@@ -999,20 +1005,22 @@ bool QQuickStackView::childMouseEventFilter(QQuickItem *item, QEvent *event)
// breaking its state (QTBUG-50305).
if (event->type() == QEvent::MouseButtonPress)
return true;
+ if (event->type() == QEvent::UngrabMouse)
+ return false;
QQuickWindow *window = item->window();
return window && !window->mouseGrabberItem();
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessible::Role QQuickStackView::accessibleRole() const
{
return QAccessible::LayeredPane;
}
#endif
-void QQuickStackAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
+void QQuickStackViewAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
{
- Q_Q(QQuickStackAttached);
+ Q_Q(QQuickStackViewAttached);
int oldIndex = element ? element->index : -1;
QQuickStackView *oldView = element ? element->view : nullptr;
QQuickStackView::Status oldStatus = element ? element->status : QQuickStackView::Inactive;
@@ -1031,22 +1039,23 @@ void QQuickStackAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem
emit q->statusChanged();
}
-QQuickStackAttached::QQuickStackAttached(QObject *parent) :
- QObject(*(new QQuickStackAttachedPrivate), parent)
+QQuickStackViewAttached::QQuickStackViewAttached(QObject *parent)
+ : QObject(*(new QQuickStackViewAttachedPrivate), parent)
{
- Q_D(QQuickStackAttached);
+ Q_D(QQuickStackViewAttached);
QQuickItem *item = qobject_cast<QQuickItem *>(parent);
if (item) {
+ connect(item, &QQuickItem::visibleChanged, this, &QQuickStackViewAttached::visibleChanged);
QQuickItemPrivate::get(item)->addItemChangeListener(d, QQuickItemPrivate::Parent);
d->itemParentChanged(item, item->parentItem());
} else if (parent) {
- qmlInfo(parent) << "StackView must be attached to an Item";
+ qmlWarning(parent) << "StackView must be attached to an Item";
}
}
-QQuickStackAttached::~QQuickStackAttached()
+QQuickStackViewAttached::~QQuickStackViewAttached()
{
- Q_D(QQuickStackAttached);
+ Q_D(QQuickStackViewAttached);
QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
if (parentItem)
QQuickItemPrivate::get(parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Parent);
@@ -1059,9 +1068,9 @@ QQuickStackAttached::~QQuickStackAttached()
This attached property holds the stack index of the item it's
attached to, or \c -1 if the item is not in a stack.
*/
-int QQuickStackAttached::index() const
+int QQuickStackViewAttached::index() const
{
- Q_D(const QQuickStackAttached);
+ Q_D(const QQuickStackViewAttached);
return d->element ? d->element->index : -1;
}
@@ -1072,9 +1081,9 @@ int QQuickStackAttached::index() const
This attached property holds the stack view of the item it's
attached to, or \c null if the item is not in a stack.
*/
-QQuickStackView *QQuickStackAttached::view() const
+QQuickStackView *QQuickStackViewAttached::view() const
{
- Q_D(const QQuickStackAttached);
+ Q_D(const QQuickStackViewAttached);
return d->element ? d->element->view : nullptr;
}
@@ -1091,13 +1100,61 @@ QQuickStackView *QQuickStackAttached::view() const
\value StackView.Activating The item is being activated (becoming the current item).
\value StackView.Active The item is active, that is, the current item.
*/
-QQuickStackView::Status QQuickStackAttached::status() const
+QQuickStackView::Status QQuickStackViewAttached::status() const
{
- Q_D(const QQuickStackAttached);
+ Q_D(const QQuickStackViewAttached);
return d->element ? d->element->status : QQuickStackView::Inactive;
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlattachedproperty bool QtQuick.Controls::StackView::visible
+
+ This attached property holds the visibility of the item it's attached to.
+ The value follows the value of \l Item::visible.
+
+ By default, StackView shows incoming items when the enter transition begins,
+ and hides outgoing items when the exit transition ends. Setting this property
+ explicitly allows the default behavior to be overridden, making it possible
+ to keep items that are below the top-most item visible.
+
+ \note The default transitions of most styles slide outgoing items outside the
+ view, and may also animate their opacity. In order to keep a full stack
+ of items visible, consider customizing the \l transitions so that the
+ items underneath can be seen.
+
+ \image qtquickcontrols2-stackview-visible.png
+
+ \snippet qtquickcontrols2-stackview-visible.qml 1
+*/
+bool QQuickStackViewAttached::isVisible() const
+{
+ const QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ return parentItem && parentItem->isVisible();
+}
+
+void QQuickStackViewAttached::setVisible(bool visible)
+{
+ Q_D(QQuickStackViewAttached);
+ d->explicitVisible = true;
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ parentItem->setVisible(visible);
+}
+
+void QQuickStackViewAttached::resetVisible()
+{
+ Q_D(QQuickStackViewAttached);
+ d->explicitVisible = false;
+ if (!d->element || !d->element->view)
+ return;
+
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ parentItem->setVisible(parentItem == d->element->view->currentItem());
+}
+
+/*!
\qmlattachedsignal QtQuick.Controls::StackView::activated()
\since QtQuick.Controls 2.1