Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save torarnv/3892505 to your computer and use it in GitHub Desktop.
Save torarnv/3892505 to your computer and use it in GitHub Desktop.
QML examples for WebKit integration
From 95f638764157606fdff3dd1ebd0aff521a37237e Mon Sep 17 00:00:00 2001
From: Andras Becsi <andras.becsi@digia.com>
Date: Wed, 26 Sep 2012 17:48:37 +0200
Subject: [PATCH] Add QML examples for WebKit integration
Add flickrview and youtubeview examples covering the use of the
WebKit WebView QML API.
- FlickrView is an example that utilizes the flickr.com RSS
feed of public photos and displays the full size images in
the WebView.
It is also possible to browse the Flickr profile of the images.
Navigaton is restricted to flickr.com.
- YouTubeView is a QML example that utilizes the WebView to
play HTML5 videos retrieved using the youtube API.
The application has a search functionality and some preset
video streams.
Change-Id: I88d09e416d6791f620e0590f7b9ce8f49173e64e
---
.gitignore | 1 +
examples/examples.pro | 2 +-
examples/qml/flickrview/flickrview.pro | 9 +
examples/qml/flickrview/flickrview.qml | 275 ++++++++++++
examples/qml/flickrview/flickrview.qmlproject | 16 +
examples/qml/flickrview/main.cpp | 41 ++
examples/qml/qml.pro | 4 +
examples/qml/shared/Button.qml | 91 ++++
examples/qml/shared/LoadIndicator.qml | 62 +++
examples/qml/shared/images/arrow.png | Bin 0 -> 10960 bytes
examples/qml/shared/images/busy.png | Bin 0 -> 2629 bytes
examples/qml/shared/images/flickr.png | Bin 0 -> 6818 bytes
examples/qml/shared/images/less.png | Bin 0 -> 4335 bytes
examples/qml/shared/images/more.png | Bin 0 -> 4261 bytes
examples/qml/shared/qmldir | 2 +
examples/qml/shared/shared.h | 50 +++
examples/qml/shared/shared.pro | 11 +
examples/qml/youtubeview/content/YouTubeDialog.qml | 99 +++++
examples/qml/youtubeview/content/player.html | 51 +++
examples/qml/youtubeview/main.cpp | 41 ++
examples/qml/youtubeview/youtubeview.pro | 12 +
examples/qml/youtubeview/youtubeview.qml | 490 +++++++++++++++++++++
examples/qml/youtubeview/youtubeview.qmlproject | 16 +
23 files changed, 1272 insertions(+), 1 deletion(-)
create mode 100644 examples/qml/flickrview/flickrview.pro
create mode 100644 examples/qml/flickrview/flickrview.qml
create mode 100644 examples/qml/flickrview/flickrview.qmlproject
create mode 100644 examples/qml/flickrview/main.cpp
create mode 100644 examples/qml/qml.pro
create mode 100644 examples/qml/shared/Button.qml
create mode 100644 examples/qml/shared/LoadIndicator.qml
create mode 100644 examples/qml/shared/images/arrow.png
create mode 100644 examples/qml/shared/images/busy.png
create mode 100644 examples/qml/shared/images/flickr.png
create mode 100644 examples/qml/shared/images/less.png
create mode 100644 examples/qml/shared/images/more.png
create mode 100644 examples/qml/shared/qmldir
create mode 100644 examples/qml/shared/shared.h
create mode 100644 examples/qml/shared/shared.pro
create mode 100644 examples/qml/youtubeview/content/YouTubeDialog.qml
create mode 100644 examples/qml/youtubeview/content/player.html
create mode 100644 examples/qml/youtubeview/main.cpp
create mode 100644 examples/qml/youtubeview/youtubeview.pro
create mode 100644 examples/qml/youtubeview/youtubeview.qml
create mode 100644 examples/qml/youtubeview/youtubeview.qmlproject
diff --git a/.gitignore b/.gitignore
index 990859d..b406ebe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ examples/*/*/*[.]app
!examples/tutorials/*
!examples/tutorials/*/*
!examples/ja_JP/*/*
+!examples/qml/*/*
demos/*/*
!demos/spectrum/*
demos/spectrum/bin
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..b0dc054
--- /dev/null
+++ b/examples/qml/flickrview/flickrview.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+
+QT += quick qml webkit
+SOURCES += 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..4c4c80a
--- /dev/null
+++ b/examples/qml/flickrview/flickrview.qml
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** 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"
+ width: thumbnailContainer.width
+ anchors {
+ horizontalCenter: thumbnailContainer.horizontalCenter
+ bottom: thumbnailContainer.bottom
+ }
+
+ model: model
+ delegate: Component {
+ Image {
+ source: thumbnail
+ MouseArea {
+ anchors.fill: parent
+ onClicked: webView.url = link + "/lightbox"
+ }
+ Component.onCompleted: if (listView.height < thumbnailHeight) listView.height = thumbnailHeight + 10
+ }
+ }
+
+ focus: true
+ spacing: 10
+ leftMargin: 10
+ rightMargin: 30
+ 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 {
+ 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
+ return
+ case WebView.LoadStartedStatus:
+ break
+ case WebView.LoadStoppedStatus:
+ break
+ case WebView.LoadFailedStatus:
+ break
+ }
+ opacity = 0
+ }
+
+ 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/flickrview/main.cpp b/examples/qml/flickrview/main.cpp
new file mode 100644
index 0000000..19bd30c
--- /dev/null
+++ b/examples/qml/flickrview/main.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** 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 "../shared/shared.h"
+QWEBKIT_EXAMPLE_MAIN(flickrview)
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
new file mode 100644
index 0000000000000000000000000000000000000000..1dcec4432dec0e3b8be70e65912ef2fcd486789a
GIT binary patch
literal 10960
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
PDWoK?j;NA-`Qd*6&lk#a
literal 0
HcmV?d00001
diff --git a/examples/qml/shared/images/busy.png b/examples/qml/shared/images/busy.png
new file mode 100644
index 0000000000000000000000000000000000000000..664c2b1491498ee0158cb7674602265cc5f5c70c
GIT binary patch
literal 2629
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
literal 0
HcmV?d00001
diff --git a/examples/qml/shared/images/flickr.png b/examples/qml/shared/images/flickr.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0f050254a34f83c48ea1297ee3a1c7ebb156f2a
GIT binary patch
literal 6818
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
Qz5oCK07*qoM6N<$f}PO;fB*mh
literal 0
HcmV?d00001
diff --git a/examples/qml/shared/images/less.png b/examples/qml/shared/images/less.png
new file mode 100644
index 0000000000000000000000000000000000000000..136919b09ff274f31da20f2a541507760501ae4d
GIT binary patch
literal 4335
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
literal 0
HcmV?d00001
diff --git a/examples/qml/shared/images/more.png b/examples/qml/shared/images/more.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe7f87e15fb32a10a33063a4b7ea088368325ed7
GIT binary patch
literal 4261
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
literal 0
HcmV?d00001
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.h b/examples/qml/shared/shared.h
new file mode 100644
index 0000000..ffb211f
--- /dev/null
+++ b/examples/qml/shared/shared.h
@@ -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>
+#define QWEBKIT_EXAMPLE_MAIN(NAME) int main(int argc, char* argv[]) \
+{\
+ QGuiApplication app(argc,argv);\
+ QQuickView view;\
+ view.setSource(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + QLatin1String("/" #NAME ".qml")));\
+ view.setResizeMode(QQuickView::SizeRootObjectToView);\
+ view.show();\
+ return app.exec();\
+}
diff --git a/examples/qml/shared/shared.pro b/examples/qml/shared/shared.pro
new file mode 100644
index 0000000..f7f0ab1
--- /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 \
+ shared.h \
+ 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..ce55608
--- /dev/null
+++ b/examples/qml/youtubeview/content/YouTubeDialog.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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 {
+ anchors.fill: parent
+ id: container
+
+ color: "black"
+
+ signal presetClicked(string name)
+
+ property int neededHeight: 0
+
+ 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)
+ Component.onCompleted: container.neededHeight += height
+ }
+ }
+
+ 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..49986ef
--- /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 },
+ 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/main.cpp b/examples/qml/youtubeview/main.cpp
new file mode 100644
index 0000000..f4c982c
--- /dev/null
+++ b/examples/qml/youtubeview/main.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** 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 "../shared/shared.h"
+QWEBKIT_EXAMPLE_MAIN(youtubeview)
diff --git a/examples/qml/youtubeview/youtubeview.pro b/examples/qml/youtubeview/youtubeview.pro
new file mode 100644
index 0000000..5cd641a
--- /dev/null
+++ b/examples/qml/youtubeview/youtubeview.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+QT += quick qml webkit
+SOURCES += 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..4e6292c
--- /dev/null
+++ b/examples/qml/youtubeview/youtubeview.qml
@@ -0,0 +1,490 @@
+/****************************************************************************
+**
+** 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 topInformation
+** 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 topInformation 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 topInformation 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
+ visible: panel.state == "search"
+ 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 }
+ },
+
+ 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 }
+ },
+
+ State {
+ name: "hidden"
+ PropertyChanges { target: panel; color: "gray"; opacity: 0.2; y: -height + container.padding }
+ }
+ ]
+
+ Timer {
+ id: hideTimer
+ interval: 3000
+ repeat: false
+ onTriggered: panel.state = "hidden"
+ }
+
+ MouseArea {
+ visible: panel.state == "hidden"
+ 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"
+
+ property int requiredHeight: 0
+
+ anchors {
+ top: panel.top
+ bottom: button.top
+ left: panel.left
+ right: panel.right
+ }
+ model: model
+ delegate: delegate
+ header: listHeader
+ footer: listFooter
+
+ focus: true
+ visible: panel.state == "list"
+ 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
+ }
+ }
+ }
+
+ Component {
+ id: listHeader
+ Rectangle {
+ visible: model.startIndex != 1 && model.status == XmlListModel.Ready
+ color: "black"
+ anchors.verticalCenter: parent.verticalCenter
+ width: height
+ height: visible ? listView.requiredHeight : 0
+ Image { anchors.centerIn: parent; width: 50; height: 50; source: "../shared/images/less.png" }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: model.requestLess()
+ }
+ }
+ }
+
+ Component {
+ id: listFooter
+ Rectangle {
+ visible: model.totalResults > model.endIndex && model.status == XmlListModel.Ready
+ color: "black"
+ anchors.verticalCenter: parent.verticalCenter
+ width: height
+ height: visible ? listView.requiredHeight : 0
+ Image { anchors.centerIn: parent; width: 50; height: 50; source: "../shared/images/more.png" }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: model.requestMore()
+ }
+ }
+ }
+
+ Component {
+ id: delegate
+ Image {
+ source: thumbnail
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ currentVideo.vId = id
+ currentVideo.title = title
+ }
+ }
+ Component.onCompleted: {
+ if (listView.requiredHeight < thumbnailHeight)
+ listView.requiredHeight = thumbnailHeight
+ if (currentVideo.title == "") {
+ currentVideo.vId = id
+ currentVideo.title = 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: "."
+ }
+}
--
1.7.12.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment