diff --git a/examples/gallerydata/contents/ui/gallery/MultipleColumnsGallery.qml b/examples/gallerydata/contents/ui/gallery/MultipleColumnsGallery.qml --- a/examples/gallerydata/contents/ui/gallery/MultipleColumnsGallery.qml +++ b/examples/gallerydata/contents/ui/gallery/MultipleColumnsGallery.qml @@ -23,11 +23,13 @@ import org.kde.kirigami 2.2 ScrollablePage { - id: page + id: root Layout.fillWidth: true //implicitWidth: Units.gridUnit * (Math.floor(Math.random() * 35) + 8) - title: "Multiple Columns" + property int depth: 1 + + title: "Page " + depth actions { main: Action { @@ -67,7 +69,7 @@ } ColumnLayout { - width: page.width + width: root.width spacing: Units.smallSpacing Controls.Label { @@ -82,7 +84,7 @@ Controls.Button { text: "Push Another Page" anchors.horizontalCenter: parent.horizontalCenter - onClicked: pageStack.push(Qt.resolvedUrl("MultipleColumnsGallery.qml")); + onClicked: pageStack.push(Qt.resolvedUrl("MultipleColumnsGallery.qml"), {"depth": root.depth + 1}); } Controls.Button { text: "Pop A Page" @@ -93,11 +95,11 @@ anchors.horizontalCenter: parent.horizontalCenter Controls.TextField { id: edit - text: page.title + text: root.title } Controls.Button { text: "Rename Page" - onClicked: page.title = edit.text; + onClicked: root.title = edit.text; } } } diff --git a/examples/simpleexamples/simpleChatApp.qml b/examples/simpleexamples/simpleChatApp.qml --- a/examples/simpleexamples/simpleChatApp.qml +++ b/examples/simpleexamples/simpleChatApp.qml @@ -20,7 +20,7 @@ import QtQuick 2.6 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.2 as QQC2 -import org.kde.kirigami 2.2 as Kirigami +import org.kde.kirigami 2.4 as Kirigami Kirigami.ApplicationWindow { id: root @@ -53,11 +53,9 @@ } ] } - contextDrawer: Kirigami.GlobalDrawer { + contextDrawer: Kirigami.OverlayDrawer { id: contextDrawer - contentItem.implicitWidth: columnWidth //they can depend on the page like that or be defined directly here - actions: pageStack.get(1).contextualActions edge: Qt.RightEdge modal: !root.wideScreen onModalChanged: drawerOpen = !modal @@ -69,59 +67,57 @@ leftPadding: 0 rightPadding: 0 - topContent: QQC2.Control { - anchors { - left: parent.left - right: parent.right - } - background: Rectangle { - anchors.fill: parent - color: Kirigami.Theme.highlightColor - opacity: 0.8 - } + contentItem: ColumnLayout { + + readonly property int implicitWidth: root.columnWidth + spacing: 0 + QQC2.Control { + Layout.fillWidth: true + background: Rectangle { + anchors.fill: parent + color: Kirigami.Theme.highlightColor + opacity: 0.8 + } - padding: Kirigami.Units.gridUnit + padding: Kirigami.Units.gridUnit - contentItem: ColumnLayout { - id: titleLayout - spacing: Kirigami.Units.gridUnit - - RowLayout { + contentItem: ColumnLayout { + id: titleLayout spacing: Kirigami.Units.gridUnit - Rectangle { - color: Kirigami.Theme.highlightedTextColor - radius: width - implicitWidth: Kirigami.Units.iconSizes.medium - implicitHeight: implicitWidth - } - ColumnLayout { - QQC2.Label { - Layout.fillWidth: true + + RowLayout { + spacing: Kirigami.Units.gridUnit + Rectangle { color: Kirigami.Theme.highlightedTextColor - text: "KDE" + radius: width + implicitWidth: Kirigami.Units.iconSizes.medium + implicitHeight: implicitWidth } - QQC2.Label { - Layout.fillWidth: true - color: Kirigami.Theme.highlightedTextColor - font.pointSize: Kirigami.Units.fontMetrics.font.pointSize * 0.8 - text: "#kde: kde.org" + ColumnLayout { + QQC2.Label { + Layout.fillWidth: true + color: Kirigami.Theme.highlightedTextColor + text: "KDE" + } + QQC2.Label { + Layout.fillWidth: true + color: Kirigami.Theme.highlightedTextColor + font.pointSize: Kirigami.Units.fontMetrics.font.pointSize * 0.8 + text: "#kde: kde.org" + } } } - } - QQC2.Label { - Layout.fillWidth: true - color: Kirigami.Theme.highlightedTextColor - text: "Main room for KDE community, other rooms are listed at kde.org/rooms" - wrapMode: Text.WordWrap + QQC2.Label { + Layout.fillWidth: true + color: Kirigami.Theme.highlightedTextColor + text: "Main room for KDE community, other rooms are listed at kde.org/rooms" + wrapMode: Text.WordWrap + } } } - } - ColumnLayout { - spacing: 0 Kirigami.Separator { Layout.fillWidth: true - Layout.maximumHeight: 1//implicitHeight } QQC2.ScrollView { @@ -261,7 +257,7 @@ Kirigami.Separator { Rectangle { anchors.fill: parent - color: Kirigami.Theme.viewFocusColor + color: Kirigami.Theme.focusColor visible: chatTextInput.activeFocus } anchors { @@ -302,10 +298,10 @@ ColumnLayout { x: Kirigami.Units.gridUnit anchors.verticalCenter: parent.verticalCenter - Kirigami.Label { + QQC2.Label { text: modelData % 2 ? "John Doe" : "John Applebaum" } - Kirigami.Label { + QQC2.Label { text: "Message " + modelData } } diff --git a/kirigami.qrc b/kirigami.qrc --- a/kirigami.qrc +++ b/kirigami.qrc @@ -33,6 +33,7 @@ src/controls/GlobalDrawer.qml src/controls/templates/AbstractListItem.qml src/controls/templates/private/MenuIcon.qml + src/controls/templates/private/GenericDrawerIcon.qml src/controls/templates/private/PassiveNotification.qml src/controls/templates/private/ContextIcon.qml src/controls/templates/private/ScrollView.qml diff --git a/src/controls/ContextDrawer.qml b/src/controls/ContextDrawer.qml --- a/src/controls/ContextDrawer.qml +++ b/src/controls/ContextDrawer.qml @@ -115,7 +115,7 @@ root.actions[0]; } } - topMargin: menu.height - menu.contentHeight + topMargin: root.handle.y > 0 ? menu.height - menu.contentHeight : 0 header: Item { height: heading.height width: menu.width diff --git a/src/controls/OverlayDrawer.qml b/src/controls/OverlayDrawer.qml --- a/src/controls/OverlayDrawer.qml +++ b/src/controls/OverlayDrawer.qml @@ -65,11 +65,25 @@ anchors.centerIn: parent width: height height: Units.iconSizes.smallMedium - source: root.edge == Qt.LeftEdge ? Qt.resolvedUrl("templates/private/MenuIcon.qml") : (root.edge == Qt.RightEdge ? Qt.resolvedUrl("templates/private/ContextIcon.qml") : "") + source: { + switch(root.edge) { + case Qt.LeftEdge: + return Qt.resolvedUrl("templates/private/MenuIcon.qml"); + case Qt.RightEdge: { + if (root.hasOwnProperty("actions")) { + return Qt.resolvedUrl("templates/private/ContextIcon.qml"); + } else { + return Qt.resolvedUrl("templates/private/GenericDrawerIcon.qml"); + } + } + default: + return ""; + } + } onItemChanged: { if(item) { - item.morph = Qt.binding(function(){return root.position}) - item.color = Qt.binding(function(){return root.handle.pressed ? Theme.highlightedTextColor : Theme.textColor}) + item.drawer = Qt.binding(function(){return root}); + item.color = Qt.binding(function(){return root.handle.pressed ? Theme.highlightedTextColor : Theme.textColor}); } } } diff --git a/src/controls/Separator.qml b/src/controls/Separator.qml --- a/src/controls/Separator.qml +++ b/src/controls/Separator.qml @@ -20,7 +20,7 @@ import QtQuick 2.1 import QtQuick.Layouts 1.2 -import org.kde.kirigami 2.2 +import org.kde.kirigami 2.4 /** * A visual separator diff --git a/src/controls/ToolBarApplicationHeader.qml b/src/controls/ToolBarApplicationHeader.qml --- a/src/controls/ToolBarApplicationHeader.qml +++ b/src/controls/ToolBarApplicationHeader.qml @@ -54,17 +54,15 @@ Separator { id: separator Layout.preferredHeight: parent.height * 0.6 - //assumption on the internal structure of the parent - visible: index > 0 || delegateItem.parent.x > 0 } Heading { id: title Layout.fillWidth: true Layout.preferredWidth: implicitWidth Layout.minimumWidth: Math.min(titleTextMetrics.width, delegateItem.width - buttonTextMetrics.requiredWidth) - leftPadding: delegateItem.parent.x > 0 ? 0 : Units.largeSpacing + leftPadding: Units.largeSpacing opacity: delegateItem.current ? 1 : 0.4 maximumLineCount: 1 color: Theme.textColor 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 @@ -21,7 +21,7 @@ import QtQuick.Controls 2.0 as QQC2 import QtQuick.Layouts 1.2 import "private" -import org.kde.kirigami 2.2 +import org.kde.kirigami 2.4 /** @@ -129,7 +129,8 @@ id: stack anchors { fill: parent - leftMargin: (titleList.scrollingLocked && titleList.wideMode) || headerStyle == ApplicationHeaderStyle.Titles && depth < 2 ? 0 : navButtons.width + leftMargin: navButtons.width + rightMargin: __appWindow.contextDrawer && __appWindow.contextDrawer.handleVisible && __appWindow.contextDrawer.handle && __appWindow.contextDrawer.handle.y == 0 ? __appWindow.contextDrawer.handle.width : 0 } initialItem: titleList @@ -186,6 +187,24 @@ } } } + Separator { + id: separator + height: parent.height * 0.6 + visible: navButtons.width > 0 + anchors { + verticalCenter: parent.verticalCenter + left: navButtons.right + } + } + Separator { + height: parent.height * 0.6 + visible: stack.anchors.rightMargin > 0 + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + rightMargin: stack.anchors.rightMargin + } + } Repeater { model: __appWindow.pageStack.layers.depth -1 delegate: Loader { @@ -197,16 +216,22 @@ } } - RowLayout { + Row { id: navButtons anchors { left: parent.left top: parent.top bottom: parent.bottom + topMargin: Units.smallSpacing + bottomMargin: Units.smallSpacing + } + Item { + height: parent.height + width: __appWindow.globalDrawer && __appWindow.globalDrawer.handleVisible && __appWindow.globalDrawer.handle && __appWindow.globalDrawer.handle.y == 0 ? __appWindow.globalDrawer.handle.width : 0 } } - ListView { + Flickable { id: titleList readonly property bool wideMode: typeof __appWindow.pageStack.wideMode !== "undefined" ? __appWindow.pageStack.wideMode : __appWindow.wideMode property int internalHeaderStyle: header.headerStyle == ApplicationHeaderStyle.Auto ? (titleList.wideMode ? ApplicationHeaderStyle.Titles : ApplicationHeaderStyle.Breadcrumb) : header.headerStyle @@ -220,23 +245,24 @@ property Item forwardButton clip: true - cacheBuffer: width ? Math.max(0, width * count) : 0 - displayMarginBeginning: __appWindow.pageStack.width * count - orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds - model: __appWindow.pageStack.depth - spacing: 0 - currentIndex: __appWindow.pageStack && __appWindow.pageStack.currentIndex !== undefined ? __appWindow.pageStack.currentIndex : 0 + readonly property alias model: mainRepeater.model + contentWidth: contentItem.width + contentHeight: height + + readonly property int currentIndex: __appWindow.pageStack && __appWindow.pageStack.currentIndex !== undefined ? __appWindow.pageStack.currentIndex : 0 + readonly property int count: mainRepeater.count function gotoIndex(idx) { //don't actually scroll in widescreen mode - if (titleList.wideMode) { + if (titleList.wideMode || contentItem.children.length < 2) { return; } listScrollAnim.running = false var pos = titleList.contentX; var destPos; - titleList.positionViewAtIndex(idx, ListView.Center); + titleList.contentX = Math.max((contentItem.children[idx].x + contentItem.children[idx].width) - titleList.width, Math.min(titleList.contentX, contentItem.children[idx].x)); destPos = titleList.contentX; listScrollAnim.from = pos; listScrollAnim.to = destPos; @@ -263,7 +289,7 @@ onContentWidthChanged: gotoIndex(currentIndex); onContentXChanged: { - if (moving && !titleList.scrollMutex && titleList.scrollingLocked && !__appWindow.pageStack.contentItem.moving) { + if (movingHorizontally && !titleList.scrollMutex && titleList.scrollingLocked && !__appWindow.pageStack.contentItem.moving) { titleList.scrollMutex = true; __appWindow.pageStack.contentItem.contentX = titleList.contentX - titleList.originX + __appWindow.pageStack.contentItem.originX; titleList.scrollMutex = false; @@ -289,63 +315,72 @@ easing.type: Easing.InOutQuad } - delegate: MouseArea { - id: delegate - readonly property int currentIndex: index - readonly property var currentModelData: modelData - clip: true - - width: { - //more columns shown? - if (titleList.scrollingLocked && delegateLoader.page) { - return delegateLoader.page.width; - } else { - return Math.min(titleList.width, delegateLoader.implicitWidth + Units.smallSpacing); - } - } - height: titleList.height - onClicked: { - if (__appWindow.pageStack.currentIndex == modelData) { - //scroll up if current otherwise make current - if (!__appWindow.pageStack.currentItem.flickable) { - return; - } - if (__appWindow.pageStack.currentItem.flickable.contentY > -__appWindow.header.height) { - scrollTopAnimation.to = -__appWindow.pageStack.currentItem.flickable.topMargin; - scrollTopAnimation.running = true; + Row { + id: contentItem + spacing: 0 + Repeater { + id: mainRepeater + model: __appWindow.pageStack.depth + delegate: MouseArea { + id: delegate + readonly property int currentIndex: index + readonly property var currentModelData: modelData + clip: true + + 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); + } else { + return Math.min(titleList.width, delegateLoader.implicitWidth + Units.smallSpacing); + } } - } else { - __appWindow.pageStack.currentIndex = modelData; - } - } - - Loader { - id: delegateLoader - height: parent.height - x: titleList.wideMode || headerStyle == ApplicationHeaderStyle.Titles ? (Math.min(delegate.width - implicitWidth, Math.max(0, titleList.contentX - delegate.x + navButtons.width + (navButtons.width > 0 ? Units.smallSpacing : 0)))) : 0 - width: parent.width - x + height: titleList.height + onClicked: { + if (__appWindow.pageStack.currentIndex == modelData) { + //scroll up if current otherwise make current + if (!__appWindow.pageStack.currentItem.flickable) { + return; + } + if (__appWindow.pageStack.currentItem.flickable.contentY > -__appWindow.header.height) { + scrollTopAnimation.to = -__appWindow.pageStack.currentItem.flickable.topMargin; + scrollTopAnimation.running = true; + } + + } else { + __appWindow.pageStack.currentIndex = modelData; + } + } - Connections { - target: delegateLoader.page - Component.onDestruction: delegateLoader.sourceComponent = null + Loader { + id: delegateLoader + height: parent.height + x: titleList.wideMode || headerStyle == ApplicationHeaderStyle.Titles ? (Math.min(delegate.width - implicitWidth, Math.max(0, titleList.contentX - delegate.x))) : 0 + width: parent.width - x + + Connections { + target: delegateLoader.page + Component.onDestruction: delegateLoader.sourceComponent = null + } + + sourceComponent: header.pageDelegate + + readonly property Page page: __appWindow.pageStack.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 int index: parent.currentIndex + readonly property var modelData: parent.currentModelData + } } - - sourceComponent: header.pageDelegate - - readonly property Page page: __appWindow.pageStack.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 int index: parent.currentIndex - readonly property var modelData: parent.currentModelData } } Connections { target: titleList.scrollingLocked ? __appWindow.pageStack.contentItem : null onContentXChanged: { - if (!titleList.contentItem.moving && !titleList.scrollMutex) { + if (!titleList.dragging && !titleList.movingHorizontally && !titleList.scrollMutex) { titleList.contentX = __appWindow.pageStack.contentItem.contentX - __appWindow.pageStack.contentItem.originX + titleList.originX; } } diff --git a/src/controls/templates/InlineMessage.qml b/src/controls/templates/InlineMessage.qml --- a/src/controls/templates/InlineMessage.qml +++ b/src/controls/templates/InlineMessage.qml @@ -95,7 +95,7 @@ /** * A grouped property describing an optional icon. - * * source: The source of the icon. + * * source: The source of the icon, a freedesktop-compatible icon name is recommended. * * color: An optional tint color for the icon. * * If no custom icon is set, an icon appropriate to the message type 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 @@ -62,6 +62,33 @@ */ readonly property bool animating : enterAnimation.animating || exitAnimation.animating || positionResetAnim.running + /** + * A grouped property describing an optional icon. + * * source: The source of the icon, a freedesktop-compatible icon name is recommended. + * * color: An optional tint color for the icon. + * + * If no custom icon is set, a menu icon is shown for the application globalDrawer + * and an overflow menu icon is shown for the contextDrawer. + * That's the default for the GlobalDrawer and ContextDrawer components respectively. + * + * For OverlayDrawer the default is view-right-close or view-left-close depending on the drawer location + * @since 2.5 + */ + readonly property QtObject handleOpenIcon: IconPropertiesGroup {source: root.edge == Qt.RightEdge ? "view-right-close" : "view-left-close"} + + /** + * A grouped property describing an optional icon. + * * source: The source of the icon, a freedesktop-compatible icon name is recommended. + * * color: An optional tint color for the icon. + * + * If no custom icon is set, an X icon is shown, + * which will morph into the Menu or overflow icons + * + * For OverlayDrawer the default is view-right-new or view-left-new depending on the drawer location + * @since 2.5 + */ + readonly property QtObject handleClosedIcon: IconPropertiesGroup {source: root.edge == Qt.RightEdge ? "view-right-new" : "view-left-new"} + /** * handleVisible: bool * If true, a little handle will be visible to make opening the drawer easier @@ -78,16 +105,23 @@ id: drawerHandle z: root.modal ? applicationWindow().overlay.z + (root.position > 0 ? +1 : -1) : root.background.parent.z + 1 preventStealing: true + hoverEnabled: desktopMode parent: applicationWindow().overlay.parent property int startX property int mappedStartX + + property bool desktopMode: applicationWindow() && applicationWindow().header.toString().indexOf("ToolBarApplicationHeader") !== -1 + onPressed: { root.peeking = true; startX = mouse.x; mappedStartX = mapToItem(parent, startX, 0).x } onPositionChanged: { + if (!pressed) { + return; + } var pos = mapToItem(parent, mouse.x - startX, mouse.y); switch(root.edge) { case Qt.LeftEdge: @@ -124,7 +158,10 @@ } anchors { - bottom: parent.bottom + top: drawerHandle.desktopMode ? parent.top : undefined + + bottom: drawerHandle.desktopMode ? undefined : parent.bottom + bottomMargin: { if (!applicationWindow()) { return; 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 @@ -18,17 +18,18 @@ */ import QtQuick 2.1 +import QtQuick.Layouts 1.2 import QtQuick.Controls 2.0 as Controls -import org.kde.kirigami 2.2 +import org.kde.kirigami 2.4 Controls.ToolButton { id: button - z: 99 enabled: !Settings.isMobile && (__appWindow.pageStack.currentIndex > 0 || applicationWindow().pageStack.contentItem.contentX > 0) - implicitWidth: height visible: applicationWindow().pageStack.contentItem.contentWidth > applicationWindow().pageStack.width + width: height + height: parent.height onClicked: { if (applicationWindow().pageStack.layers && applicationWindow().pageStack.layers.depth > 1) { diff --git a/src/controls/templates/private/ContextIcon.qml b/src/controls/templates/private/ContextIcon.qml --- a/src/controls/templates/private/ContextIcon.qml +++ b/src/controls/templates/private/ContextIcon.qml @@ -20,13 +20,13 @@ import QtQuick 2.1 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 -import org.kde.kirigami 2.2 +import org.kde.kirigami 2.4 Item { id: canvas width: height height: Units.iconSizes.smallMedium - property real morph: 0 + property OverlayDrawer drawer property color color: Theme.textColor opacity: 0.8 layer.enabled: true @@ -42,36 +42,38 @@ anchors { horizontalCenter: parent.horizontalCenter top: parent.top - leftMargin: canvas.width/4 * morph + //horizontalCenterOffset: -parent.width/2 + topMargin: (parent.height/2 - iconRoot.thickness/2) * drawer.position } antialiasing: true - transformOrigin: Item.Left - width: (1 - morph) * height + morph * ((parent.width / Math.sqrt(2)) - height/2) + transformOrigin: Item.Center + width: (1 - drawer.position) * height + drawer.position * (Math.sqrt(2*(parent.width*parent.width))) height: iconRoot.thickness color: canvas.color - rotation: 45 * morph + rotation: 45 * drawer.position } Rectangle { anchors.centerIn: parent - width: height * (1 - morph) - height: iconRoot.thickness * (1-morph) + width: height + height: iconRoot.thickness color: canvas.color } Rectangle { anchors { horizontalCenter: parent.horizontalCenter bottom: parent.bottom - leftMargin: canvas.width/4 * morph + // topMargin: -iconRoot.thickness/2 * drawer.position + bottomMargin: (parent.height/2 - iconRoot.thickness/2) * drawer.position } antialiasing: true - transformOrigin: Item.Left - width: (1 - morph) * height + morph * ((parent.width / Math.sqrt(2)) - height/2) + transformOrigin: Item.Center + width: (1 - drawer.position) * height + drawer.position * (Math.sqrt(2*(parent.width*parent.width))) height: iconRoot.thickness color: canvas.color - rotation: -45 * morph + rotation: -45 * drawer.position } } } 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 @@ -18,17 +18,20 @@ */ import QtQuick 2.1 +import QtQuick.Layouts 1.2 import QtQuick.Controls 2.0 as Controls -import org.kde.kirigami 2.2 +import org.kde.kirigami 2.4 Controls.ToolButton { id: button - z: 99 property Flickable headerFlickable - implicitWidth: height - visible: headerFlickable.internalHeaderStyle == ApplicationHeaderStyle.Titles && !applicationWindow().pageStack.contentItem.atXEnd && applicationWindow().pageStack.layers.depth < 2 + //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 + width: height + height: parent.height onClicked: applicationWindow().pageStack.goForward(); diff --git a/src/controls/Separator.qml b/src/controls/templates/private/GenericDrawerIcon.qml copy from src/controls/Separator.qml copy to src/controls/templates/private/GenericDrawerIcon.qml --- a/src/controls/Separator.qml +++ b/src/controls/templates/private/GenericDrawerIcon.qml @@ -1,6 +1,5 @@ /* - * Copyright 2012 Marco Martin - * Copyright 2016 Aleix Pol Gonzalez + * 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 @@ -20,20 +19,30 @@ import QtQuick 2.1 import QtQuick.Layouts 1.2 -import org.kde.kirigami 2.2 +import QtGraphicalEffects 1.0 +import org.kde.kirigami 2.4 as Kirigami -/** - * A visual separator - * - * Useful for splitting one set of items from another. - * - * @inherit QtQuick.Rectangle - */ +Item { + width: height + height: Kirigami.Units.iconSizes.smallMedium + property Kirigami.OverlayDrawer drawer + property color color: Theme.textColor + opacity: 0.8 + layer.enabled: true -Rectangle { - height: Math.floor(Units.devicePixelRatio) - width: Math.floor(Units.devicePixelRatio) - Layout.preferredWidth: Math.floor(Units.devicePixelRatio) - Layout.preferredHeight: Math.floor(Units.devicePixelRatio) - color: Qt.tint(Theme.textColor, Qt.rgba(Theme.backgroundColor.r, Theme.backgroundColor.g, Theme.backgroundColor.b, 0.7)) + Kirigami.Icon { + selected: drawer.handle.pressed + opacity: 1 - drawer.position + anchors.fill: parent + source: drawer.handleClosedIcon.source + color: drawer.handleClosedIcon.color + } + Kirigami.Icon { + selected: drawer.handle.pressed + opacity: drawer.position + anchors.fill: parent + source: drawer.handleOpenIcon.source + color: drawer.handleOpenIcon.color + } } + diff --git a/src/controls/templates/private/MenuIcon.qml b/src/controls/templates/private/MenuIcon.qml --- a/src/controls/templates/private/MenuIcon.qml +++ b/src/controls/templates/private/MenuIcon.qml @@ -20,13 +20,13 @@ import QtQuick 2.1 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 -import org.kde.kirigami 2.2 +import org.kde.kirigami 2.4 Item { id: canvas width: height height: Units.iconSizes.smallMedium - property real morph: 0 + property OverlayDrawer drawer property color color: Theme.textColor opacity: 0.8 layer.enabled: true @@ -38,39 +38,40 @@ margins: Units.smallSpacing } property int thickness: Math.floor(Units.devicePixelRatio)*2 + Rectangle { anchors { right: parent.right top: parent.top - rightMargin: canvas.width/4 * morph + topMargin: -iconRoot.thickness/2 * drawer.position } antialiasing: true transformOrigin: Item.Right - width: (1 - morph) * parent.width + morph * ((parent.width / Math.sqrt(2)) - height/2) + width: (1 - drawer.position) * parent.width + drawer.position * (Math.sqrt(2*(parent.width*parent.width))) height: iconRoot.thickness color: canvas.color - rotation: -45 * morph + rotation: -45 * drawer.position } Rectangle { anchors.centerIn: parent - width: parent.width - parent.width * morph + width: parent.width - parent.width * drawer.position height: iconRoot.thickness color: canvas.color } Rectangle { anchors { right: parent.right bottom: parent.bottom - rightMargin: canvas.width/4 * morph + bottomMargin: -iconRoot.thickness/2 * drawer.position } antialiasing: true transformOrigin: Item.Right - width: (1 - morph) * parent.width + morph * ((parent.width / Math.sqrt(2)) - height/2) + width: (1 - drawer.position) * parent.width + drawer.position * (Math.sqrt(2*(parent.width*parent.width))) height: iconRoot.thickness color: canvas.color - rotation: 45 * morph + rotation: 45 * drawer.position } } } 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,6 +44,7 @@ anchors.fill: parent DropShadow { + visible: !parent.parent.desktopMode || root.handle.pressed || (root.modal && root.position > 0) anchors.fill: handleGraphics horizontalOffset: 0 verticalOffset: Units.devicePixelRatio @@ -59,15 +60,30 @@ width: Units.iconSizes.smallMedium + Units.smallSpacing * 2 height: width radius: Units.devicePixelRatio*2 + border.color: parent.parent.desktopMode && parent.parent.containsMouse ? Theme.highlightColor : "transparent" Loader { anchors.centerIn: parent width: height height: Units.iconSizes.smallMedium - source: root.edge == Qt.LeftEdge ? Qt.resolvedUrl("../../templates/private/MenuIcon.qml") : (root.edge == Qt.RightEdge ? Qt.resolvedUrl("../../templates/private/ContextIcon.qml") : "") + source: { + switch(root.edge) { + case Qt.LeftEdge: + return Qt.resolvedUrl("../../templates/private/MenuIcon.qml"); + case Qt.RightEdge: { + if (root.hasOwnProperty("actions")) { + return Qt.resolvedUrl("../../templates/private/ContextIcon.qml"); + } else { + return Qt.resolvedUrl("../../templates/private/GenericDrawerIcon.qml"); + } + } + default: + return ""; + } + } onItemChanged: { if(item) { - item.morph = Qt.binding(function(){return root.position}) - item.color = Qt.binding(function(){return root.handle.pressed ? Theme.highlightedTextColor : Theme.textColor}) + item.drawer = Qt.binding(function(){return root}); + item.color = Qt.binding(function(){return root.handle.pressed ? Theme.highlightedTextColor : Theme.textColor}); } } } @@ -96,7 +112,7 @@ focus: false //default to a sidebar in desktop mode - modal: (applicationWindow() && applicationWindow().width < width*2) || edge == Qt.TopEdge || edge == Qt.BottomEdge + modal: true drawerOpen: !modal closePolicy: modal ? Popup.CloseOnEscape | Popup.CloseOnPressOutside : Popup.NoAutoClose handleVisible: modal || !drawerOpen