diff --git a/src/controls/ListBrowser.qml b/src/controls/ListBrowser.qml index 5d75793..b8630c1 100644 --- a/src/controls/ListBrowser.qml +++ b/src/controls/ListBrowser.qml @@ -1,280 +1,282 @@ /* * Copyright 2018 Camilo Higuita * * 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 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.10 import QtQuick.Controls 2.10 import QtQuick.Layouts 1.3 import org.kde.mauikit 1.0 as Maui import org.kde.kirigami 2.7 as Kirigami Kirigami.ScrollablePage { id: control property int itemSize : Maui.Style.iconSizes.big property bool checkable : false property bool showPreviewThumbnails: true property alias model : _listView.model property alias delegate : _listView.delegate property alias section : _listView.section property alias contentY: _listView.contentY property alias currentIndex : _listView.currentIndex property alias currentItem : _listView.currentItem property alias count : _listView.count property alias cacheBuffer : _listView.cacheBuffer + property alias orientation: _listView.orientation property int margins : 0 property alias topMargin: _listView.topMargin property alias bottomMargin: _listView.bottomMargin property alias rightMargin: _listView.rightMargin property alias leftMargin: _listView.leftMargin property alias listView: _listView property alias holder : _holder property bool enableLassoSelection : false property alias lassoRec : selectLayer signal itemsSelected(var indexes) signal itemClicked(int index) signal itemDoubleClicked(int index) signal itemRightClicked(int index) signal itemToggled(int index, bool state) signal areaClicked(var mouse) signal areaRightClicked() signal keyPress(var event) spacing: Maui.Style.space.tiny + contentWidth: _listView.contentWidth focus: true padding: 0 leftPadding: padding rightPadding: padding topPadding: padding bottomPadding: padding Keys.enabled: false Kirigami.Theme.colorSet: Kirigami.Theme.View supportsRefreshing: false ListView { id: _listView focus: true clip: control.clip spacing: control.spacing snapMode: ListView.NoSnap boundsBehavior: !Kirigami.Settings.isMobile? Flickable.StopAtBounds : Flickable.OvershootBounds interactive: Kirigami.Settings.hasTransientTouchInput highlightFollowsCurrentItem: true highlightMoveDuration: 0 highlightResizeDuration : 0 keyNavigationEnabled : true keyNavigationWraps : true Keys.onPressed: control.keyPress(event) topMargin: control.margins bottomMargin: control.margins leftMargin: control.margins rightMargin: control.margins Maui.Holder { id: _holder anchors.fill : parent } delegate: Maui.ListBrowserDelegate { id: delegate width: parent.width leftPadding: Maui.Style.space.small rightPadding: Maui.Style.space.small padding: 0 iconSizeHint : height checkable: control.checkable showThumbnails: control.showPreviewThumbnails Connections { target: delegate onClicked: { control.currentIndex = index control.itemClicked(index) } onDoubleClicked: { control.currentIndex = index control.itemDoubleClicked(index) } onPressAndHold: { control.currentIndex = index control.itemRightClicked(index) } onRightClicked: { control.currentIndex = index control.itemRightClicked(index) } onToggled: { control.currentIndex = index control.itemToggled(index, state) } } } MouseArea { id: _mouseArea z: -1 anchors.fill: parent propagateComposedEvents: false preventStealing: true acceptedButtons: Qt.RightButton | Qt.LeftButton onClicked: { control.areaClicked(mouse) control.forceActiveFocus() if(mouse.button === Qt.RightButton) { control.areaRightClicked() return } } onPositionChanged: { if(_mouseArea.pressed && control.enableLassoSelection && selectLayer.visible) { if(mouseX >= selectLayer.newX) { selectLayer.width = (mouseX + 10) < (control.x + control.width) ? (mouseX - selectLayer.x) : selectLayer.width; } else { selectLayer.x = mouseX < control.x ? control.x : mouseX; selectLayer.width = selectLayer.newX - selectLayer.x; } if(mouseY >= selectLayer.newY) { selectLayer.height = (mouseY + 10) < (control.y + control.height) ? (mouseY - selectLayer.y) : selectLayer.height; if(!_listView.atYEnd && mouseY > (control.y + control.height)) _listView.contentY += 10 } else { selectLayer.y = mouseY < control.y ? control.y : mouseY; selectLayer.height = selectLayer.newY - selectLayer.y; if(!_listView.atYBeginning && selectLayer.y === 0) _listView.contentY -= 10 } } } onPressed: { if (mouse.source !== Qt.MouseEventNotSynthesized) { mouse.accepted = false } if(control.enableLassoSelection && mouse.button === Qt.LeftButton ) { selectLayer.visible = true; selectLayer.x = mouseX; selectLayer.y = mouseY; selectLayer.newX = mouseX; selectLayer.newY = mouseY; selectLayer.width = 0 selectLayer.height = 0; } } onReleased: { if(mouse.button !== Qt.LeftButton || !control.enableLassoSelection || !selectLayer.visible) { mouse.accepted = false return; } if(selectLayer.y > _listView.contentHeight) { return selectLayer.reset(); } var lassoIndexes = [] var limitY = mouse.y === lassoRec.y ? lassoRec.y+lassoRec.height : mouse.y for(var y = lassoRec.y; y < limitY; y+=10) { const index = _listView.indexAt(_listView.width/2,y+_listView.contentY) if(!lassoIndexes.includes(index) && index>-1 && index< _listView.count) lassoIndexes.push(index) } control.itemsSelected(lassoIndexes) selectLayer.reset() } } Maui.Rectangle { id: selectLayer property int newX: 0 property int newY: 0 height: 0 width: 0 x: 0 y: 0 visible: false color: Qt.rgba(control.Kirigami.Theme.highlightColor.r,control.Kirigami.Theme.highlightColor.g, control.Kirigami.Theme.highlightColor.b, 0.2) opacity: 0.7 borderColor: control.Kirigami.Theme.highlightColor borderWidth: 2 solidBorder: false function reset() { selectLayer.x = 0; selectLayer.y = 0; selectLayer.newX = 0; selectLayer.newY = 0; selectLayer.visible = false; selectLayer.width = 0; selectLayer.height = 0; } } } } diff --git a/src/controls/ListItemTemplate.qml b/src/controls/ListItemTemplate.qml index 54a946f..83d9c80 100644 --- a/src/controls/ListItemTemplate.qml +++ b/src/controls/ListItemTemplate.qml @@ -1,326 +1,326 @@ /* * Copyright 2018 Camilo Higuita * * 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 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.9 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.3 import QtGraphicalEffects 1.0 import org.kde.kirigami 2.7 as Kirigami import org.kde.mauikit 1.0 as Maui import org.kde.mauikit 1.1 as MauiLab Item { id: control default property alias content: _layout.data implicitHeight: Maui.Style.rowHeight // implicitWidth: _layout.implicitWidth property alias text1 : _label1.text property alias text2 : _label2.text property alias text3 : _label3.text property alias text4 : _label4.text property alias label1 : _label1 property alias label2 : _label2 property alias label3 : _label3 property alias label4 : _label4 property alias iconItem : _iconLoader.item property alias iconVisible : _iconContainer.visible property alias leftLabels : _leftLabels property alias rightLabels : _rightLabels property int iconSizeHint : Maui.Style.iconSizes.big property int imageSizeHint : iconSizeHint property int imageWidth : imageSizeHint property int imageHeight : imageSizeHint property string imageSource property string iconSource property bool checkable : false property bool checked : false property bool isCurrentItem: false property bool labelsVisible: true property bool hovered : false property int fillMode : Image.PreserveAspectCrop property int maskRadius: Maui.Style.radiusV signal toggled(bool state) Component { id: _imgComponent Image { id: img anchors.centerIn: parent source: control.imageSource height: Math.min(parent.height, control.imageSizeHint) width: height sourceSize.width:control.imageWidth sourceSize.height: control.imageHeight horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter fillMode: control.fillMode cache: true asynchronous: true smooth: false layer.enabled: control.maskRadius layer.effect: OpacityMask { maskSource: Item { width: img.width height: img.height Rectangle { anchors.fill: parent radius: control.maskRadius } } } Rectangle { anchors.fill: parent border.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.8) radius: control.maskRadius opacity: 0.2 color: control.hovered ? control.Kirigami.Theme.highlightColor : "transparent" Kirigami.Icon { anchors.centerIn: parent height: Math.min(22, parent.height * 0.7) width: height source: "folder-images" isMask: true color: parent.border.color opacity: 1 - img.progress } } } } Component { id: _iconComponent Item { Kirigami.Icon { source: control.iconSource anchors.centerIn: parent fallback: "qrc:/assets/application-x-zerosize.svg" height: Math.min(parent.height, control.iconSizeHint) width: height color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor ColorOverlay { visible: control.hovered opacity: 0.3 anchors.fill: parent source: parent color: control.Kirigami.Theme.highlightColor } } } } RowLayout { id: _layout anchors.fill: parent spacing: Maui.Style.space.tiny Item { id: _checkBoxContainer visible: control.checkable || control.checked Layout.fillHeight: true - Layout.preferredWidth: height + Layout.preferredWidth: Math.min(height, Maui.Style.iconSizes.big + Maui.Style.space.medium) Maui.Badge { id: _emblem size: Math.min(Maui.Style.iconSizes.medium, parent.height) anchors.centerIn: parent color: control.checked ? Kirigami.Theme.highlightColor : Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.8) border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7)) onClicked: { control.checked = !control.checked control.toggled(control.checked) } MauiLab.CheckMark { visible: opacity > 0 color: Kirigami.Theme.highlightedTextColor anchors.centerIn: parent height: control.checked ? 10 : 0 width: height opacity: control.checked ? 1 : 0 Behavior on height { NumberAnimation { duration: Kirigami.Units.shortDuration easing.type: Easing.InOutQuad } } Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration easing.type: Easing.InOutQuad } } } } } Item { id: _iconContainer visible: (control.width > Kirigami.Units.gridUnit * 10) && (iconSource.length > 0 || imageSource.length > 0) Layout.fillHeight: true Layout.fillWidth: !control.labelsVisible - Layout.preferredWidth: height + Layout.preferredWidth: Math.min(parent.height, Math.max(control.iconSizeHint, imageSizeHint) + Maui.Style.space.medium) Loader { id: _iconLoader width: Math.min(parent.height, Math.max(control.iconSizeHint, imageSizeHint) ) height: width anchors.centerIn: parent sourceComponent: _iconContainer.visible ? (control.imageSource ? _imgComponent : (control.iconSource ? _iconComponent : null) ): null } } ColumnLayout { id: _leftLabels visible: control.labelsVisible Layout.fillHeight: true Layout.fillWidth: true Layout.margins: Maui.Style.space.tiny Layout.leftMargin: _iconContainer.visible || _checkBoxContainer.visible ? 0 : Maui.Style.space.small spacing: 0 Label { id: _label1 visible: text.length Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: _label2.visible ? Qt.AlignBottom : Qt.AlignVCenter elide: Text.ElideMiddle wrapMode: Text.NoWrap color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor font.weight: Font.Normal font.pointSize: Maui.Style.fontSizes.default } Label { id: _label2 visible: text.length Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: _label1.visible ? Qt.AlignTop : Qt.AlignVCenter elide: Text.ElideRight wrapMode: Text.NoWrap color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor opacity: control.isCurrentItem ? 0.8 : 0.6 font.weight: Font.Normal font.pointSize: Maui.Style.fontSizes.medium } } ColumnLayout { id: _rightLabels visible: control.width > Kirigami.Units.gridUnit * 15 && control.labelsVisible Layout.fillHeight: true Layout.fillWidth: true Layout.margins: Maui.Style.space.tiny spacing: 0 Label { id: _label3 visible: text.length > 0 Layout.fillHeight: true Layout.fillWidth: true Layout.alignment: Qt.AlignRight horizontalAlignment: Qt.AlignRight font.pointSize: Maui.Style.fontSizes.small font.weight: Font.Light wrapMode: Text.NoWrap elide: Text.ElideMiddle color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor opacity: control.isCurrentItem ? 0.8 : 0.6 } Label { id: _label4 visible: text.length > 0 Layout.fillHeight: true Layout.fillWidth: true Layout.alignment: Qt.AlignRight horizontalAlignment: Qt.AlignRight font.pointSize: Maui.Style.fontSizes.small font.weight: Font.Light wrapMode: Text.NoWrap elide: Text.ElideMiddle color: control.isCurrentItem ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor opacity: control.isCurrentItem ? 0.8 : 0.6 } } } } diff --git a/src/controls/labs/Page.qml b/src/controls/labs/Page.qml index c4df436..6bd0dca 100644 --- a/src/controls/labs/Page.qml +++ b/src/controls/labs/Page.qml @@ -1,838 +1,838 @@ /* * Copyright 2019 Camilo Higuita * * 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 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.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.3 import org.kde.mauikit 1.0 as Maui import org.kde.kirigami 2.7 as Kirigami import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 Pane { id: control focus: true padding: 0 leftPadding: control.padding rightPadding: control.padding topPadding: control.padding bottomPadding: control.padding default property alias content: _content.data property alias headerBackground : _headerBackground readonly property alias internalHeight : _content.height property Flickable flickable : null property int footerPositioning : ListView.InlineFooter property int headerPositioning : Kirigami.Settings.isMobile && flickable ? ListView.PullBackHeader : ListView.InlineHeader property string title property int margins: 0 property int leftMargin : margins property int rightMargin: margins property int topMargin: margins property int bottomMargin: margins property bool altHeader : false property bool autoHideHeader : false property bool autoHideFooter : false property int autoHideHeaderMargins : Maui.Style.toolBarHeight property int autoHideFooterMargins : Maui.Style.toolBarHeight property int autoHideFooterDelay : 1000 property int autoHideHeaderDelay : 1000 property bool floatingHeader : control.flickable && control.flickable.contentHeight > control.height && !altHeader ? !_private.flickableAtStart : false property bool floatingFooter: !_private.flickableAtEnd QtObject { id: _private property bool flickableAtEnd : control.flickable ? control.flickable.atYBeginning : true property bool flickableAtStart : control.flickable ? true : true property int topMargin : !control.altHeader ? (control.floatingHeader ? 0 : _headerContent.height) : 0 property int bottomMargin: control.floatingFooter ? control.bottomMargin : control.bottomMargin + _footerContent.height Behavior on topMargin { enabled: control.header.visible && control.headerPositioning === ListView.InlineHeader NumberAnimation { duration: Kirigami.Units.shortDuration easing.type: Easing.InOutQuad } } // Behavior on bottomMargin // { // NumberAnimation // { // duration: Kirigami.Units.shortDuration // easing.type: Easing.InOutQuad // } // } } Timer { id: _flickTimer interval: 700 onTriggered: { if(control.footerPositioning !== ListView.InlineFooter || !control.footer.visible) { _flickTimer.stop() return } if(control.flickable.atYEnd) { _private.flickableAtEnd = true control.flickable.contentY += control.bottomMargin + _footerContent.height }else { _private.flickableAtEnd = false control.flickable.contentY -= control.bottomMargin + _footerContent.height } console.log("AT ENBD CHANGES", _private.flickableAtEnd, control.flickable.atYEnd, control.floatingFooter) } } Connections { target: control.flickable - enabled: control.flickable && control.flickable.contentHeight > control.height + enabled: control.flickable && control.flickable.contentHeight > _content.height onAtYBeginningChanged: { if(control.headerPositioning !== ListView.InlineHeader || !control.header.visible || control.altHeader || control.flickable.contentHeight <= control.height) { return } if(control.flickable.atYBeginning && !control.floatingHeader) { return } if(!control.flickable.atYBeginning && control.floatingHeader) { return } if(_private.flickableAtStart === control.flickable.atYBeginning) { return } _private.flickableAtStart = flickable.atYBeginning console.log("AT START CHANGES", _private.flickableAtStart, control.flickable.atYBeginning, control.floatingHeader) } onAtYEndChanged: control.evaluateFloatingFooter(500) } property bool showTitle : true property alias headBar : _headBar property alias footBar: _footBar Kirigami.Theme.colorSet: Kirigami.Theme.View signal goBackTriggered() signal goForwardTriggered() background: Rectangle { color: Kirigami.Theme.backgroundColor } onFlickableChanged: returnToBounds() // Connections // { // target: control.footer // enabled: control.footer // // onVisibleChanged: evaluateFloatingFooter() // } Connections { target: control.flickable ? control.flickable : null enabled: control.flickable && ((control.header && control.headerPositioning === ListView.PullBackHeader) || (control.footer && control.footerPositioning === ListView.PullBackFooter)) property int oldContentY property bool updatingContentY: false onContentYChanged: { _headerAnimation.enabled = false _footerAnimation.enabled = false if(!control.flickable.dragging && control.flickable.atYBeginning) { control.returnToBounds() } if (updatingContentY || !control.flickable || !control.flickable.dragging) { oldContentY = control.flickable.contentY; return; //TODO: merge //if moves but not dragging, just update oldContentY } if(control.flickable.contentHeight < control.height) { return } var oldFHeight var oldHHeight if (control.footer && control.footerPositioning === ListView.PullBackFooter && control.footer.visible) { oldFHeight = control.footer.height control.footer.height = Math.max(0, Math.min(control.footer.implicitHeight, control.footer.height + oldContentY - control.flickable.contentY)); } if (control.header && control.headerPositioning === ListView.PullBackHeader && control.header.visible && !control.altHeader) { oldHHeight = control.header.height control.header.height = Math.max(0, Math.min(control.header.implicitHeight, control.header.height + oldContentY - control.flickable.contentY)); } //if the implicitHeight is changed, use that to simulate scroll if (control.header && oldHHeight !== control.header.height && control.header.visible && !control.altHeader) { updatingContentY = true control.flickable.contentY -= (oldHHeight - control.header.height) updatingContentY = false } else { oldContentY = control.flickable.contentY } } onMovementEnded: { if (control.header && control.header.visible && control.headerPositioning === ListView.PullBackHeader && !control.altHeader) { _headerAnimation.enabled = true if (control.header.height >= (control.header.implicitHeight/2) || control.flickable.atYBeginning ) { control.header.height = control.header.implicitHeight } else { control.header.height = 0 } } if (control.footer && control.footer.visible && control.footerPositioning === ListView.PullBackFooter) { _footerAnimation.enabled = true if (control.footer.height >= (control.footer.implicitHeight/2) || control.flickable.atYEnd) { if(control.flickable.atYEnd) { control.footer.height = control.footer.implicitHeight control.flickable.contentY = control.flickable.contentHeight - control.flickable.height oldContentY = control.flickable.contentY }else { control.footer.height = control.footer.implicitHeight } } else { control.footer.height = 0 } } } } /* Component.onCompleted: { if(control.header && control.header instanceof Maui.ToolBar) { control.header.visible = header.visibleCount > 0 } }*/ property Item header : Maui.ToolBar { id: _headBar visible: visibleCount > 0 width: visible ? parent.width : 0 height: visible ? implicitHeight : 0 Kirigami.Theme.inherit: false Kirigami.Theme.colorSet: Kirigami.Theme.Window /** to not break the visible binding just check the count state of the header and act upon it **/ // readonly property bool hide : visibleCount === 0 // onHideChanged: // { // if(!header.visible) // { // return // } // // if(hide) // { // pullBackHeader() // }else // { // pullDownHeader() // } // } // Label // { // visible: false // color: "yellow" // text: _headBar.visibleCount + " / " + _headBar.count + " - " + _headBar.height + " / " + header.height + " - " + _headBar.visible + " / " + header.visible // } Behavior on height { id: _headerAnimation enabled: false NumberAnimation { duration: Kirigami.Units.longDuration easing.type: Easing.InOutQuad } } Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration easing.type: Easing.InOutQuad } } Component { id: _titleComponent Label { text: control.title elide : Text.ElideRight font.bold : false font.weight: Font.Bold color : Kirigami.Theme.textColor font.pointSize: Maui.Style.fontSizes.big horizontalAlignment : Text.AlignHCenter verticalAlignment : Text.AlignVCenter } } middleContent: Loader { visible: item Layout.fillWidth: sourceComponent === _titleComponent Layout.fillHeight: sourceComponent === _titleComponent sourceComponent: control.title && control.showTitle ? _titleComponent : null } background: Rectangle { id: _headerBackground color: _headBar.Kirigami.Theme.backgroundColor Kirigami.Separator { id: _border opacity: 0.6 color: Qt.darker(parent.color, 2) anchors.left: parent.left anchors.right: parent.right } Kirigami.Separator { id: _border2 opacity: 0.4 color: Qt.lighter(parent.color, 2.5) anchors.left: parent.left anchors.right: parent.right anchors.bottomMargin: 1 } FastBlur { anchors.fill: parent visible: control.floatingHeader && !altHeader opacity: 0.25 transparentBorder: false source: ShaderEffectSource { samples : 0 recursive: true sourceItem: _content sourceRect: Qt.rect(0, 0-control.topMargin, headBar.width, headBar.height) } radius: 64 } } } // Label // { // // visible: false // z: 999999999999 // color: "yellow" // text: _footBar.visibleCount + " / " + _footBar.count + " - " + _footBar.height + " / " + footer.height + " - " + _footBar.visible + " / " + footer.visible // } property Item footer : Maui.ToolBar { id: _footBar visible: visibleCount > 0 width: visible ? parent.width : 0 height: visible ? implicitHeight : 0 position: ToolBar.Footer Behavior on height { id: _footerAnimation enabled: false NumberAnimation { duration: Kirigami.Units.longDuration easing.type: Easing.InOutQuad } } background: Rectangle { color: _footBar.Kirigami.Theme.backgroundColor Kirigami.Separator { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right } FastBlur { anchors.fill: parent visible: control.floatingFooter opacity: 0.4 transparentBorder: false source: ShaderEffectSource { samples : 0 recursive: true sourceItem: _content sourceRect: Qt.rect(0, control.height - (footBar.height), footBar.width, footBar.height) } radius: 64 } } } states: [ State { when: !altHeader && header.visible AnchorChanges { target: _headerContent anchors.top: parent.top anchors.bottom: undefined } AnchorChanges { target: _border anchors.top: undefined anchors.bottom: parent.bottom } AnchorChanges { target: _border2 anchors.top: undefined anchors.bottom: parent.bottom } PropertyChanges { target: _headBar position: ToolBar.Header } }, State { when: altHeader && header.visible AnchorChanges { target: _headerContent anchors.top: undefined anchors.bottom: parent.bottom } AnchorChanges { target: _border anchors.top: parent.top anchors.bottom: undefined } AnchorChanges { target: _border2 anchors.top: parent.top anchors.bottom: undefined } PropertyChanges { target: header height: header.implicitHeight } PropertyChanges { target: _headBar position: ToolBar.Footer } } ] // transitions: Transition { // // smoothly reanchor myRect and move into new position // AnchorAnimation { duration: 1000 } // } onAutoHideHeaderChanged: pullDownHeader() onAutoHideFooterChanged: pullDownFooter() onAltHeaderChanged: pullDownHeader() Column { id: _headerContent anchors.left: parent.left anchors.right: parent.right children: header z: _content.z+1 } // Label // { // anchors.centerIn: _headerContent // text: header.height + "/" + _headerContent.height + " - " + _layout.anchors.topMargin // color: "orange" // z: _headerContent.z + 1 // visible: header.visible // } Item { id: _layout anchors.fill: parent anchors.bottomMargin: control.altHeader ? _headerContent.height : 0 anchors.topMargin: _private.topMargin Item { id: _content anchors.fill: parent anchors.margins: control.margins anchors.leftMargin: control.leftMargin anchors.rightMargin: control.rightMargin anchors.topMargin: control.topMargin anchors.bottomMargin: _private.bottomMargin } Column { id: _footerContent anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom children: footer } } Timer { id: _autoHideHeaderTimer interval: autoHideHeaderDelay onTriggered: { if(control.autoHideHeader && !control.altHeader) { pullBackHeader() } stop() } } Timer { id: _autoHideFooterTimer interval: control.autoHideFooterDelay onTriggered: { if(control.autoHideFooter) { pullBackFooter() } stop() } } Item { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right height: visible ? _headerContent.height + control.autoHideHeaderMargins : 0 z: _content.z +1 visible: control.autoHideHeader && !control.altHeader && !Kirigami.Settings.isMobile HoverHandler { target: parent acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus onHoveredChanged: { if(!control.autoHideHeader || control.altHeader) { _autoHideHeaderTimer.stop() return } if(!hovered) { _autoHideHeaderTimer.start() }else { pullDownHeader() _autoHideHeaderTimer.stop() } } } } Item { anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right height: visible ? _footerContent.height + control.autoHideFooterMargins : 0 z: _footerContent.z - 1 visible: control.autoHideFooter && !control.altHeader && !Kirigami.Settings.isMobile HoverHandler { target: parent acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus onHoveredChanged: { if(!control.autoHideFooter) { return } if(!hovered) { _autoHideFooterTimer.start() }else { pullDownFooter() _autoHideFooterTimer.stop() } } } } // Item // { // anchors.fill: parent // anchors.topMargin: header.height // anchors.bottomMargin: footer.height // z: _content.z + 9999 // // TapHandler // { // target: parent // enabled: control.autoHideHeader && !control.altHeader // // grabPermissions: PointerHandler.TakeOverForbidden | PointerHandler.ApprovesTakeOverByHandlersOfSameType | PointerHandler.CanTakeOverFromAnything // // onSingleTapped: // { // if(!control.autoHideHeader) // { // return // } // console.log("Pgae tapped") // header.visible = !header.visible // } // } // } Keys.onBackPressed: { control.goBackTriggered(); } Shortcut { sequence: "Forward" onActivated: control.goForwardTriggered(); } Shortcut { sequence: StandardKey.Forward onActivated: control.goForwardTriggered(); } Shortcut { sequence: StandardKey.Back onActivated: control.goBackTriggered(); } function returnToBounds() { if(control.header) { pullDownHeader() } if(control.footer) { pullDownFooter() } evaluateFloatingFooter(0) } function pullBackHeader() { _headerAnimation.enabled = true header.height= 0 } function pullDownHeader() { _headerAnimation.enabled = true header.height = header.implicitHeight } function pullBackFooter() { _footerAnimation.enabled = true footer.height= 0 } function pullDownFooter() { _footerAnimation.enabled = true footer.height = footer.implicitHeight } function evaluateFloatingFooter(interval) { if(control.footerPositioning !== ListView.InlineFooter) { _flickTimer.stop() return } _flickTimer.interval = interval if(!control.flickable) { _flickTimer.stop() return } if(control.flickable.atYEnd && !control.floatingFooter) { _flickTimer.stop() return } if(!control.flickable.atYEnd && control.floatingFooter) { _flickTimer.stop() return } if(_private.flickableAtEnd === control.flickable.atYEnd) { _flickTimer.stop() return } _flickTimer.restart() } }