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 }