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
@@ -26,50 +26,82 @@
Kirigami.ApplicationWindow {
id: root
- header: Kirigami.ToolBarApplicationHeader {}
-
globalDrawer: Kirigami.GlobalDrawer {
title: "Widget gallery"
titleIcon: "applications-graphics"
bannerImageSource: "banner.jpg"
actions: [
Kirigami.Action {
- text: "Submenu 1"
+ text: "Top Bar Style"
iconName: "view-list-icons"
Kirigami.Action {
- text: "Action 1"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "Auto"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.Auto
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.Auto
+ }
+ Kirigami.Action {
+ text: "Breadcrumb"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.Breadcrumb
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.Breadcrumb
}
Kirigami.Action {
- text: "Action 2"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "TabBar"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.TabBar
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.TabBar
}
Kirigami.Action {
- text: "Action 3"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "Titles"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.Titles
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.Titles
+ }
+ Kirigami.Action {
+ text: "ToolBar"
+ visible: !Kirigami.Settings.isMobile
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.ToolBar
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.ToolBar
+ }
+ Kirigami.Action {
+ text: "None"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.None
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.None
}
},
Kirigami.Action {
- text: "Submenu 2"
+ text: "Top Bar Sizing"
iconName: "folder-sync"
+ visible: Kirigami.Settings.isMobile
+ Kirigami.Action {
+ text: "Slide Away"
+ onTriggered: {
+ root.pageStack.globalToolBar.minimumHeight = 0;
+ root.pageStack.globalToolBar.preferredHeight = 42;
+ }
+ checked: root.pageStack.globalToolBar.minimumHeight == 0
+ }
Kirigami.Action {
- text: "Action 4"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "Fixed"
+ onTriggered: {
+ root.pageStack.globalToolBar.minimumHeight = 42;
+ root.pageStack.globalToolBar.preferredHeight = 42;
+ }
+ checked: root.pageStack.globalToolBar.minimumHeight == 42
}
Kirigami.Action {
- text: "Action 5"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "Resizing"
+ onTriggered: {
+ root.pageStack.globalToolBar.minimumHeight = 20;
+ root.pageStack.globalToolBar.preferredHeight = 52;
+ }
+ checked: root.pageStack.globalToolBar.minimumHeight == 20
}
},
Kirigami.Action {
- text: "Checkable"
+ text: "Modal Drawer"
iconName: "go-next"
checkable: true
- checked: false
- onTriggered: {
- showPassiveNotification("Action checked: " + checked)
- }
+ checked: globalDrawer.modal
+ onCheckedChanged: globalDrawer.modal = checked
},
Kirigami.Action {
text: "Open A Page"
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
@@ -26,40 +26,74 @@
Kirigami.ApplicationWindow {
id: root
- header: Kirigami.ApplicationHeader {}
-
globalDrawer: Kirigami.GlobalDrawer {
title: "Widget gallery"
titleIcon: "applications-graphics"
bannerImageSource: "banner.jpg"
actions: [
Kirigami.Action {
- text: "Submenu 1"
+ text: "Top Bar Style"
iconName: "view-list-icons"
Kirigami.Action {
- text: "Action 1"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "Auto"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.Auto
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.Auto
+ }
+ Kirigami.Action {
+ text: "Breadcrumb"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.Breadcrumb
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.Breadcrumb
+ }
+ Kirigami.Action {
+ text: "TabBar"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.TabBar
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.TabBar
}
Kirigami.Action {
- text: "Action 2"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "Titles"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.Titles
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.Titles
}
Kirigami.Action {
- text: "Action 3"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "ToolBar"
+ visible: !Kirigami.Settings.isMobile
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.ToolBar
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.ToolBar
+ }
+ Kirigami.Action {
+ text: "None"
+ onTriggered: root.pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.None
+ checked: root.pageStack.globalToolBar.style == Kirigami.ApplicationHeaderStyle.None
}
},
Kirigami.Action {
- text: "Submenu 2"
+ text: "Top Bar Sizing"
iconName: "folder-sync"
+ visible: Kirigami.Settings.isMobile
+ Kirigami.Action {
+ text: "Slide Away"
+ onTriggered: {
+ root.pageStack.globalToolBar.minimumHeight = 0;
+ root.pageStack.globalToolBar.preferredHeight = 42;
+ }
+ checked: root.pageStack.globalToolBar.minimumHeight == 0
+ }
Kirigami.Action {
- text: "Action 4"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "Fixed"
+ onTriggered: {
+ root.pageStack.globalToolBar.minimumHeight = 42;
+ root.pageStack.globalToolBar.preferredHeight = 42;
+ }
+ checked: root.pageStack.globalToolBar.minimumHeight == 42
}
Kirigami.Action {
- text: "Action 5"
- onTriggered: showPassiveNotification(text + " clicked")
+ text: "Resizing"
+ onTriggered: {
+ root.pageStack.globalToolBar.minimumHeight = 20;
+ root.pageStack.globalToolBar.preferredHeight = 52;
+ }
+ checked: root.pageStack.globalToolBar.minimumHeight == 20
}
},
Kirigami.Action {
diff --git a/examples/gallerydata/contents/ui/gallery/LayersGallery.qml b/examples/gallerydata/contents/ui/gallery/LayersGallery.qml
--- a/examples/gallerydata/contents/ui/gallery/LayersGallery.qml
+++ b/examples/gallerydata/contents/ui/gallery/LayersGallery.qml
@@ -27,7 +27,7 @@
Layout.fillWidth: true
//implicitWidth: Units.gridUnit * (Math.floor(Math.random() * 35) + 8)
- title: "Multiple Columns"
+ title: "Layers"
actions {
main: Action {
diff --git a/examples/simpleexamples/simpleChatApp.qml b/examples/simpleexamples/simpleChatApp.qml
--- a/examples/simpleexamples/simpleChatApp.qml
+++ b/examples/simpleexamples/simpleChatApp.qml
@@ -25,7 +25,7 @@
Kirigami.ApplicationWindow {
id: root
- header: Kirigami.ToolBarApplicationHeader {}
+ //header: Kirigami.ToolBarApplicationHeader {}
//FIXME: perhaps the default logic for going widescreen should be refined upstream
wideScreen: width > columnWidth * 3
property int columnWidth: Kirigami.Units.gridUnit * 13
@@ -56,7 +56,7 @@
contextDrawer: Kirigami.OverlayDrawer {
id: contextDrawer
//they can depend on the page like that or be defined directly here
- edge: Qt.RightEdge
+ edge: Qt.application.layoutDirection == Qt.RightToLeft ? Qt.LeftEdge : Qt.RightEdge
modal: !root.wideScreen
onModalChanged: drawerOpen = !modal
handleVisible: applicationWindow == undefined ? false : applicationWindow().controlsVisible
diff --git a/kirigami.qrc b/kirigami.qrc
--- a/kirigami.qrc
+++ b/kirigami.qrc
@@ -28,6 +28,12 @@
src/controls/private/BannerImage.qml
src/controls/private/BannerGroup.qml
src/controls/private/EdgeShadow.qml
+ src/controls/private/AbstractPageHeader.qml
+ src/controls/private/PageRowGlobalToolBarStyleGroup.qml
+ src/controls/private/PageRowGlobalToolBarUI.qml
+ src/controls/private/PrivateActionToolButton.qml
+ src/controls/private/TitlesPageHeader.qml
+ src/controls/private/ToolBarPageHeader.qml
src/controls/Separator.qml
src/controls/OverlayDrawer.qml
src/controls/OverlaySheet.qml
diff --git a/src/controls/AbstractApplicationHeader.qml b/src/controls/AbstractApplicationHeader.qml
--- a/src/controls/AbstractApplicationHeader.qml
+++ b/src/controls/AbstractApplicationHeader.qml
@@ -18,7 +18,7 @@
*/
import QtQuick 2.5
-import org.kde.kirigami 2.4
+import org.kde.kirigami 2.5
import "private"
import "templates" as T
@@ -38,16 +38,28 @@
T.AbstractApplicationHeader {
id: root
+ Theme.inherit: false
+ Theme.textColor: root.parent.Theme.highlightedTextColor
+ Theme.backgroundColor: root.parent.Theme.highlightColor
+ Theme.highlightColor: root.parent.Theme.backgroundColor
+
background: Rectangle {
- color: Theme.highlightColor
+ color: Theme.backgroundColor
EdgeShadow {
id: shadow
- edge: Qt.TopEdge
anchors {
right: parent.right
left: parent.left
top: parent.bottom
}
+ edge: Qt.TopEdge
+ opacity: (!root.page.header || root.page.header.toString().indexOf("ToolBar") === -1)
+ Behavior on opacity {
+ OpacityAnimator {
+ duration: Units.longDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
}
}
}
diff --git a/src/controls/ApplicationWindow.qml b/src/controls/ApplicationWindow.qml
--- a/src/controls/ApplicationWindow.qml
+++ b/src/controls/ApplicationWindow.qml
@@ -114,6 +114,7 @@
PageRow {
id: __pageStack
+ globalToolBar.style: Kirigami.ApplicationHeaderStyle.Auto
anchors {
fill: parent
//HACK: workaround a bug in android iOS keyboard management
diff --git a/src/controls/OverlayDrawer.qml b/src/controls/OverlayDrawer.qml
--- a/src/controls/OverlayDrawer.qml
+++ b/src/controls/OverlayDrawer.qml
@@ -66,7 +66,15 @@
width: height
height: Units.iconSizes.smallMedium
source: {
- switch(root.edge) {
+ var edge = root.edge;
+ if (Qt.application.layoutDirection == Qt.RightToLeft) {
+ if (edge == Qt.LeftEdge) {
+ edge = Qt.RightEdge;
+ } else {
+ edge = Qt.LeftEdge;
+ }
+ }
+ switch(edge) {
case Qt.LeftEdge:
return Qt.resolvedUrl("templates/private/MenuIcon.qml");
case Qt.RightEdge: {
diff --git a/src/controls/Page.qml b/src/controls/Page.qml
--- a/src/controls/Page.qml
+++ b/src/controls/Page.qml
@@ -207,11 +207,11 @@
*
* @since 2.1
*/
- readonly property bool isCurrentPage: typeof applicationWindow === "undefined" || !applicationWindow().pageStack
+ readonly property bool isCurrentPage: typeof applicationWindow === "undefined" || !globalToolBar.row
? true
- : (applicationWindow().pageStack.layers.depth > 1
- ? applicationWindow().pageStack.layers.currentItem == root
- : applicationWindow().pageStack.currentItem == root)
+ : (globalToolBar.row.layers.depth > 1
+ ? globalToolBar.row.layers.currentItem == root
+ : globalToolBar.row.currentItem == root)
PageActionPropertyGroup {
id: actionsGroup
@@ -246,8 +246,68 @@
}
}
- //on material the shadow would bleed over
- clip: header !== undefined
+ //FIXME: on material the shadow would bleed over
+ clip: root.header != null;
+
+ Component.onCompleted: {
+ parentChanged(root.parent);
+ }
+ onParentChanged: {
+ if (!parent) {
+ return;
+ }
+ globalToolBar.stack = null;
+ globalToolBar.row = null;
+
+ if (root.parent.hasOwnProperty("__pageRow")) {
+ globalToolBar.row = root.parent.__pageRow;
+ }
+ if (root.T2.StackView.view) {
+ globalToolBar.stack = root.T2.StackView.view;
+ globalToolBar.row = root.T2.StackView.view.parent;
+ }
+ if (globalToolBar.row) {
+ globalToolBar.row.globalToolBar.actualStyleChanged.connect(globalToolBar.syncSource);
+ globalToolBar.syncSource();
+ }
+ }
+
+ //global top toolbar if we are in a PageRow (in the row or as a layer)
+ Loader {
+ id: globalToolBar
+ z: 9999
+ parent: root.clip ? root.parent : root
+ height: item ? item.implicitHeight : 0
+ anchors {
+ left: parent ? root.left : undefined
+ right: parent ? root.right : undefined
+ bottom: parent ? root.top : undefined
+ }
+ property Kirigami.PageRow row
+ property T2.StackView stack
+
+ active: row && (row.globalToolBar.actualStyle == Kirigami.ApplicationHeaderStyle.ToolBar || globalToolBar.row.globalToolBar.actualStyle == Kirigami.ApplicationHeaderStyle.Titles)
+
+ function syncSource() {
+ if (row && active) {
+ setSource(Qt.resolvedUrl(row.globalToolBar.actualStyle == Kirigami.ApplicationHeaderStyle.ToolBar ? "private/ToolBarPageHeader.qml" : "private/TitlesPageHeader.qml"),
+ //TODO: find container reliably, remove assumption
+ {"pageRow": Qt.binding(function() {return row}),
+ "page": root,
+ "current": Qt.binding(function() {return stack || !root.parent ? true : row.currentIndex == root.parent.level})});
+ }
+ }
+
+ Separator {
+ z: 999
+ anchors.verticalCenter: globalToolBar.verticalCenter
+ height: globalToolBar.height * 0.6
+ visible: globalToolBar.row && root.parent && globalToolBar.row.contentItem.contentX < root.parent.x - globalToolBar.row.globalToolBar.leftReservedSpace
+ Kirigami.Theme.textColor: globalToolBar.item ? globalToolBar.item.Kirigami.Theme.textColor : undefined
+ }
+ }
+
+ //bottom action buttons
Loader {
id: actionButtons
z: 9999
@@ -260,9 +320,12 @@
//It should be T2.Page, Qt 5.7 doesn't like it
property Item page: root
height: item ? item.height : 0
- source: typeof applicationWindow !== "undefined" && ((applicationWindow().header && applicationWindow().header.toString().indexOf("ToolBarApplicationHeader") === 0) ||
- (applicationWindow().footer && applicationWindow().footer.visible && applicationWindow().footer.toString().indexOf("ToolBarApplicationHeader") === 0))
- ? "" : Qt.resolvedUrl("./private/ActionButton.qml")
+ active: typeof applicationWindow !== "undefined" && (!globalToolBar.row || globalToolBar.row.globalToolBar.actualStyle != Kirigami.ApplicationHeaderStyle.ToolBar) &&
+ //Legacy
+ (typeof applicationWindow === "undefined" ||
+ (!applicationWindow().header || applicationWindow().header.toString().indexOf("ToolBarApplicationHeader") === -1) &&
+ (!applicationWindow().footer || applicationWindow().footer.toString().indexOf("ToolBarApplicationHeader") === -1))
+ source: Qt.resolvedUrl("./private/ActionButton.qml")
}
Layout.fillWidth: true
diff --git a/src/controls/PageRow.qml b/src/controls/PageRow.qml
--- a/src/controls/PageRow.qml
+++ b/src/controls/PageRow.qml
@@ -23,6 +23,8 @@
import QtQuick.Templates 2.0 as T
import QtQuick.Controls 2.0 as QQC2
import org.kde.kirigami 2.4
+import "private" as Private
+import "templates" as KT
/**
* PageRow implements a row-based navigation model, which can be used
@@ -98,6 +100,29 @@
* @since 5.38
*/
property bool separatorVisible: true
+
+ /**
+ * globalToolBar: grouped property
+ * Controls the appearance of an optional global toolbar for the whole PageRow.
+ * It's a grouped property comprised of the following properties:
+ * * style: (Kirigami.ApplicationHeaderStyle) can have the following values:
+ * ** Auto: depending on application formfactor, it can behave automatically like other values, such as a Breadcrumb on mobile and ToolBar on desktop
+ * ** Breadcrumb: it will show a breadcrumb of all the page titles in the stack, for easy navigation
+ * ** Titles: each page will only have its own tile on top
+ * ** TabBar: the global toolbar will look like a TabBar to select the pages
+ * ** ToolBar: each page will have the title on top together buttons and menus to represent all of the page actions: not available on Mobile systems.
+ * ** None: no global toolbar will be shown
+ *
+ * * actualStyle: this will represent the actual style of the toolbar: it can be different from style in the case style is Auto
+ * * showNavigationButtons: if true, forward and backward navigation buttons will be shown on the left of the toolbar
+ * * minimumHeight: (int) minimum height of the header, which will be resized when scrolling, only in Mobile mode (default: preferredHeight, sliding but no scaling)
+ property int preferredHeight: (int) the height the toolbar will usually have (default: 42)
+ property int maximumHeight: (int) The height the toolbar will have in mobile mode when the app is in reachable mode (default: preferredHeight * 1.5)
+ * * leftReservedSpace: (int, readonly) how many pixels are reserved at the left of the page toolBar (for navigation buttons or drawer handle)
+ property int rightReservedSpace: (int, readonly) how many pixels are reserved at the right of the page toolbar (drawer handle)
+ * @since 5.48
+ */
+ readonly property alias globalToolBar: globalToolBar
//END PROPERTIES
//BEGIN FUNCTIONS
@@ -348,10 +373,23 @@
script: mainView.flick(100, 0)
}
}
+
+ Private.PageRowGlobalToolBarStyleGroup {
+ id: globalToolBar
+ readonly property int leftReservedSpace: globalToolBarUI.item ? globalToolBarUI.item.leftReservedSpace : 0
+ readonly property int rightReservedSpace: globalToolBarUI.item ? globalToolBarUI.item.rightReservedSpace : 0
+ readonly property int height: globalToolBarUI.height
+ readonly property Item leftHandleAnchor: globalToolBarUI.item ? globalToolBarUI.item.leftHandleAnchor : null
+ readonly property Item rightHandleAnchor: globalToolBarUI.item ? globalToolBarUI.item.rightHandleAnchor : null
+ }
+
QQC2.StackView {
id: layersStack
z: 99
- anchors.fill: parent
+ anchors {
+ fill: parent
+ topMargin: depth > 1 && globalToolBarUI.visible ? globalToolBarUI.height: 0
+ }
initialItem: mainView
function clear () {
//don't let it kill the main page row
@@ -415,6 +453,20 @@
}
}
+ Loader {
+ id: globalToolBarUI
+ anchors {
+ left: parent.left
+ top: parent.top
+ right: parent.right
+ }
+ z: 100
+ active: globalToolBar.actualStyle != ApplicationHeaderStyle.None
+ visible: active
+ height: active ? implicitHeight : 0
+ source: Qt.resolvedUrl("private/PageRowGlobalToolBarUI.qml");
+ }
+
ListView {
id: mainView
boundsBehavior: Flickable.StopAtBounds
@@ -435,6 +487,7 @@
currentItem.page.forceActiveFocus();
}
}
+
model: ObjectModel {
id: pagesLogic
readonly property var componentCache: new Array()
@@ -569,16 +622,23 @@
readonly property int hint: page && page.implicitWidth ? page.implicitWidth : root.defaultColumnWidth
readonly property int roundedHint: Math.floor(root.width/hint) > 0 ? root.width/Math.floor(root.width/hint) : root.width
+ property T.Control __pageRow: root
+
+ property Item footer
property Item page
- property Item owner
onPageChanged: {
if (page) {
owner = page.parent;
page.parent = container;
- page.anchors.fill = container;
+ page.anchors.left = container.left;
+ page.anchors.top = container.top;
+ page.anchors.right = container.right;
+ page.anchors.bottom = container.bottom;
+ page.anchors.topMargin = Qt.binding(function() {return globalToolBarUI.height});
}
}
+ property Item owner
drag.filterChildren: true
onClicked: {
switch (mouse.button) {
@@ -602,11 +662,13 @@
Separator {
z: 999
anchors {
- top: parent.top
+ top: page ? page.top : parent.top
bottom: parent.bottom
left: parent.left
+ //ensure a sharp angle
+ topMargin: -width
}
- visible: root.separatorVisible && container.level > 0
+ visible: root.separatorVisible && mainView.contentX < container.x
}
states: [
State {
diff --git a/src/controls/ToolBarApplicationHeader.qml b/src/controls/ToolBarApplicationHeader.qml
--- a/src/controls/ToolBarApplicationHeader.qml
+++ b/src/controls/ToolBarApplicationHeader.qml
@@ -39,6 +39,7 @@
//FIXME: needs a property difinition to have its own type in qml
property string _internal: ""
+ Component.onCompleted: print("Warning: ToolbarApplicationHeader is deprecated, remove and use the automatic internal toolbar instead.")
pageDelegate: Item {
id: delegateItem
readonly property bool current: __appWindow.pageStack.currentIndex == index
diff --git a/src/controls/private/AbstractPageHeader.qml b/src/controls/private/AbstractPageHeader.qml
new file mode 100644
--- /dev/null
+++ b/src/controls/private/AbstractPageHeader.qml
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018 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.5
+import QtQuick.Controls 2.0 as Controls
+import QtQuick.Layouts 1.2
+import org.kde.kirigami 2.4
+
+AbstractApplicationHeader {
+ anchors.fill: parent
+ property Item container
+ property bool current
+
+ minimumHeight: pageRow.globalToolBar.minimumHeight
+ maximumHeight: pageRow.globalToolBar.maximumHeight
+ preferredHeight: pageRow.globalToolBar.preferredHeight
+ implicitHeight: page.y
+
+ leftPadding: Qt.application.layoutDirection == Qt.LeftToRight
+ ? Math.max(0, pageRow.contentItem.contentX - mapToItem(pageRow.contentItem.contentItem, 0, 0).x + pageRow.globalToolBar.leftReservedSpace)
+ : Math.max(0, mapToItem(pageRow.contentItem.contentItem, width, 0).x - (pageRow.contentItem.contentX + pageRow.width) + pageRow.globalToolBar.leftReservedSpace)
+
+ rightPadding: Qt.application.layoutDirection == Qt.LeftToRight
+ ? Math.min(pageRow.globalToolBar.rightReservedSpace, Math.max(0, mapToItem(pageRow.contentItem.contentItem, width, 0).x - (pageRow.contentItem.contentX + pageRow.width) + pageRow.globalToolBar.rightReservedSpace))
+ : Math.max(0, pageRow.contentItem.contentX - mapToItem(pageRow.contentItem.contentItem, 0, 0).x + pageRow.globalToolBar.rightReservedSpace)
+}
diff --git a/src/controls/private/PageRowGlobalToolBarStyleGroup.qml b/src/controls/private/PageRowGlobalToolBarStyleGroup.qml
new file mode 100644
--- /dev/null
+++ b/src/controls/private/PageRowGlobalToolBarStyleGroup.qml
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2018 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.1
+import org.kde.kirigami 2.4 as Kirigami
+
+QtObject {
+ id: globalToolBar
+ property int style: Kirigami.ApplicationHeaderStyle.None
+ readonly property int actualStyle: {
+ if (style == Kirigami.ApplicationHeaderStyle.Auto) {
+ //Legacy: if ApplicationHeader or ToolbarApplicationHeader are in the header or footer, disable the toolbar here
+ if (typeof applicationWindow !== "undefined" && applicationWindow().header && applicationWindow().header.toString().indexOf("ApplicationHeader") !== -1) {
+ return Kirigami.ApplicationHeaderStyle.None
+ }
+
+ //non legacy logic
+ return (Kirigami.Settings.isMobile
+ ? (root.wideMode ? Kirigami.ApplicationHeaderStyle.Titles : Kirigami.ApplicationHeaderStyle.Breadcrumb)
+ : Kirigami.ApplicationHeaderStyle.ToolBar)
+ } else {
+ //forbid ToolBar on mobile systems
+ return Kirigami.Settings.isMobile && style == Kirigami.ApplicationHeaderStyle.ToolBar ? Kirigami.ApplicationHeaderStyle.Breadcrumb : style;
+ }
+ }
+
+ property bool showNavigationButtons: style != Kirigami.ApplicationHeaderStyle.TabBar && (!Kirigami.Settings.isMobile || Qt.platform.os == "ios")
+
+ property int minimumHeight: 0
+ property int preferredHeight: 42
+ property int maximumHeight: preferredHeight
+}
diff --git a/src/controls/private/PageRowGlobalToolBarUI.qml b/src/controls/private/PageRowGlobalToolBarUI.qml
new file mode 100644
--- /dev/null
+++ b/src/controls/private/PageRowGlobalToolBarUI.qml
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2018 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.1
+import QtQuick.Layouts 1.2
+import org.kde.kirigami 2.4 as Kirigami
+import "../templates/private" as TemplatesPrivate
+
+
+Kirigami.AbstractApplicationHeader {
+ id: header
+ readonly property int leftReservedSpace: buttonsLayout.visible && buttonsLayout.visibleChildren.length > 1 ? buttonsLayout.width : 0
+ readonly property int rightReservedSpace: rightHandleAnchor.visible ? backButton.background.implicitHeight : 0
+
+ readonly property alias leftHandleAnchor: leftHandleAnchor
+ readonly property alias rightHandleAnchor: rightHandleAnchor
+
+ height: visible ? implicitHeight : 0
+ minimumHeight: globalToolBar.minimumHeight
+ preferredHeight: globalToolBar.preferredHeight
+ maximumHeight: globalToolBar.maximumHeight
+
+ RowLayout {
+ anchors.fill: parent
+ spacing: 0
+ RowLayout {
+ id: buttonsLayout
+
+ visible: globalToolBar.showNavigationButtons && globalToolBar.actualStyle != Kirigami.ApplicationHeaderStyle.None
+
+ Item {
+ id: leftHandleAnchor
+ visible: typeof applicationWindow() !== "undefined" && applicationWindow().globalDrawer.handleVisible && applicationWindow().globalDrawer.handle.handleAnchor == leftHandleAnchor
+ Layout.preferredWidth: backButton.background.implicitHeight
+ Layout.preferredHeight: backButton.background.implicitHeight
+ }
+ TemplatesPrivate.BackButton {
+ id: backButton
+ Layout.leftMargin: leftHandleAnchor.visible ? 0 : Kirigami.Units.smallSpacing
+ Layout.preferredWidth: background.implicitHeight
+ Layout.preferredHeight: background.implicitHeight
+ }
+ TemplatesPrivate.ForwardButton {
+ Layout.preferredWidth: background.implicitHeight
+ Layout.preferredHeight: background.implicitHeight
+ }
+ Kirigami.Separator {
+ Layout.preferredHeight: parent.parent.height * 0.6
+ //FIXME: hacky
+ opacity: buttonsLayout.visibleChildren.length > 1
+ }
+ }
+ Loader {
+ id: breadcrumbLoader
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ active: globalToolBar.actualStyle == Kirigami.ApplicationHeaderStyle.TabBar || globalToolBar.actualStyle == Kirigami.ApplicationHeaderStyle.Breadcrumb
+
+ //TODO: different implementation?
+ sourceComponent: Kirigami.ApplicationHeader {
+ minimumHeight: height
+ preferredHeight: height
+ maximumHeight: height
+ backButtonEnabled: false
+ anchors.fill:parent
+ background.visible: false
+ headerStyle: globalToolBar.style
+ }
+ }
+ Item {
+ id: rightHandleAnchor
+ visible: typeof applicationWindow() !== "undefined" && applicationWindow().contextDrawer && applicationWindow().contextDrawer.handleVisible && applicationWindow().contextDrawer.handle.handleAnchor == rightHandleAnchor
+ Layout.preferredWidth: backButton.background.implicitHeight
+ Layout.preferredHeight: backButton.background.implicitHeight
+ }
+ }
+ background.visible: breadcrumbLoader.active
+}
+
diff --git a/src/controls/private/PrivateActionToolButton.qml b/src/controls/private/PrivateActionToolButton.qml
--- a/src/controls/private/PrivateActionToolButton.qml
+++ b/src/controls/private/PrivateActionToolButton.qml
@@ -25,15 +25,16 @@
Controls.ToolButton {
id: control
- implicitWidth: showText && ( kirigamiAction ? kirigamiAction.text.length > 0 : text.length > 0) ? Math.max(background.implicitWidth, control.background.contentWidth) : implicitHeight
+ implicitWidth: showText && ( kirigamiAction ? kirigamiAction.text.length > 0 : text.length > 0) ? Math.max(layout.implicitWidth + Units.largeSpacing*2, background.implicitWidth) : implicitHeight
implicitHeight: background.implicitHeight
Theme.colorSet: Theme.Button
- Theme.inherit: false
+ Theme.inherit: kirigamiAction && kirigamiAction.icon.color.a === 0
Theme.backgroundColor: kirigamiAction && kirigamiAction.icon.color.a ? kirigamiAction.icon.color : undefined
- Theme.textColor: kirigamiAction && kirigamiAction.icon.color.a ? Theme.highlightedTextColor : undefined
+ Theme.textColor: kirigamiAction && !flat && kirigamiAction.icon.color.a ? Theme.highlightedTextColor : undefined
hoverEnabled: true
+ flat: true
//TODO: replace with upstream action when we depend on Qt 5.10
property Action kirigamiAction
property bool showText: true
@@ -72,11 +73,11 @@
contentItem: MouseArea {
hoverEnabled: true
onPressed: mouse.accepted = false
- Theme.colorSet: checked || (!control.flat && control.kirigamiAction && control.kirigamiAction.icon.color.a) ? Theme.Selection : Theme.Button
- Theme.inherit: false
+ Theme.colorSet: checked && (!control.flat && control.kirigamiAction && control.kirigamiAction.icon.color.a) ? Theme.Selection : Theme.Button
+ Theme.inherit: control.kirigamiAction && Theme.colorSet != Theme.Selection && control.kirigamiAction.icon.color.a == 0
RowLayout {
id: layout
- onImplicitWidthChanged: control.background.contentWidth = implicitWidth + 16
+
anchors.centerIn: parent
Icon {
id: mainIcon
diff --git a/src/controls/private/TitlesPageHeader.qml b/src/controls/private/TitlesPageHeader.qml
new file mode 100644
--- /dev/null
+++ b/src/controls/private/TitlesPageHeader.qml
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018 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.5
+import QtQuick.Controls 2.0 as Controls
+import QtQuick.Layouts 1.2
+import org.kde.kirigami 2.4
+
+
+
+AbstractPageHeader {
+ id: root
+
+ Heading {
+ id: title
+ anchors.fill: parent
+ leftPadding: Units.largeSpacing
+ opacity: root.current ? 1 : 0.4
+ maximumLineCount: 1
+ color: Theme.textColor
+ elide: Text.ElideRight
+ font.pointSize: -1
+ font.pixelSize: Math.max(1, height*0.7)
+ text: page ? page.title : ""
+ MouseArea {
+ anchors.fill: parent
+ onClicked: page.forceActiveFocus()
+ }
+ }
+}
+
diff --git a/src/controls/private/ToolBarPageHeader.qml b/src/controls/private/ToolBarPageHeader.qml
new file mode 100644
--- /dev/null
+++ b/src/controls/private/ToolBarPageHeader.qml
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2018 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.5
+import QtQuick.Controls 2.0 as Controls
+import QtQuick.Layouts 1.2
+import org.kde.kirigami 2.4
+
+
+
+AbstractPageHeader {
+ id: root
+
+ implicitWidth: titleTextMetrics.width/2 + buttonTextMetrics.collapsedButtonsWidth
+ Layout.minimumWidth: ctxActionsButton.width*4
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: page.forceActiveFocus()
+ }
+ RowLayout {
+ id: titleLayout
+ anchors {
+ verticalCenter: parent.verticalCenter
+ left: parent.left
+ right: actionsLayout.left
+ }
+
+ Heading {
+ id: title
+ Layout.fillWidth: true
+
+ Layout.preferredWidth: implicitWidth
+ Layout.minimumWidth: Math.min(titleTextMetrics.width, root.width - buttonTextMetrics.requiredWidth)
+ leftPadding: Units.largeSpacing
+ opacity: root.current ? 1 : 0.4
+ maximumLineCount: 1
+ color: Theme.textColor
+ elide: Text.ElideRight
+ text: page ? page.title : ""
+ }
+ }
+
+ TextMetrics {
+ id: titleTextMetrics
+ text: page ? page.title : ""
+ font: title.font
+ }
+ TextMetrics {
+ id: buttonTextMetrics
+ text: (page.actions.left ? page.actions.left.text : "") + (page.actions.main ? page.actions.main.text : "") + (page.actions.right ? page.actions.right.text : "")
+ readonly property int collapsedButtonsWidth: ctxActionsButton.width + (page.actions.left ? ctxActionsButton.width + Units.gridUnit : 0) + (page.actions.main ? ctxActionsButton.width + Units.gridUnit : 0) + (page.actions.right ? ctxActionsButton.width + Units.gridUnit : 0)
+ readonly property int requiredWidth: width + collapsedButtonsWidth
+ }
+
+ RowLayout {
+ id: actionsLayout
+ anchors {
+ verticalCenter: parent.verticalCenter
+ right: ctxActionsButton.visible ? ctxActionsButton.left : parent.right
+ }
+
+ readonly property bool toobig: root.width - root.leftPadding - root.rightPadding - titleTextMetrics.width - Units.gridUnit < buttonTextMetrics.requiredWidth
+
+ PrivateActionToolButton {
+ Layout.alignment: Qt.AlignVCenter
+ kirigamiAction: page && page.actions ? page.actions.left : null
+ showText: !parent.toobig
+ }
+ PrivateActionToolButton {
+ Layout.alignment: Qt.AlignVCenter
+ Layout.rightMargin: Units.smallSpacing
+ kirigamiAction: page && page.actions ? page.actions.main : null
+ showText: !parent.toobig
+ flat: false
+ }
+ PrivateActionToolButton {
+ Layout.alignment: Qt.AlignVCenter
+ kirigamiAction: page && page.actions ? page.actions.right : null
+ showText: !parent.toobig
+ }
+ }
+
+ PrivateActionToolButton {
+ id: ctxActionsButton
+ showMenuArrow: page.actions.contextualActions.length == 1
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ rightMargin: Units.smallSpacing
+ }
+ Action {
+ id: overflowAction
+ icon.name: "overflow-menu"
+ tooltip: qsTr("More Actions")
+ visible: children.length > 0
+ children: page && page.actions.contextualActions ? page.actions.contextualActions : null
+ }
+
+ kirigamiAction: page && page.actions.contextualActions.length === 1 ? page.actions.contextualActions[0] : overflowAction
+ }
+}
+
diff --git a/src/controls/templates/AbstractApplicationHeader.qml b/src/controls/templates/AbstractApplicationHeader.qml
--- a/src/controls/templates/AbstractApplicationHeader.qml
+++ b/src/controls/templates/AbstractApplicationHeader.qml
@@ -41,19 +41,25 @@
property int minimumHeight: 0
property int preferredHeight: Units.gridUnit * 2
property int maximumHeight: Units.gridUnit * 3
+ property PageRow pageRow: __appWindow.pageStack
+ property Page page: pageRow.currentItem
default property alias contentItem: mainItem.data
readonly property int paintedHeight: headerItem.y + headerItem.height - 1
LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft
LayoutMirroring.childrenInherit: true
+ property int leftPadding: 0
+ property int topPadding: 0
+ property int rightPadding: 0
+ property int bottomPadding: 0
//FIXME: remove
property QtObject __appWindow: applicationWindow();
anchors {
left: parent.left
right: parent.right
}
- height: preferredHeight
+ implicitHeight: preferredHeight
/**
* background: Item
@@ -68,25 +74,22 @@
background.anchors.fill = headerItem;
}
+ onMinimumHeightChanged: implicitHeight = preferredHeight;
+ onPreferredHeightChanged: implicitHeight = preferredHeight;
+
opacity: height > 0 ? 1 : 0
- Behavior on opacity {
- OpacityAnimator {
- duration: Units.longDuration
- easing.type: Easing.InOutQuad
- }
- }
- Behavior on height {
- enabled: __appWindow.pageStack.currentItem && __appWindow.pageStack.currentItem.flickable && !__appWindow.pageStack.currentItem.flickable.moving
+ Behavior on implicitHeight {
+ enabled: root.page && root.page.flickable && !root.page.flickable.moving
NumberAnimation {
duration: Units.longDuration
easing.type: Easing.InOutQuad
}
}
Connections {
target: __appWindow
- onControlsVisibleChanged: root.height = __appWindow.controlsVisible ? root.preferredHeight : 0;
+ onControlsVisibleChanged: root.implicitHeight = __appWindow.controlsVisible ? root.preferredHeight : 0;
}
Item {
@@ -98,73 +101,77 @@
bottom: parent.bottom
}
- height: __appWindow.reachableMode && __appWindow.reachableModeEnabled ? root.maximumHeight : root.preferredHeight
+ height: __appWindow.reachableMode && __appWindow.reachableModeEnabled ? root.maximumHeight : (root.minimumHeight > 0 ? Math.max(root.height, root.minimumHeight) : root.preferredHeight)
Connections {
id: headerSlideConnection
- target: __appWindow.pageStack.currentItem ? __appWindow.pageStack.currentItem.flickable : null
+ target: root.page ? root.page.flickable : null
property int oldContentY
onContentYChanged: {
if (!Settings.isMobile ||
!__appWindow.controlsVisible ||
- !__appWindow.pageStack.currentItem ||
- __appWindow.pageStack.currentItem.flickable.atYBeginning ||
- __appWindow.pageStack.currentItem.flickable.atYEnd) {
+ !root.page ||
+ root.page.flickable.atYBeginning ||
+ root.page.flickable.atYEnd) {
return;
//if moves but not dragging, just update oldContentY
- } else if (!__appWindow.pageStack.currentItem.flickable.dragging) {
- oldContentY = __appWindow.pageStack.currentItem.flickable.contentY;
+ } else if (!root.page.flickable.dragging) {
+ oldContentY = root.page.flickable.contentY;
return;
- }
-
+ }
if (__appWindow.wideScreen || !Settings.isMobile) {
- root.height = root.preferredHeight;
+ root.implicitHeight = root.preferredHeight;
} else {
var oldHeight = root.height;
- root.height = Math.max(root.minimumHeight,
+ root.implicitHeight = Math.max(root.minimumHeight,
Math.min(root.preferredHeight,
- root.height + oldContentY - __appWindow.pageStack.currentItem.flickable.contentY));
-
+ root.height + oldContentY - root.page.flickable.contentY));
+
//if the height is changed, use that to simulate scroll
if (oldHeight != height) {
- __appWindow.pageStack.currentItem.flickable.contentY = oldContentY;
+ root.page.flickable.contentY = oldContentY;
} else {
- oldContentY = __appWindow.pageStack.currentItem.flickable.contentY;
+ oldContentY = root.page.flickable.contentY;
}
}
}
onMovementEnded: {
if (__appWindow.wideScreen || !Settings.isMobile) {
return;
}
- if (root.height > (root.preferredHeight - root.minimumHeight)/2 ) {
- root.height = root.preferredHeight;
+ if (root.height > root.minimumHeight + (root.preferredHeight - root.minimumHeight)/2 ) {
+ root.implicitHeight = root.preferredHeight;
} else {
- root.height = root.minimumHeight;
+ root.implicitHeight = root.minimumHeight;
}
}
}
Connections {
- target: __appWindow.pageStack
+ target: pageRow
onCurrentItemChanged: {
- if (!__appWindow.pageStack.currentItem) {
+ if (!root.page) {
return;
}
- if (__appWindow.pageStack.currentItem.flickable) {
- headerSlideConnection.oldContentY = __appWindow.pageStack.currentItem.flickable.contentY;
+ if (root.page.flickable) {
+ headerSlideConnection.oldContentY = root.page.flickable.contentY;
} else {
headerSlideConnection.oldContentY = 0;
}
- root.height = root.preferredHeight;
+ root.implicitHeight = root.preferredHeight;
}
}
Item {
id: mainItem
+ clip: childrenRect.width > width
anchors {
fill: parent
+ leftMargin: root.leftPadding
+ topMargin: root.topPadding
+ rightMargin: root.rightPadding
+ bottomMargin: root.bottomPadding
}
}
}
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
@@ -95,7 +95,8 @@
color: header.background && header.background.color && header.background.color == Theme.highlightColor ? Theme.highlightedTextColor : Theme.textColor
elide: Text.ElideRight
text: page ? page.title : ""
- font.pointSize: Math.max(1, titleList.height / (1.6 * Units.devicePixelRatio))
+ font.pointSize: -1
+ font.pixelSize: Math.max(1, titleList.height * 0.7)
verticalAlignment: Text.AlignVCenter
wrapMode: Text.NoWrap
Rectangle {
@@ -206,10 +207,10 @@
}
}
Repeater {
- model: __appWindow.pageStack.layers.depth -1
+ model: pageRow.layers.depth -1
delegate: Loader {
sourceComponent: header.pageDelegate
- readonly property Page page: __appWindow.pageStack.layers.get(modelData+1)
+ readonly property Page page: pageRow.layers.get(modelData+1)
readonly property bool current: true;
Component.onCompleted: stack.push(this)
Component.onDestruction: stack.pop()
@@ -233,7 +234,7 @@
Flickable {
id: titleList
- readonly property bool wideMode: typeof __appWindow.pageStack.wideMode !== "undefined" ? __appWindow.pageStack.wideMode : __appWindow.wideMode
+ readonly property bool wideMode: header.headerStyle != ApplicationHeaderStyle.Breadcrumb && typeof pageRow.wideMode !== "undefined" ? pageRow.wideMode : __appWindow.wideMode
property int internalHeaderStyle: header.headerStyle == ApplicationHeaderStyle.Auto ? (titleList.wideMode ? ApplicationHeaderStyle.Titles : ApplicationHeaderStyle.Breadcrumb) : header.headerStyle
//if scrolling the titlebar should scroll also the pages and vice versa
property bool scrollingLocked: (header.headerStyle == ApplicationHeaderStyle.Titles || titleList.wideMode)
@@ -251,7 +252,7 @@
contentWidth: contentItem.width
contentHeight: height
- readonly property int currentIndex: __appWindow.pageStack && __appWindow.pageStack.currentIndex !== undefined ? __appWindow.pageStack.currentIndex : 0
+ readonly property int currentIndex: pageRow && pageRow.currentIndex !== undefined ? pageRow.currentIndex : 0
readonly property int count: mainRepeater.count
function gotoIndex(idx) {
@@ -280,18 +281,18 @@
id: contentXSyncTimer
interval: 0
onTriggered: {
- titleList.contentX = __appWindow.pageStack.contentItem.contentX - __appWindow.pageStack.contentItem.originX + titleList.originX;
+ titleList.contentX = pageRow.contentItem.contentX - pageRow.contentItem.originX + titleList.originX;
}
}
onCountChanged: contentXSyncTimer.restart();
onCurrentIndexChanged: gotoIndex(currentIndex);
onModelChanged: gotoIndex(currentIndex);
onContentWidthChanged: gotoIndex(currentIndex);
onContentXChanged: {
- if (movingHorizontally && !titleList.scrollMutex && titleList.scrollingLocked && !__appWindow.pageStack.contentItem.moving) {
+ if (movingHorizontally && !titleList.scrollMutex && titleList.scrollingLocked && !pageRow.contentItem.moving) {
titleList.scrollMutex = true;
- __appWindow.pageStack.contentItem.contentX = titleList.contentX - titleList.originX + __appWindow.pageStack.contentItem.originX;
+ pageRow.contentItem.contentX = titleList.contentX - titleList.originX + pageRow.contentItem.originX;
titleList.scrollMutex = false;
}
}
@@ -301,14 +302,14 @@
onMovementEnded: {
if (titleList.scrollingLocked) {
//this will trigger snap as well
- __appWindow.pageStack.contentItem.flick(0,0);
+ pageRow.contentItem.flick(0,0);
}
}
onFlickEnded: movementEnded();
NumberAnimation {
id: scrollTopAnimation
- target: __appWindow.pageStack.currentItem && __appWindow.pageStack.currentItem.flickable ? __appWindow.pageStack.currentItem.flickable : null
+ target: pageRow.currentItem && pageRow.currentItem.flickable ? pageRow.currentItem.flickable : null
property: "contentY"
to: 0
duration: Units.longDuration
@@ -320,7 +321,7 @@
spacing: 0
Repeater {
id: mainRepeater
- model: __appWindow.pageStack.depth
+ model: pageRow.depth
delegate: MouseArea {
id: delegate
readonly property int currentIndex: index
@@ -330,26 +331,26 @@
width: {
//more columns shown?
if (titleList.scrollingLocked && delegateLoader.page) {
- return delegateLoader.page.width - (index == 0 ? navButtons.width : 0) - (index == __appWindow.pageStack.depth-1 ? stack.anchors.rightMargin : 0);
+ return delegateLoader.page.width - (index == 0 ? navButtons.width : 0) - (index == pageRow.depth-1 ? stack.anchors.rightMargin : 0);
} else {
return Math.min(titleList.width, delegateLoader.implicitWidth + Units.smallSpacing);
}
}
height: titleList.height
onClicked: {
- if (__appWindow.pageStack.currentIndex == modelData) {
+ if (pageRow.currentIndex == modelData) {
//scroll up if current otherwise make current
- if (!__appWindow.pageStack.currentItem.flickable) {
+ if (!pageRow.currentItem.flickable) {
return;
}
- if (__appWindow.pageStack.currentItem.flickable.contentY > -__appWindow.header.height) {
- scrollTopAnimation.to = -__appWindow.pageStack.currentItem.flickable.topMargin;
+ if (pageRow.currentItem.flickable.contentY > -__appWindow.header.height) {
+ scrollTopAnimation.to = -pageRow.currentItem.flickable.topMargin;
scrollTopAnimation.running = true;
}
} else {
- __appWindow.pageStack.currentIndex = modelData;
+ pageRow.currentIndex = modelData;
}
}
@@ -366,22 +367,22 @@
sourceComponent: header.pageDelegate
- readonly property Page page: __appWindow.pageStack.get(modelData)
+ readonly property Page page: pageRow.get(modelData)
//NOTE: why not use ListViewCurrentIndex? because listview itself resets
//currentIndex in some situations (since here we are using an int as a model,
//even more often) so the property binding gets broken
- readonly property bool current: __appWindow.pageStack.currentIndex == index
+ readonly property bool current: pageRow.currentIndex == index
readonly property int index: parent.currentIndex
readonly property var modelData: parent.currentModelData
}
}
}
}
Connections {
- target: titleList.scrollingLocked ? __appWindow.pageStack.contentItem : null
+ target: titleList.scrollingLocked ? pageRow.contentItem : null
onContentXChanged: {
if (!titleList.dragging && !titleList.movingHorizontally && !titleList.scrollMutex) {
- titleList.contentX = __appWindow.pageStack.contentItem.contentX - __appWindow.pageStack.contentItem.originX + titleList.originX;
+ titleList.contentX = pageRow.contentItem.contentX - pageRow.contentItem.originX + titleList.originX;
}
}
}
diff --git a/src/controls/templates/OverlayDrawer.qml b/src/controls/templates/OverlayDrawer.qml
--- a/src/controls/templates/OverlayDrawer.qml
+++ b/src/controls/templates/OverlayDrawer.qml
@@ -105,14 +105,22 @@
id: drawerHandle
z: root.modal ? applicationWindow().overlay.z + (root.position > 0 ? +1 : -1) : root.background.parent.z + 1
preventStealing: true
- hoverEnabled: desktopMode
+ hoverEnabled: handleAnchor
parent: applicationWindow().overlay.parent
+ property Item handleAnchor: (!Settings.isMobile && applicationWindow().pageStack && applicationWindow().pageStack.globalToolBar && applicationWindow().pageStack.globalToolBar.actualStyle != ApplicationHeaderStyle.None)
+ ? (root.edge == Qt.LeftEdge
+ ? applicationWindow().pageStack.globalToolBar.leftHandleAnchor
+ : applicationWindow().pageStack.globalToolBar.rightHandleAnchor)
+ : (applicationWindow().header && applicationWindow().header.toString().indexOf("ToolBarApplicationHeader") !== -1 ? applicationWindow().header : null)
+ //FIXME: temporary solution, we need a scenepostracker item
+ onHandleAnchorChanged: {
+ handleAnchor.parent.yChanged.connect(handleAnchor.yChanged);
+ }
property int startX
property int mappedStartX
- property bool desktopMode: applicationWindow() && applicationWindow().header && applicationWindow().header.toString().indexOf("ToolBarApplicationHeader") !== -1
- enabled: root.handleVisible && root.modal
+ enabled: root.handleVisible
onPressed: {
root.peeking = true;
@@ -150,19 +158,17 @@
x: {
switch(root.edge) {
case Qt.LeftEdge:
- return root.background.width * root.position;
+ return root.background.width * root.position + Units.smallSpacing;
case Qt.RightEdge:
- return drawerHandle.parent.width - (root.background.width * root.position) - width;
+ return drawerHandle.parent.width - (root.background.width * root.position) - width - Units.smallSpacing;
default:
return 0;
}
}
+ y: handleAnchor && anchors.bottom ? handleAnchor.parent.mapToItem(root.contentItem, 0, handleAnchor.y).y : 0
anchors {
- top: drawerHandle.desktopMode ? parent.top : undefined
-
- bottom: drawerHandle.desktopMode ? undefined : parent.bottom
-
+ bottom: drawerHandle.handleAnchor ? undefined : parent.bottom
bottomMargin: {
if (!applicationWindow()) {
return;
@@ -207,8 +213,8 @@
}
visible: root.enabled && (root.edge == Qt.LeftEdge || root.edge == Qt.RightEdge)
- width: Units.iconSizes.medium + Units.smallSpacing*2
- height: width
+ width: handleAnchor ? handleAnchor.width : Units.iconSizes.medium + Units.smallSpacing*2
+ height: handleAnchor ? handleAnchor.height : width
opacity: root.handleVisible ? 1 : 0
Behavior on opacity {
NumberAnimation {
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
@@ -26,8 +26,8 @@
Controls.ToolButton {
id: button
- enabled: !Settings.isMobile && (__appWindow.pageStack.currentIndex > 0 || applicationWindow().pageStack.contentItem.contentX > 0)
- visible: applicationWindow().pageStack.contentItem.contentWidth > applicationWindow().pageStack.width
+ enabled: applicationWindow().pageStack.layers.depth > 1 ||applicationWindow().pageStack.currentIndex > 0 || applicationWindow().pageStack.contentItem.contentX > 0
+ visible: applicationWindow().pageStack.layers.depth > 1 || applicationWindow().pageStack.contentItem.contentWidth > applicationWindow().pageStack.width
width: height
height: parent.height
@@ -43,7 +43,6 @@
width: Math.min(parent.width, Units.iconSizes.smallMedium)
height: width
opacity: parent.enabled ? 1 : 0.6
- selected: header.background && header.background.color && header.background.color == Theme.highlightColor
source: (LayoutMirroring.enabled ? "go-previous-symbolic-rtl" : "go-previous-symbolic")
}
Controls.ToolTip {
diff --git a/src/controls/templates/private/ForwardButton.qml b/src/controls/templates/private/ForwardButton.qml
--- a/src/controls/templates/private/ForwardButton.qml
+++ b/src/controls/templates/private/ForwardButton.qml
@@ -27,9 +27,8 @@
id: button
property Flickable headerFlickable
- //visible: headerFlickable.internalHeaderStyle == ApplicationHeaderStyle.Titles && !applicationWindow().pageStack.contentItem.atXEnd && applicationWindow().pageStack.layers.depth < 2
- enabled: __appWindow.pageStack.currentIndex < __appWindow.pageStack.depth-1 || !applicationWindow().pageStack.contentItem.atXEnd
- visible: applicationWindow().pageStack.contentItem.contentWidth > applicationWindow().pageStack.width
+ enabled: applicationWindow().pageStack.currentIndex < applicationWindow().pageStack.depth-1 || !applicationWindow().pageStack.contentItem.atXEnd
+ visible: applicationWindow().pageStack.layers.depth == 1 && applicationWindow().pageStack.contentItem.contentWidth > applicationWindow().pageStack.width
width: height
height: parent.height
@@ -40,7 +39,6 @@
width: Math.min(parent.width, Units.iconSizes.smallMedium)
height: width
opacity: parent.enabled ? 1 : 0.6
- selected: header.background && header.background.color && header.background.color == Theme.highlightColor
source: (LayoutMirroring.enabled ? "go-next-symbolic-rtl" : "go-next-symbolic")
}
Controls.ToolTip {
diff --git a/src/enums.h b/src/enums.h
--- a/src/enums.h
+++ b/src/enums.h
@@ -32,7 +32,9 @@
Auto = 0,
Breadcrumb,
Titles,
- TabBar
+ TabBar,
+ ToolBar, ///@since 5.48
+ None ///@since 5.48
};
};
diff --git a/src/styles/org.kde.desktop/AbstractApplicationHeader.qml b/src/styles/org.kde.desktop/AbstractApplicationHeader.qml
--- a/src/styles/org.kde.desktop/AbstractApplicationHeader.qml
+++ b/src/styles/org.kde.desktop/AbstractApplicationHeader.qml
@@ -37,9 +37,12 @@
T.AbstractApplicationHeader {
id: root
+ Theme.inherit: false
+
background: Rectangle {
color: Theme.backgroundColor
Separator {
+ visible: (!root.page.header || root.page.header.toString().indexOf("ToolBar") === -1)
anchors {
left: parent.left
right: parent.right
diff --git a/src/styles/org.kde.desktop/OverlayDrawer.qml b/src/styles/org.kde.desktop/OverlayDrawer.qml
--- a/src/styles/org.kde.desktop/OverlayDrawer.qml
+++ b/src/styles/org.kde.desktop/OverlayDrawer.qml
@@ -44,7 +44,7 @@
anchors.fill: parent
DropShadow {
- visible: !parent.parent.desktopMode || root.handle.pressed || (root.modal && root.position > 0)
+ visible: !parent.parent.handleAnchor || root.handle.pressed || (root.modal && root.position > 0)
anchors.fill: handleGraphics
horizontalOffset: 0
verticalOffset: Units.devicePixelRatio
@@ -57,16 +57,24 @@
id: handleGraphics
anchors.centerIn: parent
color: root.handle.pressed ? Theme.highlightColor : Theme.backgroundColor
- width: Units.iconSizes.smallMedium + Units.smallSpacing * 2
+ width: Units.iconSizes.medium
height: width
radius: Units.devicePixelRatio*2
- border.color: parent.parent.desktopMode && parent.parent.containsMouse ? Theme.highlightColor : "transparent"
+ border.color: parent.parent.handleAnchor && parent.parent.containsMouse ? Theme.hoverColor : "transparent"
Loader {
anchors.centerIn: parent
width: height
height: Units.iconSizes.smallMedium
source: {
- switch(root.edge) {
+ var edge = root.edge;
+ if (Qt.application.layoutDirection == Qt.RightToLeft) {
+ if (edge == Qt.LeftEdge) {
+ edge = Qt.RightEdge;
+ } else {
+ edge = Qt.LeftEdge;
+ }
+ }
+ switch(edge) {
case Qt.LeftEdge:
return Qt.resolvedUrl("../../templates/private/MenuIcon.qml");
case Qt.RightEdge: {
@@ -114,7 +122,7 @@
//default to a sidebar in desktop mode
modal: true
drawerOpen: !modal
- closePolicy: modal ? Popup.CloseOnEscape | Popup.CloseOnPressOutside : Popup.NoAutoClose
+ closePolicy: modal ? Popup.CloseOnEscape | Popup.CloseOnReleaseOutside : Popup.NoAutoClose
handleVisible: (modal || !drawerOpen) && (typeof(applicationWindow)===typeof(Function) && applicationWindow() ? applicationWindow().controlsVisible : true)
onPositionChanged: {