diff --git a/examples/galleryapp/resources.qrc b/examples/galleryapp/resources.qrc
--- a/examples/galleryapp/resources.qrc
+++ b/examples/galleryapp/resources.qrc
@@ -16,6 +16,8 @@
../gallerydata/contents/ui/gallery/TabBarGallery.qml
../gallerydata/contents/ui/gallery/TextFieldGallery.qml
../gallerydata/contents/ui/gallery/ColorsGallery.qml
+ ../gallerydata/contents/ui/gallery/MetricsGallery.qml
+ ../gallerydata/contents/ui/gallery/LayersGallery.qml
../gallerydata/contents/ui/ExampleApp.qml
../gallerydata/contents/ui/DesktopExampleApp.qml
../gallerydata/metadata.desktop
diff --git a/examples/gallerydata/contents/ui/DesktopExampleApp.qml b/examples/gallerydata/contents/ui/DesktopExampleApp.qml
--- a/examples/gallerydata/contents/ui/DesktopExampleApp.qml
+++ b/examples/gallerydata/contents/ui/DesktopExampleApp.qml
@@ -64,16 +64,16 @@
},
Kirigami.Action {
text: "Checkable"
- iconName: "view-list-details"
+ iconName: "go-next"
checkable: true
checked: false
onTriggered: {
showPassiveNotification("Action checked: " + checked)
}
},
Kirigami.Action {
text: "Open A Page"
- iconName: "configure"
+ iconName: "view-list-details"
checkable: true
//Need to do this, otherwise it breaks the bindings
property bool current: pageStack.currentItem ? pageStack.currentItem.objectName == "settingsPage" : false
@@ -83,6 +83,13 @@
onTriggered: {
pageStack.push(settingsComponent);
}
+ },
+ Kirigami.Action {
+ text: "Open A Layer"
+ iconName: "configure"
+ onTriggered: {
+ pageStack.layers.push(Qt.resolvedUrl("gallery/LayersGallery.qml"));
+ }
}
]
diff --git a/examples/gallerydata/contents/ui/ExampleApp.qml b/examples/gallerydata/contents/ui/ExampleApp.qml
--- a/examples/gallerydata/contents/ui/ExampleApp.qml
+++ b/examples/gallerydata/contents/ui/ExampleApp.qml
@@ -64,16 +64,16 @@
},
Kirigami.Action {
text: "Checkable"
- iconName: "view-list-details"
+ iconName: "go-next"
checkable: true
checked: false
onTriggered: {
showPassiveNotification("Action checked: " + checked)
}
},
Kirigami.Action {
text: "Open A Page"
- iconName: "configure"
+ iconName: "view-list-details"
checkable: true
//Need to do this, otherwise it breaks the bindings
property bool current: pageStack.currentItem ? pageStack.currentItem.objectName == "settingsPage" : false
@@ -83,6 +83,13 @@
onTriggered: {
pageStack.push(settingsComponent);
}
+ },
+ Kirigami.Action {
+ text: "Open A Layer"
+ iconName: "configure"
+ onTriggered: {
+ pageStack.layers.push(Qt.resolvedUrl("gallery/LayersGallery.qml"));
+ }
}
]
diff --git a/examples/gallerydata/contents/ui/gallery/LayersGallery.qml b/examples/gallerydata/contents/ui/gallery/LayersGallery.qml
new file mode 100644
--- /dev/null
+++ b/examples/gallerydata/contents/ui/gallery/LayersGallery.qml
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2015 Marco Martin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import QtQuick 2.0
+import QtQuick.Controls 2.0 as Controls
+import QtQuick.Layouts 1.2
+import org.kde.kirigami 2.0
+
+ScrollablePage {
+ id: page
+ Layout.fillWidth: true
+ //implicitWidth: Units.gridUnit * (Math.floor(Math.random() * 35) + 8)
+
+ title: "Multiple Columns"
+
+ actions {
+ main: Action {
+ iconName: "document-edit"
+ text: "Main Action Text"
+ onTriggered: {
+ showPassiveNotification("Action button in buttons page clicked");
+ }
+ }
+ left: Action {
+ iconName: "go-previous"
+ text: "Left Action Text"
+ onTriggered: {
+ showPassiveNotification("Left action triggered")
+ }
+ }
+ contextualActions: [
+ Action {
+ text:"Action 1"
+ iconName: "go-next"
+ onTriggered: showPassiveNotification("Action 1 clicked")
+ },
+ Action {
+ text:"Action 2"
+ iconName: "folder"
+ enabled: false
+ onTriggered: showPassiveNotification("Action 2 clicked")
+ }
+ ]
+ }
+
+ ColumnLayout {
+ width: page.width
+ spacing: Units.smallSpacing
+
+ Label {
+ Layout.fillWidth: true
+ wrapMode: Text.WordWrap
+ text: "This page is used to test multiple layers: it will cover all the columns"
+ }
+
+ Controls.Button {
+ text: "Push A New Layer"
+ anchors.horizontalCenter: parent.horizontalCenter
+ onClicked: pageStack.layers.push(Qt.resolvedUrl("LayersGallery.qml"));
+ }
+ Controls.Button {
+ text: "Pop A Layer"
+ anchors.horizontalCenter: parent.horizontalCenter
+ onClicked: pageStack.layers.pop();
+ }
+ }
+
+
+}
diff --git a/src/controls/ContextDrawer.qml b/src/controls/ContextDrawer.qml
--- a/src/controls/ContextDrawer.qml
+++ b/src/controls/ContextDrawer.qml
@@ -81,7 +81,9 @@
* This can be any type of object that a ListView can accept as model.
* It expects items compatible with either QAction or Kirigami Action
*/
- property var actions: pageStack.currentItem ? pageStack.currentItem.contextualActions : null
+ property var actions: pageStack.layers.depth > 1
+ ? pageStack.layers.currentItem.contextualActions
+ : (pageStack.currentItem ? pageStack.currentItem.contextualActions : null)
enabled: menu.count > 0
edge: Qt.RightEdge
drawerOpen: false
@@ -93,14 +95,6 @@
handleVisible: applicationWindow == undefined || applicationWindow().wideScreen == true ? false : applicationWindow().controlsVisible
- Connections {
- target: pageStack
- onCurrentItemChanged: {
- if (pageStack.currentItem)
- actions = pageStack.currentItem.contextualActions
- }
- }
-
contentItem: ScrollView {
implicitWidth: Units.gridUnit * 20
ListView {
diff --git a/src/controls/Page.qml b/src/controls/Page.qml
--- a/src/controls/Page.qml
+++ b/src/controls/Page.qml
@@ -256,7 +256,7 @@
}
height: item ? item.height : 0
source: (applicationWindow().header && applicationWindow().header.toString().indexOf("ToolBarApplicationHeader") === 0) ||
- (applicationWindow().footer && applicationWindow().footer.toString().indexOf("ToolBarApplicationHeader") === 0)
+ (applicationWindow().footer && applicationWindow().footer.visible && applicationWindow().footer.toString().indexOf("ToolBarApplicationHeader") === 0)
? "" : Qt.resolvedUrl("./private/ActionButton.qml")
}
diff --git a/src/controls/PageRow.qml b/src/controls/PageRow.qml
--- a/src/controls/PageRow.qml
+++ b/src/controls/PageRow.qml
@@ -21,6 +21,7 @@
import QtQuick.Layouts 1.2
import QtQml.Models 2.2
import QtQuick.Templates 2.0 as T
+import QtQuick.Controls 2.0 as QQC2
import org.kde.kirigami 2.0
/**
@@ -297,6 +298,14 @@
}
}
+ /**
+ * layers: QtQuick.Controls.PageStack
+ * Access to the modal layers.
+ * Sometimes an application needs a modal page that always covers all the rows.
+ * For instance the full screen image of an image viewer or a settings page.
+ * @since 5.38
+ */
+ property alias layers: layersStack
//END FUNCTIONS
onInitialPageChanged: {
@@ -323,9 +332,21 @@
script: mainView.flick(100, 0)
}
}
+ QQC2.StackView {
+ id: layersStack
+ z: 99
+ anchors.fill: parent
+ initialItem: mainView
+ function clear () {
+ //don't let it kill the main page row
+ var d = root.depth;
+ for (var i = 1; i < d; ++i) {
+ pop();
+ }
+ }
+ }
ListView {
id: mainView
- z: 99
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
orientation: Qt.Horizontal
diff --git a/src/controls/private/ActionButton.qml b/src/controls/private/ActionButton.qml
--- a/src/controls/private/ActionButton.qml
+++ b/src/controls/private/ActionButton.qml
@@ -42,6 +42,13 @@
transform: Translate {
id: translateTransform
+ y: mouseArea.internalVisibility ? 0 : button.height
+ Behavior on y {
+ NumberAnimation {
+ duration: Units.longDuration
+ easing.type: mouseArea.internalVisibility == true ? Easing.InQuad : Easing.OutQuad
+ }
+ }
}
Item {
@@ -78,15 +85,6 @@
visible: action != null || leftAction != null || rightAction != null
property bool internalVisibility: (applicationWindow === undefined || (applicationWindow().controlsVisible && applicationWindow().height > root.height*2)) && (root.action === null || root.action.visible === undefined || root.action.visible)
preventStealing: true
- onInternalVisibilityChanged: {
- showAnimation.running = false;
- if (internalVisibility) {
- showAnimation.to = 0;
- } else {
- showAnimation.to = button.height;
- }
- showAnimation.running = true;
- }
drag {
target: button
@@ -213,13 +211,6 @@
}
}
- NumberAnimation {
- id: showAnimation
- target: translateTransform
- properties: "y"
- duration: Units.longDuration
- easing.type: mouseArea.internalVisibility == true ? Easing.InQuad : Easing.OutQuad
- }
Item {
id: background
anchors {
diff --git a/src/controls/templates/ApplicationHeader.qml b/src/controls/templates/ApplicationHeader.qml
--- a/src/controls/templates/ApplicationHeader.qml
+++ b/src/controls/templates/ApplicationHeader.qml
@@ -18,6 +18,7 @@
*/
import QtQuick 2.5
+import QtQuick.Controls 2.0 as QQC2
import QtQuick.Layouts 1.2
import "private"
import org.kde.kirigami 2.0
@@ -56,10 +57,10 @@
property bool backButtonEnabled: (!titleList.isTabBar && (!Settings.isMobile || Qt.platform.os == "ios"))
onBackButtonEnabledChanged: {
- if (backButtonEnabled) {
+ if (backButtonEnabled && !titleList.backButton) {
var component = Qt.createComponent(Qt.resolvedUrl("private/BackButton.qml"));
titleList.backButton = component.createObject(titleList.parent);
- } else {
+ } else if (titleList.backButton) {
titleList.backButton.destroy();
}
}
@@ -92,7 +93,7 @@
elide: Text.ElideRight
text: page ? page.title : ""
font.pixelSize: titleList.height / 1.6
- height: parent.height
+ verticalAlignment: Text.AlignVCenter
Rectangle {
anchors {
bottom: parent.bottom
@@ -120,6 +121,23 @@
opacity: 0.4
}
+ QQC2.StackView {
+ id: stack
+ anchors {
+ fill: parent
+ leftMargin: titleList.scrollingLocked && titleList.wideMode ? 0 : titleList.backButton.width
+ }
+ initialItem: titleList
+ }
+ Repeater {
+ model: __appWindow.pageStack.layers.depth -1
+ delegate: Loader {
+ sourceComponent: header.pageDelegate
+ readonly property Page page: __appWindow.pageStack.layers.get(modelData+1)
+ Component.onCompleted: stack.push(this)
+ Component.onDestruction: stack.pop()
+ }
+ }
ListView {
id: titleList
readonly property bool wideMode: typeof __appWindow.pageStack.wideMode !== "undefined" ? __appWindow.pageStack.wideMode : titleList.wideMode
@@ -129,19 +147,10 @@
//uses this to have less strings comparisons
property bool scrollMutex
property bool isTabBar: header.headerStyle == ApplicationHeaderStyle.TabBar
- Component.onCompleted: {
- //only iOS and desktop systems put the back button on top left corner
- if (header.backButtonEnabled) {
- var component = Qt.createComponent(Qt.resolvedUrl("private/BackButton.qml"));
- titleList.backButton = component.createObject(titleList.parent);
- }
- }
+
property Item backButton
clip: true
- anchors {
- fill: parent
- leftMargin: titleList.scrollingLocked && titleList.wideMode ? 0 : backButton.width
- }
+
cacheBuffer: width ? Math.max(0, width * count) : 0
displayMarginBeginning: __appWindow.pageStack.width * count
orientation: ListView.Horizontal
diff --git a/src/controls/templates/private/BackButton.qml b/src/controls/templates/private/BackButton.qml
--- a/src/controls/templates/private/BackButton.qml
+++ b/src/controls/templates/private/BackButton.qml
@@ -29,7 +29,13 @@
implicitWidth: height
visible: applicationWindow().pageStack.contentItem.contentWidth > applicationWindow().pageStack.contentItem.width
z: 99
- onClicked: applicationWindow().pageStack.goBack();
+ onClicked: {
+ if (applicationWindow().pageStack.layers && applicationWindow().pageStack.layers.depth > 1) {
+ applicationWindow().pageStack.layers.pop();
+ } else {
+ applicationWindow().pageStack.goBack();
+ }
+ }
Icon {
anchors.fill: parent
opacity: parent.enabled ? 1 : 0.6