Warning, /plasma/plasma-mobile/containments/homescreens/folio/package/contents/ui/FolderView.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
0002 // SPDX-License-Identifier: LGPL-2.0-or-later
0003 
0004 import QtQuick
0005 import QtQuick.Layouts
0006 import QtQuick.Effects
0007 import QtQuick.Controls as QQC2
0008 
0009 import org.kde.kirigami 2.20 as Kirigami
0010 
0011 import org.kde.plasma.private.mobileshell as MobileShell
0012 import org.kde.private.mobile.homescreen.folio 1.0 as Folio
0013 
0014 import "./delegate"
0015 
0016 Folio.DelegateTouchArea {
0017     id: root
0018 
0019     property var homeScreen
0020 
0021     // the position on the screen for animations to start from
0022     property real folderPositionX
0023     property real folderPositionY
0024 
0025     property Folio.FolioApplicationFolder folder: Folio.HomeScreenState.currentFolder
0026 
0027     onClicked: close();
0028 
0029     function close() {
0030         Folio.HomeScreenState.closeFolder();
0031     }
0032 
0033     Connections {
0034         target: Folio.HomeScreenState
0035 
0036         function onFolderAboutToOpen(x, y) {
0037             root.folderPositionX = x - Folio.HomeScreenState.viewLeftPadding;
0038             root.folderPositionY = y - Folio.HomeScreenState.viewRightPadding;
0039         }
0040     }
0041 
0042     FolderViewTitle {
0043         id: titleText
0044         width: root.width
0045 
0046         // have to use y instead of anchors to avoid animations
0047         y: Math.round((root.height / 2) - (folderBackground.height / 2) - Kirigami.Units.gridUnit - height)
0048         anchors.left: parent.left
0049         anchors.right: parent.right
0050 
0051         folder: root.folder
0052 
0053         opacity: (root.opacity === 1) ? 1 : 0
0054         Behavior on opacity {
0055             NumberAnimation { duration: Kirigami.Units.shortDuration }
0056         }
0057     }
0058 
0059     function updateContentWidth() {
0060         let margin = folderBackground.margin;
0061         let columns = Math.floor((folderBackground.width - margin * 2) / Folio.HomeScreenState.pageCellWidth);
0062         Folio.HomeScreenState.folderPageContentWidth = columns * Folio.HomeScreenState.pageCellWidth;
0063     }
0064 
0065     function updateContentHeight() {
0066         let margin = folderBackground.margin;
0067         let rows = Math.floor((folderBackground.height - margin * 2) / Folio.HomeScreenState.pageCellHeight);
0068         Folio.HomeScreenState.folderPageContentHeight = rows * Folio.HomeScreenState.pageCellHeight;
0069     }
0070 
0071     Connections {
0072         target: Folio.HomeScreenState
0073 
0074         function onPageCellWidthChanged() {
0075             root.updateContentWidth();
0076             root.updateContentHeight();
0077         }
0078 
0079         function onPageCellHeightChanged() {
0080             root.updateContentWidth();
0081             root.updateContentHeight();
0082         }
0083     }
0084 
0085     Rectangle {
0086         id: folderBackground
0087         color: Qt.rgba(255, 255, 255, 0.3)
0088         radius: Kirigami.Units.gridUnit
0089 
0090         readonly property real margin: Kirigami.Units.largeSpacing
0091         readonly property real maxLength: Math.min(root.width * 0.9, root.height * 0.9)
0092 
0093         width: {
0094             let perRow = 0;
0095             if (root.width < root.height) {
0096                 perRow = Math.floor((maxLength - margin * 2) / Folio.HomeScreenState.pageCellWidth);
0097             } else {
0098                 // try to get the same number of rows as columns
0099                 perRow = Math.floor((maxLength - margin * 2) / Folio.HomeScreenState.pageCellHeight);
0100             }
0101             return Math.min(root.width * 0.9, perRow * Folio.HomeScreenState.pageCellWidth + margin * 2);
0102         }
0103         height: {
0104             let perRow = 0;
0105             if (root.width < root.height) {
0106                 // try to get the same number of rows as columns
0107                 perRow = Math.floor((maxLength - margin * 2) / Folio.HomeScreenState.pageCellWidth);
0108             } else {
0109                 perRow = Math.floor((maxLength - margin * 2) / Folio.HomeScreenState.pageCellHeight);
0110             }
0111             return Math.min(root.height * 0.9, perRow * Folio.HomeScreenState.pageCellHeight + margin * 2);
0112         }
0113 
0114         onWidthChanged: {
0115             Folio.HomeScreenState.folderPageWidth = width;
0116             root.updateContentHeight();
0117             root.updateContentHeight();
0118         }
0119         onHeightChanged: {
0120             Folio.HomeScreenState.folderPageHeight = height;
0121             root.updateContentWidth();
0122             root.updateContentHeight();
0123         }
0124 
0125         x: {
0126             const folderPos = root.folderPositionX;
0127             const centerX = (root.width / 2) - (width / 2);
0128             return Math.round(folderPos + (centerX - folderPos) * Folio.HomeScreenState.folderOpenProgress);
0129         }
0130         y: {
0131             const folderPos = root.folderPositionY;
0132             const centerY = (root.height / 2) - (height / 2);
0133             return Math.round(folderPos + (centerY - folderPos) * Folio.HomeScreenState.folderOpenProgress);
0134         }
0135 
0136         transform: [
0137             Scale {
0138                 origin.x: 0
0139                 origin.y: 0
0140 
0141                 xScale: {
0142                     const iconSize = Folio.FolioSettings.delegateIconSize;
0143                     const fullWidth = folderBackground.width;
0144                     const candidate = iconSize + (fullWidth - iconSize) * Folio.HomeScreenState.folderOpenProgress;
0145                     return Math.max(0, Math.min(1, candidate / fullWidth));
0146                 }
0147                 yScale: {
0148                     const iconSize = Folio.FolioSettings.delegateIconSize;
0149                     const fullHeight = folderBackground.height;
0150                     const candidate = iconSize + (fullHeight - iconSize) * Folio.HomeScreenState.folderOpenProgress;
0151                     return Math.max(0, Math.min(1, candidate / fullHeight));
0152                 }
0153             }
0154         ]
0155 
0156         MouseArea {
0157             id: captureTouches
0158             anchors.fill: parent
0159 
0160             // clip the pages
0161             layer.enabled: true
0162 
0163             Item {
0164                 id: contentContainer
0165                 x: Folio.HomeScreenState.folderViewX
0166 
0167                 Repeater {
0168                     model: root.folder ? root.folder.applications : []
0169 
0170                     delegate: Item {
0171                         id: delegate
0172 
0173                         property var delegateModel: model.delegate
0174                         property int index: model.index
0175 
0176                         property var dragState: Folio.HomeScreenState.dragState
0177                         property bool isDropPositionThis: dragState.candidateDropPosition.location === Folio.DelegateDragPosition.Folder &&
0178                                                           dragState.candidateDropPosition.folderPosition === index
0179 
0180                         x: model.xPosition
0181                         y: model.yPosition
0182 
0183                         Behavior on x {
0184                             NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
0185                         }
0186                         Behavior on y {
0187                             NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
0188                         }
0189 
0190                         implicitWidth: Folio.HomeScreenState.pageCellWidth
0191                         implicitHeight: Folio.HomeScreenState.pageCellHeight
0192                         width: Folio.HomeScreenState.pageCellWidth
0193                         height: Folio.HomeScreenState.pageCellHeight
0194 
0195                         Loader {
0196                             id: delegateLoader
0197                             anchors.fill: parent
0198 
0199                             sourceComponent: {
0200                                 if (delegate.delegateModel.type === Folio.FolioDelegate.Application) {
0201                                     return appComponent;
0202                                 } else {
0203                                     return noneComponent;
0204                                 }
0205                             }
0206                         }
0207 
0208                         Component {
0209                             id: noneComponent
0210 
0211                             Item {}
0212                         }
0213 
0214                         Component {
0215                             id: appComponent
0216 
0217                             AppDelegate {
0218                                 id: appDelegate
0219                                 application: delegate.delegateModel.application
0220 
0221                                 // do not show if the drop animation is running to this delegate
0222                                 visible: !(root.homeScreen.dropAnimationRunning && delegate.isDropPositionThis)
0223 
0224                                 // don't show label in drag and drop mode
0225                                 labelOpacity: delegate.opacity
0226 
0227                                 onPressAndHold: {
0228                                     let mappedCoords = root.homeScreen.prepareStartDelegateDrag(delegate.delegateModel, appDelegate.delegateItem);
0229                                     Folio.HomeScreenState.startDelegateFolderDrag(
0230                                         mappedCoords.x,
0231                                         mappedCoords.y,
0232                                         appDelegate.pressPosition.x,
0233                                         appDelegate.pressPosition.y,
0234                                         root.folder,
0235                                         delegate.index
0236                                     );
0237 
0238                                     contextMenu.open();
0239                                 }
0240 
0241                                 onPressAndHoldReleased: {
0242                                     // cancel the event if the delegate is not dragged
0243                                     if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.AwaitingDraggingDelegate) {
0244                                         homeScreen.cancelDelegateDrag();
0245                                     }
0246                                 }
0247 
0248                                 onRightMousePress: {
0249                                     contextMenu.open();
0250                                 }
0251 
0252                                 ContextMenuLoader {
0253                                     id: contextMenu
0254 
0255                                     // close menu when drag starts
0256                                     Connections {
0257                                         target: Folio.HomeScreenState
0258 
0259                                         function onSwipeStateChanged() {
0260                                             if (Folio.HomeScreenState.swipeState === Folio.HomeScreenState.DraggingDelegate) {
0261                                                 contextMenu.close();
0262                                             }
0263                                         }
0264                                     }
0265 
0266                                     actions: [
0267                                         Kirigami.Action {
0268                                             icon.name: "emblem-favorite"
0269                                             text: i18n("Remove")
0270                                             onTriggered: root.folder.removeApp(delegate.index)
0271                                         }
0272                                     ]
0273                                 }
0274                             }
0275                         }
0276                     }
0277                 }
0278             }
0279         }
0280     }
0281 
0282     QQC2.PageIndicator {
0283         visible: count > 1
0284         Kirigami.Theme.inherit: false
0285         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0286 
0287         // have to use y instead of anchors to avoid animations
0288         y: Math.round((root.height / 2) + (folderBackground.height / 2) + Kirigami.Units.largeSpacing)
0289         anchors.horizontalCenter: parent.horizontalCenter
0290 
0291         currentIndex: Folio.HomeScreenState.currentFolderPage
0292         count: Folio.HomeScreenState.currentFolder ? Folio.HomeScreenState.currentFolder.applications.numberOfPages : 0
0293 
0294         opacity: (root.opacity === 1) ? 1 : 0
0295         Behavior on opacity {
0296             NumberAnimation { duration: Kirigami.Units.shortDuration }
0297         }
0298     }
0299 }