~unity-team/unity8/dash-only

« back to all changes in this revision

Viewing changes to qml/Components/LazyImage.qml

  • Committer: Kevin Gunn
  • Date: 2016-10-24 19:51:33 UTC
  • Revision ID: kevin.gunn@canonical.com-20161024195133-61lwdzzdwsnue1mn
shave some more

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2013-2016 Canonical, Ltd.
3
 
 *
4
 
 * Authors:
5
 
 *   Michał Sawicz <michal.sawicz@canonical.com>
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or modify
8
 
 * it under the terms of the GNU General Public License as published by
9
 
 * the Free Software Foundation; version 3.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
import QtQuick 2.4
21
 
import Ubuntu.Components 1.3
22
 
 
23
 
Item {
24
 
    id: root
25
 
 
26
 
    property url source
27
 
    // TODO convert into enums when available in QML
28
 
    property string scaleTo
29
 
 
30
 
    property real initialWidth: scaleTo == "width" || scaleTo == "fit" ? width : units.gu(10)
31
 
    property real initialHeight: scaleTo == "height" || scaleTo == "fit" ? height : units.gu(10)
32
 
    property real lastScaledDimension: scaleTo == "height" || scaleTo == "fit" ? width : height
33
 
 
34
 
    property alias sourceSize: image.sourceSize
35
 
    property alias asynchronous: image.asynchronous
36
 
    property alias cache: image.cache
37
 
    property alias sourceImage: image
38
 
 
39
 
    property bool useUbuntuShape: true
40
 
    property bool pressed: false
41
 
 
42
 
    state: "default"
43
 
 
44
 
    onSourceChanged: {
45
 
        if (state === "ready") {
46
 
            state = "default";
47
 
            image.nextSource = source;
48
 
        } else {
49
 
            image.source = source;
50
 
        }
51
 
    }
52
 
 
53
 
    Loader {
54
 
        id: placeholder
55
 
        objectName: "placeholder"
56
 
        anchors.fill: shape
57
 
        active: useUbuntuShape
58
 
        visible: opacity != 0
59
 
        sourceComponent: UbuntuShape {
60
 
            backgroundColor: "#22FFFFFF"
61
 
        }
62
 
 
63
 
        ActivityIndicator {
64
 
            id: activity
65
 
            anchors.centerIn: parent
66
 
            opacity: 0
67
 
            visible: opacity != 0
68
 
 
69
 
            running: visible
70
 
        }
71
 
 
72
 
        Image {
73
 
            id: errorImage
74
 
            objectName: "errorImage"
75
 
            anchors.centerIn: parent
76
 
            opacity: 0
77
 
            visible: opacity != 0
78
 
 
79
 
            source: "graphics/close.png"
80
 
            sourceSize { width: units.gu(3); height: units.gu(3) }
81
 
        }
82
 
    }
83
 
 
84
 
    Loader {
85
 
        id: shape
86
 
        objectName: "shape"
87
 
        height: root.initialHeight
88
 
        width: root.initialWidth
89
 
        anchors.centerIn: root.scaleTo == "fit" ? parent : undefined
90
 
        active: useUbuntuShape
91
 
        opacity: 0
92
 
        visible: opacity != 0
93
 
        sourceComponent: UbuntuShapeOverlay {
94
 
            property bool pressed: false
95
 
            overlayColor: Qt.rgba(0, 0, 0, pressed ? 0.1 : 0)
96
 
            overlayRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
97
 
        }
98
 
        onLoaded: {
99
 
            item.source = image;
100
 
            item.pressed = Qt.binding(function() { return root.pressed; });
101
 
        }
102
 
 
103
 
        Image {
104
 
            id: image
105
 
            objectName: "image"
106
 
 
107
 
            property url nextSource
108
 
            property string format: image.implicitWidth > image.implicitHeight ? "landscape" : "portrait"
109
 
 
110
 
            anchors.fill: parent
111
 
            visible: !useUbuntuShape
112
 
            fillMode: Image.PreserveAspectFit
113
 
            asynchronous: true
114
 
            cache: false
115
 
            sourceSize.width: root.scaleTo == "width" ? root.width
116
 
                                : root.scaleTo == "fit" && root.width <= root.height ? root.width
117
 
                                : 0
118
 
            sourceSize.height: root.scaleTo == "height" ? root.height
119
 
                                : root.scaleTo == "fit" && root.height <= root.width ? root.height
120
 
                                : 0
121
 
        }
122
 
    }
123
 
 
124
 
    states: [
125
 
        State {
126
 
            name: "default"
127
 
            when: image.source == ""
128
 
            PropertyChanges { target: root; implicitWidth: root.initialWidth; implicitHeight: root.initialHeight }
129
 
            PropertyChanges { target: errorImage; opacity: 0 }
130
 
        },
131
 
        State {
132
 
            name: "loading"
133
 
            extend: "default"
134
 
            when: image.status === Image.Loading
135
 
            PropertyChanges { target: activity; opacity: 1 }
136
 
        },
137
 
        State {
138
 
            name: "ready"
139
 
            when: image.status === Image.Ready && image.source != ""
140
 
            PropertyChanges { target: root; implicitWidth: shape.width; implicitHeight: shape.height }
141
 
            PropertyChanges { target: placeholder; opacity: 0 }
142
 
            PropertyChanges { target: shape; opacity: 1
143
 
                width: root.scaleTo == "width" || (root.scaleTo == "fit" && image.format == "landscape") ? root.width
144
 
                    : root.scaleTo == "" ?  image.implicitWidth : image.implicitWidth * height / image.implicitHeight
145
 
                height: root.scaleTo == "height" || (root.scaleTo == "fit" && image.format == "portrait") ? root.height
146
 
                    : root.scaleTo == "" ? image.implicitHeight : image.implicitHeight * width / image.implicitWidth
147
 
            }
148
 
        },
149
 
        State {
150
 
            name: "error"
151
 
            extend: "default"
152
 
            when: image.status === Image.Error
153
 
            PropertyChanges { target: errorImage; opacity: 1.0 }
154
 
        }
155
 
    ]
156
 
 
157
 
    transitions: [
158
 
        Transition {
159
 
            to: "ready"
160
 
            objectName: "readyTransition"
161
 
            SequentialAnimation {
162
 
                PropertyAction { target: shape; property: "visible" }
163
 
                ParallelAnimation {
164
 
                    NumberAnimation { target: shape; property: "opacity"; easing.type: Easing.Linear }
165
 
                    UbuntuNumberAnimation { target: root; properties: "implicitWidth,implicitHeight" }
166
 
                    UbuntuNumberAnimation { target: shape; properties: "width,height" }
167
 
                    NumberAnimation {
168
 
                        targets: [placeholder, activity, errorImage]; property: "opacity";
169
 
                        easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
170
 
                    }
171
 
                }
172
 
                ScriptAction { script: { lastScaledDimension = scaleTo == "height" || scaleTo == "fit" ? root.width : root.height } }
173
 
            }
174
 
        },
175
 
 
176
 
        Transition {
177
 
            to: "*"
178
 
            objectName: "genericTransition"
179
 
            SequentialAnimation {
180
 
                ParallelAnimation {
181
 
                    NumberAnimation { target: shape; property: "opacity"; easing.type: Easing.Linear }
182
 
                    NumberAnimation {
183
 
                        targets: [placeholder, activity, errorImage]; property: "opacity";
184
 
                        easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
185
 
                    }
186
 
                    UbuntuNumberAnimation { target: root; properties: "implicitWidth,implicitHeight" }
187
 
                    UbuntuNumberAnimation { target: shape; properties: "width,height" }
188
 
                }
189
 
                PropertyAction { target: shape; property: "visible" }
190
 
            }
191
 
 
192
 
            onRunningChanged: {
193
 
                if (!running && state === "default" && image.nextSource !== "") {
194
 
                    image.source = image.nextSource;
195
 
                    image.nextSource = "";
196
 
                }
197
 
            }
198
 
        }
199
 
    ]
200
 
}