diff options
Diffstat (limited to 'examples')
20 files changed, 1180 insertions, 1 deletions
diff --git a/examples/examples.pro b/examples/examples.pro index c1f9422..06a2000 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -SUBDIRS += browser embedded scroller webkit xmlpatterns +SUBDIRS += browser embedded scroller webkit xmlpatterns qml diff --git a/examples/qml/flickrview/flickrview.pro b/examples/qml/flickrview/flickrview.pro new file mode 100644 index 0000000..712ae9a --- /dev/null +++ b/examples/qml/flickrview/flickrview.pro @@ -0,0 +1,11 @@ +TEMPLATE = app + +DEFINES += QWEBKIT_EXAMPLE_NAME=\\\"flickrview\\\" + +QT += quick qml webkit +SOURCES += ../shared/main.cpp + +target.path = $$[QT_INSTALL_EXAMPLES]/qtwebkit-examples-and-demos/examples/qml/flickrview +qml.files = flickrview.qml +qml.path = $$[QT_INSTALL_EXAMPLES]/qtwebkit-examples-and-demos/examples/qml/flickrview +INSTALLS += target qml diff --git a/examples/qml/flickrview/flickrview.qml b/examples/qml/flickrview/flickrview.qml new file mode 100644 index 0000000..5b09d68 --- /dev/null +++ b/examples/qml/flickrview/flickrview.qml @@ -0,0 +1,270 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtWebKit 3.0 +import QtQuick.XmlListModel 2.0 +import "../shared" + +Rectangle { + id: container + width: 1024 + height: 768 + + property string initialUrl: "https://www.flickr.com/explore/interesting/7days/?" + + Rectangle { + id: thumbnailContainer + color: "black" + + anchors.bottom: container.bottom + width: container.width + height: 100 + + gradient: Gradient { + GradientStop { position: 0.0; color: "gray" } + GradientStop { position: 0.33; color: "black" } + } + + Text { + id: info + color: "white" + anchors.horizontalCenter: thumbnailContainer.horizontalCenter + text: webView.title + } + + ListView { + id: listView + orientation: "Horizontal" + anchors { + topMargin: 20 + fill: parent + } + + model: model + delegate: Component { + Image { + source: thumbnail + MouseArea { + anchors.fill: parent + onClicked: webView.url = link + "/lightbox" + } + } + } + + focus: true + spacing: 10 + leftMargin: 10 + rightMargin: 35 + visible: model.status == XmlListModel.Ready + } + + Rectangle { + id: updateInfo + + property real distance: -(listView.contentWidth - listView.contentX - thumbnailContainer.width) + property real threshold: Math.max(2.5 * listView.height, thumbnailContainer.width - listView.contentWidth + 2 * listView.height) + property bool triggerUpdate: false + + opacity: 0.8 + x: thumbnailContainer.width - distance + width: listView.height + color: "transparent" + + anchors { + top: thumbnailContainer.top + bottom: thumbnailContainer.bottom + } + + Timer { + interval: 200; running: updateInfo.state == "update"; repeat: false + onTriggered: { model.reload(); updateInfo.triggerUpdate = false; } + } + + states: [ + State { + name: "pull" + when: updateInfo.distance <= updateInfo.threshold && listView.dragging + PropertyChanges { target: message; text: "Pull\nto\nupdate" } + }, + + State { + name: "release" + when: updateInfo.distance > updateInfo.threshold && listView.dragging + PropertyChanges { target: message; text: "Release\nto\nupdate" } + }, + + State { + name: "update" + when: updateInfo.triggerUpdate && listView.atXEnd && !listView.dragging + PropertyChanges { target: message; text: "Updating" } + } + ] + + onStateChanged: { + if (state == "release") + triggerUpdate = true + if (state == "pull") + triggerUpdate = false + } + + Rectangle { + id: icon + width: 30 + color: "transparent" + anchors { + topMargin: 10 + top: parent.top + bottom: parent.bottom + left: parent.left + } + Image { + source: "../shared/images/arrow.png" + width: 30 + height: 30 + visible: updateInfo.state != "update" + rotation: updateInfo.state == "release" ? 180 : 0 + Behavior on rotation { NumberAnimation { duration: 100} } + SequentialAnimation on x { + running: listView.atXEnd && !listView.dragging + loops: Animation.Infinite + PropertyAnimation { to: 5; duration: 250 } + PropertyAnimation { to: 0; duration: 250 } + } + anchors { + verticalCenter: parent.verticalCenter + } + } + } + + Text { + id: message + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.family: "Monospace" + color: "white" + anchors { + top: parent.top + bottom: parent.bottom + right: parent.right + left: icon.right + } + } + } + + LoadIndicator { + anchors.fill: parent + color: "black" + running: !listView.visible && model.status != XmlListModel.Error + } + } + + Rectangle { + id: content + width: container.width + color: "black" + anchors { + top: container.top + bottom: thumbnailContainer.top + } + + WebView { + id: webView + anchors.fill: parent + opacity: 0 + + url: container.initialUrl + + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + onLoadingChanged: { + switch (loadRequest.status) + { + case WebView.LoadSucceededStatus: + opacity = 1 + break + default: + opacity = 0 + break + } + } + + onNavigationRequested: { + var pattern = new RegExp('^(https|http)://www.flickr.com|^(https|http)://login.yahoo.com'); + switch (request.navigationType) + { + case WebView.LinkClickedNavigation: + case WebView.FormSubmittedNavigation: + case WebView.BackForwardNavigation: + case WebView.ReloadNavigation: + case WebView.FormResubmittedNavigation: + case WebView.OtherNavigation: + if (pattern.test(request.url)) { + request.action = WebView.AcceptRequest + return + } + } + // Disallow navigating outside of flickr.com + request.action = WebView.IgnoreRequest + } + } + + LoadIndicator { + anchors.fill: parent + imageSource: "images/flickr.png" + running: webView.loading + } + } + + XmlListModel { + id: model + namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";" + source: "http://api.flickr.com/services/feeds/photos_public.gne?format=rss2" + query: "/rss/channel/item" + XmlRole { name: "thumbnail"; query: "media:thumbnail/@url/string()" } + XmlRole { name: "thumbnailHeight"; query: "media:thumbnail/@height/number()" } + XmlRole { name: "content"; query: "media:content/@url/string()" } + XmlRole { name: "link"; query: "link/string()" } + } + +} diff --git a/examples/qml/flickrview/flickrview.qmlproject b/examples/qml/flickrview/flickrview.qmlproject new file mode 100644 index 0000000..7f47c02 --- /dev/null +++ b/examples/qml/flickrview/flickrview.qmlproject @@ -0,0 +1,16 @@ +import QmlProject 1.1 + +Project { + mainFile: "flickrview.qml" + + /* Include .qml, .js, and image files from current directory and subdirectories */ + QmlFiles { + directory: "." + } + JavaScriptFiles { + directory: "." + } + ImageFiles { + directory: "." + } +} diff --git a/examples/qml/qml.pro b/examples/qml/qml.pro new file mode 100644 index 0000000..9513539 --- /dev/null +++ b/examples/qml/qml.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS += shared \ + flickrview \ + youtubeview diff --git a/examples/qml/shared/Button.qml b/examples/qml/shared/Button.qml new file mode 100644 index 0000000..336edc3 --- /dev/null +++ b/examples/qml/shared/Button.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: container + property string text: "Button" + property real buttonWidth: label.width + 10 + property real buttonHeight: label.height + 10 + property real fontSize: 10 + signal clicked + + width: buttonWidth + 5 + height: buttonHeight + 5 + + Rectangle { + id: buttonElement + + anchors.centerIn: parent + + height: parent.buttonHeight + width: parent.buttonWidth + border.width: 2 + border.color: "black" + smooth: true + + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: container.clicked() + } + + gradient: Gradient { + GradientStop { + position: 0.0 + color: mouseArea.pressed ? "grey" : "darkgrey" + } + GradientStop { + position: 1.0 + color: mouseArea.pressed ? "darkgrey" : "black" + } + } + + Text { + id: label + anchors.centerIn: parent + font.pointSize: container.fontSize + text: container.text + color: "white" + } + } +} diff --git a/examples/qml/shared/LoadIndicator.qml b/examples/qml/shared/LoadIndicator.qml new file mode 100644 index 0000000..d7bdf2c --- /dev/null +++ b/examples/qml/shared/LoadIndicator.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: container + + property bool running: false + property string imageSource: "images/busy.png" + + visible: running + + Image { + id: image + anchors.centerIn: parent + source: container.imageSource + ParallelAnimation { + running: container.running + NumberAnimation { target: image; property: "opacity"; from: 0.0; to: 1.0; duration: 200 } + NumberAnimation { target: image; property: "rotation"; from: 0; to: 360; loops: Animation.Infinite; duration: 1200 } + } + } +} diff --git a/examples/qml/shared/images/arrow.png b/examples/qml/shared/images/arrow.png Binary files differnew file mode 100644 index 0000000..1dcec44 --- /dev/null +++ b/examples/qml/shared/images/arrow.png diff --git a/examples/qml/shared/images/busy.png b/examples/qml/shared/images/busy.png Binary files differnew file mode 100644 index 0000000..664c2b1 --- /dev/null +++ b/examples/qml/shared/images/busy.png diff --git a/examples/qml/shared/images/flickr.png b/examples/qml/shared/images/flickr.png Binary files differnew file mode 100644 index 0000000..d0f0502 --- /dev/null +++ b/examples/qml/shared/images/flickr.png diff --git a/examples/qml/shared/images/less.png b/examples/qml/shared/images/less.png Binary files differnew file mode 100644 index 0000000..136919b --- /dev/null +++ b/examples/qml/shared/images/less.png diff --git a/examples/qml/shared/images/more.png b/examples/qml/shared/images/more.png Binary files differnew file mode 100644 index 0000000..fe7f87e --- /dev/null +++ b/examples/qml/shared/images/more.png diff --git a/examples/qml/shared/main.cpp b/examples/qml/shared/main.cpp new file mode 100644 index 0000000..4be3b2a --- /dev/null +++ b/examples/qml/shared/main.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** 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 <QGuiApplication> +#include <QQuickView> +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc,argv); + QQuickView view; + view.setSource(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + QLatin1String("/"QWEBKIT_EXAMPLE_NAME".qml"))); + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.show(); + return app.exec(); +} diff --git a/examples/qml/shared/qmldir b/examples/qml/shared/qmldir new file mode 100644 index 0000000..ffd9414 --- /dev/null +++ b/examples/qml/shared/qmldir @@ -0,0 +1,2 @@ +Button 2.0 Button.qml +LoadIndicator 2.0 LoadIndicator.qml diff --git a/examples/qml/shared/shared.pro b/examples/qml/shared/shared.pro new file mode 100644 index 0000000..f40ebb0 --- /dev/null +++ b/examples/qml/shared/shared.pro @@ -0,0 +1,11 @@ +#just install the files +TEMPLATE = aux + +qml.files = images \ + LoadIndicator.qml \ + Button.qml \ + main.cpp \ + qmldir + +qml.path = $$[QT_INSTALL_EXAMPLES]/qtwebkit-examples-and-demos/examples/qml/shared +INSTALLS = qml diff --git a/examples/qml/youtubeview/content/YouTubeDialog.qml b/examples/qml/youtubeview/content/YouTubeDialog.qml new file mode 100644 index 0000000..e1422e9 --- /dev/null +++ b/examples/qml/youtubeview/content/YouTubeDialog.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "../../shared" + +Rectangle { + id: container + + color: "black" + + signal presetClicked(string name) + + property int neededHeight: view.contentItem.childrenRect.height + + ListModel { + id: model + ListElement { + name: "trailers" + } + ListElement { + name: "ClevverMovies" + } + ListElement { + name: "nogoodflix" + } + ListElement { + name: "PalaceFilms" + } + ListElement { + name: "CieonMovies" + } + ListElement { + name: "FilmsActuTrailers" + } + ListElement { + name: "movieclipsTRAILERS" + } + } + + Component { + id: delegate + Button { + buttonWidth: 200 + text: name + onClicked: presetClicked(name) + } + } + + ListView { + id: view + anchors.centerIn: parent + width: 200 + height: (container.neededHeight > parent.height) ? parent.height : container.neededHeight + model: model + delegate: delegate + boundsBehavior: Flickable.StopAtBounds + } +} diff --git a/examples/qml/youtubeview/content/player.html b/examples/qml/youtubeview/content/player.html new file mode 100644 index 0000000..6f3a1e9 --- /dev/null +++ b/examples/qml/youtubeview/content/player.html @@ -0,0 +1,51 @@ +<html> + <head> + <title>-1</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/> + </head> + <body bgcolor="black" marginwidth="0" marginheight="0"> + <!-- The <iframe> (and video player) will replace this <div> tag. --> + <div id="player"></div> + <script> + function getVideoId() { + return window.location.href.slice(window.location.href.indexOf('?') + 1); + } + // This code loads the IFrame Player API code asynchronously. + var tag = document.createElement('script'); + tag.src = "https://www.youtube.com/iframe_api"; + var firstScriptTag = document.getElementsByTagName('script')[0]; + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + + // This function creates an <iframe> (and YouTube player) + // after the API code downloads. + var player; + function onYouTubeIframeAPIReady() { + player = new YT.Player('player', { + playerVars: { 'html5': 1, 'iv_load_policy': 3 }, + frameborder: '0', + height: '100%', + width: '100%', + videoId: getVideoId(), + events: { + 'onReady': onPlayerReady, + 'onStateChange': onPlayerStateChange + } + }); + } + + // The API will call this function when the video player is ready. + function onPlayerReady(event) { + document.title = 0; + } + + // The API calls this function when the player's state changes. + function onPlayerStateChange(event) { + if (event.data == YT.PlayerState.PLAYING) { + document.title = 1; + } else if (event.data == YT.PlayerState.ENDED || event.data == YT.PlayerState.PAUSED) { + document.title = 2; + } + } + </script> + </body> +</html> diff --git a/examples/qml/youtubeview/youtubeview.pro b/examples/qml/youtubeview/youtubeview.pro new file mode 100644 index 0000000..8263818 --- /dev/null +++ b/examples/qml/youtubeview/youtubeview.pro @@ -0,0 +1,14 @@ +TEMPLATE = app + +DEFINES += QWEBKIT_EXAMPLE_NAME=\\\"youtubeview\\\" + +QT += quick qml webkit +SOURCES += ../shared/main.cpp + +target.path = $$[QT_INSTALL_EXAMPLES]/qtwebkit-examples-and-demos/examples/qml/youtubeview +qml.files = youtubeview.qml content +qml.path = $$[QT_INSTALL_EXAMPLES]/qtwebkit-examples-and-demos/examples/qml/youtubeview +INSTALLS += target qml + +OTHER_FILES += \ + player.html diff --git a/examples/qml/youtubeview/youtubeview.qml b/examples/qml/youtubeview/youtubeview.qml new file mode 100644 index 0000000..191e105 --- /dev/null +++ b/examples/qml/youtubeview/youtubeview.qml @@ -0,0 +1,484 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtWebKit 3.0 +import QtQuick.XmlListModel 2.0 +import "content" +import "../shared" + +Rectangle { + id: container + width: 850 + height: 480 + color: "black" + focus: true + + property QtObject videoStatus: QtObject { + property int initial: -1 + property int ready: 0 + property int playing: 1 + property int paused: 2 + } + + QtObject { + id: currentVideo + property string vId: "" + property string title: "" + property int status: videoStatus.initial + } + + readonly property int padding: 20 + + Rectangle { + id: content + anchors.fill: parent + color: "black" + + WebView { + id: webView + anchors.fill: parent + opacity: 0 + + url: "content/player.html?" + currentVideo.vId + + Behavior on opacity { NumberAnimation { duration: 200 } } + + onLoadingChanged: { + switch (loadRequest.status) + { + case WebView.LoadSucceededStatus: + opacity = 1 + return + case WebView.LoadStartedStatus: + case WebView.LoadStoppedStatus: + break + case WebView.LoadFailedStatus: + topInfo.text = "Failed to load the requested video" + break + } + opacity = 0 + } + onTitleChanged: { + currentVideo.status = 1 * title + if (title == videoStatus.paused || title == videoStatus.ready) + panel.state = "list" + else if (title == videoStatus.playing) + panel.state = "hidden" + } + } + + YouTubeDialog { + id: presetDialog + anchors.fill: parent + visible: false + onPresetClicked: { + model.userName = name + model.startIndex = 1 + panel.state = "list" + searchBinding.when = false + presetsBinding.when = true + model.reload() + } + } + } + + Rectangle { + id: panel + height: 100 + color: "black"; + state: "list" + + Behavior on y { NumberAnimation { duration: 200 } } + Behavior on height { NumberAnimation { duration: 200 } } + Behavior on opacity { NumberAnimation { duration: 400 } } + + Binding { id: presetsBinding; target: model; property: "source"; value: model.usersSource; when: false } + Binding { id: searchBinding; target: model; property: "source"; value: model.searchSource; when: false } + + anchors { + left: container.left + right: container.right + } + + states: [ + State { + name: "search" + PropertyChanges { target: panel; color: "black"; opacity: 0.8; y: -height + topInfo.height + searchPanel.height + button.height } + PropertyChanges { target: listView; visible: false } + PropertyChanges { target: searchPanel; opacity: 0.8 } + PropertyChanges { target: hideTimer; running: false } + PropertyChanges { target: presetDialog; visible: true } + }, + + State { + name: "list" + PropertyChanges { target: panel; color: "black"; opacity: 0.8; y: 0 } + PropertyChanges { target: listView; visible: true; focus: true } + PropertyChanges { target: searchPanel; visible: false } + PropertyChanges { target: listView; visible: true } + }, + + State { + name: "hidden" + PropertyChanges { target: panel; color: "gray"; opacity: 0.2; y: -height + container.padding } + PropertyChanges { target: showListArea; visible: true } + } + ] + + Timer { + id: hideTimer + interval: 3000 + repeat: false + onTriggered: panel.state = "hidden" + } + + MouseArea { + id: showListArea + height: container.padding + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + } + onPressed: { + panel.state = "list" + if (currentVideo.status == videoStatus.playing) + hideTimer.restart() + } + } + + ListView { + id: listView + orientation: "Horizontal" + + anchors { + top: panel.top + bottom: button.top + left: panel.left + right: panel.right + } + + focus: true + model: model + + header: Component { + Rectangle { + visible: model.startIndex != 1 && model.status == XmlListModel.Ready + color: "black" + anchors.verticalCenter: parent.verticalCenter + width: height + height: visible ? listView.contentItem.height : 0 + Image { anchors.centerIn: parent; width: 50; height: 50; source: "../shared/images/less.png" } + MouseArea { + anchors.fill: parent + onClicked: model.requestLess() + } + } + } + + footer: Component { + Rectangle { + visible: model.totalResults > model.endIndex && model.status == XmlListModel.Ready + color: "black" + anchors.verticalCenter: parent.verticalCenter + width: height + height: visible ? listView.contentItem.height : 0 + Image { anchors.centerIn: parent; width: 50; height: 50; source: "../shared/images/more.png" } + MouseArea { + anchors.fill: parent + onClicked: model.requestMore() + } + } + } + + delegate: Component { + Image { + source: thumbnail + MouseArea { + anchors.fill: parent + onClicked: { + currentVideo.vId = id + currentVideo.title = title + } + } + Component.onCompleted: { + if (currentVideo.title == "") { + currentVideo.vId = id + currentVideo.title = title + } + } + } + } + + onDraggingChanged: { + if (dragging) + hideTimer.stop() + else if (currentVideo.status == videoStatus.playing) + hideTimer.start() + } + } + + LoadIndicator { + anchors.fill: parent + color: "black" + running: panel.state == "list" && model.status != XmlListModel.Ready + } + + Rectangle { + id: searchPanel + Behavior on opacity { NumberAnimation { duration: 400 } } + + height: searchField.height + container.padding + + anchors { + left: parent.left + right: parent.right + bottom: button.top + } + + opacity: 0 + color: "black" + + gradient: Gradient { + GradientStop { + position: 0.0 + color: "grey" + } + GradientStop { + position: 1.0 + color: "black" + } + } + + Rectangle { + id: searchField + color: "white" + radius: 2 + anchors.centerIn: parent + width: 220 + border.color: "black" + border.width: 2 + height: input.height + container.padding + TextInput { + id: input + color: "black" + anchors.centerIn: parent + horizontalAlignment: TextInput.AlignHCenter + font.capitalization: Font.AllLowercase + maximumLength: 30 + cursorVisible: true + focus: parent.visible + text: "movie trailers" + Keys.onPressed: { + if (event.key == Qt.Key_Return || event.key == Qt.Key_Enter) { + model.startIndex = 1 + panel.state = "list" + presetsBinding.when = false + searchBinding.when = true + model.reload() + } + } + } + MouseArea { + anchors.fill: parent + onPressed: input.focus = true + } + } + } + + Button { + id: button + buttonHeight: container.padding + buttonWidth: container.width + fontSize: 8 + + visible: panel.state != "hidden" + + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + } + + states: [ + State { + name: "search" + PropertyChanges { target: button; text: "Press to switch back to the video list" } + }, + + State { + name: "list" + PropertyChanges { target: button; text: "Press to search for videos" } + } + ] + + state: panel.state + + onClicked: { + if (panel.state == "search") + panel.state = "list" + else + panel.state = "search" + } + } + } + + Rectangle { + height: 10 + color: "black" + opacity: (panel.state == "hidden") ? 0 : 0.8 + + Behavior on opacity { NumberAnimation { duration: 200 } } + + anchors { + top: container.top + left: container.left + right: container.right + } + + Text { + id: topInfo + color: "white" + font.pointSize: 8 + anchors.centerIn: parent + Binding on text { + value: "Results " + model.startIndex + " through " + ((model.endIndex > model.totalResults) ? model.totalResults : model.endIndex) + " out of " + model.totalResults + when: model.status == XmlListModel.Ready && panel.state == "list" && model.count + } + Binding on text { + value: "No results found."; + when: model.state == XmlListModel.Ready && !model.count + } + Binding on text { + value: "Search for videos" + when: panel.state == "search" + } + } + } + + Rectangle { + height: 10 + color: "black" + opacity: (panel.state == "hidden") ? 0 : 0.8 + + Behavior on opacity { NumberAnimation { duration: 200 } } + + anchors { + top: panel.bottom + left: container.left + right: container.right + } + + Text { + id: bottomInfo + color: "white" + font.weight: Font.DemiBold + font.pointSize: 8 + anchors.centerIn: parent + text: { + if (panel.state == "search") + return "Choose from preset video streams" + else + return currentVideo.title + } + } + } + + XmlListModel { + id: model + + property int totalResults: 0 + property int itemsPerPage: 0 + property int startIndex: 1 + property int endIndex: itemsPerPage + startIndex - 1 + + property string userName: "trailers" + property string baseUrl: "https://gdata.youtube.com/feeds/api" + property string defaultQuery: "alt=rss&orderby=published&v=2&start-index=" + startIndex + property string searchSource: baseUrl + "/videos?" + defaultQuery + "&q=\'" + input.text + "\'" + property string usersSource: baseUrl + "/users/" + userName + "/uploads?" + defaultQuery + + function requestMore() { + startIndex += itemsPerPage + reload() + } + + function requestLess() { + startIndex -= itemsPerPage + reload() + } + + onSourceChanged: { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function(){ + if (xhr.readyState == XMLHttpRequest.DONE) { + if (xhr.status != 200) { + console.log("Something went wrong, received HTTP status code " + xhr.status); + return; + } + var doc = xhr.responseXML.documentElement; + for (var i = 0; i < doc.childNodes.length; ++i) { + var child = doc.childNodes[i]; + for (var j = 0; j < child.childNodes.length; ++j) { + if (child.childNodes[j].nodeName == "itemsPerPage") + itemsPerPage = child.childNodes[j].childNodes[0].nodeValue; + if (child.childNodes[j].nodeName == "totalResults") + totalResults = child.childNodes[j].childNodes[0].nodeValue; + } + } + } + } + xhr.open("GET", source); + xhr.send(); + } + + namespaceDeclarations: "declare namespace media='http://search.yahoo.com/mrss/';declare namespace yt='http://gdata.youtube.com/schemas/2007';" + + source: usersSource + query: "/rss/channel/item" + + XmlRole { name: "id"; query: "media:group/yt:videoid/string()"} + XmlRole { name: "title"; query: "media:group/media:title/string()" } + XmlRole { name: "thumbnail"; query: "media:group/media:thumbnail[1]/@url/string()" } + XmlRole { name: "thumbnailHeight"; query: "media:group/media:thumbnail[1]/@height/number()" } + } +} diff --git a/examples/qml/youtubeview/youtubeview.qmlproject b/examples/qml/youtubeview/youtubeview.qmlproject new file mode 100644 index 0000000..51f0a40 --- /dev/null +++ b/examples/qml/youtubeview/youtubeview.qmlproject @@ -0,0 +1,16 @@ +import QmlProject 1.1 + +Project { + mainFile: "youtubeview.qml" + + /* Include .qml, .js, and image files from current directory and subdirectories */ + QmlFiles { + directory: "." + } + JavaScriptFiles { + directory: "." + } + ImageFiles { + directory: "." + } +} |