diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2012-05-18 22:17:50 +0200 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2012-05-21 08:45:49 +0200 |
commit | fe556c0ec2522e09681c39b0d9501acffeee8640 (patch) | |
tree | 14473ac5ccb53f0646b0c2c903e2a9b6668cdfb8 /examples | |
parent | 2fb8d34aeab6e979a404f5b2262e9040bd8ce4cf (diff) |
Added maximize and window closing behavior to qml-compositor.
Change-Id: I13ebfa400d8ce669bf45ee533a2aa9a7190421d5
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'examples')
-rw-r--r-- | examples/qml-compositor/WindowChrome.qml | 9 | ||||
-rw-r--r-- | examples/qml-compositor/WindowContainer.qml | 112 | ||||
-rw-r--r-- | examples/qml-compositor/closebutton.png | bin | 0 -> 25957 bytes | |||
-rw-r--r-- | examples/qml-compositor/compositor.js | 8 | ||||
-rw-r--r-- | examples/qml-compositor/main.cpp | 33 | ||||
-rw-r--r-- | examples/qml-compositor/main.qml | 37 | ||||
-rw-r--r-- | examples/qml-compositor/qml-compositor.pro | 2 |
7 files changed, 180 insertions, 21 deletions
diff --git a/examples/qml-compositor/WindowChrome.qml b/examples/qml-compositor/WindowChrome.qml index 6fb2ebe4d..459a0ff20 100644 --- a/examples/qml-compositor/WindowChrome.qml +++ b/examples/qml-compositor/WindowChrome.qml @@ -45,12 +45,19 @@ Item { anchors.fill: parent property variant window: parent; + property bool selected: root.selectedWindow === window MouseArea { anchors.fill: parent enabled: !window.focus + hoverEnabled: !window.focus onClicked: { - window.takeFocus(); + if (selected) { + window.takeFocus(); + } else { + root.selectedWindow = window + root.focus = true + } } } } diff --git a/examples/qml-compositor/WindowContainer.qml b/examples/qml-compositor/WindowContainer.qml index ae70e3b87..dd5eeded4 100644 --- a/examples/qml-compositor/WindowContainer.qml +++ b/examples/qml-compositor/WindowContainer.qml @@ -39,18 +39,38 @@ ****************************************************************************/ import QtQuick 2.0 +import QtQuick.Window 2.0 Item { id: container - x: -400; - y: 0; + x: targetX + y: targetY + width: targetWidth + height: targetHeight + scale: targetScale + + visible: isFullscreen || !root.hasFullscreenWindow + onVisibleChanged: { + child.clientRenderingEnabled = visible + console.log("visibility changed: " + visible); + } + opacity: 0 - property variant child: null; - property variant chrome: null; - property bool animationsEnabled: false; - property int index; + 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; @@ -62,6 +82,16 @@ Item { 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; } @@ -76,8 +106,8 @@ Item { id: effect source: child anchors.fill: child - blend: { if (child && child.focus) 0.0; else 0.6 } - opacity: 0.8 + blend: { if (child && chrome && (chrome.selected || child.focus)) 0.0; else 0.6 } + opacity: 1.0 z: 1 Behavior on blend { @@ -91,6 +121,49 @@ Item { 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; } @@ -102,4 +175,27 @@ Item { function runDestroyAnimation() { 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: { + compositor.destroyClientForWindow(child) + } + } + } } diff --git a/examples/qml-compositor/closebutton.png b/examples/qml-compositor/closebutton.png Binary files differnew file mode 100644 index 000000000..5b5616e98 --- /dev/null +++ b/examples/qml-compositor/closebutton.png diff --git a/examples/qml-compositor/compositor.js b/examples/qml-compositor/compositor.js index ba0f74e4e..2e7c3c3f8 100644 --- a/examples/qml-compositor/compositor.js +++ b/examples/qml-compositor/compositor.js @@ -42,7 +42,7 @@ var windowList = null; var indexes = null; function relayout() { - if (windowList.length == 0) + if (windowList === null || windowList.length == 0) return; var dim = Math.ceil(Math.sqrt(windowList.length)); @@ -84,10 +84,10 @@ function relayout() { var cx = (ix + 0.5) * w; var cy = (iy + 0.5) * h; - windowList[i].scale = 0.98 * Math.min(w / windowList[i].width, h / windowList[i].height); + windowList[i].targetScale = 0.98 * Math.min(w / windowList[i].width, h / windowList[i].height); - windowList[i].x = (cx - windowList[i].width / 2); - windowList[i].y = (cy - windowList[i].height / 2); + windowList[i].targetX = (cx - windowList[i].width / 2); + windowList[i].targetY = (cy - windowList[i].height / 2); } } diff --git a/examples/qml-compositor/main.cpp b/examples/qml-compositor/main.cpp index 9571c802e..84e4e3454 100644 --- a/examples/qml-compositor/main.cpp +++ b/examples/qml-compositor/main.cpp @@ -55,49 +55,75 @@ class QmlCompositor : public QQuickView, public WaylandCompositor { Q_OBJECT + Q_PROPERTY(WaylandSurface* fullscreenSurface READ fullscreenSurface WRITE setFullscreenSurface NOTIFY fullscreenSurfaceChanged) + public: QmlCompositor() : WaylandCompositor(this) + , m_fullscreenSurface(0) { enableSubSurfaceExtension(); setSource(QUrl("main.qml")); setResizeMode(QQuickView::SizeRootObjectToView); + setClearColor(Qt::black); winId(); connect(this, SIGNAL(frameSwapped()), this, SLOT(frameSwappedSlot())); } + WaylandSurface *fullscreenSurface() const + { + return m_fullscreenSurface; + } + 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 destroyClientForWindow(QVariant window) { + WaylandSurface *surface = qobject_cast<WaylandSurfaceItem *>(qvariant_cast<QObject *>(window))->surface(); + destroyClientForSurface(surface); + } + + void setFullscreenSurface(WaylandSurface *surface) { + if (surface == m_fullscreenSurface) + return; + m_fullscreenSurface = surface; + emit fullscreenSurfaceChanged(); + } + private slots: void surfaceMapped() { WaylandSurface *surface = qobject_cast<WaylandSurface *>(sender()); WaylandSurfaceItem *item = surface->surfaceItem(); - item->takeFocus(); + //item->takeFocus(); emit windowAdded(QVariant::fromValue(static_cast<QQuickItem *>(item))); } void surfaceUnmapped() { WaylandSurface *surface = qobject_cast<WaylandSurface *>(sender()); + if (surface == m_fullscreenSurface) + m_fullscreenSurface = 0; QQuickItem *item = surface->surfaceItem(); emit windowDestroyed(QVariant::fromValue(item)); } void surfaceDestroyed(QObject *object) { WaylandSurface *surface = static_cast<WaylandSurface *>(object); + if (surface == m_fullscreenSurface) + m_fullscreenSurface = 0; QQuickItem *item = surface->surfaceItem(); emit windowDestroyed(QVariant::fromValue(item)); } void frameSwappedSlot() { - frameFinished(); + frameFinished(m_fullscreenSurface); } protected: @@ -115,6 +141,9 @@ protected: connect(surface, SIGNAL(mapped()), this, SLOT(surfaceMapped())); connect(surface,SIGNAL(unmapped()), this,SLOT(surfaceUnmapped())); } + +private: + WaylandSurface *m_fullscreenSurface; }; int main(int argc, char *argv[]) diff --git a/examples/qml-compositor/main.qml b/examples/qml-compositor/main.qml index bd859f04d..a5cb8c5b9 100644 --- a/examples/qml-compositor/main.qml +++ b/examples/qml-compositor/main.qml @@ -44,25 +44,51 @@ import "compositor.js" as CompositorLogic Item { id: root - width: 1024 - height: 768 + property variant selectedWindow: null + property bool hasFullscreenWindow: compositor.fullscreenSurface !== null + + onHasFullscreenWindowChanged: console.log("has fullscreen window: " + hasFullscreenWindow); 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"); var windowContainer = windowContainerComponent.createObject(root); window.parent = windowContainer; - windowContainer.width = window.width; - windowContainer.height = window.height; + windowContainer.targetWidth = window.width; + windowContainer.targetHeight = window.height; windowContainer.child = window; var windowChromeComponent = Qt.createComponent("WindowChrome.qml"); @@ -85,7 +111,8 @@ Item { function windowDestroyed(window) { var windowContainer = window.parent; - windowContainer.runDestroyAnimation(); + if (windowContainer.runDestroyAnimation) + windowContainer.runDestroyAnimation(); } function removeWindow(window) { diff --git a/examples/qml-compositor/qml-compositor.pro b/examples/qml-compositor/qml-compositor.pro index 866f54c81..dd99f8c64 100644 --- a/examples/qml-compositor/qml-compositor.pro +++ b/examples/qml-compositor/qml-compositor.pro @@ -17,7 +17,7 @@ QT += compositor SOURCES += main.cpp -OTHER_FILES = ContrastEffect.qml main.qml WindowChrome.qml WindowContainer.qml background.jpg compositor.js +OTHER_FILES = ContrastEffect.qml main.qml WindowChrome.qml WindowContainer.qml background.jpg closebutton.png compositor.js target.path = $$[QT_INSTALL_EXAMPLES]/qtwayland/qml-compositor sources.files = $$OTHER_FILES $$SOURCES $$HEADERS $$RESOURCES $$FORMS qml-compositor.pro |