diff options
Diffstat (limited to 'tests/manual/qt-shell/qml/Chrome.qml')
-rw-r--r-- | tests/manual/qt-shell/qml/Chrome.qml | 458 |
1 files changed, 458 insertions, 0 deletions
diff --git a/tests/manual/qt-shell/qml/Chrome.qml b/tests/manual/qt-shell/qml/Chrome.qml new file mode 100644 index 000000000..9eb2f1965 --- /dev/null +++ b/tests/manual/qt-shell/qml/Chrome.qml @@ -0,0 +1,458 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtWayland.Compositor + +Item { + id: chrome + + property bool positionSet: false + + x: shellSurface.windowGeometry.x - leftResizeHandle.width + y: shellSurface.windowGeometry.y - topResizeHandle.height - titleBar.height + width: shellSurface.windowGeometry.width + leftResizeHandle.width + rightResizeHandle.width + height: shellSurface.windowGeometry.height + topResizeHandle.height + titleBar.height + bottomResizeHandle.height + + property rect oldGeometry: Qt.rect(0, 0, 100, 100) + property bool isChild: parent.shellSurface !== undefined + property alias shellSurface: shellSurfaceItem.shellSurface + + property int windowState: Qt.WindowNoState + + signal destroyAnimationFinished + signal activated + signal deactivated + + property int windowFlags: shellSurface.windowFlags !== Qt.Window + ? shellSurface.windowFlags + : defaultFlags + onDecorationsShowingChanged:{ + shellSurfaceItem.updateFrameMargins() + } + + Component.onCompleted: { + shellSurface.active = true + } + + property int defaultFlags: (Qt.Window + | Qt.WindowMaximizeButtonHint + | Qt.WindowMinimizeButtonHint + | Qt.WindowCloseButtonHint) + + property bool frameless: (chrome.windowFlags & Qt.FramelessWindowHint) != 0 + || (chrome.windowState & Qt.WindowFullScreen) != 0 + || ((chrome.windowFlags & Qt.Popup) == Qt.Popup + && (chrome.windowFlags & Qt.Tool) != Qt.Tool) + + property bool decorationsShowing: (chrome.windowFlags & Qt.Window) != 0 && !frameless + + transform: [ + Scale { + id: scaleTransform + origin.x: chrome.width / 2 + origin.y: chrome.height / 2 + } + ] + + Rectangle { + id: leftResizeHandle + color: "gray" + width: visible ? 5 : 0 + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + visible: decorationsShowing + + HandleHandler { + enabled: (chrome.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + flags: westBound + } + } + + Rectangle { + id: rightResizeHandle + color: "gray" + width: visible ? 5 : 0 + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + visible: decorationsShowing + + HandleHandler { + enabled: (chrome.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + flags: eastBound + } + } + + Rectangle { + id: topResizeHandle + color: "gray" + height: visible ? 5 : 0 + anchors.left: parent.left + anchors.top: parent.top + anchors.right: parent.right + visible: decorationsShowing + + HandleHandler { + enabled: (chrome.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + flags: northBound + } + } + + Rectangle { + id: bottomResizeHandle + color: "gray" + height: visible ? 5 : 0 + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.right: parent.right + visible: decorationsShowing + + HandleHandler { + enabled: (chrome.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + flags: southBound + } + } + + Rectangle { + id: topLeftResizeHandle + color: "gray" + height: 5 + width: 5 + anchors.left: parent.left + anchors.top: parent.top + visible: decorationsShowing + + HandleHandler { + enabled: (chrome.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + flags: westBound | northBound + } + } + + Rectangle { + id: topRightResizeHandle + color: "gray" + height: 5 + width: 5 + anchors.right: parent.right + anchors.top: parent.top + visible: decorationsShowing + + HandleHandler { + enabled: (chrome.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + flags: eastBound | northBound + } + } + + Rectangle { + id: bottomLeftResizeHandle + color: "gray" + height: 5 + width: 5 + anchors.left: parent.left + anchors.bottom: parent.bottom + visible: decorationsShowing + + HandleHandler { + enabled: (chrome.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + flags: westBound | southBound + } + } + + Rectangle { + id: bottomRightResizeHandle + color: "gray" + height: 5 + width: 5 + anchors.right: parent.right + anchors.bottom: parent.bottom + visible: decorationsShowing + + HandleHandler { + enabled: (chrome.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + flags: eastBound | southBound + } + } + + function constrainPoint(mousePos) { + var x0 = usableArea.x + var y0 = usableArea.y + var x1 = x0 + usableArea.width + var y1 = y0 + usableArea.height + return Qt.point(Math.min(Math.max(x0,mousePos.x), x1), + Math.min(Math.max(y0,mousePos.y), y1)) + } + + function maxContentRect() { + var x0 = usableArea.x + leftResizeHandle.width + var x1 = usableArea.x + usableArea.width - rightResizeHandle.width + var y0 = usableArea.y + topResizeHandle.height + titleBar.height + var y1 = usableArea.y + usableArea.height - bottomResizeHandle.height + return Qt.rect(x0, y0, x1 - x0, y1 - y0) + } + + function randomPos(windowSize, screenSize) { + var res = (windowSize >= screenSize) ? 0 : Math.floor(Math.random() * (screenSize - windowSize)) + return res + } + + function activate() + { + shellSurface.active = true + shellSurfaceItem.raise() + activated() + } + + function deactivate() + { + shellSurface.active = true + deactivated() + } + + function setWindowState(nextState) { + var currentState = chrome.windowState + if (currentState === nextState) + return + + console.log("setWindowState", nextState.toString(16)) + + if ((currentState & (Qt.WindowMinimized | Qt.WindowMaximized | Qt.WindowFullScreen)) == 0) + chrome.oldGeometry = chrome.shellSurface.windowGeometry + + chrome.windowState = nextState + + if ((nextState & Qt.WindowMinimized) != 0) { + console.log("MINIMIZE") + chrome.shellSurface.requestWindowGeometry(nextState, Qt.rect(0, 0, 1, 1)) + shellSurfaceItem.visible = false + } else if ((nextState & Qt.WindowFullScreen) != 0) { + console.log("FULLSCREENIZE") + chrome.shellSurface.requestWindowGeometry(nextState, Qt.rect(0, 0, output.window.width, output.window.height)) + shellSurfaceItem.visible = true + } else if ((nextState & Qt.WindowMaximized) != 0) { + console.log("MAXIMIZE") + chrome.shellSurface.requestWindowGeometry(nextState, maxContentRect()) + shellSurfaceItem.visible = true + } else { + console.log("NORMALIZE", chrome.oldGeometry) + chrome.shellSurface.requestWindowGeometry(nextState, chrome.oldGeometry) + shellSurfaceItem.visible = true + } + } + + Rectangle { + id: titleBar + anchors.top: topResizeHandle.bottom + anchors.left: leftResizeHandle.right + anchors.right: rightResizeHandle.left + height: visible ? xButton.height + 10 : 0 + color: shellSurface.active ? "cornflowerblue" : "lightgray" + visible: !frameless + + Text { + anchors.left: parent.left + anchors.right: rowLayout.left + anchors.verticalCenter: parent.verticalCenter + + font.pixelSize: xButton.height + text: shellSurface.windowTitle + fontSizeMode: Text.Fit + } + + RowLayout { + id: rowLayout + anchors.right: parent.right + anchors.rightMargin: 5 + + ToolButton { + text: "-" + Layout.margins: 5 + visible: (chrome.windowFlags & Qt.WindowMinimizeButtonHint) != 0 + onClicked: { + var newState + if ((shellSurface.windowState & Qt.WindowMinimized) != 0) + newState = chrome.windowState & ~Qt.WindowMinimized + else + newState = chrome.windowState | Qt.WindowMinimized + + if ((newState & Qt.WindowMaximized) != 0) + newState &= ~Qt.WindowMaximized + + setWindowState(newState) + } + } + + ToolButton { + text: "+" + Layout.margins: 5 + visible: (chrome.windowFlags & Qt.WindowMaximizeButtonHint) != 0 + onClicked: { + var newState + if ((shellSurface.windowState & Qt.WindowMaximized) != 0) + newState = shellSurface.windowState & ~Qt.WindowMaximized + else + newState = shellSurface.windowState | Qt.WindowMaximized + + if ((newState & Qt.WindowMinimized) != 0) + newState &= ~Qt.WindowMinimized + + setWindowState(newState) + } + } + + ToolButton { + id: xButton + text: "X" + Layout.margins: 5 + visible: (chrome.windowFlags & Qt.WindowCloseButtonHint) != 0 + onClicked: shellSurface.sendClose() + } + } + + DragHandler { + target: null + property real xOffset: -1.0 + property real yOffset: -1.0 + property bool started: false + enabled: (shellSurface.windowState & (Qt.WindowMinimized|Qt.WindowMaximized)) == 0 + + onGrabChanged: { + started = false + activate() + } + + onCentroidChanged: { + if (!active) + return + + if (!started) { + xOffset = shellSurface.windowPosition.x - centroid.scenePressPosition.x + yOffset = shellSurface.windowPosition.y - centroid.scenePressPosition.y + started = true + chrome.positionAutomatic = false + } + + var pos = chrome.constrainPoint(centroid.scenePosition) + shellSurface.windowPosition = Qt.point(pos.x + xOffset, pos.y + yOffset) + } + } + } + + ShellSurfaceItem { + id: shellSurfaceItem + anchors.top: titleBar.bottom + anchors.bottom: bottomResizeHandle.top + anchors.left: leftResizeHandle.right + anchors.right: rightResizeHandle.left + + moveItem: chrome + + staysOnBottom: shellSurface.windowFlags & Qt.WindowStaysOnBottomHint + staysOnTop: !staysOnBottom && shellSurface.windowFlags & Qt.WindowStaysOnTopHint + function updateFrameMargins() + { + shellSurface.frameMarginLeft = (decorationsShowing ? leftResizeHandle.width : 0) + shellSurface.frameMarginRight = (decorationsShowing ? rightResizeHandle.width : 0) + shellSurface.frameMarginTop = (decorationsShowing ? topResizeHandle.height : 0) + + (!frameless ? titleBar.height : 0) + shellSurface.frameMarginBottom = (decorationsShowing ? bottomResizeHandle.height : 0) + } + + Component.onCompleted: { + updateFrameMargins() + } + + onSurfaceDestroyed: { + bufferLocked = true; + destroyAnimation.start(); + } + + Connections { + target: shellSurface + function onWindowFlagsChanged() { + console.log("FLAGS", shellSurface.windowFlags.toString(16)) + shellSurfaceItem.updateFrameMargins() + } + + function onWindowStateChanged() { + setWindowState(shellSurface.windowState) + } + + function onActiveChanged() { + if (shellSurface.active) { + shellSurfaceItem.raise() + activated() + } else { + deactivated() + } + } + + function onStartResize() { + console.log("START SYSTEM RESIZE") + } + function onStartMove() { + console.log("START SYSTEM MOVE") + } + + function onRaiseRequested() { + console.log("RAISE") + shellSurfaceItem.raise() + } + function onLowerRequested() { + console.log("LOWER") + shellSurfaceItem.lower() + } + + function onWindowGeometryChanged() { + console.log("GEOM CHANGE", shellSurface.windowGeometry) + } + } + + Connections { + target: shellSurface.surface + function onHasContentChanged() { + if (!chrome.positionSet) { + var rect = shellSurface.windowGeometry + var w = rect.width + var h = rect.height + + var space = maxContentRect() + + var randomize = shellSurface.positionAutomatic + var xpos = randomize ? randomPos(w, space.width) + space.x : Math.max(rect.x, space.x) + var ypos = randomize ? randomPos(h, space.height) + space.y : Math.max(rect.y, space.y) + shellSurface.windowPosition = Qt.point(xpos, ypos) + } + chrome.positionSet = true + } + } + + SequentialAnimation { + id: destroyAnimation + + ParallelAnimation { + NumberAnimation { target: scaleTransform; property: "yScale"; to: 2/height; duration: 150 } + NumberAnimation { target: scaleTransform; property: "xScale"; to: 0.4; duration: 150 } + NumberAnimation { target: chrome; property: "opacity"; to: chrome.isChild ? 0 : 1; duration: 150 } + } + NumberAnimation { target: scaleTransform; property: "xScale"; to: 0; duration: 150 } + ScriptAction { script: chrome.destroyAnimationFinished() } + } + + SequentialAnimation { + id: receivedFocusAnimation + + ParallelAnimation { + NumberAnimation { target: scaleTransform; property: "yScale"; to: 1.02; duration: 100; easing.type: Easing.OutQuad } + NumberAnimation { target: scaleTransform; property: "xScale"; to: 1.02; duration: 100; easing.type: Easing.OutQuad } + } + ParallelAnimation { + NumberAnimation { target: scaleTransform; property: "yScale"; to: 1; duration: 100; easing.type: Easing.InOutQuad } + NumberAnimation { target: scaleTransform; property: "xScale"; to: 1; duration: 100; easing.type: Easing.InOutQuad } + } + } + } +} |