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 }