Warning, /plasma/plasma-simplemenu/package/contents/ui/ItemGridView.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.4
0008
0009 import org.kde.plasma.components 2.0 as PlasmaComponents
0010 import org.kde.plasma.extras 2.0 as PlasmaExtras
0011 import org.kde.kquickcontrolsaddons 2.0
0012 import org.kde.draganddrop 2.0
0013
0014 FocusScope {
0015 id: itemGrid
0016
0017 signal keyNavLeft
0018 signal keyNavRight
0019 signal keyNavUp
0020 signal keyNavDown
0021
0022 property bool dragEnabled: false
0023 property bool showLabels: true
0024 property alias usesPlasmaTheme: gridView.usesPlasmaTheme
0025
0026 property int iconSize: root.iconSize
0027
0028 property alias currentIndex: gridView.currentIndex
0029 property alias currentItem: gridView.currentItem
0030 property alias contentItem: gridView.contentItem
0031 property alias count: gridView.count
0032 property alias flow: gridView.flow
0033 property alias snapMode: gridView.snapMode
0034 property alias model: gridView.model
0035
0036 property alias cellWidth: gridView.cellWidth
0037 property alias cellHeight: gridView.cellHeight
0038
0039 property alias horizontalScrollBarPolicy: scrollArea.horizontalScrollBarPolicy
0040 property alias verticalScrollBarPolicy: scrollArea.verticalScrollBarPolicy
0041
0042 implicitWidth: gridView.contentWidth
0043 implicitHeight: gridView.contentHeight
0044
0045 onFocusChanged: {
0046 if (!focus) {
0047 currentIndex = -1;
0048 }
0049 }
0050
0051 function currentRow() {
0052 if (currentIndex == -1) {
0053 return -1;
0054 }
0055
0056 return Math.floor(currentIndex / Math.floor(width / cellWidth));
0057 }
0058
0059 function currentCol() {
0060 if (currentIndex == -1) {
0061 return -1;
0062 }
0063
0064 return currentIndex - (currentRow() * Math.floor(width / cellWidth));
0065 }
0066
0067 function lastRow() {
0068 var columns = Math.floor(width / cellWidth);
0069 return Math.ceil(count / columns) - 1;
0070 }
0071
0072 function tryActivate(row, col) {
0073 if (count) {
0074 var columns = Math.floor(width / cellWidth);
0075 var rows = Math.ceil(count / columns);
0076 row = Math.min(row, rows - 1);
0077 col = Math.min(col, columns - 1);
0078 currentIndex = Math.min(row ? ((Math.max(1, row) * columns) + col)
0079 : col,
0080 count - 1);
0081
0082 gridView.forceActiveFocus();
0083 }
0084 }
0085
0086 function forceLayout() {
0087 gridView.forceLayout();
0088 }
0089
0090 ActionMenu {
0091 id: actionMenu
0092
0093 onActionClicked: {
0094 visualParent.actionTriggered(actionId, actionArgument);
0095 }
0096 }
0097
0098 DropArea {
0099 id: dropArea
0100
0101 anchors.fill: parent
0102
0103 onDragMove: {
0104 if (!dragEnabled || gridView.animating) {
0105 return;
0106 }
0107
0108 var cPos = mapToItem(gridView.contentItem, event.x, event.y);
0109 var item = gridView.itemAt(cPos.x, cPos.y);
0110
0111 if (item && item != kicker.dragSource && kicker.dragSource && kicker.dragSource.parent == gridView.contentItem) {
0112 item.GridView.view.model.moveRow(dragSource.itemIndex, item.itemIndex);
0113 }
0114
0115 }
0116
0117 Timer {
0118 id: resetAnimationDurationTimer
0119
0120 interval: 80
0121 repeat: false
0122
0123 onTriggered: {
0124 gridView.animationDuration = interval - 20;
0125 }
0126 }
0127
0128 PlasmaExtras.ScrollArea {
0129 id: scrollArea
0130
0131 anchors.fill: parent
0132
0133 focus: true
0134
0135 horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
0136
0137 GridView {
0138 id: gridView
0139
0140 property bool usesPlasmaTheme: false
0141
0142 property bool animating: false
0143 property int animationDuration: dragEnabled ? resetAnimationDurationTimer.interval : 0
0144
0145 focus: true
0146
0147 currentIndex: -1
0148
0149 move: Transition {
0150 enabled: itemGrid.dragEnabled
0151
0152 SequentialAnimation {
0153 PropertyAction { target: gridView; property: "animating"; value: true }
0154
0155 NumberAnimation {
0156 duration: gridView.animationDuration
0157 properties: "x, y"
0158 easing.type: Easing.OutQuad
0159 }
0160
0161 PropertyAction { target: gridView; property: "animating"; value: false }
0162 }
0163 }
0164
0165 moveDisplaced: Transition {
0166 enabled: itemGrid.dragEnabled
0167
0168 SequentialAnimation {
0169 PropertyAction { target: gridView; property: "animating"; value: true }
0170
0171 NumberAnimation {
0172 duration: gridView.animationDuration
0173 properties: "x, y"
0174 easing.type: Easing.OutQuad
0175 }
0176
0177 PropertyAction { target: gridView; property: "animating"; value: false }
0178 }
0179 }
0180
0181 keyNavigationWraps: false
0182 boundsBehavior: Flickable.StopAtBounds
0183
0184 delegate: ItemGridDelegate {
0185 showLabel: showLabels
0186 }
0187
0188 highlight: PlasmaComponents.Highlight {}
0189 highlightFollowsCurrentItem: true
0190 highlightMoveDuration: 0
0191
0192 onCountChanged: {
0193 animationDuration = 0;
0194 resetAnimationDurationTimer.start();
0195 }
0196
0197 onModelChanged: {
0198 currentIndex = -1;
0199 }
0200
0201 Keys.onLeftPressed: {
0202 if (currentIndex == -1) {
0203 currentIndex = 0;
0204 return;
0205 }
0206
0207 if (currentCol() != 0) {
0208 event.accepted = true;
0209 moveCurrentIndexLeft();
0210 } else {
0211 itemGrid.keyNavLeft();
0212 }
0213 }
0214
0215 Keys.onRightPressed: {
0216 if (currentIndex == -1) {
0217 currentIndex = 0;
0218 return;
0219 }
0220
0221 var columns = Math.floor(width / cellWidth);
0222
0223 if (currentCol() != columns - 1 && currentIndex != count - 1) {
0224 event.accepted = true;
0225 moveCurrentIndexRight();
0226 } else {
0227 itemGrid.keyNavRight();
0228 }
0229 }
0230
0231 Keys.onUpPressed: {
0232 if (currentIndex == -1) {
0233 currentIndex = 0;
0234 return;
0235 }
0236
0237 if (currentRow() != 0) {
0238 event.accepted = true;
0239 moveCurrentIndexUp();
0240 positionViewAtIndex(currentIndex, GridView.Contain);
0241 } else {
0242 itemGrid.keyNavUp();
0243 }
0244 }
0245
0246 Keys.onDownPressed: {
0247 if (currentIndex == -1) {
0248 currentIndex = 0;
0249 return;
0250 }
0251
0252 if (currentRow() < itemGrid.lastRow()) {
0253 // Fix moveCurrentIndexDown()'s lack of proper spatial nav down
0254 // into partial columns.
0255 event.accepted = true;
0256 var columns = Math.floor(width / cellWidth);
0257 var newIndex = currentIndex + columns;
0258 currentIndex = Math.min(newIndex, count - 1);
0259 positionViewAtIndex(currentIndex, GridView.Contain);
0260 } else {
0261 itemGrid.keyNavDown();
0262 }
0263 }
0264 }
0265 }
0266
0267 MouseArea {
0268 anchors.fill: parent
0269
0270 property int pressX: -1
0271 property int pressY: -1
0272 property int lastX: -1
0273 property int lastY: -1
0274 property Item pressedItem: null
0275
0276 acceptedButtons: Qt.LeftButton | Qt.RightButton
0277
0278 hoverEnabled: true
0279
0280 function updatePositionProperties(x, y) {
0281 // Prevent hover event synthesis in QQuickWindow interfering
0282 // with keyboard navigation by ignoring repeated events with
0283 // identical coordinates. As the work done here would be re-
0284 // dundant in any case, these are safe to ignore.
0285 if (lastX == x && lastY == y) {
0286 return;
0287 }
0288
0289 lastX = x;
0290 lastY = y;
0291
0292 var cPos = mapToItem(gridView.contentItem, x, y);
0293 var item = gridView.itemAt(cPos.x, cPos.y);
0294
0295 if (!item) {
0296 gridView.currentIndex = -1;
0297 pressedItem = null;
0298 } else {
0299 gridView.currentIndex = item.itemIndex;
0300 itemGrid.focus = (currentIndex != -1)
0301 }
0302
0303 return item;
0304 }
0305
0306 onPressed: {
0307 mouse.accepted = true;
0308
0309 updatePositionProperties(mouse.x, mouse.y);
0310 pressX = mouse.x;
0311 pressY = mouse.y;
0312
0313 if (mouse.button == Qt.RightButton) {
0314 if (gridView.currentItem) {
0315 if (gridView.currentItem.hasActionList) {
0316 var mapped = mapToItem(gridView.currentItem, mouse.x, mouse.y);
0317 gridView.currentItem.openActionMenu(mapped.x, mapped.y);
0318 }
0319 } else {
0320 var mapped = mapToItem(rootItem, mouse.x, mouse.y);
0321 contextMenu.open(mapped.x, mapped.y);
0322 }
0323 } else {
0324 pressedItem = gridView.currentItem;
0325 }
0326 }
0327
0328 onReleased: {
0329 mouse.accepted = true;
0330
0331 if (gridView.currentItem && gridView.currentItem == pressedItem) {
0332 if ("trigger" in gridView.model) {
0333 gridView.model.trigger(pressedItem.itemIndex, "", null);
0334
0335 if ("toggle" in root) {
0336 root.toggle();
0337 } else {
0338 root.visible = false;
0339 }
0340 }
0341 } else if (!pressedItem && mouse.button == Qt.LeftButton) {
0342 if ("toggle" in root) {
0343 root.toggle();
0344 } else {
0345 root.visible = false;
0346 }
0347 }
0348
0349 pressX = -1;
0350 pressY = -1;
0351 pressedItem = null;
0352 }
0353
0354 onPressAndHold: {
0355 if (!dragEnabled) {
0356 pressX = -1;
0357 pressY = -1;
0358 return;
0359 }
0360
0361 var cPos = mapToItem(gridView.contentItem, mouse.x, mouse.y);
0362 var item = gridView.itemAt(cPos.x, cPos.y);
0363
0364 if (!item) {
0365 return;
0366 }
0367
0368 if (!dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) {
0369 kicker.dragSource = item;
0370 dragHelper.startDrag(kicker, item.url);
0371 }
0372
0373 pressX = -1;
0374 pressY = -1;
0375 pressedItem = null;
0376 }
0377
0378 onPositionChanged: {
0379 var item = updatePositionProperties(mouse.x, mouse.y);
0380
0381 if (gridView.currentIndex != -1) {
0382 if (dragEnabled && pressX != -1 && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) {
0383 if ("pluginName" in item.m) {
0384 dragHelper.startDrag(kicker, item.url, item.icon,
0385 "text/x-plasmoidservicename", item.m.pluginName);
0386 } else {
0387 dragHelper.startDrag(kicker, item.url, item.icon);
0388 }
0389
0390 kicker.dragSource = item;
0391
0392 pressX = -1;
0393 pressY = -1;
0394 }
0395 }
0396 }
0397
0398 onContainsMouseChanged: {
0399 if (!containsMouse) {
0400 if (!actionMenu.opened) {
0401 gridView.currentIndex = -1;
0402 }
0403
0404 pressX = -1;
0405 pressY = -1;
0406 lastX = -1;
0407 lastY = -1;
0408 pressedItem = null;
0409 }
0410 }
0411 }
0412 }
0413 }