Twitter example
authorJaroslaw Staniek <staniek@kde.org>
Thu, 30 May 2013 21:35:05 +0000 (21:35 +0000)
committerTomasz Olszak <olszak.tomasz@gmail.com>
Tue, 4 Jun 2013 08:23:15 +0000 (10:23 +0200)
Includes scaling, shadows, scroll indicator, improved list

Change-Id: I6ab043c53fd25bb78a09c9e62054aa0bf6d60712
Reviewed-by: Tomasz Olszak <olszak.tomasz@gmail.com>
15 files changed:
README
examples/examples.pro
examples/twitter/content/ListDelegate.qml [new file with mode: 0644]
examples/twitter/content/ScrollDecorator.qml [new file with mode: 0644]
examples/twitter/content/Settings.qml [new file with mode: 0644]
examples/twitter/content/TizenSansRegular.ttf [new file with mode: 0644]
examples/twitter/content/TwitterModel.qml [new file with mode: 0644]
examples/twitter/content/TwitterView.qml [new file with mode: 0644]
examples/twitter/content/pics/00_scroll_bar_v.9.png [new file with mode: 0644]
examples/twitter/content/pics/00_scroll_bar_v_ef.9.png [new file with mode: 0644]
examples/twitter/content/private/NinePatchImageWithEffect.qml [new file with mode: 0644]
examples/twitter/content/private/ScrollSizer.qml [new file with mode: 0644]
examples/twitter/content/utils.js [new file with mode: 0644]
examples/twitter/main.qml [new file with mode: 0644]
examples/twitter/twitter.qmlproject [new file with mode: 0644]

diff --git a/README b/README
index 2f502b1..54d812c 100644 (file)
--- a/README
+++ b/README
@@ -25,7 +25,8 @@ Licensing
 
 * License headers are included in source code files (LGPL, BSD)
 
-* Images stored in src/styles/images come from 'uifw' package (Tizen 2.1 beta release):
+* Images and fonts stored in src/styles/images and other directories come from 'uifw' package
+  (Tizen 2.1 beta release):
   https://review.tizen.org/git/?p=platform/framework/native/uifw.git;a=tag;h=refs/tags/2.1b_release,
   from uifw.git/res/common/usr/share/osp/bitmaps/ directory.
   They are licensed under the Apache 2.0, see the LICENSE.APLv2 file.
index e105ae6..48b59a4 100644 (file)
@@ -1,3 +1,3 @@
 TEMPLATE=subdirs
 
-SUBDIRS+= touch
+SUBDIRS+= touch twitter
diff --git a/examples/twitter/content/ListDelegate.qml b/examples/twitter/content/ListDelegate.qml
new file mode 100644 (file)
index 0000000..3937d29
--- /dev/null
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import "utils.js" as Utils
+
+Item {
+    id: root
+    width: parent.width
+    height: textitem.contentHeight + 2 * 40
+
+    property alias text: textitem.text
+    signal clicked
+
+    Settings { id: settings }
+
+    Rectangle {
+        anchors.fill: parent
+        color: "#5787c2"
+        visible: mouse.pressed
+        z: 1
+    }
+    Rectangle {
+        id: whiteLine
+        anchors.left: textitem.left
+        anchors.right: textitem.right
+        y: parent.height
+        height: Utils.scaleLine(1)
+        color: "white"
+        visible: index < (listView.count - 1)
+    }
+    Rectangle {
+        id: grayLine
+        anchors.left: textitem.left
+        anchors.right: textitem.right
+        y: parent.height - 1
+        height: Utils.scaleLine(1)
+        color: "#d3d1cb"
+        visible: whiteLine.visible
+    }
+    Text {
+        id: textitem
+
+        function richStatus(text) {
+            return text.replace(/([#@][\w]+)/g, '<span style="color:#80c43d;">$&</span>')
+                .replace(/(http:\/\/)([^ \n\t]+)/g, '<a href="$1$2" style="color:#80c43d;text-decoration:none;">$2</a>');
+        }
+        text: '<html><body style="">'
+              + '<span style="text-transform:uppercase;color:'
+              + (mouse.pressed ? '#cccccc' : '#999999')
+              + ';">'
+              + Utils.prettyDate(model.date)
+              + '</span><br/>'
+              + '<span style="color:'
+              + (mouse.pressed ? 'white' : 'black')
+              + ';">'
+              + richStatus(model.statusText)
+              + '</span></body></html>'
+        anchors.verticalCenter: parent.verticalCenter
+        width: parent.width - x * 2
+        x: 30
+        y: 40
+        z: 2
+
+        anchors.rightMargin: 30
+        anchors.bottomMargin: 40
+        wrapMode: Text.Wrap
+        textFormat: Text.RichText
+        font.family: settings.defaultFont
+        font.pixelSize: 36
+        elide: Text.ElideLeft
+        MouseArea {
+            id: mouse
+            anchors.fill: parent
+            onClicked: root.clicked()
+        }
+    }
+}
diff --git a/examples/twitter/content/ScrollDecorator.qml b/examples/twitter/content/ScrollDecorator.qml
new file mode 100644 (file)
index 0000000..4da1e00
--- /dev/null
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import "private"
+
+Item {
+    id: root
+    anchors.fill: flickableItem
+
+    property Flickable flickableItem
+
+    Item {
+        id: priv
+        property int minIndicatorSize: 20
+        property int hideTimeout: 500
+        property int showTimeout: 150
+        property int shadowLength: 25
+
+        function canFlick(direction) {
+            return flickableItem.flickableDirection === direction ||
+                    flickableItem.flickableDirection === Flickable.HorizontalAndVerticalFlick ||
+                    flickableItem.flickableDirection === Flickable.AutoFlickDirection;
+        }
+    }
+
+    Rectangle {
+        id: verticalShadow
+        anchors.fill: root
+        opacity: 0
+        gradient: Gradient {
+            GradientStop { position: 0.0; color: "#32000000" }
+            GradientStop { position: priv.shadowLength/flickableItem.height; color: "#00000000" }
+            GradientStop { position: 1.0 - (priv.shadowLength/flickableItem.height); color: "#00000000" }
+            GradientStop { position: 1.0; color: "#32000000" }
+        }
+
+        states: State {
+            name: "visible"
+            when: flickableItem && flickableItem.movingVertically
+            PropertyChanges { target: verticalShadow; opacity: 1; visible: true }
+        }
+
+        transitions: [
+            Transition {
+                from: "visible"
+                to: ""
+                NumberAnimation { target: verticalShadow; property: "opacity"; duration: priv.hideTimeout; onStopped: verticalShadow.visible = false }
+            },
+            Transition {
+                from: ""
+                to: "visible"
+                NumberAnimation { target: verticalShadow; property: "opacity"; duration: priv.showTimeout }
+            }
+        ]
+    }
+
+    Rectangle {
+        id: horizontalShadow
+        anchors.centerIn: root
+        width: root.height
+        height: root.width
+        opacity: 0
+        rotation: 90
+        gradient: Gradient {
+            GradientStop { position: 0.0; color: "#32000000" }
+            GradientStop { position: priv.shadowLength/flickableItem.height; color: "transparent" }
+            GradientStop { position: 1.0 - (priv.shadowLength/flickableItem.height); color: "transparent" }
+            GradientStop { position: 1.0; color: "#32000000" }
+        }
+
+        states: State {
+            name: "visible"
+            when: flickableItem && flickableItem.movingHorizontally
+            PropertyChanges { target: horizontalShadow; opacity: 1 }
+        }
+
+        transitions: [
+            Transition {
+                from: "visible"
+                to: ""
+                NumberAnimation { target: horizontalShadow; property: "opacity"; duration: priv.hideTimeout; onStopped: verticalShadow.visible = false }
+            },
+            Transition {
+                from: ""
+                to: "visible"
+                NumberAnimation { target: horizontalShadow; property: "opacity"; duration: priv.showTimeout }
+            }
+        ]
+    }
+
+    Component {
+        id: verticalSizerWrapper
+        ScrollSizer {
+            id: verticalSizer
+            positionRatio: flickableItem ? flickableItem.visibleArea.yPosition : 0
+            sizeRatio: flickableItem ? flickableItem.visibleArea.heightRatio : 0
+            maxPosition: flickableItem ? flickableItem.height : 0
+            minSize: priv.minIndicatorSize
+        }
+    }
+
+    Component {
+        id: horizontalSizerWrapper
+        ScrollSizer {
+            id: horizontalSizer
+            positionRatio: flickableItem ? flickableItem.visibleArea.xPosition : 0
+            sizeRatio: flickableItem ? flickableItem.visibleArea.widthRatio : 0
+            maxPosition: flickableItem ? flickableItem.width : 0
+            minSize: priv.minIndicatorSize
+        }
+    }
+
+    Loader { id: verticalSizerLoader }
+    Loader { id: horizontalSizerLoader }
+
+    NinePatchImageWithEffect {
+        id: verticalIndicator
+        anchors.right: parent.right
+        anchors.rightMargin: 6
+        opacity: 0
+        source: "pics/00_scroll_bar_v.9.png"
+        effectSource: "pics/00_scroll_bar_v_ef.9.png"
+        leftCut: 7; topCut: 7; rightCut: 10; bottomCut: 10
+
+        y: shouldShow && verticalSizerLoader.status == Loader.Ready ? verticalSizerLoader.item.position : 0
+        height: shouldShow && verticalSizerLoader.status == Loader.Ready ? verticalSizerLoader.item.size - (horizontalIndicator.shouldShow ? 8 : 0) : 0
+
+        property bool shouldShow: flickableItem && priv.canFlick(Flickable.VerticalFlick) && (flickableItem.height > 0 && flickableItem.contentHeight > flickableItem.height)
+
+        onShouldShowChanged: {
+            if (shouldShow)
+                verticalSizerLoader.sourceComponent = verticalSizerWrapper;
+            else
+                verticalSizerLoader.sourceComponent = undefined;
+        }
+
+        states: State {
+            name: "visible"
+            when: flickableItem && flickableItem.movingVertically
+            PropertyChanges { target: verticalIndicator; opacity: 1 }
+        }
+        transitions: [
+            Transition {
+                from: "visible"
+                to: ""
+                NumberAnimation { target: verticalIndicator; property: "opacity"; duration: priv.hideTimeout }
+            },
+            Transition {
+                from: ""
+                to: "visible"
+                NumberAnimation { target: verticalIndicator; property: "opacity"; duration: priv.showTimeout }
+            }
+        ]
+    }
+
+    NinePatchImageWithEffect {
+        id: horizontalIndicator
+        anchors.bottom: parent.bottom
+        opacity: 0
+        // FIXME not tested
+        source: "pics/00_scroll_bar_v.9.png"
+        effectSource: "pics/00_scroll_bar_v_ef.9.png"
+        leftCut: 4; topCut: 5; rightCut: 14; bottomCut: 10
+
+        x: shouldShow && horizontalSizerLoader.status == Loader.Ready ? horizontalSizerLoader.item.position : 0
+        width: shouldShow && horizontalSizerLoader.status == Loader.Ready ? horizontalSizerLoader.item.size - (verticalIndicator.shouldShow ? 8 : 0) : 0
+        height: implicitWidth
+
+        property bool shouldShow: flickableItem && priv.canFlick(Flickable.HorizontalFlick) && (flickableItem.width > 0 && flickableItem.contentWidth > flickableItem.width)
+
+        onShouldShowChanged: {
+            if (shouldShow)
+                horizontalSizerLoader.sourceComponent = horizontalSizerWrapper;
+            else
+                horizontalSizerLoader.sourceComponent = undefined;
+        }
+
+        states: State {
+            name: "visible"
+            when: flickableItem && flickableItem.movingHorizontally
+            PropertyChanges { target: horizontalIndicator; opacity: 1 }
+        }
+        transitions: [
+            Transition {
+                from: "visible"
+                to: ""
+                NumberAnimation { target: horizontalIndicator; property: "opacity"; duration: priv.hideTimeout }
+            },
+            Transition {
+                from: ""
+                to: "visible"
+                NumberAnimation { target: horizontalIndicator; property: "opacity"; duration: priv.showTimeout }
+            }
+        ]
+    }
+}
diff --git a/examples/twitter/content/Settings.qml b/examples/twitter/content/Settings.qml
new file mode 100644 (file)
index 0000000..0c62f98
--- /dev/null
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+
+Item {
+    property string defaultFont: 'TizenSans'
+    FontLoader {
+        id: loader
+        source: "TizenSansRegular.ttf"
+    }
+}
diff --git a/examples/twitter/content/TizenSansRegular.ttf b/examples/twitter/content/TizenSansRegular.ttf
new file mode 100644 (file)
index 0000000..356c266
Binary files /dev/null and b/examples/twitter/content/TizenSansRegular.ttf differ
diff --git a/examples/twitter/content/TwitterModel.qml b/examples/twitter/content/TwitterModel.qml
new file mode 100644 (file)
index 0000000..32a95d3
--- /dev/null
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.XmlListModel 2.0
+import "utils.js" as Utils
+
+XmlListModel {
+    property bool ready: false
+    property string user
+
+    source:'https://api.twitter.com/1/statuses/user_timeline.xml?include_entities=true'
+          + '&exclude_replies=true&trim_user=true&include_rts=true&screen_name=' + user + '&count=50'
+    query: "/statuses/status"
+    XmlRole { name: "date"; query: "created_at/string()" }
+    XmlRole { name: "statusText"; query: "text/string()" }
+
+    onStatusChanged: {
+        ready = (status == XmlListModel.Ready)
+        if (Utils.debug) {
+            switch (status) {
+            case XmlListModel.Ready:    console.log("[READY]   '" + source + "' | "  + count + " items")
+            case XmlListModel.Error:    console.log("[ERROR]   '" + source + "' | Error: ''" + errorString() + "'")
+            case XmlListModel.Loading:  console.log("[LOADING] '" + source + "'")
+            }
+        }
+    }
+}
diff --git a/examples/twitter/content/TwitterView.qml b/examples/twitter/content/TwitterView.qml
new file mode 100644 (file)
index 0000000..de025fe
--- /dev/null
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import "utils.js" as Utils
+
+Item {
+    property string userName: "QtForTizen"
+    Rectangle {
+        width: Utils.appWidth
+        height: Utils.appHeight
+        anchors.centerIn: parent
+        scale: Math.min(parent.width / width, parent.height / height)
+        color: "#f8f6ef"
+        Settings { id: settings }
+
+        Text {
+            id: header
+            anchors.top: parent.top
+            anchors.left: parent.left
+            anchors.right: parent.right
+            anchors.leftMargin: 30
+            anchors.rightMargin: 30
+            anchors.topMargin: 30
+            color: "#3b73b6"
+            text: qsTr("TWEETS")
+            font.family: settings.defaultFont
+            font.pixelSize: 36
+        }
+        Text {
+            id: header2
+            anchors.top: header.bottom
+            anchors.left: header.left
+            anchors.right: header.right
+            anchors.leftMargin: header.leftMargin
+            anchors.rightMargin: header.rightMargin
+            height: 14 + contentHeight
+            color: header.color
+            text: userName
+            font.family: settings.defaultFont
+            font.pixelSize: 24
+        }
+        ListView {
+            id: listView
+            anchors.top: header2.bottom
+            anchors.left: parent.left
+            anchors.right: parent.right
+            anchors.bottom: parent.bottom
+            clip: true
+
+            delegate: ListDelegate {
+            }
+
+            model: TwitterModel {
+                id: xmlModel
+                user: userName
+            }
+        }
+        ScrollDecorator {
+            flickableItem: listView
+        }
+    }
+}
diff --git a/examples/twitter/content/pics/00_scroll_bar_v.9.png b/examples/twitter/content/pics/00_scroll_bar_v.9.png
new file mode 100644 (file)
index 0000000..5726a64
Binary files /dev/null and b/examples/twitter/content/pics/00_scroll_bar_v.9.png differ
diff --git a/examples/twitter/content/pics/00_scroll_bar_v_ef.9.png b/examples/twitter/content/pics/00_scroll_bar_v_ef.9.png
new file mode 100644 (file)
index 0000000..07b6a0e
Binary files /dev/null and b/examples/twitter/content/pics/00_scroll_bar_v_ef.9.png differ
diff --git a/examples/twitter/content/private/NinePatchImageWithEffect.qml b/examples/twitter/content/private/NinePatchImageWithEffect.qml
new file mode 100644 (file)
index 0000000..f71a57a
--- /dev/null
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+    id:root
+    implicitWidth: base.implicitWidth
+    implicitHeight: base.implicitHeight
+    property alias source: base.source
+    property alias effectSource: effect.source
+    property color color
+    property int leftCut
+    property int rightCut
+    property int topCut
+    property int bottomCut
+
+    BorderImage {
+        id: base
+        anchors.fill: parent
+        border {
+            left: root.leftCut
+            right: root.rightCut
+            top: root.topCut
+            bottom: root.bottomCut
+        }
+    }
+
+    BorderImage {
+        id: effect
+        anchors.fill: base
+        border {
+            left: root.leftCut
+            right: root.rightCut
+            top: root.topCut
+            bottom: root.bottomCut
+        }
+    }
+}
diff --git a/examples/twitter/content/private/ScrollSizer.qml b/examples/twitter/content/private/ScrollSizer.qml
new file mode 100644 (file)
index 0000000..bf4b055
--- /dev/null
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+    id: sizer
+
+    // relative (0..1) position of top and bottom
+    property real positionRatio
+    property real sizeRatio
+
+    // max position and min size
+    property real maxPosition
+    property real minSize
+
+    // size underflow
+    property real sizeUnderflow: (sizeRatio * maxPosition) < minSize
+                                 ? minSize - (sizeRatio * maxPosition) : 0
+
+    // raw start and end position considering minimum size
+    property real rawStartPos: positionRatio * (maxPosition - sizeUnderflow)
+    property real rawEndPos: (positionRatio + sizeRatio) * (maxPosition - sizeUnderflow) + sizeUnderflow
+
+    // overshoot amount at start and end
+    property real overshootStart: rawStartPos < 0 ? -rawStartPos : 0
+    property real overshootEnd: rawEndPos > maxPosition ? rawEndPos - maxPosition : 0
+
+    // overshoot adjusted start and end
+    property real adjStartPos: rawStartPos + overshootStart
+    property real adjEndPos: rawEndPos - overshootStart - overshootEnd
+
+    // final position and size of thumb
+    property int position: 0.5 + (adjStartPos + minSize > maxPosition
+                                  ? maxPosition - minSize : adjStartPos)
+    property int size: 0.5 + ((adjEndPos - position) < minSize
+                              ? minSize : (adjEndPos - position))
+}
diff --git a/examples/twitter/content/utils.js b/examples/twitter/content/utils.js
new file mode 100644 (file)
index 0000000..a82cbcb
--- /dev/null
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $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$
+**
+****************************************************************************/
+
+.pragma library
+
+var debug = false;
+
+// initial app window size
+var appWidth = 720;
+var appHeight = 1280;
+
+// initial scale
+var appScale = 1;
+
+// returns line height scaled so it's visible on lower DPI (useful for testing on PC)
+function scaleLine(height)
+{
+    return height * 1.0 / appScale
+}
+
+/*
+ * Javascript Humane Dates
+ * Copyright (c) 2008 Dean Landolt (deanlandolt.com)
+ * Re-write by Zach Leatherman (zachleat.com)
+ *
+ * Adopted from the John Resig's pretty.js
+ * at http://ejohn.org/blog/javascript-pretty-date
+ * and henrah's proposed modification
+ * at http://ejohn.org/blog/javascript-pretty-date/#comment-297458
+ *
+ * Licensed under the MIT license.
+ */
+function prettyDate(date_str) {
+                var time_formats = [
+                    [60, 'Just Now'],
+                    [90, '1 Minute'], // 60*1.5
+                    [3600, 'Minutes', 60], // 60*60, 60
+                    [5400, '1 Hour'], // 60*60*1.5
+                    [86400, 'Hours', 3600], // 60*60*24, 60*60
+                    [129600, '1 Day'], // 60*60*24*1.5
+                    [604800, 'Days', 86400], // 60*60*24*7, 60*60*24
+                    [907200, '1 Week'], // 60*60*24*7*1.5
+                    [2628000, 'Weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
+                    [3942000, '1 Month'], // 60*60*24*(365/12)*1.5
+                    [31536000, 'Months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
+                    [47304000, '1 Year'], // 60*60*24*365*1.5
+                    [3153600000, 'Years', 31536000], // 60*60*24*365*100, 60*60*24*365
+                    [4730400000, '1 Century'], // 60*60*24*365*100*1.5
+                ];
+
+                var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," "),
+                    dt = new Date,
+                    seconds = ((dt - new Date(time) + (dt.getTimezoneOffset() * 60000)) / 1000),
+                    token = ' Ago',
+                    i = 0,
+                    format;
+
+                if (seconds < 0) {
+                    seconds = Math.abs(seconds);
+                    token = '';
+                }
+
+                while (format = time_formats[i++]) {
+                    if (seconds < format[0]) {
+                        if (format.length == 2) {
+                            return format[1] + (i > 1 ? token : ''); // Conditional so we don't return Just Now Ago
+                        } else {
+                            return Math.round(seconds / format[2]) + ' ' + format[1] + (i > 1 ? token : '');
+                        }
+                    }
+                }
+
+                // overflow for centuries
+                if (seconds > 4730400000) {
+                    return Math.round(seconds / 4730400000) + ' Centuries' + token;
+                }
+
+                return date_str;
+            }
diff --git a/examples/twitter/main.qml b/examples/twitter/main.qml
new file mode 100644 (file)
index 0000000..62d9d82
--- /dev/null
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Jarosław Staniek <staniek@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import "content"
+import "content/utils.js" as Utils
+
+ApplicationWindow {
+    id: main
+    width: Utils.appWidth * Utils.appScale
+    height: Utils.appHeight * Utils.appScale
+
+    StackView {
+        id: pageStack
+        anchors.fill: parent
+
+        initialItem: TwitterView {}
+    }
+}
diff --git a/examples/twitter/twitter.qmlproject b/examples/twitter/twitter.qmlproject
new file mode 100644 (file)
index 0000000..e5a8bf0
--- /dev/null
@@ -0,0 +1,16 @@
+import QmlProject 1.1
+
+Project {
+    mainFile: "main.qml"
+
+    /* Include .qml, .js, and image files from current directory and subdirectories */
+    QmlFiles {
+        directory: "."
+    }
+    JavaScriptFiles {
+        directory: "."
+    }
+    ImageFiles {
+        directory: "."
+    }
+}