diff --git a/containments/desktop/package/contents/ui/ActionButton.qml b/containments/desktop/package/contents/ui/ActionButton.qml index 7983f0ace..a468bc445 100644 --- a/containments/desktop/package/contents/ui/ActionButton.qml +++ b/containments/desktop/package/contents/ui/ActionButton.qml @@ -1,147 +1,148 @@ /* * Copyright 2011 Marco Martin * Copyright 2013 Sebastian Kügler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents PlasmaCore.ToolTipArea { id: button location: PlasmaCore.Types.LeftEdge mainText: action !== undefined ? action.text : "" mainItem: toolTipDelegate //API - property QtObject svg + property PlasmaCore.Svg svg property alias elementId: icon.elementId property QtObject action property bool backgroundVisible: false property int iconSize: 32 property int pressedOffset: 1 property bool checked: false property bool toggle: false property string text signal clicked - width: buttonRow.width - height: buttonRow.height + implicitWidth: buttonRow.implicitWidth + implicitHeight: buttonRow.implicitHeight opacity: action==undefined||action.enabled?1:0.6 Behavior on opacity { NumberAnimation { duration: units.longDuration easing.type: Easing.InOutQuad } } onCheckedChanged: { if (checked) { buttonItem.elementId = "pressed" shadowItem.opacity = 0 } else { buttonItem.elementId = "normal" shadowItem.opacity = 1 } } PlasmaCore.Svg { id: buttonSvg imagePath: "widgets/actionbutton" } PlasmaCore.SvgItem { id: shadowItem svg: buttonSvg elementId: "shadow" width: iconSize+13//button.backgroundVisible?iconSize+8:iconSize height: width visible: button.backgroundVisible } Row { id: buttonRow Item { width: buttonItem.visible?buttonItem.width:iconSize height: buttonItem.visible?buttonItem.height:iconSize PlasmaCore.SvgItem { id: buttonItem svg: buttonSvg elementId: "normal" width: shadowItem.width height: shadowItem.height visible: backgroundVisible } PlasmaCore.SvgItem { id: icon width: iconSize height: iconSize svg: button.svg anchors.centerIn: parent } } Text { id: actionText text: button.text style: Text.Outline color: theme.textColor styleColor: Qt.rgba(1,1,1,0.4) anchors.verticalCenter: parent.verticalCenter } } MouseArea { anchors.fill: parent anchors.leftMargin: -10 anchors.topMargin: -10 anchors.rightMargin: -10 anchors.bottomMargin: -10 preventStealing: true onPressed: { buttonItem.elementId = "pressed" shadowItem.opacity = 0; button.x = button.x + button.pressedOffset; button.y = button.y + button.pressedOffset; } onReleased: { if (button.checked || !button.toggle) { buttonItem.elementId = "normal" shadowItem.opacity = 1 button.checked = false } else { button.checked = true } button.x = button.x - button.pressedOffset; button.y = button.y - button.pressedOffset; } onClicked: { if (action) { action.trigger() } else { button.clicked() } + appletContainer.editMode = false; } } } diff --git a/containments/desktop/package/contents/ui/AppletAppearance.qml b/containments/desktop/package/contents/ui/AppletAppearance.qml deleted file mode 100644 index cd51b2b6c..000000000 --- a/containments/desktop/package/contents/ui/AppletAppearance.qml +++ /dev/null @@ -1,733 +0,0 @@ -/* - * Copyright 2011-2013 Sebastian Kügler - * Copyright 2011 Marco Martin - * Copyright 2014 David Edmundson - * Copyright 2015 Eike Hein - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -import QtQuick 2.0 -import QtQuick.Layouts 1.1 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras -import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons -import org.kde.plasma.plasmoid 2.0 - -Item { - id: appletItem - - property int handleWidth: iconSize - property int minimumHandleHeight: 7 * (root.iconSize + 7) + margins.top + margins.bottom - property int handleHeight: (height < minimumHandleHeight) ? minimumHandleHeight : height - property string category - - property bool showAppletHandle: temporaryShowAppletHandle || plasmoid.editMode - property bool temporaryShowAppletHandle: false - property real controlsOpacity: (plasmoid.immutable || !showAppletHandle) ? 0 : 1 - property string backgroundHints: "NoBackground" - property bool hasBackground: false - property bool handleMerged: (height > minimumHandleHeight && !appletHandle.forceFloating) - property bool animationsEnabled: false - property bool floating: true // turns off layoutManagment space handling for appletItem - - property alias innerEndHeight: mouseListener.endHeight - property alias innerEndWidth: mouseListener.endWidth - property alias innerHeight: mouseListener.height - property alias innerWidth: mouseListener.width - - property int minimumWidth: Math.max(root.layoutManager.cellSize.width, - appletContainer.minimumWidth + - margins.left + - margins.right); - - property int minimumHeight: Math.max(root.layoutManager.cellSize.height, - appletContainer.minimumHeight + - margins.top + - margins.bottom); - - property int maximumWidth: appletContainer.maximumWidth + - margins.left + - margins.right; - - property int maximumHeight: appletContainer.maximumHeight + - margins.top + - margins.bottom; - - property alias applet: appletContainer.applet - - property Item contents: appletContainer - property alias margins: plasmoidBackground.margins - property alias imagePath: plasmoidBackground.imagePath - - property int lastX: 0 - property int lastY: 0 - - visible: false - - Timer { - id: positionTimer - - repeat: false - running: false - interval: 100 - - onTriggered: { - releasePosition(); - positionItem(); - if (showAppletHandle && !handleMerged) - appletHandle.positionHandle(); - } - } - - onMinimumWidthChanged: { - if (width < minimumWidth) { - width = minimumWidth; - positionTimer.restart(); - } - } - onMinimumHeightChanged: { - if (height < minimumHeight) { - height = minimumHeight; - positionTimer.restart(); - } - } - onMaximumWidthChanged: { - if (width > maximumWidth) { - width = maximumWidth; - positionTimer.restart(); - } - } - onMaximumHeightChanged: { - if (height > maximumHeight) { - height = maximumHeight; - positionTimer.restart(); - } - } - - onHeightChanged: { - if (height > maximumHeight) - innerEndHeight = maximumHeight; - else if (height < minimumHeight) - innerEndHeight = minimumHeight; - else - innerEndHeight = height; - } - onWidthChanged: { - if (width > maximumWidth) - innerEndWidth = maximumWidth; - else if (width < minimumWidth) - innerEndWidth = minimumWidth; - else - innerEndWidth = width; - } - - onXChanged: { - if (animationsEnabled) { - animationsEnabled = false; - mouseListener.x += lastX - x; - animationsEnabled = true; - } - mouseListener.x = mouseListener.endX = (width - innerEndWidth)/2; - lastX = x; - } - onYChanged: { - if (animationsEnabled) { - animationsEnabled = false; - mouseListener.y += lastY - y; - animationsEnabled = true; - } - mouseListener.y = mouseListener.endY = (height - innerEndHeight)/2; - lastY = y; - } - - // use this function to position appletItem instead of root.layoutManager.positionItem(appletItem) - function positionItem() { - if (floating) - return; - root.layoutManager.positionItem(appletItem); - } - - // use this function to free appletItem position instead of - // root.layoutManager.setSpaceAvailable(appletItem.x, appletItem.y, appletItem.width, appletItem.height, true) - function releasePosition() { - if (!floating) - root.layoutManager.setSpaceAvailable(x, y, width, height, true); - } - - function updateBackgroundHints() { - hasBackground = (applet.backgroundHints !== "NoBackground"); - if (applet.backgroundHints === 1) { - appletItem.imagePath = "widgets/background"; - backgroundHints = "StandardBackground"; - } else if (applet.backgroundHints === 2) { - appletItem.imagePath = "widgets/translucentbackground" - backgroundHints = "TranslucentBackground"; - } else if (applet.backgroundHints === 0) { - appletItem.imagePath = "" - backgroundHints = "NoBackground"; - } else { - backgroundHints = "DefaultBackground"; - appletItem.imagePath = "widgets/background"; - } - //print("Backgroundhints changed: " + appletItem.imagePath); - } - - KQuickControlsAddons.MouseEventListener { - id: mouseListener - // used as inner applet (which would not be sized over or under size limits ) - // centered in appletItem.onXChanged and onYChanged due to allow animations on X and Y - - property int pressX: -1 - property int pressY: -1 - - // for animations - property int endHeight: minimumHeight - property int endWidth: minimumWidth - property int endX: 0 - property int endY: 0 - - function startDrag(mouse) { - dragMouseArea.dragging = true; - - eventGenerator.sendGrabEventRecursive(appletItem, KQuickControlsAddons.EventGenerator.UngrabMouse); - eventGenerator.sendGrabEvent(dragMouseArea, KQuickControlsAddons.EventGenerator.GrabMouse); - eventGenerator.sendMouseEvent(dragMouseArea, KQuickControlsAddons.EventGenerator.MouseButtonPress, mouse.x, mouse.y, Qt.LeftButton, Qt.LeftButton, 0); - } - - height: endHeight - width: endWidth - z: 10 - - hoverEnabled: true - - onPressed: { - if (!plasmoid.immutable && mouse.modifiers === Qt.AltModifier) { - if (!dragMouseArea.dragging) { - startDrag(mouse) - } - - return; - } - - pressX = mouse.x; - pressY = mouse.y; - } - - onPressAndHold: { - if (!plasmoid.immutable && plasmoid.configuration.pressToMove) { - if (!dragMouseArea.dragging && !root.isDrag(pressX, pressY, mouse.x, mouse.y)) { - temporaryShowAppletHandle = true; - - startDrag(mouse) - } - } - - pressX = -1; - pressY = -1; - } - - onContainsMouseChanged: { - animationsEnabled = true; - - if (!plasmoid.immutable && (!plasmoid.configuration.pressToMove || !containsMouse)) { - hoverTracker.restart(); - } - } - - Timer { - id: hoverTracker - repeat: false - interval: root.handleDelay - onTriggered: { - if (mouseListener.containsMouse || (appletHandle.item && (appletHandle.item.containsMouse || appletHandle.item.pressed))) { - if (!plasmoid.configuration.pressToMove) { - temporaryShowAppletHandle = true; - } - } else if (!dragMouseArea.dragging) { - temporaryShowAppletHandle = false; - } - } - } - - Item { - anchors { left: parent.left; top: parent.top; bottom: parent.bottom; } - width: parent.width+handleWidth; - z: mouseListener.z + 4 - - PlasmaCore.FrameSvgItem { - id: plasmoidBackground - visible: backgroundHints !== PlasmaCore.Types.NoBackground - imagePath: "widgets/background" - anchors { left: parent.left; top: parent.top; bottom: parent.bottom; } - width: parent.width - _handleWidth - smooth: true - - property real _handleWidth: (showAppletHandle && handleMerged) ? 0 : handleWidth - - Behavior on _handleWidth { - enabled: animationsEnabled - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - } - - Connections { - target: plasmoid - onImmutableChanged: { -// print(" TB dragMouseArea.visible: " + plasmoid.immutable) - dragMouseArea.visible = !plasmoid.immutable; - temporaryShowAppletHandle = false; - } - onAppletRemoved: { -// print("Applet removed Applet-" + applet.id) - if (applet.id === appletItem.applet.id) { -// print("Destroying Applet-" + applet.id) - root.layoutManager.saveRotation(appletItem); - appletItem.releasePosition(); - //applet.action("remove").trigger(); - //appletItem.destroy() - appletItem.destroy(); - } - } - } - Connections { - target: applet - - onBackgroundHintsChanged: { -// print("plasmoid.backgroundHintsChanged"); - updateBackgroundHints(); - } - } - - MouseArea { - id: dragMouseArea - - anchors.fill: parent - z: appletContainer.z - 2 - visible: !plasmoid.immutable - - property int zoffset: 1000 - - drag.target: appletItem - property bool dragging: false // Set by mouseListener.onPressAndHold -- drag.active only becomes true on movement. - - function endDrag() { - appletItem.z = appletItem.z - zoffset; - repositionTimer.running = false; - placeHolderPaint.opacity = 0; - animationsEnabled = true; - appletItem.floating = false; - appletItem.positionItem(); - root.layoutManager.save(); - dragging = false; - } - - onDraggingChanged: { - cursorShape = dragging ? Qt.DragMoveCursor : Qt.ArrowCursor; - } - - onPressed: { - appletItem.z = appletItem.z + zoffset; - animationsEnabled = false; - mouse.accepted = true; - appletItem.releasePosition(); - appletItem.floating = true; - - placeHolder.syncWithItem(appletItem); - placeHolderPaint.opacity = root.haloOpacity; - } - - onPositionChanged: { - var pos = mapToItem(root.parent, mouse.x, mouse.y); - var newCont = plasmoid.containmentAt(pos.x, pos.y); - - if (newCont && newCont !== plasmoid) { - var newPos = newCont.mapFromApplet(plasmoid, pos.x, pos.y); - newCont.addApplet(appletItem.applet, newPos.x, newPos.y); - placeHolderPaint.opacity = 0; - } else { - placeHolder.syncWithItem(appletItem); - } - } - - onCanceled: { - endDrag(); - appletHandle.positionHandle(); - } - - onReleased: { - endDrag(); - appletHandle.positionHandle(); - } - } - - Item { - id: appletContainer - anchors { - fill: parent - leftMargin: plasmoidBackground.margins.left - rightMargin: plasmoidBackground.margins.right + handleWidth - topMargin: plasmoidBackground.margins.top - bottomMargin: plasmoidBackground.margins.bottom - } - z: mouseListener.z+1 - - property QtObject applet - readonly property int maxInt: 1000000 // dirty hack to convert js number to qml int - - property var minimumSize: { - var size; - if (applet && applet.Layout) { - var layout = applet.Layout - size = { 'width': layout.minimumWidth, - 'height': layout.minimumHeight }; - } else { - size = { 'width': 0, 'height': 0 }; - } - - return size; - } - - property var maximumSize: { - var size; - if (applet && applet.Layout) { - var layout = applet.Layout - size = { 'width': layout.maximumWidth, - 'height': layout.maximumHeight }; - } else { - size = { 'width': Number.POSITIVE_INFINITY, - 'height': Number.POSITIVE_INFINITY }; - - } - - if (size.width > maxInt) - size.width = maxInt; - if (size.height > maxInt) - size.height = maxInt; - - return size; - } - - onMinimumSizeChanged: { - minimumHeight = minimumSize.height - if (minimumHeight > maximumSize.height) - maximumHeight = minimumHeight - else if (maximumHeight !== maximumSize.height) - maximumHeight = maximumSize.height - - minimumWidth = minimumSize.width - if (minimumWidth > maximumSize.width) - maximumWidth = minimumWidth - else if (maximumWidth !== maximumSize.width) - maximumWidth = maximumSize.width - } - - onMaximumSizeChanged: { - maximumHeight = maximumSize.height - if (maximumHeight < minimumSize.height) - minimumHeight = maximumHeight - else if (minimumHeight !== minimumSize.height) - minimumHeight = minimumSize.height - - maximumWidth = maximumSize.width - if (maximumWidth < minimumSize.width) - minimumWidth = maximumWidth - else if (minimumWidth !== minimumSize.width) - minimumWidth = minimumSize.width - } - - property int minimumWidth: 0 - property int minimumHeight: 0 - - property int maximumWidth: maxInt - property int maximumHeight: maxInt - - function appletDestroyed() { -// print("Applet DESTROYED."); - appletItem.releasePosition(); - applet.action("remove").trigger(); - appletItem.destroy() - } - - onAppletChanged: { - if (!applet) { - return; - } - applet.parent = appletContainer; - applet.anchors.fill = appletContainer; - - updateBackgroundHints(); - } - Connections { - target: appletHandle.item - onRemoveApplet: { - killAnim.running = true; - } - } - Behavior on opacity { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - SequentialAnimation { - id: killAnim - PlasmaExtras.DisappearAnimation { - targetItem: appletItem - } - ScriptAction { - script: { - appletItem.scale = 1; - appletContainer.appletDestroyed(); - } - } - } - Loader { - id: busyLoader - - anchors.centerIn: parent - - z: appletContainer.z + 1 - - active: applet && applet.busy - - source: "BusyOverlay.qml" - asynchronous: true - } - - Component.onCompleted: PlasmaExtras.AppearAnimation { - targetItem: appletItem - } - } - - Loader { - id: appletHandle - z: appletContainer.z + 1 - property bool forceFloating : false - anchors { - verticalCenter: parent.verticalCenter - right: plasmoidBackground.right - } - Connections { - target: appletItem - onShowAppletHandleChanged: { - if (appletItem.showAppletHandle) { - appletItem.z += dragMouseArea.zoffset; - appletHandle.positionHandle(); - if (appletHandle.source == "") { - appletHandle.source = "AppletHandle.qml"; - } - } else { - appletItem.z -= dragMouseArea.zoffset; - } - } - onHandleMergedChanged: { - if (appletItem.handleMerged) { - appletHandle.anchors.verticalCenterOffset = 0; - } else { - appletHandle.positionHandle(); - } - } - } - Connections { - target: appletHandle.item - onMoveFinished: { - appletHandle.positionHandle(); - } - } - - function positionHandle() - { - // Don't show handle outside of desktop - var available = plasmoid.availableScreenRect; - var x = Math.min(Math.max(0, appletItem.x + mouseListener.endX), available.width - appletItem.width + mouseListener.endX); - var y = Math.min(Math.max(0, appletItem.y + mouseListener.endY), available.height - appletItem.height + mouseListener.endY); - var verticalCenter = (y + mouseListener.endHeight / 2); - var topOutside = (verticalCenter - minimumHandleHeight / 2); - var bottomOutside = verticalCenter + minimumHandleHeight / 2 - available.height; - if (bottomOutside > 0) { - anchors.verticalCenterOffset = -bottomOutside; - } else if (topOutside < 0) { - anchors.verticalCenterOffset = -topOutside; - } else { - anchors.verticalCenterOffset = 0; - } - var rightOutside = x + mouseListener.endWidth + handleWidth - available.width; - appletHandle.anchors.rightMargin = appletItem.margins.right + Math.max(0, rightOutside); - appletHandle.forceFloating = rightOutside > 0; - } - } - } - - Behavior on x { - enabled: animationsEnabled - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - Behavior on y { - enabled: animationsEnabled - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - Behavior on width { - enabled: animationsEnabled - NumberAnimation { - id: widthAnimation - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - Behavior on height { - enabled: animationsEnabled - NumberAnimation { - id: heightAnimation - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - } - - Behavior on controlsOpacity { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad - } - } - - //sides - ResizeHandle { - anchors { - left: parent.left - top: parent.top - right: parent.right - leftMargin: units.gridUnit - rightMargin: units.gridUnit - } - cursorShape: Qt.SizeVerCursor - moveX: false - moveY: true - resizeWidth: false - resizeHeight: true - } - ResizeHandle { - anchors { - left: parent.left - bottom: parent.bottom - right: parent.right - leftMargin: units.gridUnit - rightMargin: units.gridUnit - } - cursorShape: Qt.SizeVerCursor - moveX: false - moveY: false - resizeWidth: false - resizeHeight: true - } - ResizeHandle { - anchors { - left: parent.left - top: parent.top - bottom: parent.bottom - topMargin: units.gridUnit - bottomMargin: units.gridUnit - } - enabled: !parent.LayoutMirroring.enabled || !showAppletHandle - cursorShape: Qt.SizeHorCursor - moveX: true - moveY: false - resizeWidth: true - resizeHeight: false - } - ResizeHandle { - anchors { - right: parent.right - top: parent.top - bottom: parent.bottom - topMargin: units.gridUnit - bottomMargin: units.gridUnit - } - enabled: parent.LayoutMirroring.enabled || !showAppletHandle - cursorShape: Qt.SizeHorCursor - moveX: false - moveY: false - resizeWidth: true - resizeHeight: false - } - //corners - ResizeHandle { - anchors { - left: parent.left - top: parent.top - } - enabled: !parent.LayoutMirroring.enabled || !showAppletHandle - cursorShape: Qt.SizeFDiagCursor - moveX: true - moveY: true - resizeWidth: true - resizeHeight: true - } - ResizeHandle { - anchors { - right: parent.right - top: parent.top - } - enabled: parent.LayoutMirroring.enabled || !showAppletHandle - cursorShape: Qt.SizeBDiagCursor - moveX: false - moveY: true - resizeWidth: true - resizeHeight: true - } - ResizeHandle { - anchors { - left: parent.left - bottom: parent.bottom - } - enabled: !parent.LayoutMirroring.enabled || !showAppletHandle - cursorShape: Qt.SizeBDiagCursor - moveX: true - moveY: false - resizeWidth: true - resizeHeight: true - } - ResizeHandle { - anchors { - right: parent.right - bottom: parent.bottom - } - enabled: parent.LayoutMirroring.enabled || !showAppletHandle - cursorShape: Qt.SizeFDiagCursor - moveX: false - moveY: false - resizeWidth: true - resizeHeight: true - } - - Component.onCompleted: { - floating = false; - layoutTimer.running = true - layoutTimer.restart() - visible = false - } -} diff --git a/containments/desktop/package/contents/ui/AppletHandle.qml b/containments/desktop/package/contents/ui/AppletHandle.qml deleted file mode 100644 index 245378ed7..000000000 --- a/containments/desktop/package/contents/ui/AppletHandle.qml +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2011-2013 Sebastian Kügler - * Copyright 2011 Marco Martin - * Copyright 2014 David Edmundson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -import QtQuick 2.0 -import QtQuick.Layouts 1.1 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons -import org.kde.plasma.components 2.0 as PlasmaComponents - -KQuickControlsAddons.MouseEventListener { - id: appletHandle - - opacity: appletItem.controlsOpacity - visible: opacity > 0 - width: appletItem.handleWidth - height: Math.max(appletItem.innerHeight - appletItem.margins.top - appletItem.margins.bottom, buttonColumn.implicitHeight) - hoverEnabled: true - onContainsMouseChanged: { - if (!containsMouse && !pressed) { - hoverTracker.restart() - } - } - onReleased: { - if (!containsMouse) { - hoverTracker.restart() - } - } - - //z: dragMouseArea.z + 1 - - property int buttonMargin: 6 - property int minimumHeight: 6 * (root.iconSize + buttonMargin) - - signal removeApplet - signal moveFinished - - transform: Translate { - x: (handleMerged ? 0 : controlsOpacity * appletHandle.width) * (appletHandle.LayoutMirroring.enabled ? -1 : 1) - } - - PlasmaCore.FrameSvgItem { - id: noBackgroundHandle - visible: controlsOpacity > 0 - z: plasmoidBackground.z - 10 - - anchors { - top: parent.top - bottom: parent.bottom - left: parent.left - right: parent.right -// verticalCenter: parent.verticalCenter - - leftMargin: -margins.left - topMargin: -margins.top - rightMargin: -margins.right - bottomMargin: -margins.bottom - } - - smooth: true - imagePath: (backgroundHints == "NoBackground" || !handleMerged) ? "widgets/background" : "" - } - - PlasmaComponents.Label { - id: toolTipDelegate - - width: contentWidth - height: undefined - - property Item toolTip - - text: (toolTip != null) ? toolTip.mainText : "" - } - ColumnLayout { - id: buttonColumn - width: appletItem.handleWidth - - anchors { - top: parent.top - bottom: parent.bottom - right: parent.right - } - spacing: buttonMargin*2 - ActionButton { - svg: configIconsSvg - elementId: "size-diagonal-tr2bl" - iconSize: root.iconSize - mainText: i18n("Resize") - active: !resizeHandle.pressed - - ResizeHandle { - id: resizeHandle - anchors { - fill: parent - margins: -buttonMargin - } - onPressed: parent.hideToolTip(); - cursorShape: parent.LayoutMirroring.enabled ? Qt.SizeFDiagCursor : Qt.SizeBDiagCursor - moveX: parent.LayoutMirroring.enabled - moveY: true - resizeWidth: true - resizeHeight: true - visible: true - } - } - ActionButton { - id: rotateButton - svg: configIconsSvg - elementId: "rotate" - mainText: i18n("Rotate") - iconSize: root.iconSize - action: (applet) ? applet.action("rotate") : null - active: !rotateHandle.pressed - Component.onCompleted: { - if (action && typeof(action) != "undefined") { - action.enabled = true - } - } - MouseArea { - id: rotateHandle - anchors { - fill: parent - margins: -buttonMargin - } - - property int startRotation - property real startCenterRelativeAngle; - - function pointAngle(pos) { - 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); - } - } - - function centerRelativePos(x, y) { - var mousePos = appletItem.parent.mapFromItem(rotateButton, x, y); - var centerPos = appletItem.parent.mapFromItem(appletItem, appletItem.width/2, appletItem.height/2); - - mousePos.x -= centerPos.x; - mousePos.y -= centerPos.y; - return mousePos; - } - - onPressed: { - parent.hideToolTip(); - mouse.accepted = true - animationsEnabled = false; - startRotation = appletItem.rotation; - startCenterRelativeAngle = pointAngle(centerRelativePos(mouse.x, mouse.y)); - } - onPositionChanged: { - - var rot = startRotation%360; - 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; - } - } - //print("Start: " + startRotation + " new: " + newRotation); - appletItem.rotation = newRotation; - } - onReleased: { - // save rotation -// print("saving..."); - root.layoutManager.saveItem(appletItem); - } - } - } - ActionButton { - svg: configIconsSvg - elementId: "configure" - iconSize: root.iconSize - visible: (action && typeof(action) != "undefined") ? action.enabled : false - action: (applet) ? applet.action("configure") : null - Component.onCompleted: { - if (action && typeof(action) != "undefined") { - action.enabled = true - } - } - } - ActionButton { - svg: configIconsSvg - elementId: "maximize" - iconSize: root.iconSize - visible: (action && typeof(action) != "undefined") ? action.enabled : false - action: (applet) ? applet.action("run associated application") : null - Component.onCompleted: { - if (action && typeof(action) != "undefined") { - action.enabled = true - } - } - } - - //spacer - MouseArea { - id: dragMouseArea - - implicitHeight: root.iconSize * 2 - Layout.fillWidth: true - Layout.fillHeight: true - property int zoffset: 1000 - drag.target: appletItem - cursorShape: Qt.DragMoveCursor - - onPressed: { - appletItem.z = appletItem.z + zoffset; - animationsEnabled = false - mouse.accepted = true - appletItem.releasePosition(); - appletItem.floating = true; - - placeHolder.syncWithItem(appletItem) - placeHolderPaint.opacity = root.haloOpacity; - } - onPositionChanged: { - var pos = mapToItem(root.parent, mouse.x, mouse.y); - var newCont = plasmoid.containmentAt(pos.x, pos.y); - - if (newCont && newCont !== plasmoid) { - var newPos = newCont.mapFromApplet(plasmoid, pos.x, pos.y); - - newCont.addApplet(appletItem.applet, newPos.x, newPos.y); - placeHolderPaint.opacity = 0; - } else { - placeHolder.syncWithItem(appletItem); - } - } - onReleased: { - appletItem.z = appletItem.z - zoffset; - repositionTimer.running = false - placeHolderPaint.opacity = 0 - animationsEnabled = true - appletItem.floating = false; - appletItem.positionItem(); - root.layoutManager.save() - appletHandle.moveFinished() - } - } - - Item { - Layout.minimumWidth: closeButton.width - Layout.minimumHeight: closeButton.height - - ActionButton { - id: closeButton - svg: configIconsSvg - elementId: "delete" - mainText: i18n("Remove") - iconSize: root.iconSize - visible: { - if (!applet) { - return false; - } - var a = applet.action("remove"); - return (a && typeof(a) != "undefined") ? a.enabled : false; - } - // 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 appletItem, we just - // emit a signal here to avoid the applet-gets-removed-before-we- - // can-animate it race condition. - onClicked: { - appletHandle.removeApplet(); - } - Component.onCompleted: { - var a = applet.action("remove"); - if (a && typeof(a) != "undefined") { - a.enabled = true - } - } - } - } - } -} diff --git a/containments/desktop/package/contents/ui/ConfigOverlay.qml b/containments/desktop/package/contents/ui/ConfigOverlay.qml new file mode 100644 index 000000000..f556adaac --- /dev/null +++ b/containments/desktop/package/contents/ui/ConfigOverlay.qml @@ -0,0 +1,251 @@ +/* + * Copyright 2019 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.12 +import QtQuick.Layouts 1.1 + +import org.kde.plasma.plasmoid 2.0 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 3.0 as PlasmaComponents + +import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager + +ContainmentLayoutManager.ConfigOverlayWithHandles { + id: overlay + + readonly property int iconSize: touchInteraction ? units.iconSizes.medium : units.iconSizes.small + PlasmaCore.Svg { + id: configIconsSvg + imagePath: "widgets/configuration-icons" + } + + PlasmaComponents.Label { + id: toolTipDelegate + + width: contentWidth + height: undefined + + property Item toolTip + + text: (toolTip != null) ? toolTip.mainText : "" + } + + SequentialAnimation { + id: removeAnim + NumberAnimation { + target: overlay.itemContainer + property: "scale" + from: 1 + to: 0 + duration: units.longDuration + easing.type: Easing.InOutQuad + } + ScriptAction { + script: { + appletContainer.applet.action("remove").trigger(); + appletContainer.editMode = false; + } + } + } + PlasmaCore.FrameSvgItem { + id: frame + anchors.verticalCenter: parent.verticalCenter + x: rightAvailableSpace > width + units.gridUnit + ? parent.width + units.gridUnit + : -width - units.gridUnit + + transform: Translate { + x: open ? 0 : (overlay.rightAvailableSpace > frame.width + units.gridUnit ? -frame.width : frame.width) + + Behavior on x { + NumberAnimation { + duration: units.longDuration + 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 + svg: configIconsSvg + elementId: "rotate" + mainText: i18n("Rotate") + iconSize: overlay.iconSize + action: (applet) ? applet.action("rotate") : null + active: !rotateHandle.pressed + Component.onCompleted: { + if (action && typeof(action) != "undefined") { + action.enabled = true + } + } + MouseArea { + id: rotateHandle + anchors.fill: parent + + property int startRotation + property real startCenterRelativeAngle; + + function pointAngle(pos) { + 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); + } + } + + function centerRelativePos(x, y) { + 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; + } + + onPressed: { + parent.hideToolTip(); + mouse.accepted = true + startRotation = overlay.itemContainer.rotation; + startCenterRelativeAngle = pointAngle(centerRelativePos(mouse.x, mouse.y)); + } + onPositionChanged: { + + var rot = startRotation%360; + 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; + } + } + //print("Start: " + startRotation + " new: " + newRotation); + overlay.itemContainer.rotation = newRotation; + } + onReleased: { + // save rotation + // print("saving..."); + appletsLayout.save(); + } + } + } + + ActionButton { + svg: configIconsSvg + elementId: "configure" + iconSize: overlay.iconSize + visible: (action && typeof(action) != "undefined") ? action.enabled : false + action: (applet) ? applet.action("configure") : null + Component.onCompleted: { + if (action && typeof(action) != "undefined") { + action.enabled = true + } + } + } + + ActionButton { + svg: configIconsSvg + elementId: "maximize" + iconSize: overlay.iconSize + visible: (action && typeof(action) != "undefined") ? action.enabled : false + action: (applet) ? applet.action("run associated application") : null + Component.onCompleted: { + if (action && typeof(action) != "undefined") { + action.enabled = true + } + } + } + + MouseArea { + drag.target: overlay.itemContainer + Layout.minimumHeight: units.gridUnit * 3 + Layout.fillHeight: true + Layout.fillWidth: true + cursorShape: Qt.DragMoveCursor + onPressed: appletsLayout.releaseSpace(overlay.itemContainer); + onPositionChanged: { + 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); + } + onReleased: { + appletsLayout.hidePlaceHolder(); + appletsLayout.positionItem(overlay.itemContainer); + } + } + + ActionButton { + id: closeButton + svg: configIconsSvg + elementId: "delete" + mainText: i18n("Remove") + iconSize: overlay.iconSize + visible: { + if (!applet) { + return false; + } + var a = applet.action("remove"); + return (a && typeof(a) != "undefined") ? a.enabled : false; + } + // 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 + // emit a signal here to avoid the applet-gets-removed-before-we- + // can-animate it race condition. + onClicked: { + removeAnim.restart(); + } + Component.onCompleted: { + var a = applet.action("remove"); + if (a && typeof(a) != "undefined") { + a.enabled = true + } + } + } + } + } +} + diff --git a/containments/desktop/package/contents/ui/ResizeHandle.qml b/containments/desktop/package/contents/ui/ResizeHandle.qml deleted file mode 100644 index 3fef5debe..000000000 --- a/containments/desktop/package/contents/ui/ResizeHandle.qml +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2011-2013 Sebastian Kügler - * Copyright 2011 Marco Martin - * Copyright 2014 David Edmundson - * Copyright 2015 Eike Hein - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -import QtQuick 2.0 -import QtQuick.Layouts 1.1 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents -import org.kde.plasma.extras 2.0 as PlasmaExtras -import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons -import org.kde.plasma.plasmoid 2.0 - - -MouseArea { - width: units.gridUnit - height: units.gridUnit - cursorShape: Qt.SizeVerCursor - z: 99999 - - //to controls the resize/move behavior - property bool moveX - property bool moveY - property bool resizeWidth - property bool resizeHeight - - //internal - property int startX - property int startY - property int startWidth - property int startHeight - - visible: applet && applet.backgroundHints !== PlasmaCore.Types.NoBackground && enabled && !plasmoid.immutable && showAppletHandle - LayoutMirroring.enabled: false - onPressed: { - mouse.accepted = true - animationsEnabled = false; - var pos = mapToItem(root, mouse.x, mouse.y); - startX = pos.x; - startY = pos.y; - startWidth = appletItem.width; - startHeight = appletItem.height; - appletItem.releasePosition(); - appletItem.floating = true; - appletContainer.clip = true - } - onPositionChanged: { - var pos = mapToItem(root, mouse.x, mouse.y); - var xDelta = moveX ? pos.x - startX : startX - pos.x; - var yDelta = moveY ? startY - pos.y : pos.y - startY; - - var oldRight = appletItem.x + appletItem.width; - if (resizeWidth) { - appletItem.width = Math.min(Math.max(appletItem.minimumWidth, startWidth - xDelta), appletItem.maximumWidth); - } - - var oldBottom = appletItem.y + appletItem.height; - if (resizeHeight) { - appletItem.height = Math.min(Math.max(appletItem.minimumHeight, startHeight + yDelta), appletItem.maximumHeight); - } - - if (moveX) { - appletItem.x = oldRight - appletItem.width; - } - if (moveY) { - appletItem.y = oldBottom - appletItem.height; - } - } - onReleased: { - animationsEnabled = true - appletItem.floating = false; - appletItem.positionItem(); - root.layoutManager.save() - appletContainer.clip = false - } -} diff --git a/containments/desktop/package/contents/ui/code/LayoutManager.js b/containments/desktop/package/contents/ui/code/LayoutManager.js deleted file mode 100644 index d5375fa36..000000000 --- a/containments/desktop/package/contents/ui/code/LayoutManager.js +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright 2011 Marco Martin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -var positions = [] - -var cellSize = { - width: units.gridUnit, - height: units.gridUnit -} - -var defaultAppletSize = { - width: cellSize.width * 6, - height: cellSize.height * 6 -} - -var resultsFlow -var plasmoid; -var itemsConfig -var rotations = {} - -//bookkeeping for the item groups -var itemGroups = {} - -function restore() -{ - var appletsMap = {}; - var applet; - var appletsLength = plasmoid.applets.length - for (var i = 0; i < appletsLength; ++i) { - applet = plasmoid.applets[i]; - appletsMap["Applet-" + applet.id] = applet; - } - - itemsConfig = {}; - var configString = String(plasmoid.configuration.ItemsGeometries) - //print("Config read from configfile: " + configString); - //array, a cell for encoded item geometry - var itemsStrings = configString.split(";") - var itemsStringsLength = itemsStrings.length - for (var i = 0; i < itemsStringsLength; ++i) { - //[id, encoded geometry] - var idConfig = itemsStrings[i].split(":") - idConfig[0] = idConfig[0].replace("%3A", ":") - //ignore if malformed or there isn't an applet with such id - if (idConfig.length < 2 || appletsMap[idConfig[0]] === undefined) { - continue; - } - - //array [x, y, width, height, rotation] - //print("Restoring applet " + idConfig[0] + " at " + idConfig[1]); - var rect = idConfig[1].split(",") - if (rect.length < 5) { - continue - } - - itemsConfig[idConfig[0]] = { - x: rect[0], - y: rect[1], - width: rect[2], - height: rect[3], - rotation: parseFloat(rect[4]) - }; - } -} - -function save() -{ - var configString = ""; - - for (var _id in itemsConfig) { - var rect = itemsConfig[_id]; - var idstring = _id.replace(":", "%3A"); - if (idstring != "undefined") { - configString += idstring + ":" + rect.x + "," + rect.y + "," + rect.width + "," + rect.height + "," + rect.rotation + ";"; - } - } - - if (plasmoid) { - plasmoid.configuration.ItemsGeometries = configString; - } -} - -function resetPositions() -{ - positions = [] -} - -//returns the available size at a given position -function availableSpace(x, y, width, height) -{ - var row = Math.round(x/cellSize.width) - var column = Math.round(y/cellSize.height) - var rowsWidth = Math.ceil(width/cellSize.width) - var columnsHeight = Math.ceil(height/cellSize.height) - - var availableSize = { - width: 0, - height: 0 - } - - if (x < 0 || y < 0) { - return availableSize; - } - - if (positions[row] === undefined || !positions[row][column]) { - for (var w = 0; w < rowsWidth; ++w) { - if (positions[row + w] && positions[row + w][column]) { - break; - } else { - availableSize.width = w+1 - } - } - - for (var h = 0; h < columnsHeight; ++h) { - //occupied? - var free = true - - //using availableSize.width instead of rowsWidth or the result will be 0 - var rowEnd = row + availableSize.width - for (var i = row; i < rowEnd; ++i) { - if (positions[i] && positions[i][column + h]) { - free = false - break - } - } - - if (free) { - availableSize.height = h+1 - } else { - //print("occupied"+row+" "+column+" "+h+" "+positions[row][column+h]+" "+availableSize.height) - break - } - } - } - - availableSize.width *= cellSize.width - availableSize.height *= cellSize.height - - //don't make it overflow - availableSize.width = Math.min(availableSize.width, - (resultsFlow.width-row*cellSize.width)) - - return availableSize -} - -function setSpaceAvailable(x, y, width, height, available) -{ - var row = Math.round(x/cellSize.width) - var column = Math.round(y/cellSize.height) - var rowsWidth = Math.round(width/cellSize.width) - var columnsHeight = Math.round(height/cellSize.height) - - var rowEnd = row + rowsWidth; - for (var i = row; i < rowEnd; ++i) { - if (!positions[i]) { - positions[i] = [] - } - var columnEnd = column + columnsHeight; - for (var j = column; j < columnEnd; ++j) { - positions[i][j] = !available - //print("set "+i+" "+j+" "+!available) - } - } -} - -function adjustItemSizeToAvailableScreenRegion(x, y, width, height) -{ - var pos = root.mapToItem(root.parent, x, y); - pos = plasmoid.adjustToAvailableScreenRegion(pos.x, pos.y, width, height); - pos = root.mapFromItem(root.parent, pos.x, pos.y); - return pos; -} - -function normalizeItemPosition(item) -{ - var x = Math.max(0, Math.round(item.x/cellSize.width)*cellSize.width) - var y = Math.max(0, Math.round(item.y/cellSize.height)*cellSize.height) - - var width = Math.max(cellSize.width, Math.round(item.width/cellSize.width)*cellSize.width) - var height = Math.max(cellSize.height, Math.round(item.height/cellSize.height)*cellSize.height) - - var pos = adjustItemSizeToAvailableScreenRegion(x, y, width, height); - item.x = pos.x; - item.y = pos.y; - - /*item.width = width - item.height = height*/ -} - -function positionItem(item) -{ - var x = Math.max(0, Math.round(item.x/cellSize.width)*cellSize.width) - var y = Math.max(0, Math.round(item.y/cellSize.height)*cellSize.height) - - var pos = adjustItemSizeToAvailableScreenRegion(x, y, item.width, item.height); - x = pos.x; - y = pos.y; - - var forwardX = x - var forwardY = y - var backX = x - cellSize.width - var backY = y - var avail - - while (forwardY < plasmoid.height) { - //look forward - var forwardAvail = availableSpace(forwardX, forwardY, - Math.max(item.minimumWidth, item.width), - Math.max(item.minimumHeight, item.height)) - //print("checking forward "+item.x+" "+item.y+" "+forwardX/cellSize.width+" "+forwardY/cellSize.height+" "+forwardAvail.width/cellSize.width+" "+forwardAvail.height/cellSize.height) - - //print("response: forwardAvail: "+forwardAvail.width+"x"+forwardAvail.height+" minimumSize: "+item.minimumWidth+"x"+item.minimumHeight+"\n\n") - - if (forwardAvail.width >= Math.max(item.minimumWidth, cellSize.width) && - forwardAvail.height >= Math.max(item.minimumHeight, cellSize.height)) { - x = forwardX - y = forwardY - avail = forwardAvail - break - } - forwardX += cellSize.width - //new line - if (forwardX+item.width > resultsFlow.width) { - forwardX = 0 - forwardY += cellSize.height - //forward positions exausted - //scrolling now - /*if (forwardY > resultsFlow.height) { - break; - }*/ - } - - //backwards positions exausted - if (backY < 0) { - continue - } - - //look backwards - var backAvail = availableSpace(backX, backY, - Math.max(item.minimumWidth, item.width), - Math.max(item.minimumHeight, item.height)) - //print("checking backwards "+backX/cellSize.width+" "+backY/cellSize.height+" "+backAvail.width/cellSize.width+" "+backAvail.height/cellSize.height) - - if (backAvail.width >= Math.max(item.minimumWidth, cellSize.width) && - backAvail.height >= Math.max(item.minimumHeight, cellSize.height)) { - x = backX - y = backY - avail = backAvail - break - } - backX -= cellSize.width - if (backX < 0) { - backX = resultsFlow.width - item.width - backY -= cellSize.height - } - } - - var width = Math.max(cellSize.width*Math.max(1, Math.ceil(item.minimumWidth/cellSize.width)), - Math.round(Math.min(avail.width, item.width)/cellSize.width)*cellSize.width) - var height = Math.max(cellSize.height*Math.max(1, Math.ceil(item.minimumHeight/cellSize.height)), - Math.round(Math.min(avail.height, item.height)/cellSize.height)*cellSize.height) - - setSpaceAvailable(x, y, width, height, false) - //resultsFlow.height = Math.max(resultsFlow.height, y+cellSize.height) - - item.x = x - item.y = y - item.width = width - item.height = height - - saveItem(item); -} - -function removeApplet(applet) { - // Keeps config in sync, deletion of items in the scene - // are handled in AppletAppearance and main.qml - delete itemsConfig["Applet-"+applet.id]; - delete itemGroups["Applet-"+applet.id]; -} - -function saveItem(item) { - var rect = { - x: item.x, - y: item.y, - width: item.width, - height: item.height, - rotation: item.rotation - }; - - //save only things that actually have a category (exclude the placeholder) - if (item.category) { - //print("-- Saving rotation : " + rect.rotation); - itemsConfig[item.category] = rect - } -} - -function saveRotation(item) { - if (item.category) { - rotations[item.category] = item.rotation; - } -} - -function restoreRotation(item) { - if (item.category && rotations[item.category]) { - item.rotation = rotations[item.category]; - } -} diff --git a/containments/desktop/package/contents/ui/main.qml b/containments/desktop/package/contents/ui/main.qml index 2bdbbb5df..f934a8cd6 100644 --- a/containments/desktop/package/contents/ui/main.qml +++ b/containments/desktop/package/contents/ui/main.qml @@ -1,618 +1,414 @@ /*************************************************************************** * Copyright (C) 2011-2013 Sebastian Kügler * - * Copyright (C) 2011 Marco Martin * + * Copyright (C) 2011-2019 Marco Martin * * Copyright (C) 2014-2015 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.4 import QtQuick.Layouts 1.1 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.draganddrop 2.0 as DragDrop import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons import org.kde.private.desktopcontainment.desktop 0.1 as Desktop import org.kde.private.desktopcontainment.folder 0.1 as Folder -import "code/LayoutManager.js" as LayoutManager +import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager + import "code/FolderTools.js" as FolderTools FolderViewDropArea { id: root objectName: isFolder ? "folder" : "desktop" width: isPopup ? undefined : preferredWidth(false) // Initial size when adding to e.g. desktop. height: isPopup ? undefined : preferredHeight(false) // Initial size when adding to e.g. desktop. Layout.minimumWidth: preferredWidth(!isPopup) Layout.minimumHeight: preferredHeight(!isPopup) Layout.preferredWidth: preferredWidth(false) Layout.preferredHeight: preferredHeight(false) Layout.maximumWidth: isPopup ? preferredWidth(false) : -1 Layout.maximumHeight: isPopup ? preferredHeight(false) : -1 Plasmoid.switchWidth: { // Support expanding into the full representation only on vertical panels. if (isPopup && plasmoid.formFactor === PlasmaCore.Types.Vertical) { return units.iconSizeHints.panel; } return 0; } Plasmoid.switchHeight: { // Support expanding into the full representation only on vertical panels. if (isPopup && plasmoid.formFactor === PlasmaCore.Types.Vertical) { return units.iconSizeHints.panel; } return 0; } LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft LayoutMirroring.childrenInherit: true property bool isFolder: (plasmoid.pluginName === "org.kde.plasma.folder") property bool isContainment: ("containmentType" in plasmoid) property bool isPopup: (plasmoid.location !== PlasmaCore.Types.Floating) property bool useListViewMode: isPopup && plasmoid.configuration.viewMode === 0 property Component appletAppearanceComponent property Item toolBox - property var layoutManager: LayoutManager property int handleDelay: 800 property real haloOpacity: 0.5 property int iconSize: units.iconSizes.small property int iconWidth: iconSize property int iconHeight: iconWidth readonly property int hoverActivateDelay: 750 // Magic number that matches Dolphin's auto-expand folders delay. preventStealing: true // Plasmoid.title is set by a Binding {} in FolderViewLayer Plasmoid.toolTipSubText: "" Plasmoid.icon: (!plasmoid.configuration.useCustomIcon && folderViewLayer.ready) ? folderViewLayer.view.model.iconName : plasmoid.configuration.icon Plasmoid.compactRepresentation: (isFolder && !isContainment) ? compactRepresentation : null Plasmoid.associatedApplicationUrls: folderViewLayer.ready ? folderViewLayer.model.resolvedUrl : null onIconHeightChanged: updateGridSize() anchors { leftMargin: (isContainment && plasmoid.availableScreenRect) ? plasmoid.availableScreenRect.x : 0 topMargin: (isContainment && plasmoid.availableScreenRect) ? plasmoid.availableScreenRect.y : 0 rightMargin: (isContainment && plasmoid.availableScreenRect) && parent ? parent.width - (plasmoid.availableScreenRect.x + plasmoid.availableScreenRect.width) : 0 bottomMargin: (isContainment && plasmoid.availableScreenRect) && parent ? parent.height - (plasmoid.availableScreenRect.y + plasmoid.availableScreenRect.height) : 0 } Behavior on anchors.topMargin { NumberAnimation { duration: units.longDuration; easing.type: Easing.InOutQuad } } Behavior on anchors.leftMargin { NumberAnimation { duration: units.longDuration; easing.type: Easing.InOutQuad } } Behavior on anchors.rightMargin { NumberAnimation { duration: units.longDuration; easing.type: Easing.InOutQuad } } Behavior on anchors.bottomMargin { NumberAnimation { duration: units.longDuration; easing.type: Easing.InOutQuad } } function updateGridSize() { - LayoutManager.cellSize.width = root.iconWidth + toolBoxSvg.elementSize("left").width + toolBoxSvg.elementSize("right").width - LayoutManager.cellSize.height = root.iconHeight + toolBoxSvg.elementSize("top").height + toolBoxSvg.elementSize("bottom").height; - LayoutManager.defaultAppletSize.width = LayoutManager.cellSize.width * 6; - LayoutManager.defaultAppletSize.height = LayoutManager.cellSize.height * 6; + appletsLayout.cellWidth = root.iconWidth + toolBoxSvg.elementSize("left").width + toolBoxSvg.elementSize("right").width + appletsLayout.cellHeight = root.iconHeight + toolBoxSvg.elementSize("top").height + toolBoxSvg.elementSize("bottom").height; + appletsLayout.defaultItemWidth = appletsLayout.cellWidth * 6; + appletsLayout.defaultItemHeight = appletsLayout.cellHeight * 6; layoutTimer.restart(); } function addLauncher(desktopUrl) { if (!isFolder) { return; } folderViewLayer.view.linkHere(desktopUrl); } - function addApplet(applet, x, y) { - if (!appletAppearanceComponent) { - appletAppearanceComponent = Qt.createComponent("AppletAppearance.qml"); - } - - if (appletAppearanceComponent.status !== Component.Ready) { - console.warn("Error loading AppletAppearance.qml:", appletAppearanceComponent.errorString()); - return; - } - - var category = "Applet-" + applet.id; - - var container = appletAppearanceComponent.createObject(resultsFlow, { - category: category - }); - - applet.parent = container - applet.visible = true; - - var config = LayoutManager.itemsConfig[category]; - - // We have it in the config. - if (config !== undefined && config.width !== undefined && - config.height !== undefined && - config.width > 0 && config.height > 0) { - container.width = config.width; - container.height = config.height; - // We have a default. - } else if (applet.width > 0 && applet.height > 0) { - container.width = applet.width; - container.height = applet.height; - // The container needs to be bigger than applet of margins factor. - if (applet.backgroundHints !== PlasmaCore.Types.NoBackground) { - container.width += container.margins.left + container.margins.right; - container.height += container.margins.top + container.margins.bottom; - } - // Give up, assign the global default. - } else { - container.width = LayoutManager.defaultAppletSize.width; - container.height = LayoutManager.defaultAppletSize.height; - } - - container.applet = applet; - - // Coordinated passed by param? - if ( x >= 0 && y >= 0) { - if (x + container.width > root.width) { - x = root.width - container.width - 10; - } - if (y + container.height > root.height) { - x = root.height - container.height; - } - - // On applet undo or via scripting, the applet position will be saved - // in applet's scene coordinates so remap it to resultsflow's coordinates. - var pos = root.parent.mapToItem(resultsFlow, x, y); - - container.x = pos.x; - container.y = pos.y; - - // To be sure it's restored at the same position, take margins into account - // if there is a background. - if (applet.backgroundHints !== PlasmaCore.Types.NoBackground) { - container.x -= container.margins.left; - container.y -= container.margins.top; - } - - // Coordinates stored? - } else if (config !== undefined && config.x !== undefined && config.y !== undefined && - config.x >= 0 && config.y >= 0) { - container.x = config.x; - container.y = config.y; - } - - // Rotation stored and significant? - if (config !== undefined && config.rotation !== undefined && - (config.rotation > 5 || config.rotation < -5)) { - container.rotation = config.rotation; - } else { - LayoutManager.restoreRotation(container); - } - - LayoutManager.itemGroups[container.category] = container; - - if (container.x >= 0 && container.y >= 0) { - LayoutManager.positionItem(container); - } - } - function preferredWidth(minimum) { if (isContainment || !folderViewLayer.ready) { return -1; } else if (useListViewMode) { return (minimum ? folderViewLayer.view.cellHeight * 4 : units.gridUnit * 16); } return (folderViewLayer.view.cellWidth * (minimum ? 1 : 3)) + (units.largeSpacing * 2); } function preferredHeight(minimum) { if (isContainment || !folderViewLayer.ready) { return -1; } else if (useListViewMode) { var height = (folderViewLayer.view.cellHeight * (minimum ? 1 : 15)) + units.smallSpacing; } else { var height = (folderViewLayer.view.cellHeight * (minimum ? 1 : 2)) + units.largeSpacing } if (plasmoid.configuration.labelMode !== 0) { height += folderViewLayer.item.labelHeight; } return height; } function isDrag(fromX, fromY, toX, toY) { var length = Math.abs(fromX - toX) + Math.abs(fromY - toY); return length >= Qt.styleHints.startDragDistance; } onFocusChanged: { if (focus && isFolder) { folderViewLayer.item.forceActiveFocus(); } } onDragEnter: { if (isContainment && plasmoid.immutable && !(isFolder && FolderTools.isFileDrag(event))) { event.ignore(); } // Don't allow any drops while listing. if (isFolder && folderViewLayer.view.status === Folder.FolderModel.Listing) { event.ignore(); } // Firefox tabs are regular drags. Since all of our drop handling is asynchronous // we would accept this drop and have Firefox not spawn a new window. (Bug 337711) if (event.mimeData.formats.indexOf("application/x-moz-tabbrowser-tab") > -1) { event.ignore(); } } onDragMove: { // TODO: We should reject drag moves onto file items that don't accept drops // (cf. QAbstractItemModel::flags() here, but DeclarativeDropArea currently // is currently incapable of rejecting drag events. // Trigger autoscroll. if (isFolder && FolderTools.isFileDrag(event)) { handleDragMove(folderViewLayer.view, mapToItem(folderViewLayer.view, event.x, event.y)); } else if (isContainment) { - placeHolder.width = LayoutManager.defaultAppletSize.width; - placeHolder.height = LayoutManager.defaultAppletSize.height; - placeHolder.minimumWidth = placeHolder.minimumHeight = 0; - placeHolder.x = event.x - placeHolder.width / 2; - placeHolder.y = event.y - placeHolder.width / 2; - LayoutManager.positionItem(placeHolder); - LayoutManager.setSpaceAvailable(placeHolder.x, placeHolder.y, placeHolder.width, placeHolder.height, true); - placeHolderPaint.opacity = root.haloOpacity; + appletsLayout.showPlaceHolderAt( + Qt.rect(event.x - appletsLayout.minimumItemWidth / 2, + event.y - appletsLayout.minimumItemHeight / 2, + appletsLayout.minimumItemWidth, + appletsLayout.minimumItemHeight) + ); } } onDragLeave: { // Cancel autoscroll. if (isFolder) { handleDragEnd(folderViewLayer.view); } if (isContainment) { - placeHolderPaint.opacity = 0; + appletsLayout.hidePlaceHolder(); } } onDrop: { if (isFolder && FolderTools.isFileDrag(event)) { handleDragEnd(folderViewLayer.view); folderViewLayer.view.drop(root, event, mapToItem(folderViewLayer.view, event.x, event.y)); } else if (isContainment) { - placeHolderPaint.opacity = 0; - var pos = root.parent.mapFromItem(resultsFlow, event.x - placeHolder.width / 2, event.y - placeHolder.height / 2); - plasmoid.processMimeData(event.mimeData, pos.x, pos.y); + plasmoid.processMimeData(event.mimeData, + event.x - appletsLayout.placeHolder.width / 2, event.y - appletsLayout.placeHolder.height / 2); event.accept(event.proposedAction); + appletsLayout.hidePlaceHolder(); } } Component { id: compactRepresentation CompactRepresentation { folderView: folderViewLayer.view } } Connections { target: plasmoid ignoreUnknownSignals: true - onAppletAdded: { - addApplet(applet, x, y); - // Clean any eventual invalid chunks in the config. - LayoutManager.save(); - } - - onAppletRemoved: { - // Clean any eventual invalid chunks in the config. - LayoutManager.removeApplet(applet); - LayoutManager.save(); - } onImmutableChanged: { if (root.isContainment && !plasmoid.immutable) { pressToMoveHelp.show(); } } onAvailableScreenRegionChanged: layoutTimer.restart(); } Connections { target: plasmoid.configuration onPressToMoveChanged: { if (plasmoid.configuration.pressToMove && plasmoid.configuration.pressToMoveHelp && !plasmoid.immutable) { pressToMoveHelp.show(); } } } Binding { target: toolBox property: "visible" value: plasmoid.configuration.showToolbox } Desktop.InfoNotification { id: pressToMoveHelp enabled: plasmoid.configuration.pressToMove && plasmoid.configuration.pressToMoveHelp iconName: "plasma" titleText: i18n("Widgets unlocked") text: i18n("You can press and hold widgets to move them and reveal their handles.") acknowledgeActionText: i18n("Got it") onAcknowledged: { plasmoid.configuration.pressToMoveHelp = false; } } PlasmaCore.FrameSvgItem { id : highlightItemSvg visible: false imagePath: isPopup ? "widgets/viewitem" : "" prefix: "hover" } PlasmaCore.FrameSvgItem { id : listItemSvg visible: false imagePath: isPopup ? "widgets/viewitem" : "" prefix: "normal" } PlasmaCore.Svg { id: toolBoxSvg imagePath: "widgets/toolbox" property int rightBorder: elementSize("right").width property int topBorder: elementSize("top").height property int bottomBorder: elementSize("bottom").height property int leftBorder: elementSize("left").width } - PlasmaCore.Svg { - id: configIconsSvg - imagePath: "widgets/configuration-icons" - } - + // Can be removed? KQuickControlsAddons.EventGenerator { id: eventGenerator } - MouseArea { // unfocus any plasmoid when clicking empty desktop area - anchors.fill: parent - onPressed: { - root.forceActiveFocus(); - mouse.accepted = false // Bug 351277 - - if (toolBox && toolBox.open) { - toolBox.open = false; - } - } - } - - Loader { - id: folderViewLayer - - anchors.fill: parent - - property bool ready: status == Loader.Ready - property Item view: item ? item.view : null - property QtObject model: item ? item.model : null - - focus: true - - active: isFolder - asynchronous: false - - source: "FolderViewLayer.qml" - - onFocusChanged: { - if (!focus && model) { - model.clearSelection(); - } - } - - Connections { - target: folderViewLayer.view - - // `FolderViewDropArea` is not a FocusScope. We need to forward manually. - onPressed: { - folderViewLayer.forceActiveFocus(); - } - } + Connections { + target: plasmoid + onEditModeChanged: appletsLayout.editMode = plasmoid.editMode } - Item { - id: resultsFlow + ContainmentLayoutManager.AppletsLayout { + id: appletsLayout anchors.fill: parent - - anchors { - top: parent.top - topMargin: 5 - horizontalCenter: parent.horizontalCenter - } - - visible: isContainment - enabled: isContainment - - // This is just for event compression when a lot of boxes are created one after the other. - Timer { - id: layoutTimer - repeat: false - running: false - interval: 100 - onTriggered: { - LayoutManager.resetPositions() - for (var i=0; i plasmoid.availableScreenRect.height ? "ItemGeometriesHorizontal" : "ItemGeometriesVertical" + containment: plasmoid + editModeCondition: plasmoid.immutable + ? ContainmentLayoutManager.AppletsLayout.Locked + : ContainmentLayoutManager.AppletsLayout.Manual + + // Sets the containment in edit mode when we go in edit mode as well + onEditModeChanged: plasmoid.editMode = editMode + + minimumItemWidth: units.gridUnit * 3 + minimumItemHeight: minimumItemWidth + + cellWidth: units.iconSizes.small + cellHeight: cellWidth + + appletContainerComponent: ContainmentLayoutManager.BasicAppletContainer { + id: appletContainer + editModeCondition: plasmoid.immutable + ? ContainmentLayoutManager.ItemContainer.Locked + : (plasmoid.configuration.pressToMove ? ContainmentLayoutManager.ItemContainer.AfterPressAndHold : ContainmentLayoutManager.ItemContainer.AfterMouseOver) + configOverlayComponent: ConfigOverlay {} + onUserDrag: { + var pos = mapToItem(root.parent, dragCenter.x, dragCenter.y); + var newCont = plasmoid.containmentAt(pos.x, pos.y); + + if (newCont && newCont !== plasmoid) { + var newPos = newCont.mapFromApplet(plasmoid, pos.x, pos.y); + + newCont.addApplet(appletContainer.applet, newPos.x, newPos.y); + appletsLayout.hidePlaceHolder(); } - LayoutManager.save() } } - } - Item { - id: placerHolderWrapper + placeHolder: ContainmentLayoutManager.PlaceHolder {} - anchors.fill: resultsFlow - z: 0 + Loader { + id: folderViewLayer - visible: isContainment - enabled: isContainment + anchors.fill: parent - Item { - id: placeHolder + property bool ready: status == Loader.Ready + property Item view: item ? item.view : null + property QtObject model: item ? item.model : null - x: -10000 // Move offscreen initially to avoid flickering. - width: 100 - height: 100 + focus: true - property bool animationsEnabled - property int minimumWidth - property int minimumHeight - property Item syncItem + active: isFolder + asynchronous: false - function syncWithItem(item) { - syncItem = item; - minimumWidth = item.minimumWidth; - minimumHeight = item.minimumHeight; - repositionTimer.running = true; - if (placeHolderPaint.opacity < 1) { - placeHolder.delayedSyncWithItem(); - } - } - - function delayedSyncWithItem() { - placeHolder.x = placeHolder.syncItem.x; - placeHolder.y = placeHolder.syncItem.y; - placeHolder.width = placeHolder.syncItem.width + (plasmoid.immutable || !syncItem.showAppletHandle ? 0 : syncItem.handleWidth) - placeHolder.height = placeHolder.syncItem.height; - // Only positionItem here, we don't want to save. - LayoutManager.positionItem(placeHolder); - LayoutManager.setSpaceAvailable(placeHolder.x, placeHolder.y, placeHolder.width, placeHolder.height, true); - } + source: "FolderViewLayer.qml" - Timer { - id: repositionTimer - interval: 100 - repeat: false - running: false - onTriggered: placeHolder.delayedSyncWithItem() + onFocusChanged: { + if (!focus && model) { + model.clearSelection(); + } } - } - - PlasmaComponents.Highlight { - id: placeHolderPaint - - x: placeHolder.x - y: placeHolder.y - width: placeHolder.width - height: placeHolder.height - z: 0 - opacity: 0 - visible: opacity > 0 + Connections { + target: folderViewLayer.view - Behavior on opacity { - NumberAnimation { - duration: units.longDuration - easing.type: Easing.InOutQuad + // `FolderViewDropArea` is not a FocusScope. We need to forward manually. + onPressed: { + folderViewLayer.forceActiveFocus(); } } } } Component.onCompleted: { if (!isContainment) { return; } // Customize the icon and text to improve discoverability plasmoid.setAction("configure", i18n("Configure Desktop..."), "preferences-desktop-wallpaper") // WORKAROUND: that's the only place where we can inject a sensible size. // if root has width defined, it will override the value we set before // the component completes root.width = plasmoid.width; - LayoutManager.resultsFlow = resultsFlow; - LayoutManager.plasmoid = plasmoid; updateGridSize(); - - LayoutManager.restore(); - - for (var i = 0; i < plasmoid.applets.length; ++i) { - var applet = plasmoid.applets[i]; - addApplet(applet, -1, -1); - } - - // Clean any eventual invalid chunks in the config. - LayoutManager.save(); } } diff --git a/desktoppackage/contents/updates/move_desktop_layout_config.js b/desktoppackage/contents/updates/move_desktop_layout_config.js new file mode 100644 index 000000000..45d404df7 --- /dev/null +++ b/desktoppackage/contents/updates/move_desktop_layout_config.js @@ -0,0 +1,10 @@ +var allDesktops = desktops(); + +for (var i = 0; i < allDesktops.length; ++i) { + var desktop = allDesktops[i]; + desktop.currentConfigGroup = ["General"]; + var serializedItems = desktop.readConfig("ItemsGeometries"); + desktop.currentConfigGroup = []; + desktop.writeConfig("ItemGeometriesHorizontal", serializedItems); + desktop.reloadConfig() +}