Warning, /plasma/plasma-desktop/containments/panel/contents/ui/ConfigOverlay.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org> 0003 SPDX-FileCopyrightText: 2022 Niccolò Venerandi <niccolo@venerandi.com> 0004 SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 import QtQuick 2.5 0010 import QtQuick.Layouts 1.0 0011 import QtQuick.Window 0012 import org.kde.plasma.plasmoid 2.0 0013 import org.kde.plasma.core as PlasmaCore 0014 import org.kde.plasma.components 3.0 as PlasmaComponents3 0015 import org.kde.plasma.extras 2.0 as PlasmaExtras 0016 import org.kde.kquickcontrolsaddons 2.0 0017 import org.kde.kirigami 2.20 as Kirigami 0018 0019 MouseArea { 0020 id: configurationArea 0021 0022 z: 1000 0023 hoverEnabled: true 0024 0025 property Item currentApplet 0026 property real startDragOffset: 0.0 0027 0028 onPositionChanged: mouse => { 0029 if (pressed) { 0030 0031 // If the object has been dragged outside of the panel and there's 0032 // a different containment there, we remove it from the panel 0033 // containment and add it to the new one. 0034 var padding = Kirigami.Units.gridUnit * 5; 0035 if (currentApplet && (mouse.x < -padding || mouse.y < -padding || 0036 mouse.x > width + padding || mouse.y > height + padding)) { 0037 var newCont = root.containmentItemAt(mouse.x, mouse.y); 0038 0039 if (newCont && newCont !== plasmoid) { 0040 var newPos = newCont.mapFromApplet(currentApplet.applet.plasmoid, mouse.x, mouse.y); 0041 var applet = currentApplet.applet; 0042 appletsModel.remove(placeHolder.parent.index); 0043 currentApplet.destroy(); 0044 applet.anchors.fill = undefined 0045 newCont.plasmoid.addApplet(applet.plasmoid, Qt.rect(newPos.x, newPos.y, applet.width, applet.height)); 0046 return; 0047 } 0048 } 0049 if (Plasmoid.formFactor === PlasmaCore.Types.Vertical && currentApplet) { 0050 currentApplet.y = mouse.y - startDragOffset; 0051 } else { 0052 currentApplet.x = mouse.x - startDragOffset; 0053 } 0054 0055 const item = root.layoutManager.childAtCoordinates(mouse.x, mouse.y); 0056 0057 if (item && item.applet !== placeHolder) { 0058 var posInItem = mapToItem(item, mouse.x, mouse.y) 0059 var pos = root.isHorizontal ? posInItem.x : posInItem.y 0060 var size = root.isHorizontal ? item.width : item.height 0061 if (pos < size / 3) { 0062 root.layoutManager.move(placeHolder.parent, item.index) 0063 } else if (pos > size / 3 * 2) { 0064 root.layoutManager.move(placeHolder.parent, item.index+1) 0065 } 0066 } 0067 0068 } else { 0069 const item = currentLayout.childAt(mouse.x, mouse.y); 0070 if (item && item !== lastSpacer) { 0071 currentApplet = item; 0072 } 0073 } 0074 0075 if (currentApplet) { 0076 hideTimer.stop(); 0077 tooltip.raise(); 0078 } 0079 } 0080 0081 onEntered: hideTimer.stop(); 0082 0083 onExited: hideTimer.restart() 0084 0085 onCurrentAppletChanged: { 0086 if (!currentApplet) { 0087 hideTimer.start(); 0088 return; 0089 } 0090 } 0091 0092 onPressed: mouse => { 0093 // Need to set currentApplet here too, to make touch selection + drag 0094 // with with a touchscreen, because there are no entered events in that 0095 // case 0096 let item = currentLayout.childAt(mouse.x, mouse.y); 0097 // BUG 454095: Don't allow dragging lastSpacer as it's not a real applet 0098 if (!item || item == lastSpacer || item == addWidgetsButton) { 0099 configurationArea.currentApplet = null 0100 return; 0101 } 0102 tooltip.raise(); 0103 hideTimer.stop(); 0104 0105 // We set the current applet being dragged as a property of placeHolder 0106 // to be able to read its properties from the LayoutManager 0107 appletsModel.insert(item.index, {applet: placeHolder}); 0108 placeHolder.parent.inThickArea = item.inThickArea 0109 currentApplet = appletContainerComponent.createObject(dropArea, {applet: item.applet, x: item.x, 0110 y: item.y, z: 900, 0111 width: item.width, height: item.height, index: -1}) 0112 placeHolder.parent.dragging = currentApplet 0113 appletsModel.remove(item.index) 0114 root.dragAndDropping = true 0115 0116 if (Plasmoid.formFactor === PlasmaCore.Types.Vertical) { 0117 startDragOffset = mouse.y - currentApplet.y; 0118 } else { 0119 startDragOffset = mouse.x - currentApplet.x; 0120 } 0121 } 0122 0123 onReleased: mouse => finishDragOperation() 0124 0125 onCanceled: finishDragOperation() 0126 0127 function finishDragOperation() { 0128 root.dragAndDropping = false 0129 if (!currentApplet) { 0130 return; 0131 } 0132 appletsModel.set(placeHolder.parent.index, {applet: currentApplet.applet}) 0133 let newCurrentApplet = currentApplet.applet.parent 0134 newCurrentApplet.animateFrom(currentApplet.x, currentApplet.y) 0135 newCurrentApplet.dragging = null 0136 placeHolder.parent = this 0137 currentApplet.destroy() 0138 root.layoutManager.save() 0139 } 0140 0141 Item { 0142 id: placeHolder 0143 property Item dragging 0144 property bool busy: false 0145 visible: configurationArea.containsMouse 0146 Layout.preferredWidth: configurationArea.currentApplet?.Layout.preferredWidth ?? 0 0147 Layout.preferredHeight: configurationArea.currentApplet?.Layout.preferredHeight ?? 0 0148 Layout.maximumWidth: configurationArea.currentApplet?.Layout.maximumWidth ?? 0 0149 Layout.maximumHeight: configurationArea.currentApplet?.Layout.maximumHeight ?? 0 0150 Layout.minimumWidth: configurationArea.currentApplet?.Layout.minimumWidth ?? 0 0151 Layout.minimumHeight: configurationArea.currentApplet?.Layout.minimumHeight ?? 0 0152 Layout.fillWidth: configurationArea.currentApplet?.Layout.fillWidth ?? false 0153 Layout.fillHeight: configurationArea.currentApplet?.Layout.fillHeight ?? false 0154 } 0155 0156 Timer { 0157 id: hideTimer 0158 interval: Kirigami.Units.longDuration * 5 0159 onTriggered: configurationArea.currentApplet = null 0160 } 0161 0162 Rectangle { 0163 id: handle 0164 0165 x: configurationArea.currentApplet?.x ?? 0 0166 y: configurationArea.currentApplet?.y ?? 0 0167 width: configurationArea.currentApplet?.width ?? 0 0168 height: configurationArea.currentApplet?.height ?? 0 0169 0170 color: Kirigami.Theme.backgroundColor 0171 radius: 3 0172 opacity: configurationArea.currentApplet && configurationArea.containsMouse ? 0.5 : 0 0173 0174 Kirigami.Icon { 0175 visible: !root.dragAndDropping 0176 source: "transform-move" 0177 width: Math.min(parent.width, parent.height) 0178 height: width 0179 anchors.centerIn: parent 0180 } 0181 Behavior on x { 0182 enabled: !configurationArea.pressed 0183 NumberAnimation { 0184 duration: Kirigami.Units.longDuration 0185 easing.type: Easing.InOutQuad 0186 } 0187 } 0188 Behavior on y { 0189 enabled: !configurationArea.pressed 0190 NumberAnimation { 0191 duration: Kirigami.Units.longDuration 0192 easing.type: Easing.InOutQuad 0193 } 0194 } 0195 Behavior on width { 0196 enabled: !configurationArea.pressed 0197 NumberAnimation { 0198 duration: Kirigami.Units.longDuration 0199 easing.type: Easing.InOutQuad 0200 } 0201 } 0202 Behavior on height { 0203 enabled: !configurationArea.pressed 0204 NumberAnimation { 0205 duration: Kirigami.Units.longDuration 0206 easing.type: Easing.InOutQuad 0207 } 0208 } 0209 Behavior on opacity { 0210 NumberAnimation { 0211 duration: Kirigami.Units.longDuration 0212 easing.type: Easing.InOutQuad 0213 } 0214 } 0215 } 0216 PlasmaCore.PopupPlasmaWindow { 0217 id: tooltip 0218 visible: configurationArea.currentApplet && !root.dragAndDropping 0219 visualParent: configurationArea.currentApplet 0220 // Try to dodge the ruler, as we can't cover it since it's a layershell surface 0221 margin: configurationArea.Window.window?.lengthMode === 2 ? Kirigami.Units.gridUnit * 2 : 0 0222 width: mainItem.implicitWidth + leftPadding + rightPadding 0223 height: mainItem.implicitHeight + topPadding + bottomPadding 0224 0225 popupDirection: switch (Plasmoid.location) { 0226 case PlasmaCore.Types.TopEdge: 0227 return Qt.BottomEdge 0228 case PlasmaCore.Types.LeftEdge: 0229 return Qt.RightEdge 0230 case PlasmaCore.Types.RightEdge: 0231 return Qt.LeftEdge 0232 default: 0233 return Qt.TopEdge 0234 } 0235 0236 onVisualParentChanged: { 0237 if (visualParent) { 0238 const thisPlasmoid = configurationArea.currentApplet.applet.plasmoid; 0239 thisPlasmoid.contextualActionsAboutToShow(); 0240 alternativesButton.visible = thisPlasmoid.internalAction("alternatives")?.enabled ?? false; 0241 configureButton.visible = thisPlasmoid.internalAction("configure")?.enabled ?? false; 0242 label.text = thisPlasmoid.title; 0243 } 0244 } 0245 0246 mainItem: MouseArea { 0247 enabled: tooltip.visible 0248 implicitWidth: handleButtons.width 0249 implicitHeight: handleButtons.height 0250 hoverEnabled: true 0251 onEntered: hideTimer.stop(); 0252 onExited: hideTimer.restart(); 0253 0254 ColumnLayout { 0255 id: handleButtons 0256 spacing: Kirigami.Units.smallSpacing 0257 0258 PlasmaExtras.PlasmoidHeading { 0259 leftPadding: Kirigami.Units.smallSpacing * 2 0260 rightPadding: Kirigami.Units.smallSpacing * 2 0261 0262 contentItem: Kirigami.Heading { 0263 id: label 0264 level: 3 0265 horizontalAlignment: Text.AlignHCenter 0266 textFormat: Text.PlainText 0267 } 0268 } 0269 0270 PlasmaComponents3.ToolButton { 0271 Layout.fillWidth: true 0272 // we want destructive actions to be far from the initial 0273 // cursor position, so show this on the top unless it's on 0274 // a top panel 0275 visible: tooltip.location !== PlasmaCore.Types.TopEdge 0276 && (configurationArea.currentApplet?.applet.plasmoid.internalAction("remove")?.enabled ?? false) 0277 icon.name: "delete" 0278 text: i18nd("plasma_shell_org.kde.plasma.desktop", "Remove") 0279 onClicked: { 0280 configurationArea.currentApplet.applet.plasmoid.internalAction("remove").trigger(); 0281 configurationArea.currentApplet = null; 0282 } 0283 } 0284 PlasmaComponents3.ToolButton { 0285 id: configureButton 0286 Layout.fillWidth: true 0287 icon.name: "configure" 0288 text: i18nd("plasma_shell_org.kde.plasma.desktop", "Configure…") 0289 visible: configurationArea.currentApplet.applet.plasmoid.hasConfigurationInterface 0290 onClicked: { 0291 configurationArea.currentApplet.applet.plasmoid.internalAction("configure").trigger(); 0292 configurationArea.currentApplet = null; 0293 } 0294 } 0295 PlasmaComponents3.ToolButton { 0296 id: alternativesButton 0297 Layout.fillWidth: true 0298 icon.name: "widget-alternatives" 0299 text: i18nd("plasma_shell_org.kde.plasma.desktop", "Show Alternatives…") 0300 onClicked: { 0301 configurationArea.currentApplet.applet.plasmoid.internalAction("alternatives").trigger(); 0302 configurationArea.currentApplet = null; 0303 } 0304 } 0305 PlasmaComponents3.ToolButton { 0306 Layout.fillWidth: true 0307 // we want destructive actions to be far from the initial 0308 // cursor position, so show this on the bottom for top panels 0309 visible: tooltip.location === PlasmaCore.Types.TopEdge 0310 && (configurationArea.currentApplet?.applet.plasmoid.internalAction("remove")?.enabled ?? false) 0311 icon.name: "delete" 0312 text: i18nd("plasma_shell_org.kde.plasma.desktop", "Remove") 0313 onClicked: { 0314 configurationArea.currentApplet.applet.plasmoid.internalAction("remove").trigger(); 0315 configurationArea.currentApplet = null; 0316 } 0317 } 0318 0319 Kirigami.Heading { 0320 Layout.fillWidth: true 0321 visible: panelSpacerWidth.visible 0322 text: i18nd("plasma_shell_org.kde.plasma.desktop", "Spacer width") 0323 textFormat: Text.PlainText 0324 level: 3 0325 horizontalAlignment: Text.AlignHCenter 0326 } 0327 0328 PlasmaComponents3.SpinBox { 0329 id: panelSpacerWidth 0330 editable: true 0331 Layout.fillWidth: true 0332 focus: !Kirigami.InputMethod.willShowOnActive 0333 visible: configurationArea.currentApplet?.applet.plasmoid.pluginName === "org.kde.plasma.panelspacer" 0334 && !configurationArea.currentApplet.applet.plasmoid.configuration.expanding 0335 from: 0 0336 stepSize: 10 0337 to: root.width 0338 value: configurationArea.currentApplet?.applet.plasmoid.configuration.length ?? 0 0339 onValueModified: { 0340 configurationArea.currentApplet.applet.plasmoid.configuration.length = value 0341 } 0342 } 0343 } 0344 } 0345 } 0346 }