diff --git a/src/controls/ToolBar.qml b/src/controls/ToolBar.qml index 63cb025..d3d0d2c 100644 --- a/src/controls/ToolBar.qml +++ b/src/controls/ToolBar.qml @@ -1,369 +1,377 @@ /* * 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.6 import QtQuick.Controls 2.2 import org.kde.kirigami 2.9 as Kirigami import org.kde.mauikit 1.0 as Maui import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import "private" ToolBar { id: control property int preferredHeight: Maui.Style.toolBarHeight implicitHeight: preferredHeight implicitWidth: mainFlickable.contentWidth spacing: Maui.Style.space.small padding: 0 // property alias stickyRightContent : rightRowContent.sticky // property alias stickyLeftContent : leftRowContent.sticky // property alias stickyMiddleContent : middleRowContent.sticky property bool forceCenterMiddleContent : true property alias leftContent : leftRowContent.data property alias middleContent : middleRowContent.data property alias rightContent : rightRowContent.data property alias middleLayout : middleRowContent property alias leftLayout : leftRowContent property alias rightLayout : rightRowContent property alias layout : layout readonly property alias fits : _scrollView.fits property int margins: Maui.Style.space.medium readonly property int count : leftContent.length + middleContent.length + rightContent.length - property int visibleCount : leftRowContent.visibleChildren.length + middleRowContent.visibleChildren.length + rightRowContent.visibleChildren.length + readonly property int visibleCount : leftRowContent.visibleCount + middleRowContent.visibleCount + rightRowContent.visibleCount + + + property bool flickable: true property bool strech : true property bool leftSretch: strech property bool rightSretch: strech property bool middleStrech: strech // leftPadding: Kirigami.Units.smallSpacing*2 // rightPadding: Kirigami.Units.smallSpacing*2 // background: Rectangle // { // id: headBarBG // color: colorScheme.backgroundColor // implicitHeight: Maui.Style.toolBarHeightAlt // radius: floating ? Maui.Style.radiusV : 0 // border.color: floating ? colorScheme.borderColor : "transparent" // // SequentialAnimation on radius // { // ColorAnimation { to: colorScheme.backgroundColor ; duration: 1000 } // } // // Kirigami.Separator // { // visible: drawBorder // color: colorScheme.borderColor // height: Maui.Style.unit // anchors // { // left: parent.left // right: parent.right // bottom: control.position == ToolBar.Footer ? undefined : parent.bottom // top: control.position == ToolBar.Footer ? parent.top : undefined // } // } // // layer.enabled: dropShadow // layer.effect: DropShadow // { // anchors.fill: headBarBG // horizontalOffset: 0 // verticalOffset: Maui.Style.unit * (altToolBars ? -1 : 1) // radius: 8 // samples: 25 // color: Qt.darker(colorScheme.backgroundColor, 1.4) // source: headBarBG // } // } MouseArea { id: _rightFlickRec width: Maui.Style.iconSizes.medium height: parent.height visible: !mainFlickable.atXEnd && !control.fits && control.flickable hoverEnabled: true anchors { top: parent.top bottom: parent.bottom right: parent.right } z: 999 EdgeShadow { visible: true parent: parent edge: Qt.RightEdge anchors { right: parent.right top: parent.top bottom: parent.bottom } opacity: 1 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration easing.type: Easing.InOutQuad } } } Maui.Triangle { visible: !Kirigami.Settings.isMobile anchors.centerIn: parent rotation: -135 color: _rightFlickRec.hovered ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor width: Maui.Style.iconSizes.tiny height: width } enabled: !mainFlickable.atXEnd opacity: enabled ? 1 : 0.4 onClicked: { if(!mainFlickable.atXEnd) { mainFlickable.contentX += Math.min( mainFlickable.contentWidth - mainFlickable.contentX, mainFlickable.contentWidth) } if(mainFlickable.atXEnd) { mainFlickable.returnToBounds() } } } MouseArea { id: _leftFlickRec width: Maui.Style.iconSizes.medium height: parent.height visible: !mainFlickable.atXBeginning && !control.fits && control.flickable hoverEnabled: true anchors { top: parent.top bottom: parent.bottom left: parent.left } z: 999 EdgeShadow { visible: true parent: parent edge: Qt.LeftEdge anchors { left: parent.left top: parent.top bottom: parent.bottom } opacity: 1 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration easing.type: Easing.InOutQuad } } } Maui.Triangle { visible: !Kirigami.Settings.isMobile anchors.centerIn: parent rotation: 45 color: _leftFlickRec.hovered ? control.Kirigami.Theme.highlightColor : control.Kirigami.Theme.textColor width: Maui.Style.iconSizes.tiny height: width } enabled: !mainFlickable.atXBeginning opacity: enabled ? 1 : 0.4 onClicked: { if(!mainFlickable.atXBeginning) mainFlickable.contentX -= control.height if(mainFlickable.atXBeginning) mainFlickable.returnToBounds() } } Kirigami.WheelHandler { id: wheelHandler target: mainFlickable } ScrollView { id: _scrollView property bool fits : mainFlickable.contentWidth < control.width onFitsChanged: mainFlickable.returnToBounds() height: control.implicitHeight width: control.width contentWidth: mainFlickable.contentWidth contentHeight: height states: [State { when: control.position === ToolBar.Header AnchorChanges { target: _scrollView anchors.top: undefined anchors.bottom: parent.bottom } }, State { when: control.position === ToolBar.Footer AnchorChanges { target: _scrollView anchors.top: parent.top anchors.bottom: undefined } } ] // ScrollBar.horizontal: ScrollBar // { // parent: _scrollView // x: 0 // y: _scrollView.height - height // width: control.width // height: visible ? 2: 0 // active: _scrollView.ScrollBar.horizontal || _scrollView.ScrollBar.horizontal.active // } ScrollBar.horizontal: ScrollBar {parent: _scrollView; visible: false} ScrollBar.vertical: ScrollBar {parent: _scrollView; visible: false} Flickable { id: mainFlickable anchors.fill: parent anchors.leftMargin: control.margins anchors.rightMargin: control.margins flickableDirection: Flickable.HorizontalFlick interactive: !fits && Maui.Handy.isTouch contentWidth: layout.implicitWidth boundsBehavior: Kirigami.Settings.isMobile ? Flickable.DragOverBounds : Flickable.StopAtBounds clip: true RowLayout { id: layout width: mainFlickable.width height: mainFlickable.height RowLayout { id: leftRowContent + property int visibleCount : visibleChildren.length +// onVisibleChildrenChanged: visibleCount = visibleChildren.length // visible: control.leftSretch && implicitWidth property bool sticky : false Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft spacing: visibleChildren.length > 1 ? control.spacing : 0 Layout.minimumWidth: implicitWidth Layout.fillWidth: implicitWidth && control.leftSretch Layout.fillHeight: true } Item //helper to force center middle content { visible: control.forceCenterMiddleContent && control.leftSretch Layout.minimumWidth: 0 Layout.fillWidth: visible Layout.maximumWidth: visible ? Math.max(rightRowContent.implicitWidth - leftRowContent.implicitWidth, 0) : 0 } RowLayout { id: middleRowContent + property int visibleCount : visibleChildren.length +// onVisibleChildrenChanged: visibleCount = visibleChildren.length property bool sticky : false Layout.alignment: Qt.AlignCenter spacing: visibleChildren.length > 1 ? control.spacing : 0 Layout.minimumWidth: implicitWidth Layout.fillWidth: control.middleStrech Layout.fillHeight: true } Item //helper to force center middle content { visible: control.forceCenterMiddleContent && control.rightSretch Layout.minimumWidth: 0 Layout.fillWidth: visible Layout.maximumWidth: visible ? Math.max(leftRowContent.implicitWidth-rightRowContent.implicitWidth, 0) : 0 } RowLayout { id: rightRowContent - // visible: control.rightSretch && implicitWidth + property int visibleCount : visibleChildren.length +// onVisibleChildrenChanged: visibleCount = visibleChildren.length Layout.alignment: Qt.AlignVCenter | Qt.AlignRight spacing: visibleChildren.length > 1 ? control.spacing : 0 Layout.minimumWidth: implicitWidth Layout.fillWidth: implicitWidth && control.rightSretch Layout.fillHeight: true } } } } } diff --git a/src/controls/labs/Page.qml b/src/controls/labs/Page.qml index 389929e..b1f6971 100644 --- a/src/controls/labs/Page.qml +++ b/src/controls/labs/Page.qml @@ -1,535 +1,554 @@ /* * 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 : Kirigami.Settings.isMobile && flickable ? ListView.PullBackHeader : 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 onAutoHideHeaderChanged: header.opacity = 1 property bool floatingHeader : false property bool showTitle : true Kirigami.Theme.colorSet: Kirigami.Theme.View signal goBackTriggered() signal goForwardTriggered() background: Rectangle { color: Kirigami.Theme.backgroundColor } onFlickableChanged: returnToBounds() 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 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) { 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) { 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.footer && oldFHeight !== control.footer.height) || ( control.header && oldHHeight !== control.header.height)) { updatingContentY = true if(control.header && oldHHeight !== control.header.height) control.flickable.contentY -= (oldHHeight - control.header.height) updatingContentY = false } else { oldContentY = control.flickable.contentY } } onMovementEnded: { _headerAnimation.enabled = true if (control.headerPositioning === ListView.PullBackHeader && control.header) { if (control.header.height >= (control.header.implicitHeight/2) || control.flickable.atYBeginning ) { control.header.height = control.header.implicitHeight } else { control.header.height = 0 } } if (control.footerPositioning === ListView.PullBackFooter && control.footer) { 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 } } } } property alias headBar : _headBar property alias footBar: _footBar property Item header : Maui.ToolBar { id: _headBar - visible: visibleCount > 0 // coutn down the possible title loader width: visible ? parent.width : 0 height: visible ? implicitHeight : 0 - anchors.bottom: parent.bottom - position: ToolBar.Header + 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(hide) + { + pullBackHeader() + }else + { + pullDownHeader() + } + } + Behavior on height { id: _headerAnimation enabled: false NumberAnimation { duration: Kirigami.Units.longDuration easing.type: Easing.InOutQuad } } +// Label +// { +// id: _counterLabel +// text: _headBar.visibleCount + " - " + _headBar.count +// color: "yellow" +// visible: _headBar.visibleCount > 0 +// } + 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.2 transparentBorder: false source: ShaderEffectSource { // cullMode: ShaderEffect.FrontFaceCulling // hideSource: true samples : 0 recursive: true sourceItem: _content sourceRect: Qt.rect(0, 0-control.topMargin, headBar.width, headBar.height) // textureSize: Qt.size(headBar.width,headBar.height) } radius: 64 } } } property Item footer : Maui.ToolBar { id: _footBar visible: _footBar.visibleCount > 0 position: ToolBar.Footer width: visible ? parent.width : 0 height: visible ? implicitHeight : 0 } Item { id: _headerContent anchors.left: parent.left anchors.right: parent.right height: header && header.visible ? header.height : 0 - data: header ? [header] : [] + data: header z: _content.z+1 } states: [ State { when: !altHeader 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: _layout anchors.topMargin: control.floatingHeader ? 0 : _headerContent.height anchors.bottomMargin: 0 } PropertyChanges { target: _headBar position: ToolBar.Header } }, State { when: altHeader 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: _layout anchors.topMargin: 0 anchors.bottomMargin: _headerContent.height } PropertyChanges { target: _headBar position: ToolBar.Footer } } ] // transitions: Transition { // // smoothly reanchor myRect and move into new position // AnchorAnimation { duration: 1000 } // } ColumnLayout { id: _layout anchors.fill: parent spacing: 0 Item { id: _content Layout.fillHeight: true Layout.fillWidth: true Layout.margins: control.margins Layout.leftMargin: control.leftMargin Layout.rightMargin: control.rightMargin Layout.topMargin: control.topMargin Layout.bottomMargin: control.bottomMargin } Item { id: _footerContent Layout.fillWidth: true Layout.preferredHeight: footer && footer.visible ? footer.height : 0 data: footer ? [footer] : [] } } Timer { id: _timer interval: 1000 onTriggered: { if(control.autoHideHeader) { pullBackHeader() } stop() } } Item { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right height: control.height * 0.1 z: _content.z + 9999 visible: control.autoHideHeader && !control.altHeader && !Kirigami.Settings.isMobile HoverHandler { target: parent acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus onHoveredChanged: { if(!control.autoHideHeader) { return } if(!hovered) { _timer.start() }else { pullDownHeader() _timer.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) { control.header.height = control.header.implicitHeight } if(control.footer) { control.footer.height = control.footer.implicitHeight } } function pullBackHeader() { _headerAnimation.enabled = true header.height= 0 } function pullDownHeader() { _headerAnimation.enabled = true header.height= header.implicitHeight } } diff --git a/src/controls/private/BrowserView.qml b/src/controls/private/BrowserView.qml index 7963558..f1a0205 100644 --- a/src/controls/private/BrowserView.qml +++ b/src/controls/private/BrowserView.qml @@ -1,842 +1,842 @@ import QtQuick 2.9 import QtQuick.Controls 2.9 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.7 as Kirigami import org.kde.mauikit 1.0 as Maui Maui.Page { id: control title: currentFMList.pathName - + showTitle: false property url path onPathChanged: { if(control.currentView) { control.currentView.currentIndex = 0 control.currentView.forceActiveFocus() } } //group properties from the browser since the browser views are loaded async and //their properties can not be accesed inmediately, so they are stored here and then when completed they are set property alias settings : _settings BrowserSettings { id: _settings onGroupChanged: { if(settings.group) { groupBy() } else { currentView.section.property = "" } } } property Maui.FMList currentFMList property Maui.BaseModel currentFMModel property alias currentView : viewLoader.item property string filter function setCurrentFMList() { if(control.currentView) { control.currentFMList = currentView.currentFMList control.currentFMModel = currentView.currentFMModel currentView.forceActiveFocus() } } function filterSelectedItems(path) { if(selectionBar && selectionBar.count > 0 && selectionBar.contains(path)) { const uris = selectionBar.uris var res = [] for(var i in uris) { if(Maui.FM.parentDir(uris[i]) == control.path) { res.push(uris[i]) } } return res.join("\n") } return path } function groupBy() { var prop = "" var criteria = ViewSection.FullString switch(control.currentFMList.sortBy) { case Maui.FMList.LABEL: prop = "label" criteria = ViewSection.FirstCharacter break; case Maui.FMList.MIME: prop = "mime" break; case Maui.FMList.SIZE: prop = "size" break; case Maui.FMList.DATE: prop = "date" break; case Maui.FMList.MODIFIED: prop = "modified" break; } if(!prop) { control.currentView.section.property = "" return } control.settings.viewType = Maui.FMList.LIST_VIEW control.currentView.section.property = prop control.currentView.section.criteria = criteria } Menu { id: _dropMenu property string urls property url target enabled: Maui.FM.getFileInfo(target).isdir == "true" && !urls.includes(target.toString()) MenuItem { text: qsTr("Copy here") onTriggered: { const urls = _dropMenu.urls.split(",") Maui.FM.copy(urls, _dropMenu.target, false) } } MenuItem { text: qsTr("Move here") onTriggered: { const urls = _dropMenu.urls.split(",") Maui.FM.cut(urls, _dropMenu.target) } } MenuItem { text: qsTr("Link here") onTriggered: { const urls = _dropMenu.urls.split(",") for(var i in urls) Maui.FM.createSymlink(url[i], _dropMenu.target) } } MenuSeparator {} MenuItem { text: qsTr("Cancel") onTriggered: _dropMenu.close() } } Loader { id: viewLoader anchors.fill: parent focus: true sourceComponent: switch(settings.viewType) { case Maui.FMList.ICON_VIEW: return gridViewBrowser case Maui.FMList.LIST_VIEW: return listViewBrowser case Maui.FMList.MILLERS_VIEW: return millerViewBrowser } onLoaded: setCurrentFMList() } Maui.FMList { id: _commonFMList path: control.path onSortByChanged: if(settings.group) groupBy() onlyDirs: settings.onlyDirs filterType: settings.filterType filters: settings.filters sortBy: settings.sortBy hidden: settings.showHiddenFiles } Component { id: listViewBrowser Maui.ListBrowser { id: _listViewBrowser property alias currentFMList : _browserModel.list property alias currentFMModel : _browserModel topMargin: Maui.Style.contentMargins showPreviewThumbnails: settings.showThumbnails checkable: selectionMode enableLassoSelection: true spacing: Kirigami.Settings.isMobile ? Maui.Style.space.small : Maui.Style.space.medium BrowserHolder { id: _holder browser: currentFMList } holder.visible: _holder.visible holder.emoji: _holder.emoji holder.title: _holder.title holder.body: _holder.body holder.emojiSize: _holder.emojiSize model: Maui.BaseModel { id: _browserModel list: _commonFMList filter: control.filter recursiveFilteringEnabled: true sortCaseSensitivity: Qt.CaseInsensitive filterCaseSensitivity: Qt.CaseInsensitive } section.delegate: Maui.LabelDelegate { id: delegate width: parent.width height: Maui.Style.toolBarHeightAlt label: String(section).toUpperCase() labelTxt.font.pointSize: Maui.Style.fontSizes.big isSection: true } delegate: Maui.ListBrowserDelegate { id: delegate width: parent.width padding: 0 leftPadding: Maui.Style.space.small rightPadding: leftPadding iconSizeHint : Maui.Style.iconSizes.medium imageSizeHint : height * 0.8 tooltipText: model.path checkable: _listViewBrowser.checkable showThumbnails: _listViewBrowser.showPreviewThumbnails checked: selectionBar ? selectionBar.contains(model.path) : false opacity: model.hidden == "true" ? 0.5 : 1 draggable: true Drag.keys: ["text/uri-list"] Drag.mimeData: Drag.active ? { "text/uri-list": control.filterSelectedItems(model.path) } : {} Item { Layout.fillHeight: true Layout.preferredWidth: height visible: (model.issymlink == true) || (model.issymlink == "true") Kirigami.Icon { source: "link" height: Maui.Style.iconSizes.small width: Maui.Style.iconSizes.small anchors.centerIn: parent color: label1.color } } Connections { target: selectionBar onUriRemoved: { if(uri === model.path) delegate.checked = false } onUriAdded: { if(uri === model.path) delegate.checked = true } onCleared: delegate.checked = false } Connections { target: delegate onClicked: { _listViewBrowser.currentIndex = index if ((mouse.button == Qt.LeftButton) && (mouse.modifiers & Qt.ControlModifier)) { _listViewBrowser.itemsSelected([index]) }else { _listViewBrowser.itemClicked(index) } } onDoubleClicked: { _listViewBrowser.currentIndex = index _listViewBrowser.itemDoubleClicked(index) } onPressAndHold: { if(!Maui.Handy.isTouch) return _listViewBrowser.currentIndex = index _listViewBrowser.itemRightClicked(index) } onRightClicked: { _listViewBrowser.currentIndex = index _listViewBrowser.itemRightClicked(index) } onToggled: { _listViewBrowser.currentIndex = index _listViewBrowser.itemToggled(index, state) } onContentDropped: { _dropMenu.urls = drop.urls.join(",") _dropMenu.target = model.path _dropMenu.popup() } } } } } Component { id: gridViewBrowser Maui.GridBrowser { id: _gridViewBrowser property alias currentFMList : _browserModel.list property alias currentFMModel : _browserModel itemSize : thumbnailsSize + Maui.Style.space.small cellHeight: itemSize * 1.5 checkable: selectionMode showPreviewThumbnails: settings.showThumbnails enableLassoSelection: true BrowserHolder { id: _holder browser: currentFMList } holder.visible: _holder.visible holder.emoji: _holder.emoji holder.title: _holder.title holder.body: _holder.body holder.emojiSize: _holder.emojiSize model: Maui.BaseModel { id: _browserModel list: _commonFMList filter: control.filter recursiveFilteringEnabled: true sortCaseSensitivity: Qt.CaseInsensitive filterCaseSensitivity: Qt.CaseInsensitive } delegate: Item { property bool isCurrentItem : GridView.isCurrentItem height: _gridViewBrowser.cellHeight width: _gridViewBrowser.cellWidth Maui.GridBrowserDelegate { id: delegate iconSizeHint: height * 0.5 anchors.centerIn: parent height: _gridViewBrowser.cellHeight - 5 width: _gridViewBrowser.itemSize - 5 padding: Maui.Style.space.tiny isCurrentItem: parent.isCurrentItem tooltipText: model.path checkable: _gridViewBrowser.checkable showThumbnails: _gridViewBrowser.showPreviewThumbnails checked: (selectionBar ? selectionBar.contains(model.path) : false) draggable: true opacity: model.hidden == "true" ? 0.5 : 1 Drag.keys: ["text/uri-list"] Drag.mimeData: Drag.active ? { "text/uri-list": control.filterSelectedItems(model.path) } : {} Maui.Badge { iconName: "link" anchors.left: parent.left anchors.bottom: parent.bottom anchors.bottomMargin: Maui.Style.space.big visible: (model.issymlink == true) || (model.issymlink == "true") } Connections { target: selectionBar onUriRemoved: { if(uri === model.path) delegate.checked = false } onUriAdded: { if(uri === model.path) delegate.checked = true } onCleared: delegate.checked = false } Connections { target: delegate onClicked: { _gridViewBrowser.currentIndex = index if ((mouse.button == Qt.LeftButton) && (mouse.modifiers & Qt.ControlModifier)) { _gridViewBrowser.itemsSelected([index]) }else { _gridViewBrowser.itemClicked(index) } } onDoubleClicked: { _gridViewBrowser.currentIndex = index _gridViewBrowser.itemDoubleClicked(index) } onPressAndHold: { if(!Maui.Handy.isTouch) return _gridViewBrowser.currentIndex = index _gridViewBrowser.itemRightClicked(index) } onRightClicked: { _gridViewBrowser.currentIndex = index _gridViewBrowser.itemRightClicked(index) } onToggled: { _gridViewBrowser.currentIndex = index _gridViewBrowser.itemToggled(index, state) } onContentDropped: { _dropMenu.urls = drop.urls.join(",") _dropMenu.target = model.path _dropMenu.popup() } } } } } } Component { id: millerViewBrowser ScrollView { id: _millerControl property Maui.FMList currentFMList property Maui.BaseModel currentFMModel property int currentIndex signal itemClicked(int index) signal itemDoubleClicked(int index) signal itemRightClicked(int index) signal keyPress(var event) signal itemToggled(int index, bool state) signal itemsSelected(var indexes) signal areaClicked(var mouse) signal areaRightClicked() function forceActiveFocus() { _millerColumns.currentItem.forceActiveFocus() } contentWidth: _millerColumns.contentWidth contentHeight: height ScrollBar.horizontal: ScrollBar { id: horizontalScrollBar height: visible ? implicitHeight: 0 parent: _millerControl x: 0 y: _millerControl.height - height width: _millerControl.width active: _millerControl.ScrollBar.horizontal || _millerControl.ScrollBar.horizontal.active } // ScrollBar.horizontal: ScrollBar // { // id: _scrollBar // snapMode: ScrollBar.SnapAlways // policy: ScrollBar.AlwaysOn // // contentItem: Rectangle // { // implicitWidth: _scrollBar.interactive ? 13 : 4 // implicitHeight: _scrollBar.interactive ? 13 : 4 // // color: "#333" // // opacity: _scrollBar.pressed ? 0.7 : // _scrollBar.interactive && _scrollBar.hovered ? 0.5 : 0.2 // radius: 0 // } // // background: Rectangle // { // implicitWidth: _scrollBar.interactive ? 16 : 4 // implicitHeight: _scrollBar.interactive ? 16 : 4 // color: "#0e000000" // opacity: 0.0 // visible: _scrollBar.interactive // radius: 0 // // } // } ListView { id: _millerColumns anchors.fill: parent anchors.bottomMargin: horizontalScrollBar.height boundsBehavior: !Maui.Handy.isTouch? Flickable.StopAtBounds : Flickable.OvershootBounds keyNavigationEnabled: true interactive: Kirigami.Settings.hasTransientTouchInput cacheBuffer: contentWidth orientation: ListView.Horizontal snapMode: ListView.SnapToItem clip: true onCurrentItemChanged: { _millerControl.currentFMList = currentItem.currentFMList _millerControl.currentFMModel = currentItem.currentFMModel control.setCurrentFMList() currentItem.forceActiveFocus() } onCountChanged: { _millerColumns.currentIndex = _millerColumns.count-1 _millerColumns.positionViewAtEnd() } Maui.PathList { id: _millerList path: control.path onPathChanged: { _millerColumns.currentIndex = _millerColumns.count-1 _millerColumns.positionViewAtEnd() } } model: Maui.BaseModel { id: _millerModel list: _millerList } delegate: Item { property alias currentFMList : _millersFMList property alias currentFMModel : _millersFMModel property int _index : index width: Math.min(Kirigami.Units.gridUnit * 22, control.width) height: parent.height focus: true function forceActiveFocus() { _millerListView.forceActiveFocus() } Kirigami.Separator { anchors.top: parent.top anchors.bottom: parent.bottom anchors.right: parent.right width: 1 z: 999 } Maui.FMList { id: _millersFMList path: model.path onlyDirs: settings.onlyDirs filterType: settings.filterType filters: settings.filters sortBy: settings.sortBy hidden: settings.showHiddenFiles } Maui.ListBrowser { id: _millerListView anchors.fill: parent topMargin: Maui.Style.contentMargins showPreviewThumbnails: settings.showThumbnails checkable: selectionMode onKeyPress: _millerControl.keyPress(event) currentIndex : 0 onCurrentIndexChanged: _millerControl.currentIndex = currentIndex enableLassoSelection: true BrowserHolder { id: _holder browser: currentFMList } holder.visible: _holder.visible holder.emoji: _holder.emoji holder.title: _holder.title holder.body: _holder.body holder.emojiSize: _holder.emojiSize section.delegate: Maui.LabelDelegate { id: delegate width: parent.width height: Maui.Style.toolBarHeightAlt label: String(section).toUpperCase() labelTxt.font.pointSize: Maui.Style.fontSizes.big isSection: true } onAreaClicked: { _millerColumns.currentIndex = _index _millerControl.areaClicked(mouse) } onAreaRightClicked: { _millerColumns.currentIndex = _index _millerControl.areaRightClicked() } onItemsSelected: { _millerColumns.currentIndex = _index _millerControl.itemsSelected(indexes) } model: Maui.BaseModel { id: _millersFMModel list: _millersFMList filter: control.filter recursiveFilteringEnabled: true sortCaseSensitivity: Qt.CaseInsensitive filterCaseSensitivity: Qt.CaseInsensitive } delegate: Maui.ListBrowserDelegate { id: delegate width: parent.width height: implicitHeight padding: 0 leftPadding: Maui.Style.space.small rightPadding: leftPadding tooltipText: model.path iconSizeHint : Maui.Style.iconSizes.medium imageSizeHint : height * 0.8 checkable: _millerListView.checkable showThumbnails: _millerListView.showPreviewThumbnails checked: selectionBar ? selectionBar.contains(model.path) : false opacity: model.hidden == "true" ? 0.5 : 1 draggable: true Drag.keys: ["text/uri-list"] Drag.mimeData: Drag.active ? { "text/uri-list": control.filterSelectedItems(model.path) } : {} Item { Layout.fillHeight: true Layout.preferredWidth: height visible: (model.issymlink == true) || (model.issymlink == "true") Kirigami.Icon { source: "link" height: Maui.Style.iconSizes.small width: Maui.Style.iconSizes.small anchors.centerIn: parent color: label1.color } } Connections { target: selectionBar onUriRemoved: { if(uri === model.path) delegate.checked = false } onUriAdded: { if(uri === model.path) delegate.checked = true } onCleared: delegate.checked = false } Connections { target: delegate onClicked: { _millerColumns.currentIndex = _index _millerListView.currentIndex = index if ((mouse.button == Qt.LeftButton) && (mouse.modifiers & Qt.ControlModifier)) { _millerControl.itemsSelected([index]) }else { _millerControl.itemClicked(index) } } onDoubleClicked: { _millerColumns.currentIndex = _index _millerListView.currentIndex = index _millerControl.itemDoubleClicked(index) } onPressAndHold: { if(!Maui.Handy.isTouch) return _millerColumns.currentIndex = _index _millerListView.currentIndex = index _millerControl.itemRightClicked(index) } onRightClicked: { _millerColumns.currentIndex = _index _millerListView.currentIndex = index _millerControl.itemRightClicked(index) } onToggled: { _millerColumns.currentIndex = _index _millerListView.currentIndex = index _millerControl.itemToggled(index, state) } onContentDropped: { _dropMenu.urls = drop.urls.join(",") _dropMenu.target = model.path _dropMenu.popup() } } } } } } } } }