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 }