flickrview.qml Example File | Qt WebKit Examples 5.5

- Qt 5.5
- Qt WebKit Examples
- Flickr View Example
- flickrview.qml Example File
- Qt 5.5.1 Reference Documentation

# flickrview.qml Example File

webkitqml/flickrview/flickrview.qml

    /****************************************************************************
    **
    ** Copyright (C) 2015 The Qt Company Ltd.
    ** Contact: http://www.qt.io/licensing/
    **
    ** 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 The Qt Company Ltd nor the names of its
    **     contributors may be used to endorse or promote products derived
    **     from this software without specific prior written permission.
    **
    **
    ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/

    import QtQuick 2.0
    import QtWebKit 3.0
    import QtQuick.XmlListModel 2.0
    import "qrc:/shared" as 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: "qrc:/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
                    }
                }
            }

            Shared.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: {
                    switch (request.navigationType)
                    {
                    case WebView.LinkClickedNavigation:
                    case WebView.FormSubmittedNavigation:
                    case WebView.BackForwardNavigation:
                    case WebView.ReloadNavigation:
                    case WebView.FormResubmittedNavigation:
                    case WebView.OtherNavigation:
                        if (/^(https|http):\/\/(www\.flickr\.com|login\.yahoo\.com)/.test(request.url)) {
                            request.action = WebView.AcceptRequest
                            return
                        }
                    }
                    // Disallow navigating outside of flickr.com
                    request.action = WebView.IgnoreRequest
                }
            }

            Shared.LoadIndicator {
                anchors.fill: parent
                imageSource: "qrc:/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()" }
        }

    }