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 }