Warning, /plasma/plasma-desktop/containments/desktop/package/contents/ui/ConfigOverlay.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.15 0008 import QtQuick.Layouts 1.15 0009 0010 import org.kde.plasma.plasmoid 2.0 0011 import org.kde.plasma.core as PlasmaCore 0012 import org.kde.kirigami 2.20 as Kirigami 0013 import org.kde.ksvg 1.0 as KSvg 0014 0015 0016 import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager 0017 0018 ContainmentLayoutManager.ConfigOverlayWithHandles { 0019 id: overlay 0020 0021 SequentialAnimation { 0022 id: removeAnim 0023 0024 NumberAnimation { 0025 target: overlay.itemContainer 0026 property: "scale" 0027 from: 1 0028 to: 0 0029 duration: Kirigami.Units.longDuration 0030 easing.type: Easing.InOutQuad 0031 } 0032 ScriptAction { 0033 script: { 0034 appletContainer.applet.plasmoid.internalAction("remove").trigger(); 0035 appletContainer.editMode = false; 0036 } 0037 } 0038 } 0039 0040 KSvg.FrameSvgItem { 0041 id: frame 0042 0043 anchors.verticalCenter: parent.verticalCenter 0044 x: overlay.rightAvailableSpace > width + Kirigami.Units.gridUnit 0045 ? parent.width + Kirigami.Units.gridUnit 0046 : -width - Kirigami.Units.gridUnit 0047 0048 // This MouseArea is used to block input between the applet and the handle, to not make it steal by other applets 0049 MouseArea { 0050 anchors { 0051 top: parent.top 0052 bottom: parent.bottom 0053 } 0054 z: -1 0055 x: overlay.rightAvailableSpace > parent.width + Kirigami.Units.gridUnit ? -Kirigami.Units.gridUnit : 0 0056 width: Kirigami.Units.gridUnit + parent.width 0057 hoverEnabled: true 0058 } 0059 transform: Translate { 0060 x: open ? 0 : (overlay.rightAvailableSpace > frame.width + Kirigami.Units.gridUnit ? -frame.width : frame.width) 0061 0062 Behavior on x { 0063 NumberAnimation { 0064 duration: Kirigami.Units.longDuration 0065 easing.type: Easing.InOutQuad 0066 } 0067 } 0068 } 0069 width: layout.implicitWidth + margins.left + margins.right 0070 height: Math.max(layout.implicitHeight + margins.top + margins.bottom, parent.height) 0071 imagePath: "widgets/background" 0072 0073 ColumnLayout { 0074 id: layout 0075 anchors { 0076 fill: parent 0077 topMargin: parent.margins.top 0078 leftMargin: parent.margins.left 0079 bottomMargin: parent.margins.bottom 0080 rightMargin: parent.margins.right 0081 } 0082 0083 ActionButton { 0084 id: rotateButton 0085 icon.name: "object-rotate-left-symbolic" 0086 toolTip: !rotateHandle.pressed ? i18n("Click and drag to rotate") : "" 0087 action: applet ? applet.plasmoid.internalAction("rotate") : null 0088 down: rotateHandle.pressed 0089 Component.onCompleted: { 0090 if (action !== null) { 0091 action.enabled = true; 0092 } 0093 } 0094 MouseArea { 0095 id: rotateHandle 0096 anchors.fill: parent 0097 0098 property int startRotation 0099 property real startCenterRelativeAngle 0100 0101 function pointAngle(pos: point): real { 0102 var r = Math.sqrt(pos.x * pos.x + pos.y * pos.y); 0103 var cosine = pos.x / r; 0104 0105 if (pos.y >= 0) { 0106 return Math.acos(cosine) * (180/Math.PI); 0107 } else { 0108 return -Math.acos(cosine) * (180/Math.PI); 0109 } 0110 } 0111 0112 function centerRelativePos(x: real, y: real): point { 0113 var mousePos = overlay.itemContainer.parent.mapFromItem(rotateButton, x, y); 0114 var centerPos = overlay.itemContainer.parent.mapFromItem(overlay.itemContainer, overlay.itemContainer.width/2, overlay.itemContainer.height/2); 0115 0116 mousePos.x -= centerPos.x; 0117 mousePos.y -= centerPos.y; 0118 return mousePos; 0119 } 0120 0121 onPressed: mouse => { 0122 mouse.accepted = true; 0123 startRotation = overlay.itemContainer.rotation; 0124 startCenterRelativeAngle = pointAngle(centerRelativePos(mouse.x, mouse.y)); 0125 } 0126 0127 onPositionChanged: mouse => { 0128 var rot = startRotation % 360; 0129 var snap = 4; 0130 var newRotation = Math.round(pointAngle(centerRelativePos(mouse.x, mouse.y)) - startCenterRelativeAngle + startRotation); 0131 0132 if (newRotation < 0) { 0133 newRotation = newRotation + 360; 0134 } else if (newRotation >= 360) { 0135 newRotation = newRotation % 360; 0136 } 0137 0138 snapIt(0); 0139 snapIt(90); 0140 snapIt(180); 0141 snapIt(270); 0142 0143 function snapIt(snapTo) { 0144 if (newRotation > (snapTo - snap) && newRotation < (snapTo + snap)) { 0145 newRotation = snapTo; 0146 } 0147 } 0148 0149 overlay.itemContainer.rotation = newRotation; 0150 } 0151 0152 onReleased: mouse => { 0153 // save rotation 0154 appletsLayout.save(); 0155 } 0156 } 0157 } 0158 0159 ActionButton { 0160 icon.name: "configure" 0161 visible: qAction && qAction.enabled && (applet && applet.plasmoid.hasConfigurationInterface) 0162 qAction: applet ? applet.plasmoid.internalAction("configure") : null 0163 Component.onCompleted: { 0164 if (qAction) { 0165 qAction.enabled = true; 0166 } 0167 } 0168 } 0169 0170 ActionButton { 0171 // FIXME: missing from Breeze icons! See 0172 // https://bugs.kde.org/show_bug.cgi?id=472863. 0173 icon.name: "showbackground" 0174 toolTip: checked ? i18n("Hide Background") : i18n("Show Background") 0175 visible: (applet.plasmoid.backgroundHints & PlasmaCore.Types.ConfigurableBackground) 0176 checked: applet.plasmoid.effectiveBackgroundHints & PlasmaCore.Types.StandardBackground || applet.plasmoid.effectiveBackgroundHints & PlasmaCore.Types.TranslucentBackground 0177 checkable: true 0178 onClicked: { 0179 if (checked) { 0180 if (applet.plasmoid.backgroundHints & PlasmaCore.Types.StandardBackground || applet.plasmoid.backgroundHints & PlasmaCore.Types.TranslucentBackground) { 0181 applet.plasmoid.userBackgroundHints = applet.plasmoid.backgroundHints; 0182 } else { 0183 applet.plasmoid.userBackgroundHints = PlasmaCore.Types.StandardBackground; 0184 } 0185 } else { 0186 if (applet.plasmoid.backgroundHints & PlasmaCore.Types.ShadowBackground || applet.plasmoid.backgroundHints & PlasmaCore.Types.NoBackground) { 0187 applet.plasmoid.userBackgroundHints = applet.plasmoid.backgroundHints; 0188 } else { 0189 applet.plasmoid.userBackgroundHints = PlasmaCore.Types.ShadowBackground; 0190 } 0191 } 0192 } 0193 } 0194 0195 MouseArea { 0196 drag.target: overlay.itemContainer 0197 Layout.minimumHeight: Kirigami.Units.gridUnit * 3 0198 Layout.fillHeight: true 0199 Layout.fillWidth: true 0200 cursorShape: containsPress ? Qt.DragMoveCursor : Qt.OpenHandCursor 0201 hoverEnabled: true 0202 onPressed: mouse => { 0203 appletsLayout.releaseSpace(overlay.itemContainer); 0204 } 0205 onPositionChanged: mouse => { 0206 if (!pressed) { 0207 return; 0208 } 0209 appletsLayout.showPlaceHolderForItem(overlay.itemContainer); 0210 var dragPos = mapToItem(overlay.itemContainer, mouse.x, mouse.y); 0211 overlay.itemContainer.userDrag(Qt.point(overlay.itemContainer.x, overlay.itemContainer.y), dragPos); 0212 } 0213 onReleased: mouse => { 0214 appletsLayout.hidePlaceHolder(); 0215 appletsLayout.positionItem(overlay.itemContainer); 0216 } 0217 } 0218 0219 ActionButton { 0220 id: closeButton 0221 icon.name: "edit-delete-remove" 0222 toolTip: i18n("Remove") 0223 visible: { 0224 if (!applet) { 0225 return false; 0226 } 0227 var a = applet.plasmoid.internalAction("remove"); 0228 return a && a.enabled || false; 0229 } 0230 // we don't set action, since we want to catch the button click, 0231 // animate, and then trigger the "remove" action 0232 // Triggering the action is handled in the overlay.itemContainer, we just 0233 // Q_EMIT a signal here to avoid the applet-gets-removed-before-we- 0234 // can-animate it race condition. 0235 onClicked: { 0236 removeAnim.restart(); 0237 } 0238 Component.onCompleted: { 0239 var a = applet.plasmoid.internalAction("remove"); 0240 if (a) { 0241 a.enabled = true; 0242 } 0243 } 0244 } 0245 } 0246 } 0247 }