diff --git a/applets/kicker/package/contents/ui/DashboardRepresentation.qml b/applets/kicker/package/contents/ui/DashboardRepresentation.qml --- a/applets/kicker/package/contents/ui/DashboardRepresentation.qml +++ b/applets/kicker/package/contents/ui/DashboardRepresentation.qml @@ -111,6 +111,8 @@ } mainItem: MouseArea { + id: rootItem + anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton diff --git a/applets/kicker/package/contents/ui/ItemGridDelegate.qml b/applets/kicker/package/contents/ui/ItemGridDelegate.qml --- a/applets/kicker/package/contents/ui/ItemGridDelegate.qml +++ b/applets/kicker/package/contents/ui/ItemGridDelegate.qml @@ -24,85 +24,40 @@ import "../code/tools.js" as Tools -MouseArea { +Item { id: item width: GridView.view.cellWidth height: width - signal actionTriggered(string actionId, variant actionArgument) - signal aboutToShowActionMenu(variant actionMenu) - property bool showLabel: true property int itemIndex: model.index property string favoriteId: model.favoriteId != undefined ? model.favoriteId : "" property url url: model.url != undefined ? model.url : "" property variant icon: model.decoration != undefined ? model.decoration : "" property var m: model - property bool pressed: false property bool hasActionList: ((model.favoriteId != null) || (("hasActionList" in model) && (model.hasActionList == true))) - property Item view: GridView.view - property Item menu: actionMenu Accessible.role: Accessible.MenuItem Accessible.name: model.display - acceptedButtons: root.visible ? (Qt.LeftButton | Qt.RightButton) : Qt.NoButton - - onPressed: { - if (mouse.buttons & Qt.RightButton) { - if (hasActionList) { - openActionMenu(item, mouse.x, mouse.y); - } - } else { - pressed = true; - } - } - - onReleased: { - if (pressed && GridView.view.currentItem == item) { - hoverArea.hoverEnabled = false; - - if ("trigger" in GridView.view.model) { - GridView.view.model.trigger(index, "", null); - root.toggle(); - } - - itemGrid.itemActivated(index, "", null); - } - - pressed = false; - } - - onAboutToShowActionMenu: { + function openActionMenu(x, y) { var actionList = hasActionList ? model.actionList : []; Tools.fillActionMenu(actionMenu, actionList, GridView.view.model.favoritesModel, model.favoriteId); + actionMenu.visualParent = item; + actionMenu.open(x, y); } - onActionTriggered: { + function actionTriggered() { var close = Tools.triggerAction(GridView.view.model, model.index, actionId, actionArgument); if (close) { root.toggle(); } } - function openActionMenu(visualParent, x, y) { - aboutToShowActionMenu(actionMenu); - actionMenu.visualParent = visualParent; - actionMenu.open(x, y); - } - - ActionMenu { - id: actionMenu - - onActionClicked: { - actionTriggered(actionId, actionArgument); - } - } - PlasmaCore.IconItem { id: icon @@ -117,7 +72,7 @@ colorGroup: PlasmaCore.Theme.ComplementaryColorGroup animated: false - usesPlasmaTheme: view.usesPlasmaTheme + usesPlasmaTheme: GridView.view.usesPlasmaTheme source: model.decoration } diff --git a/applets/kicker/package/contents/ui/ItemGridView.qml b/applets/kicker/package/contents/ui/ItemGridView.qml --- a/applets/kicker/package/contents/ui/ItemGridView.qml +++ b/applets/kicker/package/contents/ui/ItemGridView.qml @@ -40,9 +40,6 @@ property bool showLabels: true property alias usesPlasmaTheme: gridView.usesPlasmaTheme - property int pressX: -1 - property int pressY: -1 - property alias currentIndex: gridView.currentIndex property alias currentItem: gridView.currentItem property alias contentItem: gridView.contentItem @@ -107,6 +104,14 @@ gridView.forceLayout(); } + ActionMenu { + id: actionMenu + + onActionClicked: { + visualParent.actionTriggered(actionId, actionArgument); + } + } + DropArea { id: dropArea @@ -166,248 +171,280 @@ } } - MouseEventListener { - id: hoverArea - - anchors.fill: parent + Timer { + id: resetAnimationDurationTimer - hoverEnabled: true + interval: 120 + repeat: false - onPressed: { - pressX = mouse.x; - pressY = mouse.y; + onTriggered: { + gridView.animationDuration = interval - 20; } + } - onReleased: { - pressX = -1; - pressY = -1; - } + PlasmaExtras.ScrollArea { + id: scrollArea - onClicked: { - var cPos = mapToItem(gridView.contentItem, mouse.x, mouse.y); - var item = gridView.itemAt(cPos.x, cPos.y); + anchors.fill: parent - if (!item) { - root.toggle(); - } - } + focus: true - onPositionChanged: { - var cPos = mapToItem(gridView.contentItem, mouse.x, mouse.y); - var item = gridView.itemAt(cPos.x, cPos.y); + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - if (!item) { - gridView.currentIndex = -1; - } else { - gridView.currentIndex = item.itemIndex; - itemGrid.focus = (currentIndex != -1) + GridView { + id: gridView - if (dragEnabled && pressX != -1 && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) { - if ("pluginName" in item.m) { - dragHelper.startDrag(kicker, item.url, item.icon, - "text/x-plasmoidservicename", item.m.pluginName); - } else { - dragHelper.startDrag(kicker, item.url, item.icon); - } + property bool usesPlasmaTheme: false - kicker.dragSource = item; + property int iconSize: units.iconSizes.huge - pressX = -1; - pressY = -1; - } - } - } + property bool animating: false + property int animationDuration: dropEnabled ? resetAnimationDurationTimer.interval : 0 - onContainsMouseChanged: { - if (!containsMouse) { - gridView.currentIndex = -1; - pressX = -1; - pressY = -1; - } - } + focus: true - Connections { - target: root + currentIndex: -1 - onVisibleChanged: { - if (root.visible) { - hoverArea.hoverEnabled = true; - } - } - } + move: Transition { + enabled: itemGrid.dropEnabled - Timer { - id: resetAnimationDurationTimer + SequentialAnimation { + PropertyAction { target: gridView; property: "animating"; value: true } - interval: 120 - repeat: false + NumberAnimation { + duration: gridView.animationDuration + properties: "x, y" + easing.type: Easing.OutQuad + } - onTriggered: { - gridView.animationDuration = interval - 20; + PropertyAction { target: gridView; property: "animating"; value: false } + } } - } - PlasmaExtras.ScrollArea { - id: scrollArea + moveDisplaced: Transition { + enabled: itemGrid.dropEnabled - anchors.fill: parent + SequentialAnimation { + PropertyAction { target: gridView; property: "animating"; value: true } - focus: true + NumberAnimation { + duration: gridView.animationDuration + properties: "x, y" + easing.type: Easing.OutQuad + } - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + PropertyAction { target: gridView; property: "animating"; value: false } + } + } - GridView { - id: gridView + keyNavigationWraps: false + boundsBehavior: Flickable.StopAtBounds - property bool usesPlasmaTheme: false + delegate: ItemGridDelegate { + showLabel: showLabels + } + + highlight: Item { + property bool isDropPlaceHolder: "dropPlaceholderIndex" in model && currentIndex == model.dropPlaceholderIndex - property int iconSize: units.iconSizes.huge + PlasmaComponents.Highlight { + visible: gridView.currentItem && !isDropPlaceHolder - property bool animating: false - property int animationDuration: dropEnabled ? resetAnimationDurationTimer.interval : 0 + anchors.fill: parent + } - focus: true + PlasmaCore.FrameSvgItem { + visible: gridView.currentItem && isDropPlaceHolder - currentIndex: -1 + anchors.fill: parent - move: Transition { - enabled: itemGrid.dropEnabled + imagePath: "widgets/viewitem" + prefix: "selected" - SequentialAnimation { - PropertyAction { target: gridView; property: "animating"; value: true } + opacity: 0.5 - NumberAnimation { - duration: gridView.animationDuration - properties: "x, y" - easing.type: Easing.OutQuad + PlasmaCore.IconItem { + anchors { + right: parent.right + rightMargin: parent.margins.right + bottom: parent.bottom + bottomMargin: parent.margins.bottom } - PropertyAction { target: gridView; property: "animating"; value: false } + width: units.iconSizes.smallMedium + height: width + + source: "list-add" + active: false } } + } - moveDisplaced: Transition { - enabled: itemGrid.dropEnabled + highlightFollowsCurrentItem: true + highlightMoveDuration: 0 - SequentialAnimation { - PropertyAction { target: gridView; property: "animating"; value: true } + onCurrentIndexChanged: { + if (currentIndex != -1) { + focus = true; + } + } - NumberAnimation { - duration: gridView.animationDuration - properties: "x, y" - easing.type: Easing.OutQuad - } + onCountChanged: { + animationDuration = 0; + resetAnimationDurationTimer.start(); + } - PropertyAction { target: gridView; property: "animating"; value: false } - } + onModelChanged: { + currentIndex = -1; + } + + Keys.onLeftPressed: { + if (currentCol() != 0) { + event.accepted = true; + moveCurrentIndexLeft(); + } else { + itemGrid.keyNavLeft(); } + } - keyNavigationWraps: false - boundsBehavior: Flickable.StopAtBounds + Keys.onRightPressed: { + var columns = Math.floor(width / cellWidth); - delegate: ItemGridDelegate { - showLabel: showLabels + if (currentCol() != columns - 1 && currentIndex != count -1) { + event.accepted = true; + moveCurrentIndexRight(); + } else { + itemGrid.keyNavRight(); } + } - highlight: Item { - property bool isDropPlaceHolder: "dropPlaceholderIndex" in model && currentIndex == model.dropPlaceholderIndex + Keys.onUpPressed: { + if (currentRow() != 0) { + event.accepted = true; + moveCurrentIndexUp(); + positionViewAtIndex(currentIndex, GridView.Contain); + } else { + itemGrid.keyNavUp(); + } + } - PlasmaComponents.Highlight { - visible: gridView.currentItem && !isDropPlaceHolder + Keys.onDownPressed: { + if (currentRow() < itemGrid.lastRow()) { + // Fix moveCurrentIndexDown()'s lack of proper spatial nav down + // into partial columns. + event.accepted = true; + var columns = Math.floor(width / cellWidth); + var newIndex = currentIndex + columns; + currentIndex = Math.min(newIndex, count - 1); + positionViewAtIndex(currentIndex, GridView.Contain); + } else { + itemGrid.keyNavDown(); + } + } + } + } - anchors.fill: parent - } + MouseArea { + id: hoverArea - PlasmaCore.FrameSvgItem { - visible: gridView.currentItem && isDropPlaceHolder + anchors.fill: parent - anchors.fill: parent + property int pressX: -1 + property int pressY: -1 + property int lastX: -1 + property int lastY: -1 + property Item pressedItem: null - imagePath: "widgets/viewitem" - prefix: "selected" + acceptedButtons: Qt.LeftButton | Qt.RightButton - opacity: 0.5 + hoverEnabled: true - PlasmaCore.IconItem { - anchors { - right: parent.right - rightMargin: parent.margins.right - bottom: parent.bottom - bottomMargin: parent.margins.bottom - } + onPressed: { + pressX = mouse.x; + pressY = mouse.y; - width: units.iconSizes.smallMedium - height: width + mouse.accepted = true; - source: "list-add" - active: false - } + if (mouse.button == Qt.RightButton) { + if (gridView.currentItem) { + if (gridView.currentItem.hasActionList) { + var mapped = mapToItem(gridView.currentItem, mouse.x, mouse.y); + gridView.currentItem.openActionMenu(mapped.x, mapped.y); } + } else { + var mapped = mapToItem(rootItem, mouse.x, mouse.y); + contextMenu.open(mapped.x, mapped.y); } + } else { + pressedItem = gridView.currentItem; + } + } - highlightFollowsCurrentItem: true - highlightMoveDuration: 0 + onReleased: { + mouse.accepted = true; - onCurrentIndexChanged: { - if (currentIndex != -1) { - focus = true; - } + if (gridView.currentItem && gridView.currentItem == pressedItem) { + if ("trigger" in gridView.model) { + gridView.model.trigger(pressedItem.itemIndex, "", null); + root.toggle(); } - onCountChanged: { - animationDuration = 0; - resetAnimationDurationTimer.start(); - } + itemGrid.itemActivated(pressedItem.itemIndex, "", null); + } else if (!pressedItem && mouse.button == Qt.LeftButton) { + root.toggle(); + } - onModelChanged: { - currentIndex = -1; - } + pressX = -1; + pressY = -1; + pressedItem = null; + } - Keys.onLeftPressed: { - if (currentCol() != 0) { - event.accepted = true; - moveCurrentIndexLeft(); - } else { - itemGrid.keyNavLeft(); - } - } + onPositionChanged: { + // Prevent hover event synthesis in QQuickWindow interfering + // with keyboard navigation by ignoring repeated events with + // identical coordinates. As the work done here would be re- + // dundant in any case, these are safe to ignore. + if (mouse.x == lastX && mouse.y == lastY) { + return; + } - Keys.onRightPressed: { - var columns = Math.floor(width / cellWidth); + lastX = mouse.x; + lastY = mouse.y; - if (currentCol() != columns - 1 && currentIndex != count -1) { - event.accepted = true; - moveCurrentIndexRight(); - } else { - itemGrid.keyNavRight(); - } - } + var cPos = mapToItem(gridView.contentItem, mouse.x, mouse.y); + var item = gridView.itemAt(cPos.x, cPos.y); - Keys.onUpPressed: { - if (currentRow() != 0) { - event.accepted = true; - moveCurrentIndexUp(); - positionViewAtIndex(currentIndex, GridView.Contain); - } else { - itemGrid.keyNavUp(); - } - } + if (!item) { + gridView.currentIndex = -1; + pressedItem = null; + } else { + gridView.currentIndex = item.itemIndex; + itemGrid.focus = (currentIndex != -1) - Keys.onDownPressed: { - if (currentRow() < itemGrid.lastRow()) { - // Fix moveCurrentIndexDown()'s lack of proper spatial nav down - // into partial columns. - event.accepted = true; - var columns = Math.floor(width / cellWidth); - var newIndex = currentIndex + columns; - currentIndex = Math.min(newIndex, count - 1); - positionViewAtIndex(currentIndex, GridView.Contain); + if (dragEnabled && pressX != -1 && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) { + if ("pluginName" in item.m) { + dragHelper.startDrag(kicker, item.url, item.icon, + "text/x-plasmoidservicename", item.m.pluginName); } else { - itemGrid.keyNavDown(); + dragHelper.startDrag(kicker, item.url, item.icon); } + + kicker.dragSource = item; + + pressX = -1; + pressY = -1; } } } + + onContainsMouseChanged: { + if (!containsMouse) { + gridView.currentIndex = -1; + pressX = -1; + pressY = -1; + pressedItem = null; + } + } } } }