diff options
Diffstat (limited to 'examples/wayland/qml-compositor')
-rw-r--r-- | examples/wayland/qml-compositor/ContrastEffect.qml | 90 | ||||
-rw-r--r-- | examples/wayland/qml-compositor/WindowChrome.qml | 63 | ||||
-rw-r--r-- | examples/wayland/qml-compositor/WindowContainer.qml | 212 | ||||
-rw-r--r-- | examples/wayland/qml-compositor/background.jpg | bin | 0 -> 30730 bytes | |||
-rw-r--r-- | examples/wayland/qml-compositor/closebutton.png | bin | 0 -> 25957 bytes | |||
-rw-r--r-- | examples/wayland/qml-compositor/compositor.js | 155 | ||||
-rw-r--r-- | examples/wayland/qml-compositor/main.cpp | 163 | ||||
-rw-r--r-- | examples/wayland/qml-compositor/main.qml | 127 | ||||
-rw-r--r-- | examples/wayland/qml-compositor/qml-compositor.pro | 22 |
9 files changed, 832 insertions, 0 deletions
diff --git a/examples/wayland/qml-compositor/ContrastEffect.qml b/examples/wayland/qml-compositor/ContrastEffect.qml new file mode 100644 index 000000000..c284b2907 --- /dev/null +++ b/examples/wayland/qml-compositor/ContrastEffect.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +ShaderEffect { + property variant source: null; + property color color: "#ffffff" + property real blend; + + onSourceChanged: { + if (source != null) { + source.setPaintEnabled(false); + } + } + + property string vShaderInvertedY: " + uniform highp mat4 qt_Matrix; + attribute highp vec4 qt_Vertex; + attribute highp vec2 qt_MultiTexCoord0; + varying highp vec2 qt_TexCoord0; + void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + gl_Position = qt_Matrix * qt_Vertex; + } + " + property string vShader: " + uniform highp mat4 qt_Matrix; + attribute highp vec4 qt_Vertex; + attribute highp vec2 qt_MultiTexCoord0; + varying highp vec2 qt_TexCoord0; + void main() { + qt_TexCoord0 = vec2(0, 1) + qt_MultiTexCoord0 * vec2(1, -1); + gl_Position = qt_Matrix * qt_Vertex; + } + " + + vertexShader: source && source.isYInverted ? vShaderInvertedY : vShader + + fragmentShader: " + uniform lowp sampler2D source; + uniform highp float qt_Opacity; + uniform highp vec4 color; + uniform highp float blend; + varying highp vec2 qt_TexCoord0; + void main() { + highp vec4 sourceColor = texture2D(source, qt_TexCoord0); + highp vec3 delta = sourceColor.rgb - vec3(0.5); + highp vec3 lowerContrast = vec3(0.5) + 0.4 * delta; + gl_FragColor = qt_Opacity * mix(sourceColor, color * sourceColor.a * dot(lowerContrast, vec3(11, 16, 5) * (1. / 32.)), blend); + } + " +} diff --git a/examples/wayland/qml-compositor/WindowChrome.qml b/examples/wayland/qml-compositor/WindowChrome.qml new file mode 100644 index 000000000..fe9f5d78d --- /dev/null +++ b/examples/wayland/qml-compositor/WindowChrome.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: chrome + anchors.fill: parent + + property variant window: parent; + property bool selected: root.selectedWindow === window + + MouseArea { + anchors.fill: parent + enabled: !window.focus + hoverEnabled: !window.focus + onClicked: { + if (selected) { + window.takeFocus(); + } else { + root.selectedWindow = window + root.focus = true + } + } + } +} diff --git a/examples/wayland/qml-compositor/WindowContainer.qml b/examples/wayland/qml-compositor/WindowContainer.qml new file mode 100644 index 000000000..5e073298f --- /dev/null +++ b/examples/wayland/qml-compositor/WindowContainer.qml @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Window 2.0 +import QtCompositor 1.0 + +Item { + id: container + + x: targetX + y: targetY + width: targetWidth + height: targetHeight + scale: targetScale + + visible: isFullscreen || !root.hasFullscreenWindow + onVisibleChanged: { + child.surface.clientRenderingEnabled = visible + } + + opacity: 0 + + property real targetX + property real targetY + property real targetWidth + property real targetHeight + property real targetScale + + property variant child: null + property variant chrome: null + property bool animationsEnabled: false + property bool isFullscreen: state === "fullscreen" + property int index + + state: child && chrome && chrome.selected && child.focus ? "fullscreen" : "normal" + + Behavior on x { + enabled: container.animationsEnabled; + NumberAnimation { easing.type: Easing.InCubic; duration: 200; } + } + + Behavior on y { + enabled: container.animationsEnabled; + NumberAnimation { easing.type: Easing.InQuad; duration: 200; } + } + + Behavior on width { + enabled: container.animationsEnabled; + NumberAnimation { easing.type: Easing.InCubic; duration: 200; } + } + + Behavior on height { + enabled: container.animationsEnabled; + NumberAnimation { easing.type: Easing.InCubic; duration: 200; } + } + + Behavior on scale { + enabled: container.animationsEnabled; + NumberAnimation { easing.type: Easing.InQuad; duration: 200; } + } + + Behavior on opacity { + enabled: true; + NumberAnimation { easing.type: Easing.Linear; duration: 250; } + } + + ContrastEffect { + id: effect + source: child + anchors.fill: parent + blend: { if (child && chrome && (chrome.selected || child.focus)) 0.0; else 0.6 } + opacity: 1.0 + z: 1 + + Behavior on blend { + enabled: true; + NumberAnimation { easing.type: Easing.Linear; duration: 200; } + } + } + + transform: [ + Scale { id: scaleTransform; origin.x: container.width / 2; origin.y: container.height / 2; xScale: 1; yScale: 1 } + ] + + property real fullscreenScale: Math.min(root.width / width, root.height / height) + + transitions: [ + Transition { + from: "*"; to: "normal" + SequentialAnimation { + ScriptAction { + script: { + compositor.fullscreenSurface = null + background.opacity = 1 + } + } + ParallelAnimation { + NumberAnimation { target: container; property: "x"; easing.type: Easing.Linear; to: targetX; duration: 400; } + NumberAnimation { target: container; property: "y"; easing.type: Easing.Linear; to: targetY; duration: 400; } + NumberAnimation { target: container; property: "scale"; easing.type: Easing.Linear; to: targetScale; duration: 400; } + } + ScriptAction { + script: container.z = 0 + } + } + }, + Transition { + from: "*"; to: "fullscreen" + SequentialAnimation { + ScriptAction { + script: { + container.z = 1 + background.opacity = 0 + } + } + ParallelAnimation { + NumberAnimation { target: container; property: "x"; easing.type: Easing.Linear; to: (root.width - container.width) / 2; duration: 400; } + NumberAnimation { target: container; property: "y"; easing.type: Easing.Linear; to: (root.height - container.height) / 2; duration: 400; } + NumberAnimation { target: container; property: "scale"; easing.type: Easing.Linear; to: fullscreenScale; duration: 400; } + } + ScriptAction { + script: compositor.fullscreenSurface = child.surface + } + } + } + ] + + SequentialAnimation { + id: destroyAnimation + NumberAnimation { target: scaleTransform; property: "yScale"; easing.type: Easing.Linear; to: 0.01; duration: 200; } + NumberAnimation { target: scaleTransform; property: "xScale"; easing.type: Easing.Linear; to: 0.01; duration: 150; } + NumberAnimation { target: container; property: "opacity"; easing.type: Easing.Linear; to: 0.0; duration: 150; } + ScriptAction { script: container.parent.removeWindow(container) } + } + SequentialAnimation { + id: unmapAnimation + NumberAnimation { target: container; property: "opacity"; easing.type: Easing.Linear; to: 0.0; duration: 150; } + ScriptAction { script: container.parent.removeWindow(container) } + } + + Connections { + target: container.child ? container.child.surface : null + onUnmapped: unmapAnimation.start() + } + Connections { + target: container.child ? container.child : null + onSurfaceDestroyed: { + destroyAnimation.start(); + } + } + + Image { + source: "closebutton.png" + smooth: true + + opacity: !isFullscreen && chrome && chrome.selected ? 1 : 0 + Behavior on opacity { + NumberAnimation { easing.type: Easing.InCubic; duration: 200; } + } + + x: parent.width - 32 + y: 4 + width: 24 + height: 24 + z: 4 + + MouseArea { + anchors.fill: parent + onClicked: { + child.surface.destroySurface() + } + } + } +} diff --git a/examples/wayland/qml-compositor/background.jpg b/examples/wayland/qml-compositor/background.jpg Binary files differnew file mode 100644 index 000000000..445567fbd --- /dev/null +++ b/examples/wayland/qml-compositor/background.jpg diff --git a/examples/wayland/qml-compositor/closebutton.png b/examples/wayland/qml-compositor/closebutton.png Binary files differnew file mode 100644 index 000000000..5b5616e98 --- /dev/null +++ b/examples/wayland/qml-compositor/closebutton.png diff --git a/examples/wayland/qml-compositor/compositor.js b/examples/wayland/qml-compositor/compositor.js new file mode 100644 index 000000000..f24d849c1 --- /dev/null +++ b/examples/wayland/qml-compositor/compositor.js @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +var windowList = null; +var indexes = null; + +function relayout() { + if (windowList === null || windowList.length == 0) + return; + + var dim = Math.ceil(Math.sqrt(windowList.length)); + + var cols = dim; + var rows = Math.ceil(windowList.length / cols); + + var w = root.width / dim; + var h = root.height / rows; + + var i; + var ix = 0; + var iy = 0; + var lastDim = 1; + + indexes = new Array(dim * dim); + + for (i = 0; i < windowList.length; ++i) { + if (i > 0) { + var currentDim = Math.ceil(Math.sqrt(i + 1)); + if (currentDim == lastDim) { + if (iy < currentDim - 1) { + ++iy; + if (iy == currentDim - 1) + ix = 0; + } else { + ++ix; + } + } else { + iy = 0; + ix = currentDim - 1; + } + lastDim = currentDim; + } + + indexes[iy * dim + ix] = i; + windowList[i].index = iy * dim + ix; + + var cx = (ix + 0.5) * w; + var cy = (iy + 0.5) * h; + + windowList[i].targetScale = 0.98 * Math.min(w / windowList[i].width, h / windowList[i].height); + + windowList[i].targetX = (cx - windowList[i].width / 2); + windowList[i].targetY = (cy - windowList[i].height / 2); + } +} + +function addWindow(window) +{ + if (windowList == null) + windowList = new Array(0); + + windowList.push(window); + relayout(); +} + +function removeWindow(window) +{ + var i; + for (i = 0; i < windowList.length; ++i) { + if (windowList[i] == window) + break; + } + + var index = windowList[i].index; + var dim = Math.ceil(Math.sqrt(windowList.length)); + var maxY = Math.floor((windowList.length-1) / dim); + + var shrinking = Math.ceil(Math.sqrt(windowList.length - 1)) != dim; + + while (true) { + var ix = index % dim; + var iy = Math.floor(index / dim); + + if (shrinking) { + if (iy > 0) + --iy; + else if (++ix == dim) + break; + } else { + if (iy < maxY) { + if (ix > 0) + --ix; + else + ++iy; + } else { + ++ix; + } + } + + var next = iy * dim + ix; + + var currentIndex = indexes[index]; + var nextIndex = indexes[next]; + + if (nextIndex == null) + break; + + var temp = windowList[currentIndex]; + windowList[currentIndex] = windowList[nextIndex]; + windowList[currentIndex].index = currentIndex; + windowList[nextIndex] = temp; + + index = next; + } + + windowList.splice(indexes[index], 1); + relayout(); +} diff --git a/examples/wayland/qml-compositor/main.cpp b/examples/wayland/qml-compositor/main.cpp new file mode 100644 index 000000000..26e730d43 --- /dev/null +++ b/examples/wayland/qml-compositor/main.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandquickcompositor.h" +#include "qwaylandquicksurface.h" + +#include <QtCompositor/qwaylandsurfaceitem.h> + +#include <QGuiApplication> +#include <QTimer> +#include <QPainter> +#include <QMouseEvent> + +#include <QQmlContext> + +#include <QQuickItem> +#include <QQuickView> + +class QmlCompositor : public QQuickView, public QWaylandQuickCompositor +{ + Q_OBJECT + Q_PROPERTY(QWaylandQuickSurface* fullscreenSurface READ fullscreenSurface WRITE setFullscreenSurface NOTIFY fullscreenSurfaceChanged) + +public: + QmlCompositor() + : QWaylandQuickCompositor(this, 0, DefaultExtensions | SubSurfaceExtension) + , m_fullscreenSurface(0) + { + setSource(QUrl("main.qml")); + setResizeMode(QQuickView::SizeRootObjectToView); + setColor(Qt::black); + winId(); + addDefaultShell(); + + connect(this, SIGNAL(afterRendering()), this, SLOT(sendCallbacks())); + } + + QWaylandQuickSurface *fullscreenSurface() const + { + return m_fullscreenSurface; + } + + Q_INVOKABLE QWaylandSurfaceItem *item(QWaylandSurface *surf) + { + return static_cast<QWaylandSurfaceItem *>(surf->views().first()); + } + +signals: + void windowAdded(QVariant window); + void windowDestroyed(QVariant window); + void windowResized(QVariant window); + void fullscreenSurfaceChanged(); + +public slots: + void destroyWindow(QVariant window) { + qvariant_cast<QObject *>(window)->deleteLater(); + } + + void setFullscreenSurface(QWaylandQuickSurface *surface) { + if (surface == m_fullscreenSurface) + return; + m_fullscreenSurface = surface; + emit fullscreenSurfaceChanged(); + } + +private slots: + void surfaceMapped() { + QWaylandQuickSurface *surface = qobject_cast<QWaylandQuickSurface *>(sender()); + emit windowAdded(QVariant::fromValue(surface)); + } + void surfaceUnmapped() { + QWaylandQuickSurface *surface = qobject_cast<QWaylandQuickSurface *>(sender()); + if (surface == m_fullscreenSurface) + m_fullscreenSurface = 0; + emit windowDestroyed(QVariant::fromValue(surface)); + } + + void surfaceDestroyed(QObject *object) { + QWaylandQuickSurface *surface = static_cast<QWaylandQuickSurface *>(object); + if (surface == m_fullscreenSurface) + m_fullscreenSurface = 0; + emit windowDestroyed(QVariant::fromValue(surface)); + } + + void sendCallbacks() { + if (m_fullscreenSurface) + sendFrameCallbacks(QList<QWaylandSurface *>() << m_fullscreenSurface); + else + sendFrameCallbacks(surfaces()); + } + +protected: + void resizeEvent(QResizeEvent *event) + { + QQuickView::resizeEvent(event); + QWaylandCompositor::setOutputGeometry(QRect(0, 0, width(), height())); + } + + void surfaceCreated(QWaylandSurface *surface) { + connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *))); + connect(surface, SIGNAL(mapped()), this, SLOT(surfaceMapped())); + connect(surface,SIGNAL(unmapped()), this,SLOT(surfaceUnmapped())); + } + +private: + QWaylandQuickSurface *m_fullscreenSurface; +}; + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QmlCompositor compositor; + compositor.setTitle(QLatin1String("QML Compositor")); + compositor.setGeometry(0, 0, 1024, 768); + compositor.show(); + + compositor.rootContext()->setContextProperty("compositor", &compositor); + + QObject::connect(&compositor, SIGNAL(windowAdded(QVariant)), compositor.rootObject(), SLOT(windowAdded(QVariant))); + QObject::connect(&compositor, SIGNAL(windowResized(QVariant)), compositor.rootObject(), SLOT(windowResized(QVariant))); + + return app.exec(); +} + +#include "main.moc" diff --git a/examples/wayland/qml-compositor/main.qml b/examples/wayland/qml-compositor/main.qml new file mode 100644 index 000000000..a6b54c312 --- /dev/null +++ b/examples/wayland/qml-compositor/main.qml @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtCompositor 1.0 +import "compositor.js" as CompositorLogic + +Item { + id: root + + property variant selectedWindow: null + property bool hasFullscreenWindow: typeof compositor != "undefined" && compositor.fullscreenSurface !== null + + Image { + id: background + Behavior on opacity { + NumberAnimation { easing.type: Easing.InCubic; duration: 400; } + } + anchors.fill: parent + fillMode: Image.Tile + source: "background.jpg" + smooth: true + } + + MouseArea { + anchors.fill: parent + onClicked: { + root.selectedWindow = null + root.focus = true + } + } + + MouseArea { + anchors.right: parent.right + anchors.bottom: parent.bottom + width: 2 + height: 2 + hoverEnabled: true + onEntered: { + root.selectedWindow = null + root.focus = true + } + z: 10 + } + + function windowAdded(window) { + var windowContainerComponent = Qt.createComponent("WindowContainer.qml"); + if (windowContainerComponent.status != Component.Ready) { + console.warn("Error loading WindowContainer.qml: " + windowContainerComponent.errorString()); + return; + } + var windowContainer = windowContainerComponent.createObject(root); + + windowContainer.child = compositor.item(window); + windowContainer.child.parent = windowContainer; + windowContainer.child.touchEventsEnabled = true; + + windowContainer.targetWidth = window.size.width; + windowContainer.targetHeight = window.size.height; + + var windowChromeComponent = Qt.createComponent("WindowChrome.qml"); + if (windowChromeComponent.status != Component.Ready) { + console.warn("Error loading WindowChrome.qml: " + windowChromeComponent.errorString()); + return; + } + var windowChrome = windowChromeComponent.createObject(windowContainer.child); + + CompositorLogic.addWindow(windowContainer); + + windowContainer.opacity = 1 + windowContainer.animationsEnabled = true; + windowContainer.chrome = windowChrome; + } + + function windowResized(window) { + window.width = window.surface.size.width; + window.height = window.surface.size.height; + + CompositorLogic.relayout(); + } + + function removeWindow(window) { + CompositorLogic.removeWindow(window); + window.chrome.destroy(); + window.destroy(); + } + + onHeightChanged: CompositorLogic.relayout(); + onWidthChanged: CompositorLogic.relayout(); +} diff --git a/examples/wayland/qml-compositor/qml-compositor.pro b/examples/wayland/qml-compositor/qml-compositor.pro new file mode 100644 index 000000000..f908a2f2f --- /dev/null +++ b/examples/wayland/qml-compositor/qml-compositor.pro @@ -0,0 +1,22 @@ +DEFINES += QT_COMPOSITOR_QUICK + +LIBS += -L ../../lib + +QT += quick qml +QT += quick-private + +QT += compositor + +# if you want to compile QtCompositor as part of the application +# instead of linking to it, remove the QT += compositor and uncomment +# the following line +#include (../../src/compositor/compositor.pri) + +SOURCES += main.cpp + +OTHER_FILES = ContrastEffect.qml main.qml WindowChrome.qml WindowContainer.qml background.jpg closebutton.png compositor.js + +target.path = $$[QT_INSTALL_EXAMPLES]/wayland/qml-compositor +sources.files = $$OTHER_FILES $$SOURCES $$HEADERS $$RESOURCES $$FORMS qml-compositor.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/wayland/qml-compositor +INSTALLS += target sources |