Warning, /plasma/plasma-desktop/applets/kicker/package/contents/ui/ItemMultiGridView.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2015 Eike Hein <hein@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 import QtQuick 2.15
0008 
0009 import org.kde.ksvg 1.0 as KSvg
0010 import org.kde.plasma.components as PlasmaComponents
0011 import org.kde.plasma.extras 2.0 as PlasmaExtras
0012 import org.kde.kirigami 2.20 as Kirigami
0013 import org.kde.plasma.private.kicker 0.1 as Kicker
0014 
0015 PlasmaComponents.ScrollView {
0016     id: itemMultiGrid
0017 
0018     anchors {
0019         top: parent.top
0020     }
0021 
0022     width: parent.width
0023 
0024     implicitHeight: itemColumn.implicitHeight
0025 
0026     signal keyNavLeft(int subGridIndex)
0027     signal keyNavRight(int subGridIndex)
0028     signal keyNavUp()
0029     signal keyNavDown()
0030 
0031     property bool grabFocus: false
0032 
0033     property alias model: repeater.model
0034     property alias count: repeater.count
0035     property alias flickableItem: flickable
0036 
0037 
0038     onFocusChanged: {
0039         if (!focus) {
0040             for (var i = 0; i < repeater.count; i++) {
0041                 subGridAt(i).focus = false;
0042             }
0043         }
0044     }
0045 
0046     Flickable {
0047         id: flickable
0048 
0049         flickableDirection: Flickable.VerticalFlick
0050         contentHeight: itemColumn.implicitHeight
0051 
0052         function subGridAt(index) {
0053             return repeater.itemAt(index).itemGrid;
0054         }
0055 
0056         function tryActivate(row, col) { // FIXME TODO: Cleanup messy algo.
0057             if (contentY > 0) {
0058                 row = 0;
0059             }
0060 
0061             var target = null;
0062             var rows = 0;
0063 
0064             for (var i = 0; i < repeater.count; i++) {
0065                 var grid = subGridAt(i);
0066 
0067                 if (rows <= row) {
0068                     target = grid;
0069                     rows += grid.lastRow() + 2; // Header counts as one.
0070                 } else {
0071                     break;
0072                 }
0073             }
0074 
0075             if (target) {
0076                 rows -= (target.lastRow() + 2);
0077                 target.tryActivate(row - rows, col);
0078             }
0079         }
0080 
0081         Column {
0082             id: itemColumn
0083 
0084             width: itemMultiGrid.width - Kirigami.Units.gridUnit
0085 
0086             Repeater {
0087                 id: repeater
0088 
0089                 delegate: Item {
0090                     width: itemColumn.width - Kirigami.Units.gridUnit
0091                     height: headerHeight + gridView.height + (index == repeater.count - 1 ? 0 : footerHeight)
0092 
0093                     property int headerHeight: (gridViewLabel.height
0094                         + gridViewLabelUnderline.height + Kirigami.Units.gridUnit)
0095                     property int footerHeight: (Math.ceil(headerHeight / cellSize) * cellSize) - headerHeight
0096 
0097                     property Item itemGrid: gridView
0098 
0099                     Kirigami.Heading {
0100                         id: gridViewLabel
0101 
0102                         anchors.top: parent.top
0103 
0104                         x: Kirigami.Units.smallSpacing
0105                         width: parent.width - x
0106                         height: dummyHeading.height
0107 
0108                         elide: Text.ElideRight
0109                         wrapMode: Text.NoWrap
0110                         opacity: 1.0
0111 
0112                         color: "white" // FIXME TODO: Respect theming?
0113 
0114                         level: 1
0115 
0116                         text: repeater.model.modelForRow(index).description
0117                         textFormat: Text.PlainText
0118                     }
0119 
0120                     KSvg.SvgItem {
0121                         id: gridViewLabelUnderline
0122 
0123                         anchors.top: gridViewLabel.bottom
0124 
0125                         width: parent.width - Kirigami.Units.gridUnit
0126                         height: lineSvg.horLineHeight
0127 
0128                         svg: lineSvg
0129                         elementId: "horizontal-line"
0130                     }
0131 
0132                     MouseArea {
0133                         width: parent.width
0134                         height: parent.height
0135 
0136                         onClicked: root.toggle()
0137                     }
0138 
0139                     ItemGridView {
0140                         id: gridView
0141 
0142                         anchors {
0143                             top: gridViewLabelUnderline.bottom
0144                             topMargin: Kirigami.Units.gridUnit
0145                         }
0146 
0147                         width: parent.width
0148                         height: Math.ceil(count / Math.floor(width / cellSize)) * cellSize
0149 
0150                         cellWidth: cellSize
0151                         cellHeight: cellSize
0152                         iconSize: root.iconSize
0153 
0154                         verticalScrollBarPolicy: PlasmaComponents.ScrollBar.AlwaysOff
0155 
0156                         model: repeater.model.modelForRow(index)
0157 
0158                         onFocusChanged: {
0159                             if (focus) {
0160                                 flickable.focus = true;
0161                             }
0162                         }
0163 
0164                         onCountChanged: {
0165                             if (flickable.grabFocus && index == 0 && count > 0) {
0166                                 currentIndex = 0;
0167                                 focus = true;
0168                             }
0169                         }
0170 
0171                         onCurrentItemChanged: {
0172                             if (!currentItem) {
0173                                 return;
0174                             }
0175 
0176                             if (index == 0 && currentRow() === 0) {
0177                                 flickable.contentY = 0;
0178                                 return;
0179                             }
0180 
0181                             var y = currentItem.y;
0182                             y = contentItem.mapToItem(flickable.contentItem, 0, y).y;
0183 
0184                             if (y < flickable.contentY) {
0185                                 flickable.contentY = y;
0186                             } else {
0187                                 y += cellSize;
0188                                 y -= flickable.contentY;
0189                                 y -= itemMultiGrid.height;
0190 
0191                                 if (y > 0) {
0192                                     flickable.contentY += y;
0193                                 }
0194                             }
0195                         }
0196 
0197                         onKeyNavLeft: {
0198                             flickable.keyNavLeft(index);
0199                         }
0200 
0201                         onKeyNavRight: {
0202                             flickable.keyNavRight(index);
0203                         }
0204 
0205                         onKeyNavUp: {
0206                             if (index > 0) {
0207                                 var prevGrid = subGridAt(index - 1);
0208                                 prevGrid.tryActivate(prevGrid.lastRow(), currentCol());
0209                             } else {
0210                                 flickable.keyNavUp();
0211                             }
0212                         }
0213 
0214                         onKeyNavDown: {
0215                             if (index < repeater.count - 1) {
0216                                 subGridAt(index + 1).tryActivate(0, currentCol());
0217                             } else {
0218                                 flickable.keyNavDown();
0219                             }
0220                         }
0221                     }
0222 
0223                     // HACK: Steal wheel events from the nested grid view and forward them to
0224                     // the ScrollView's internal WheelArea.
0225                     Kicker.WheelInterceptor {
0226                         anchors.fill: gridView
0227                         z: 1
0228 
0229                         destination: findWheelArea(flickable)
0230                     }
0231                 }
0232             }
0233         }
0234     }
0235 }