2022-08-28 21:48:51 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
import QtQuick 2.15
|
|
|
|
import QtQuick.Layouts 1.15
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
import org.kde.plasma.plasmoid 2.0
|
2024-08-09 01:20:25 +00:00
|
|
|
import org.kde.plasma.core as PlasmaCore
|
|
|
|
import org.kde.kirigami 2.20 as Kirigami
|
|
|
|
import org.kde.ksvg 1.0 as KSvg
|
|
|
|
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
|
|
|
|
|
|
|
ContainmentLayoutManager.ConfigOverlayWithHandles {
|
|
|
|
id: overlay
|
|
|
|
|
|
|
|
SequentialAnimation {
|
|
|
|
id: removeAnim
|
2024-08-09 01:20:25 +00:00
|
|
|
|
2022-08-28 21:48:51 +00:00
|
|
|
NumberAnimation {
|
|
|
|
target: overlay.itemContainer
|
|
|
|
property: "scale"
|
|
|
|
from: 1
|
|
|
|
to: 0
|
2024-08-09 01:20:25 +00:00
|
|
|
duration: Kirigami.Units.longDuration
|
2022-08-28 21:48:51 +00:00
|
|
|
easing.type: Easing.InOutQuad
|
|
|
|
}
|
|
|
|
ScriptAction {
|
|
|
|
script: {
|
2024-08-09 01:20:25 +00:00
|
|
|
appletContainer.applet.plasmoid.internalAction("remove").trigger();
|
2022-08-28 21:48:51 +00:00
|
|
|
appletContainer.editMode = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-09 01:20:25 +00:00
|
|
|
|
|
|
|
KSvg.FrameSvgItem {
|
2022-08-28 21:48:51 +00:00
|
|
|
id: frame
|
2024-08-09 01:20:25 +00:00
|
|
|
|
2022-08-28 21:48:51 +00:00
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
2024-08-09 01:20:25 +00:00
|
|
|
x: overlay.rightAvailableSpace > width + Kirigami.Units.iconSizes.small
|
|
|
|
? parent.width + Kirigami.Units.iconSizes.small
|
|
|
|
: -width - Kirigami.Units.iconSizes.small
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
// This MouseArea is used to block input between the applet and the handle, to not make it steal by other applets
|
|
|
|
MouseArea {
|
|
|
|
anchors {
|
|
|
|
top: parent.top
|
|
|
|
bottom: parent.bottom
|
|
|
|
}
|
|
|
|
z: -1
|
2024-08-09 01:20:25 +00:00
|
|
|
x: overlay.rightAvailableSpace > parent.width + Kirigami.Units.iconSizes.small ? -Kirigami.Units.iconSizes.small : 0
|
|
|
|
width: Kirigami.Units.iconSizes.small + parent.width
|
2022-08-28 21:48:51 +00:00
|
|
|
hoverEnabled: true
|
|
|
|
}
|
|
|
|
transform: Translate {
|
2024-08-09 01:20:25 +00:00
|
|
|
x: open ? 0 : (overlay.rightAvailableSpace > frame.width + Kirigami.Units.iconSizes.small ? -frame.width : frame.width)
|
2022-08-28 21:48:51 +00:00
|
|
|
|
|
|
|
Behavior on x {
|
|
|
|
NumberAnimation {
|
2024-08-09 01:20:25 +00:00
|
|
|
duration: Kirigami.Units.longDuration
|
2022-08-28 21:48:51 +00:00
|
|
|
easing.type: Easing.InOutQuad
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
width: layout.implicitWidth + margins.left + margins.right
|
|
|
|
height: Math.max(layout.implicitHeight + margins.top + margins.bottom, parent.height)
|
|
|
|
imagePath: "widgets/background"
|
|
|
|
|
|
|
|
ColumnLayout {
|
|
|
|
id: layout
|
|
|
|
anchors {
|
|
|
|
fill: parent
|
|
|
|
topMargin: parent.margins.top
|
|
|
|
leftMargin: parent.margins.left
|
|
|
|
bottomMargin: parent.margins.bottom
|
|
|
|
rightMargin: parent.margins.right
|
|
|
|
}
|
|
|
|
|
|
|
|
ActionButton {
|
|
|
|
id: rotateButton
|
2024-08-09 01:20:25 +00:00
|
|
|
icon.name: "object-rotate-left-symbolic"
|
|
|
|
toolTip: !rotateHandle.pressed ? i18n("Click and drag to rotate") : ""
|
|
|
|
action: applet ? applet.plasmoid.internalAction("rotate") : null
|
|
|
|
down: rotateHandle.pressed
|
2022-08-28 21:48:51 +00:00
|
|
|
Component.onCompleted: {
|
2024-08-09 01:20:25 +00:00
|
|
|
if (action !== null) {
|
|
|
|
action.enabled = true;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
MouseArea {
|
|
|
|
id: rotateHandle
|
|
|
|
anchors.fill: parent
|
|
|
|
|
|
|
|
property int startRotation
|
2024-08-09 01:20:25 +00:00
|
|
|
property real startCenterRelativeAngle
|
2022-08-28 21:48:51 +00:00
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
function pointAngle(pos: point): real {
|
2022-08-28 21:48:51 +00:00
|
|
|
var r = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
|
|
|
|
var cosine = pos.x / r;
|
|
|
|
|
|
|
|
if (pos.y >= 0) {
|
|
|
|
return Math.acos(cosine) * (180/Math.PI);
|
|
|
|
} else {
|
|
|
|
return -Math.acos(cosine) * (180/Math.PI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
function centerRelativePos(x: real, y: real): point {
|
2022-08-28 21:48:51 +00:00
|
|
|
var mousePos = overlay.itemContainer.parent.mapFromItem(rotateButton, x, y);
|
|
|
|
var centerPos = overlay.itemContainer.parent.mapFromItem(overlay.itemContainer, overlay.itemContainer.width/2, overlay.itemContainer.height/2);
|
|
|
|
|
|
|
|
mousePos.x -= centerPos.x;
|
|
|
|
mousePos.y -= centerPos.y;
|
|
|
|
return mousePos;
|
|
|
|
}
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
onPressed: mouse => {
|
|
|
|
mouse.accepted = true;
|
2022-08-28 21:48:51 +00:00
|
|
|
startRotation = overlay.itemContainer.rotation;
|
|
|
|
startCenterRelativeAngle = pointAngle(centerRelativePos(mouse.x, mouse.y));
|
|
|
|
}
|
|
|
|
|
2024-08-09 01:20:25 +00:00
|
|
|
onPositionChanged: mouse => {
|
|
|
|
var rot = startRotation % 360;
|
2022-08-28 21:48:51 +00:00
|
|
|
var snap = 4;
|
|
|
|
var newRotation = Math.round(pointAngle(centerRelativePos(mouse.x, mouse.y)) - startCenterRelativeAngle + startRotation);
|
|
|
|
|
|
|
|
if (newRotation < 0) {
|
|
|
|
newRotation = newRotation + 360;
|
|
|
|
} else if (newRotation >= 360) {
|
|
|
|
newRotation = newRotation % 360;
|
|
|
|
}
|
|
|
|
|
|
|
|
snapIt(0);
|
|
|
|
snapIt(90);
|
|
|
|
snapIt(180);
|
|
|
|
snapIt(270);
|
|
|
|
|
|
|
|
function snapIt(snapTo) {
|
|
|
|
if (newRotation > (snapTo - snap) && newRotation < (snapTo + snap)) {
|
|
|
|
newRotation = snapTo;
|
|
|
|
}
|
|
|
|
}
|
2024-08-09 01:20:25 +00:00
|
|
|
|
2022-08-28 21:48:51 +00:00
|
|
|
overlay.itemContainer.rotation = newRotation;
|
|
|
|
}
|
2024-08-09 01:20:25 +00:00
|
|
|
|
|
|
|
onReleased: mouse => {
|
2022-08-28 21:48:51 +00:00
|
|
|
// save rotation
|
|
|
|
appletsLayout.save();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ActionButton {
|
2024-08-09 01:20:25 +00:00
|
|
|
icon.name: "configure"
|
|
|
|
visible: qAction && qAction.enabled && (applet && applet.plasmoid.hasConfigurationInterface)
|
|
|
|
qAction: applet ? applet.plasmoid.internalAction("configure") : null
|
2022-08-28 21:48:51 +00:00
|
|
|
Component.onCompleted: {
|
2024-08-09 01:20:25 +00:00
|
|
|
if (qAction) {
|
|
|
|
qAction.enabled = true;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ActionButton {
|
2024-08-09 01:20:25 +00:00
|
|
|
// FIXME: missing from Breeze icons! See
|
|
|
|
// https://bugs.kde.org/show_bug.cgi?id=472863.
|
|
|
|
icon.name: "showbackground"
|
2022-08-28 21:48:51 +00:00
|
|
|
toolTip: checked ? i18n("Hide Background") : i18n("Show Background")
|
2024-08-09 01:20:25 +00:00
|
|
|
visible: (applet.plasmoid.backgroundHints & PlasmaCore.Types.ConfigurableBackground)
|
|
|
|
checked: applet.plasmoid.effectiveBackgroundHints & PlasmaCore.Types.StandardBackground || applet.plasmoid.effectiveBackgroundHints & PlasmaCore.Types.TranslucentBackground
|
2022-08-28 21:48:51 +00:00
|
|
|
checkable: true
|
|
|
|
onClicked: {
|
|
|
|
if (checked) {
|
2024-08-09 01:20:25 +00:00
|
|
|
if (applet.plasmoid.backgroundHints & PlasmaCore.Types.StandardBackground || applet.plasmoid.backgroundHints & PlasmaCore.Types.TranslucentBackground) {
|
|
|
|
applet.plasmoid.userBackgroundHints = applet.plasmoid.backgroundHints;
|
2022-08-28 21:48:51 +00:00
|
|
|
} else {
|
2024-08-09 01:20:25 +00:00
|
|
|
applet.plasmoid.userBackgroundHints = PlasmaCore.Types.StandardBackground;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
} else {
|
2024-08-09 01:20:25 +00:00
|
|
|
if (applet.plasmoid.backgroundHints & PlasmaCore.Types.ShadowBackground || applet.plasmoid.backgroundHints & PlasmaCore.Types.NoBackground) {
|
|
|
|
applet.plasmoid.userBackgroundHints = applet.plasmoid.backgroundHints;
|
2022-08-28 21:48:51 +00:00
|
|
|
} else {
|
2024-08-09 01:20:25 +00:00
|
|
|
applet.plasmoid.userBackgroundHints = PlasmaCore.Types.ShadowBackground;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MouseArea {
|
|
|
|
drag.target: overlay.itemContainer
|
2024-08-09 01:20:25 +00:00
|
|
|
Layout.minimumHeight: Kirigami.Units.iconSizes.small * 3
|
2022-08-28 21:48:51 +00:00
|
|
|
Layout.fillHeight: true
|
|
|
|
Layout.fillWidth: true
|
2024-08-09 01:20:25 +00:00
|
|
|
cursorShape: containsPress ? Qt.DragMoveCursor : Qt.OpenHandCursor
|
2022-08-28 21:48:51 +00:00
|
|
|
hoverEnabled: true
|
2024-08-09 01:20:25 +00:00
|
|
|
onPressed: mouse => {
|
|
|
|
appletsLayout.releaseSpace(overlay.itemContainer);
|
|
|
|
}
|
|
|
|
onPositionChanged: mouse => {
|
2022-08-28 21:48:51 +00:00
|
|
|
if (!pressed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
appletsLayout.showPlaceHolderForItem(overlay.itemContainer);
|
|
|
|
var dragPos = mapToItem(overlay.itemContainer, mouse.x, mouse.y);
|
|
|
|
overlay.itemContainer.userDrag(Qt.point(overlay.itemContainer.x, overlay.itemContainer.y), dragPos);
|
|
|
|
}
|
2024-08-09 01:20:25 +00:00
|
|
|
onReleased: mouse => {
|
2022-08-28 21:48:51 +00:00
|
|
|
appletsLayout.hidePlaceHolder();
|
|
|
|
appletsLayout.positionItem(overlay.itemContainer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ActionButton {
|
|
|
|
id: closeButton
|
2024-08-09 01:20:25 +00:00
|
|
|
icon.name: "edit-delete-remove"
|
2022-08-28 21:48:51 +00:00
|
|
|
toolTip: i18n("Remove")
|
|
|
|
visible: {
|
|
|
|
if (!applet) {
|
|
|
|
return false;
|
|
|
|
}
|
2024-08-09 01:20:25 +00:00
|
|
|
var a = applet.plasmoid.internalAction("remove");
|
|
|
|
return a && a.enabled || false;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
// we don't set action, since we want to catch the button click,
|
|
|
|
// animate, and then trigger the "remove" action
|
|
|
|
// Triggering the action is handled in the overlay.itemContainer, we just
|
|
|
|
// Q_EMIT a signal here to avoid the applet-gets-removed-before-we-
|
|
|
|
// can-animate it race condition.
|
|
|
|
onClicked: {
|
|
|
|
removeAnim.restart();
|
|
|
|
}
|
|
|
|
Component.onCompleted: {
|
2024-08-09 01:20:25 +00:00
|
|
|
var a = applet.plasmoid.internalAction("remove");
|
|
|
|
if (a) {
|
|
|
|
a.enabled = true;
|
2022-08-28 21:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|