1/* 2 SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org> 3 SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de> 4 SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com> 5 6 SPDX-License-Identifier: LGPL-2.0-or-later 7*/ 8 9import QtQuick 2.4 10import QtQuick.Layouts 1.1 11 12import org.kde.plasma.components 2.0 as PlasmaComponents 13import org.kde.plasma.extras 2.0 as PlasmaExtras 14import org.kde.plasma.core 2.0 as PlasmaCore 15import org.kde.draganddrop 2.0 16 17Item { 18 id: delegate 19 20 readonly property string pluginName: model.pluginName 21 readonly property bool pendingUninstall: pendingUninstallTimer.applets.indexOf(pluginName) > -1 22 23 width: list.cellWidth 24 height: list.cellHeight 25 26 DragArea { 27 anchors.fill: parent 28 supportedActions: Qt.MoveAction | Qt.LinkAction 29 //onDragStarted: tooltipDialog.visible = false 30 delegateImage: decoration 31 enabled: !delegate.pendingUninstall 32 mimeData { 33 source: parent 34 } 35 Component.onCompleted: mimeData.setData("text/x-plasmoidservicename", pluginName) 36 37 onDragStarted: { 38 kwindowsystem.showingDesktop = true; 39 main.draggingWidget = true; 40 } 41 onDrop: { 42 main.draggingWidget = false; 43 } 44 45 MouseArea { 46 id: mouseArea 47 anchors.fill: parent 48 hoverEnabled: true 49 onDoubleClicked: { 50 if (!delegate.pendingUninstall) { 51 widgetExplorer.addApplet(pluginName) 52 } 53 } 54 onEntered: delegate.GridView.view.currentIndex = index 55 onExited: delegate.GridView.view.currentIndex = - 1 56 } 57 58 ColumnLayout { 59 id: mainLayout 60 spacing: units.smallSpacing 61 anchors { 62 left: parent.left 63 right: parent.right 64 //bottom: parent.bottom 65 margins: units.smallSpacing * 2 66 rightMargin: units.smallSpacing * 2 // don't cram the text to the border too much 67 top: parent.top 68 } 69 70 Item { 71 id: iconContainer 72 width: units.iconSizes.enormous 73 height: width 74 Layout.alignment: Qt.AlignHCenter 75 opacity: delegate.pendingUninstall ? 0.6 : 1 76 Behavior on opacity { 77 OpacityAnimator { 78 duration: units.longDuration 79 easing.type: Easing.InOutQuad 80 } 81 } 82 83 Item { 84 id: iconWidget 85 anchors.fill: parent 86 PlasmaCore.IconItem { 87 anchors.fill: parent 88 source: model.decoration 89 visible: model.screenshot === "" 90 } 91 Image { 92 width: units.iconSizes.enormous 93 height: width 94 anchors.fill: parent 95 fillMode: Image.PreserveAspectFit 96 source: model.screenshot 97 } 98 } 99 100 Item { 101 id: badgeMask 102 anchors.fill: parent 103 104 Rectangle { 105 x: Math.round(-units.smallSpacing * 1.5 / 2) 106 y: x 107 width: runningBadge.width + Math.round(units.smallSpacing * 1.5) 108 height: width 109 radius: height 110 visible: running && delegate.GridView.isCurrentItem 111 } 112 } 113 114 Rectangle { 115 id: runningBadge 116 width: height 117 height: Math.round(theme.mSize(countLabel.font).height * 1.3) 118 radius: height 119 color: theme.highlightColor 120 visible: running && delegate.GridView.isCurrentItem 121 onVisibleChanged: maskShaderSource.scheduleUpdate() 122 123 PlasmaComponents.Label { 124 id: countLabel 125 anchors.fill: parent 126 horizontalAlignment: Text.AlignHCenter 127 verticalAlignment: Text.AlignVCenter 128 text: running 129 } 130 } 131 132 ShaderEffect { 133 anchors.fill: parent 134 property var source: ShaderEffectSource { 135 sourceItem: iconWidget 136 hideSource: true 137 live: false 138 } 139 property var mask: ShaderEffectSource { 140 id: maskShaderSource 141 sourceItem: badgeMask 142 hideSource: true 143 live: false 144 } 145 146 supportsAtlasTextures: true 147 148 fragmentShader: " 149 varying highp vec2 qt_TexCoord0; 150 uniform highp float qt_Opacity; 151 uniform lowp sampler2D source; 152 uniform lowp sampler2D mask; 153 void main() { 154 gl_FragColor = texture2D(source, qt_TexCoord0.st) * (1.0 - (texture2D(mask, qt_TexCoord0.st).a)) * qt_Opacity; 155 } 156 " 157 } 158 159 PlasmaComponents.ToolButton { 160 id: uninstallButton 161 anchors { 162 top: parent.top 163 right: parent.right 164 } 165 iconSource: delegate.pendingUninstall ? "edit-undo" : "edit-delete" 166 // we don't really "undo" anything but we'll pretend to the user that we do 167 tooltip: delegate.pendingUninstall ? i18nd("plasma_shell_org.kde.plasma.desktop", "Undo uninstall") 168 : i18nd("plasma_shell_org.kde.plasma.desktop", "Uninstall widget") 169 flat: false 170 visible: model.local && delegate.GridView.isCurrentItem 171 172 onHoveredChanged: { 173 if (hovered) { 174 // hovering the uninstall button triggers onExited of the main mousearea 175 delegate.GridView.view.currentIndex = index 176 } 177 } 178 179 onClicked: { 180 var pending = pendingUninstallTimer.applets 181 if (delegate.pendingUninstall) { 182 var index = pending.indexOf(pluginName) 183 if (index > -1) { 184 pending.splice(index, 1) 185 } 186 } else { 187 pending.push(pluginName) 188 } 189 pendingUninstallTimer.applets = pending 190 191 if (pending.length) { 192 pendingUninstallTimer.restart() 193 } else { 194 pendingUninstallTimer.stop() 195 } 196 } 197 } 198 } 199 PlasmaExtras.Heading { 200 id: heading 201 Layout.fillWidth: true 202 level: 4 203 text: model.name 204 elide: Text.ElideRight 205 wrapMode: Text.WordWrap 206 maximumLineCount: 2 207 lineHeight: 0.95 208 horizontalAlignment: Text.AlignHCenter 209 } 210 PlasmaComponents.Label { 211 Layout.fillWidth: true 212 // otherwise causes binding loop due to the way the Plasma sets the height 213 height: implicitHeight 214 text: model.description 215 font: theme.smallestFont 216 wrapMode: Text.WordWrap 217 elide: Text.ElideRight 218 maximumLineCount: heading.lineCount === 1 ? 3 : 2 219 horizontalAlignment: Text.AlignHCenter 220 } 221 } 222 } 223} 224