Merge lp:~unity-team/unity8/rtm-20150108 into lp:unity8/rtm-14.09

Proposed by Michał Sawicz
Status: Merged
Approved by: Michał Sawicz
Approved revision: 1416
Merged at revision: 1411
Proposed branch: lp:~unity-team/unity8/rtm-20150108
Merge into: lp:unity8/rtm-14.09
Diff against target: 1539 lines (+708/-143)
43 files modified
debian/changelog (+18/-0)
debian/control (+0/-1)
plugins/Dash/CMakeLists.txt (+3/-2)
plugins/Dash/CardCreator.js (+8/-10)
plugins/Dash/CroppedImageMinimumSourceSize.qml (+25/-19)
plugins/Dash/abstractdashview.cpp (+24/-5)
plugins/Dash/abstractdashview.h (+6/-0)
plugins/Dash/croppedimagesizer.cpp (+136/-0)
plugins/Dash/croppedimagesizer.h (+72/-0)
plugins/Dash/croppedimagesizerasyncworker.cpp (+74/-0)
plugins/Dash/croppedimagesizerasyncworker.h (+47/-0)
plugins/Dash/listviewwithpageheader.cpp (+7/-2)
plugins/Dash/listviewwithpageheader.h (+4/-4)
plugins/Dash/plugin.cpp (+2/-0)
qml/Components/ResponsiveVerticalJournal.qml (+1/-0)
qml/Dash/CardCarousel.qml (+1/-0)
qml/Dash/CardGrid.qml (+1/-2)
qml/Dash/CardHorizontalList.qml (+1/-0)
qml/Dash/CardVerticalJournal.qml (+1/-1)
qml/Dash/DashContent.qml (+2/-0)
qml/Dash/DashRenderer.qml (+2/-4)
qml/Dash/GenericScopeView.qml (+75/-24)
qml/Dash/Previews/PreviewZoomableImage.qml (+1/-0)
qml/Dash/ScopeListView.qml (+4/-2)
qml/Greeter/Infographics.qml (+9/-7)
qml/Shell.qml (+20/-2)
tests/autopilot/unity8/shell/emulators/dash.py (+1/-1)
tests/plugins/Dash/CMakeLists.txt (+1/-0)
tests/plugins/Dash/cardcreator/1.res (+4/-4)
tests/plugins/Dash/cardcreator/2.res (+2/-3)
tests/plugins/Dash/cardcreator/3.res (+10/-10)
tests/plugins/Dash/cardcreator/4.res (+3/-4)
tests/plugins/Dash/cardcreator/5.res (+10/-10)
tests/plugins/Dash/cardcreator/7.res (+2/-3)
tests/plugins/Dash/horizontaljournaltest.qml (+1/-0)
tests/plugins/Dash/listviewwithpageheadertest.cpp (+1/-1)
tests/plugins/Dash/organicgridtest.qml (+1/-0)
tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qml (+56/-0)
tests/plugins/Dash/verticaljournaltest.qml (+1/-0)
tests/qmltests/Dash/tst_Card.qml (+0/-22)
tests/qmltests/Dash/tst_DashContent.qml (+57/-0)
tests/qmltests/Dash/tst_GenericScopeView.qml (+2/-0)
tests/utils/modules/Unity/Test/UnityTestCase.qml (+12/-0)
To merge this branch: bzr merge lp:~unity-team/unity8/rtm-20150108
Reviewer Review Type Date Requested Status
Michał Sawicz Approve
Review via email: mp+245852@code.launchpad.net
To post a comment you must log in.
lp:~unity-team/unity8/rtm-20150108 updated
1414. By Albert Astals Cid

Rework how we set the ranges so we get some more asynchronousity from item views
Approved by: Andrea Cimitan

1415. By Michał Sawicz

Don't block handling power events on loading the greeter's qml and the background image.

During power button press, we call greeter.showNow(), which was taking so long to return that we couldn't handle the power button release for a few seconds. Which meant that the shutdown dialog thought it would be a good time to appear.

The easiest fix is to delay calling showNow until after we finish handling the event.
Approved by: Daniel d'Andrada, PS Jenkins bot

1416. By Michał Sawicz

Add changelog

Revision history for this message
Michał Sawicz (saviq) wrote :

As per the upstream changes.

review: Approve
lp:~unity-team/unity8/rtm-20150108 updated
1417. By Albert Astals Cid

Make sure changing a scope doesn't trigger creation/destruction of delegates until it's finished

1418. By Michał Sawicz

Update changelog

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2015-01-07 09:49:10 +0000
+++ debian/changelog 2015-01-13 15:16:16 +0000
@@ -1,3 +1,21 @@
1unity8 (8.02+15.04.20150108~rtm--0ubuntu1) UNRELEASED; urgency=medium
2
3 [ Albert Astals ]
4 * Use QImageReader not to load the image into memory twice
5 * Don't create the whole current scope delegates, just height * 3 (LP:
6 #1384393)
7 * Make CroppedImageSizer async
8 * Rework how we set the ranges so we get some more asynchronousity
9 from item views
10 * Make sure changing a scope doesn't trigger creation/destruction of
11 delegates until it's finished
12
13 [ Michael Terry ]
14 * Don't block handling power events on loading the greeter's qml and the
15 background image. (LP: #1383277)
16
17 -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 08 Jan 2015 14:02:47 +0100
18
1unity8 (8.02+15.04.20150107~rtm-0ubuntu1) 14.09; urgency=low19unity8 (8.02+15.04.20150107~rtm-0ubuntu1) 14.09; urgency=low
220
3 [ Michael Zanetti ]21 [ Michael Zanetti ]
422
=== modified file 'debian/control'
--- debian/control 2014-12-12 13:08:13 +0000
+++ debian/control 2015-01-13 15:16:16 +0000
@@ -174,7 +174,6 @@
174 libhardware2,174 libhardware2,
175 unity-schemas (>= 7.3.1+14.10.20140915),175 unity-schemas (>= 7.3.1+14.10.20140915),
176 pay-service,176 pay-service,
177 qml-module-ubuntu-connectivity,
178 ${misc:Depends},177 ${misc:Depends},
179 ${shlibs:Depends},178 ${shlibs:Depends},
180Provides: unity-launcher-impl,179Provides: unity-launcher-impl,
181180
=== modified file 'plugins/Dash/CMakeLists.txt'
--- plugins/Dash/CMakeLists.txt 2014-05-14 10:11:14 +0000
+++ plugins/Dash/CMakeLists.txt 2015-01-13 15:16:16 +0000
@@ -11,7 +11,6 @@
11 ${CMAKE_CURRENT_SOURCE_DIR}11 ${CMAKE_CURRENT_SOURCE_DIR}
12 ${CMAKE_CURRENT_BINARY_DIR}12 ${CMAKE_CURRENT_BINARY_DIR}
13 ${Qt5Qml_PRIVATE_INCLUDE_DIRS}13 ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
14 ${Qt5Quick_INCLUDE_DIRS}
15 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}14 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
16 ${Qt5V8_PRIVATE_INCLUDE_DIR}15 ${Qt5V8_PRIVATE_INCLUDE_DIR}
17)16)
@@ -25,6 +24,8 @@
25 verticaljournal.cpp24 verticaljournal.cpp
26 horizontaljournal.cpp25 horizontaljournal.cpp
27 organicgrid.cpp26 organicgrid.cpp
27 croppedimagesizer.cpp
28 croppedimagesizerasyncworker.cpp
28 )29 )
2930
30add_library(Dash-qml MODULE31add_library(Dash-qml MODULE
@@ -36,6 +37,6 @@
36 ${Qt5Quick_LIBRARIES}37 ${Qt5Quick_LIBRARIES}
37 )38 )
3839
39qt5_use_modules(Dash-qml Qml Quick)40qt5_use_modules(Dash-qml Qml Quick Concurrent)
4041
41add_unity8_plugin(Dash 0.1 Dash TARGETS Dash-qml)42add_unity8_plugin(Dash 0.1 Dash TARGETS Dash-qml)
4243
=== modified file 'plugins/Dash/CardCreator.js'
--- plugins/Dash/CardCreator.js 2014-10-20 20:51:10 +0000
+++ plugins/Dash/CardCreator.js 2015-01-13 15:16:16 +0000
@@ -82,16 +82,16 @@
82 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height }); \n\82 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height }); \n\
83 } \n\83 } \n\
84 } \n\84 } \n\
85 image: CroppedImageMinimumSourceSize { \n\85 CroppedImageMinimumSourceSize { \n\
86 id: artImage; \n\
86 objectName: "artImage"; \n\87 objectName: "artImage"; \n\
87 property bool doLoadSource: !NetworkingStatus.limitedBandwith; \n\88 source: cardData && cardData["art"] || ""; \n\
88 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["art"] || ""; } \n\
89 cache: true; \n\
90 asynchronous: root.asynchronous; \n\89 asynchronous: root.asynchronous; \n\
91 visible: false; \n\90 visible: false; \n\
92 width: %2; \n\91 width: %2; \n\
93 height: %3; \n\92 height: %3; \n\
94 } \n\93 } \n\
94 image: artImage.image; \n\
95 } \n\95 } \n\
96 } \n\96 } \n\
97 }\n';97 }\n';
@@ -181,11 +181,11 @@
181 id: mascotShapeLoader; \n\181 id: mascotShapeLoader; \n\
182 objectName: "mascotShapeLoader"; \n\182 objectName: "mascotShapeLoader"; \n\
183 asynchronous: root.asynchronous; \n\183 asynchronous: root.asynchronous; \n\
184 active: mascotImage.status === Image.Ready; \n\184 active: mascotImage.image.status === Image.Ready; \n\
185 visible: showHeader && active && status == Loader.Ready; \n\185 visible: showHeader && active && status == Loader.Ready; \n\
186 width: units.gu(6); \n\186 width: units.gu(6); \n\
187 height: units.gu(5.625); \n\187 height: units.gu(5.625); \n\
188 sourceComponent: UbuntuShape { image: mascotImage } \n\188 sourceComponent: UbuntuShape { image: mascotImage.image } \n\
189 anchors { %1 } \n\189 anchors { %1 } \n\
190 }\n';190 }\n';
191191
@@ -195,8 +195,7 @@
195 id: mascotImage; \n\195 id: mascotImage; \n\
196 objectName: "mascotImage"; \n\196 objectName: "mascotImage"; \n\
197 anchors { %1 } \n\197 anchors { %1 } \n\
198 property bool doLoadSource: !NetworkingStatus.limitedBandwith; \n\198 source: cardData && cardData["mascot"] || ""; \n\
199 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["mascot"] || ""; } \n\
200 width: units.gu(6); \n\199 width: units.gu(6); \n\
201 height: units.gu(5.625); \n\200 height: units.gu(5.625); \n\
202 horizontalAlignment: Image.AlignHCenter; \n\201 horizontalAlignment: Image.AlignHCenter; \n\
@@ -435,7 +434,7 @@
435 mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors);434 mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors);
436 }435 }
437436
438 var mascotImageVisible = useMascotShape ? 'false' : 'showHeader && resized';437 var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
439 mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);438 mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);
440 }439 }
441440
@@ -655,7 +654,6 @@
655 var imports = 'import QtQuick 2.2; \n\654 var imports = 'import QtQuick 2.2; \n\
656 import Ubuntu.Components 1.1; \n\655 import Ubuntu.Components 1.1; \n\
657 import Ubuntu.Settings.Components 0.1; \n\656 import Ubuntu.Settings.Components 0.1; \n\
658 import Ubuntu.Connectivity 1.0; \n\
659 import Dash 0.1;\n\657 import Dash 0.1;\n\
660 import Utils 0.1;\n';658 import Utils 0.1;\n';
661 var card = cardString(template, components);659 var card = cardString(template, components);
662660
=== modified file 'plugins/Dash/CroppedImageMinimumSourceSize.qml'
--- plugins/Dash/CroppedImageMinimumSourceSize.qml 2014-09-17 10:16:11 +0000
+++ plugins/Dash/CroppedImageMinimumSourceSize.qml 2015-01-13 15:16:16 +0000
@@ -15,24 +15,30 @@
15 */15 */
1616
17import QtQuick 2.317import QtQuick 2.3
1818import Dash 0.1
19Image {19
20 property bool resized: false20Item {
21 property bool resizing: false21 id: root
22 fillMode: Image.PreserveAspectCrop22
23 visible: resized23 property string source
24 onSourceSizeChanged: {24 property alias image: innerImage
25 if (!resized && !resizing) {25 property alias asynchronous: innerImage.asynchronous
26 resizing = true;26 property alias verticalAlignment: innerImage.verticalAlignment
27 var ar = width / height;27 property alias horizontalAlignment: innerImage.horizontalAlignment
28 var ssar = sourceSize.width / sourceSize.height;28 property alias fillMode: innerImage.fillMode
29 if (ar > ssar) {29
30 sourceSize = Qt.size(width, 0);30 CroppedImageSizer {
31 } else {31 id: sizer
32 sourceSize = Qt.size(0, height);32 source: root.source
33 }33 width: root.width
34 resizing = false;34 height: root.height
35 resized = true;35 }
36 }36
37 Image {
38 id: innerImage
39 anchors.fill: parent
40 fillMode: Image.PreserveAspectCrop
41 sourceSize: sizer.sourceSize.width == 0 && sizer.sourceSize.height == 0 ? undefined : sizer.sourceSize
42 source: sizer.sourceSize.width == -1 && sizer.sourceSize.height == -1 ? "" : root.source
37 }43 }
38}44}
3945
=== modified file 'plugins/Dash/abstractdashview.cpp'
--- plugins/Dash/abstractdashview.cpp 2014-05-22 13:37:05 +0000
+++ plugins/Dash/abstractdashview.cpp 2015-01-13 15:16:16 +0000
@@ -16,13 +16,12 @@
1616
17#include "abstractdashview.h"17#include "abstractdashview.h"
1818
19static const qreal bufferRatio = 0.5;
20
21AbstractDashView::AbstractDashView()19AbstractDashView::AbstractDashView()
22 : m_delegateModel(nullptr)20 : m_delegateModel(nullptr)
23 , m_asyncRequestedIndex(-1)21 , m_asyncRequestedIndex(-1)
24 , m_columnSpacing(0)22 , m_columnSpacing(0)
25 , m_rowSpacing(0)23 , m_rowSpacing(0)
24 , m_buffer(320) // Same value used in qquickitemview.cpp in Qt 5.4
26 , m_displayMarginBeginning(0)25 , m_displayMarginBeginning(0)
27 , m_displayMarginEnd(0)26 , m_displayMarginEnd(0)
28 , m_needsRelayout(false)27 , m_needsRelayout(false)
@@ -112,6 +111,27 @@
112 }111 }
113}112}
114113
114int AbstractDashView::cacheBuffer() const
115{
116 return m_buffer;
117}
118
119void AbstractDashView::setCacheBuffer(int buffer)
120{
121 if (buffer < 0) {
122 qmlInfo(this) << "Cannot set a negative cache buffer";
123 return;
124 }
125
126 if (m_buffer != buffer) {
127 m_buffer = buffer;
128 if (isComponentComplete()) {
129 polish();
130 }
131 emit cacheBufferChanged();
132 }
133}
134
115qreal AbstractDashView::displayMarginBeginning() const135qreal AbstractDashView::displayMarginBeginning() const
116{136{
117 return m_displayMarginBeginning;137 return m_displayMarginBeginning;
@@ -160,9 +180,8 @@
160180
161 const qreal from = -m_displayMarginBeginning;181 const qreal from = -m_displayMarginBeginning;
162 const qreal to = height() + m_displayMarginEnd;182 const qreal to = height() + m_displayMarginEnd;
163 const qreal buffer = (to - from) * bufferRatio;183 const qreal bufferFrom = from - m_buffer;
164 const qreal bufferFrom = from - buffer;184 const qreal bufferTo = to + m_buffer;
165 const qreal bufferTo = to + buffer;
166185
167 bool added = addVisibleItems(from, to, false);186 bool added = addVisibleItems(from, to, false);
168 bool removed = removeNonVisibleItems(bufferFrom, bufferTo);187 bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
169188
=== modified file 'plugins/Dash/abstractdashview.h'
--- plugins/Dash/abstractdashview.h 2014-05-15 14:50:23 +0000
+++ plugins/Dash/abstractdashview.h 2015-01-13 15:16:16 +0000
@@ -35,6 +35,7 @@
35 Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)35 Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
36 Q_PROPERTY(qreal columnSpacing READ columnSpacing WRITE setColumnSpacing NOTIFY columnSpacingChanged)36 Q_PROPERTY(qreal columnSpacing READ columnSpacing WRITE setColumnSpacing NOTIFY columnSpacingChanged)
37 Q_PROPERTY(qreal rowSpacing READ rowSpacing WRITE setRowSpacing NOTIFY rowSpacingChanged)37 Q_PROPERTY(qreal rowSpacing READ rowSpacing WRITE setRowSpacing NOTIFY rowSpacingChanged)
38 Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
38 Q_PROPERTY(qreal displayMarginBeginning READ displayMarginBeginning39 Q_PROPERTY(qreal displayMarginBeginning READ displayMarginBeginning
39 WRITE setDisplayMarginBeginning40 WRITE setDisplayMarginBeginning
40 NOTIFY displayMarginBeginningChanged)41 NOTIFY displayMarginBeginningChanged)
@@ -61,6 +62,9 @@
61 qreal rowSpacing() const;62 qreal rowSpacing() const;
62 void setRowSpacing(qreal rowSpacing);63 void setRowSpacing(qreal rowSpacing);
6364
65 int cacheBuffer() const;
66 void setCacheBuffer(int);
67
64 qreal displayMarginBeginning() const;68 qreal displayMarginBeginning() const;
65 void setDisplayMarginBeginning(qreal);69 void setDisplayMarginBeginning(qreal);
6670
@@ -72,6 +76,7 @@
72 void delegateChanged();76 void delegateChanged();
73 void columnSpacingChanged();77 void columnSpacingChanged();
74 void rowSpacingChanged();78 void rowSpacingChanged();
79 void cacheBufferChanged();
75 void displayMarginBeginningChanged();80 void displayMarginBeginningChanged();
76 void displayMarginEndChanged();81 void displayMarginEndChanged();
7782
@@ -113,6 +118,7 @@
113118
114 int m_columnSpacing;119 int m_columnSpacing;
115 int m_rowSpacing;120 int m_rowSpacing;
121 int m_buffer;
116 qreal m_displayMarginBeginning;122 qreal m_displayMarginBeginning;
117 qreal m_displayMarginEnd;123 qreal m_displayMarginEnd;
118 bool m_needsRelayout;124 bool m_needsRelayout;
119125
=== added file 'plugins/Dash/croppedimagesizer.cpp'
--- plugins/Dash/croppedimagesizer.cpp 1970-01-01 00:00:00 +0000
+++ plugins/Dash/croppedimagesizer.cpp 2015-01-13 15:16:16 +0000
@@ -0,0 +1,136 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "croppedimagesizer.h"
18
19#include "croppedimagesizerasyncworker.h"
20
21#include <QNetworkAccessManager>
22#include <QNetworkRequest>
23#include <QQmlEngine>
24#include <QQuickItem>
25
26CroppedImageSizer::CroppedImageSizer()
27 : m_width(0),
28 m_height(0),
29 m_sourceSize(QSize(-1, -1)),
30 m_worker(nullptr)
31{
32 connect(this, &CroppedImageSizer::inputParamsChanged, this, &CroppedImageSizer::calculateSourceSize);
33 connect(this, &CroppedImageSizer::sourceChanged, this, &CroppedImageSizer::requestImage);
34}
35
36CroppedImageSizer::~CroppedImageSizer()
37{
38 if (m_worker) {
39 m_worker->abort();
40 }
41}
42
43QUrl CroppedImageSizer::source() const
44{
45 return m_source;
46}
47
48void CroppedImageSizer::setSource(const QUrl &source)
49{
50 if (source != m_source) {
51 m_source = source;
52 Q_EMIT sourceChanged();
53 }
54}
55
56qreal CroppedImageSizer::width() const
57{
58 return m_width;
59}
60
61void CroppedImageSizer::setWidth(qreal width)
62{
63 if (width != m_width) {
64 m_width = width;
65 Q_EMIT inputParamsChanged();
66 }
67}
68
69qreal CroppedImageSizer::height() const
70{
71 return m_height;
72}
73
74void CroppedImageSizer::setHeight(qreal height)
75{
76 if (height != m_height) {
77 m_height = height;
78 Q_EMIT inputParamsChanged();
79 }
80}
81
82QSize CroppedImageSizer::sourceSize() const
83{
84 return m_sourceSize;
85}
86
87void CroppedImageSizer::setSourceSize(const QSize &sourceSize)
88{
89 if (sourceSize != m_sourceSize) {
90 m_sourceSize = sourceSize;
91 Q_EMIT sourceSizeChanged();
92 }
93}
94
95void CroppedImageSizer::setImageSize(const QSize &imageSize)
96{
97 m_imageSize = imageSize;
98 m_worker = nullptr;
99 calculateSourceSize();
100}
101
102void CroppedImageSizer::requestImage()
103{
104 if (m_worker) {
105 m_worker->abort();
106 m_worker = nullptr;
107 }
108
109 if (m_source.isValid() && qmlEngine(this) && qmlEngine(this)->networkAccessManager()) {
110 QNetworkRequest request(m_source);
111 QNetworkReply *reply = qmlEngine(this)->networkAccessManager()->get(request);
112 m_worker = new CroppedImageSizerAsyncWorker(this, reply);
113 } else {
114 setSourceSize(QSize(-1, -1));
115 }
116}
117
118void CroppedImageSizer::calculateSourceSize()
119{
120 if (m_source.isValid() && m_width > 0 && m_height > 0 && !m_worker) {
121 if (!m_imageSize.isEmpty()) {
122 const qreal ar = m_width / m_height;
123 const qreal ssar = m_imageSize.width() / (qreal)m_imageSize.height();
124 if (ar > ssar) {
125 setSourceSize(QSize(m_width, 0));
126 } else {
127 setSourceSize(QSize(0, m_height));
128 }
129 } else {
130 qWarning() << "Invalid size for " << m_source << m_imageSize;
131 setSourceSize(QSize(0, 0));
132 }
133 } else {
134 setSourceSize(QSize(-1, -1));
135 }
136}
0137
=== added file 'plugins/Dash/croppedimagesizer.h'
--- plugins/Dash/croppedimagesizer.h 1970-01-01 00:00:00 +0000
+++ plugins/Dash/croppedimagesizer.h 2015-01-13 15:16:16 +0000
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef CROPPEDIMAGESIZER_H
18#define CROPPEDIMAGESIZER_H
19
20#include <QImageReader>
21#include <QObject>
22#include <QSize>
23#include <QUrl>
24
25class CroppedImageSizerAsyncWorker;
26
27class CroppedImageSizer : public QObject
28{
29 Q_OBJECT
30
31 Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
32 Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY inputParamsChanged)
33 Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY inputParamsChanged)
34 Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
35
36public:
37 CroppedImageSizer();
38 ~CroppedImageSizer();
39
40 QUrl source() const;
41 void setSource(const QUrl &source);
42
43 qreal width() const;
44 void setWidth(qreal width);
45
46 qreal height() const;
47 void setHeight(qreal height);
48
49 QSize sourceSize() const;
50 void setSourceSize(const QSize &sourceSize);
51
52 Q_INVOKABLE void setImageSize(const QSize &imageSize);
53
54Q_SIGNALS:
55 void inputParamsChanged();
56 void sourceChanged();
57 void sourceSizeChanged();
58
59private Q_SLOT:
60 void calculateSourceSize();
61 void requestImage();
62
63private:
64 QUrl m_source;
65 qreal m_width;
66 qreal m_height;
67 QSize m_sourceSize;
68 QSize m_imageSize;
69 QPointer<CroppedImageSizerAsyncWorker> m_worker;
70};
71
72#endif
073
=== added file 'plugins/Dash/croppedimagesizerasyncworker.cpp'
--- plugins/Dash/croppedimagesizerasyncworker.cpp 1970-01-01 00:00:00 +0000
+++ plugins/Dash/croppedimagesizerasyncworker.cpp 2015-01-13 15:16:16 +0000
@@ -0,0 +1,74 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "croppedimagesizerasyncworker.h"
18
19#include "croppedimagesizer.h"
20
21#include <QNetworkReply>
22#include <QtConcurrentRun>
23
24CroppedImageSizerAsyncWorker::CroppedImageSizerAsyncWorker(CroppedImageSizer *sizer, QNetworkReply *reply)
25 : m_sizer(sizer),
26 m_reply(reply),
27 m_ignoreAbort(false)
28{
29 connect(m_reply, &QNetworkReply::finished, this, &CroppedImageSizerAsyncWorker::requestFinished);
30}
31
32void CroppedImageSizerAsyncWorker::abort()
33{
34 // This runs on main thread
35 QMutexLocker locker(&m_mutex);
36 m_sizer = nullptr;
37 // If we already started the future run we can't abort the reply
38 // since we don't know at which stage the future is, just let it finish
39 if (!m_ignoreAbort) {
40 QMetaObject::invokeMethod(m_reply, "abort", Qt::QueuedConnection);
41 }
42}
43
44void CroppedImageSizerAsyncWorker::requestFinished()
45{
46 // This runs on main thread
47 QMutexLocker locker(&m_mutex);
48 if (m_sizer) {
49 m_ignoreAbort = true;
50 QtConcurrent::run(processRequestFinished, this);
51 } else {
52 // We were aborted delete ourselves
53 m_reply->deleteLater();
54 deleteLater();
55 }
56}
57
58void CroppedImageSizerAsyncWorker::processRequestFinished(CroppedImageSizerAsyncWorker *worker)
59{
60 // This runs on non main thread
61 // m_reply has finished at this point and is protected against change by m_ignoreAbort
62 QImageReader reader(worker->m_reply);
63 const QSize imageSize = reader.size();
64
65 worker->m_mutex.lock();
66 if (worker->m_sizer) {
67 QMetaObject::invokeMethod(worker->m_sizer, "setImageSize", Qt::QueuedConnection, Q_ARG(QSize, imageSize));
68 }
69 worker->m_mutex.unlock();
70
71 // All work is done, delete ourselves
72 worker->m_reply->deleteLater();
73 worker->deleteLater();
74}
075
=== added file 'plugins/Dash/croppedimagesizerasyncworker.h'
--- plugins/Dash/croppedimagesizerasyncworker.h 1970-01-01 00:00:00 +0000
+++ plugins/Dash/croppedimagesizerasyncworker.h 2015-01-13 15:16:16 +0000
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef CROPPEDIMAGESIZERASYNCWORKER_H
18#define CROPPEDIMAGESIZERASYNCWORKER_H
19
20#include <QMutex>
21#include <QObject>
22
23class CroppedImageSizer;
24
25class QNetworkReply;
26
27class CroppedImageSizerAsyncWorker : public QObject
28{
29 Q_OBJECT
30public:
31 CroppedImageSizerAsyncWorker(CroppedImageSizer *sizer, QNetworkReply *reply);
32
33 void abort();
34
35private Q_SLOTS:
36 void requestFinished();
37
38private:
39 static void processRequestFinished(CroppedImageSizerAsyncWorker *worker);
40
41 QMutex m_mutex;
42 CroppedImageSizer *m_sizer;
43 QNetworkReply *m_reply;
44 bool m_ignoreAbort;
45};
46
47#endif
048
=== modified file 'plugins/Dash/listviewwithpageheader.cpp'
--- plugins/Dash/listviewwithpageheader.cpp 2014-10-13 15:42:02 +0000
+++ plugins/Dash/listviewwithpageheader.cpp 2015-01-13 15:16:16 +0000
@@ -334,13 +334,18 @@
334 return m_headerItemShownHeight;334 return m_headerItemShownHeight;
335}335}
336336
337qreal ListViewWithPageHeader::cacheBuffer() const337int ListViewWithPageHeader::cacheBuffer() const
338{338{
339 return m_cacheBuffer;339 return m_cacheBuffer;
340}340}
341341
342void ListViewWithPageHeader::setCacheBuffer(qreal cacheBuffer)342void ListViewWithPageHeader::setCacheBuffer(int cacheBuffer)
343{343{
344 if (cacheBuffer < 0) {
345 qmlInfo(this) << "Cannot set a negative cache buffer";
346 return;
347 }
348
344 if (cacheBuffer != m_cacheBuffer) {349 if (cacheBuffer != m_cacheBuffer) {
345 m_cacheBuffer = cacheBuffer;350 m_cacheBuffer = cacheBuffer;
346 Q_EMIT cacheBufferChanged();351 Q_EMIT cacheBufferChanged();
347352
=== modified file 'plugins/Dash/listviewwithpageheader.h'
--- plugins/Dash/listviewwithpageheader.h 2014-10-10 11:13:26 +0000
+++ plugins/Dash/listviewwithpageheader.h 2015-01-13 15:16:16 +0000
@@ -54,7 +54,7 @@
54 Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)54 Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
55 Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged)55 Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged)
56 Q_PROPERTY(qreal headerItemShownHeight READ headerItemShownHeight NOTIFY headerItemShownHeightChanged)56 Q_PROPERTY(qreal headerItemShownHeight READ headerItemShownHeight NOTIFY headerItemShownHeightChanged)
57 Q_PROPERTY(qreal cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)57 Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
5858
59 friend class ListViewWithPageHeaderTest;59 friend class ListViewWithPageHeaderTest;
60 friend class ListViewWithPageHeaderTestSection;60 friend class ListViewWithPageHeaderTestSection;
@@ -85,8 +85,8 @@
85 int stickyHeaderHeight() const;85 int stickyHeaderHeight() const;
86 qreal headerItemShownHeight() const;86 qreal headerItemShownHeight() const;
8787
88 qreal cacheBuffer() const;88 int cacheBuffer() const;
89 void setCacheBuffer(qreal cacheBuffer);89 void setCacheBuffer(int cacheBuffer);
9090
91 Q_INVOKABLE void positionAtBeginning();91 Q_INVOKABLE void positionAtBeginning();
92 Q_INVOKABLE void showHeader();92 Q_INVOKABLE void showHeader();
@@ -204,7 +204,7 @@
204 bool m_forceNoClip;204 bool m_forceNoClip;
205 bool m_inLayout;205 bool m_inLayout;
206 bool m_inContentHeightKeepHeaderShown;206 bool m_inContentHeightKeepHeaderShown;
207 qreal m_cacheBuffer;207 int m_cacheBuffer;
208208
209 // Qt 5.0 doesn't like releasing the items just after itemCreated209 // Qt 5.0 doesn't like releasing the items just after itemCreated
210 // so we delay the releasing until the next updatePolish210 // so we delay the releasing until the next updatePolish
211211
=== modified file 'plugins/Dash/plugin.cpp'
--- plugins/Dash/plugin.cpp 2014-04-30 10:06:33 +0000
+++ plugins/Dash/plugin.cpp 2015-01-13 15:16:16 +0000
@@ -17,6 +17,7 @@
1717
18#include "plugin.h"18#include "plugin.h"
1919
20#include "croppedimagesizer.h"
20#include "horizontaljournal.h"21#include "horizontaljournal.h"
21#include "listviewwithpageheader.h"22#include "listviewwithpageheader.h"
22#include "organicgrid.h"23#include "organicgrid.h"
@@ -32,4 +33,5 @@
32 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");33 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
33 qmlRegisterType<OrganicGrid>(uri, 0, 1, "OrganicGrid");34 qmlRegisterType<OrganicGrid>(uri, 0, 1, "OrganicGrid");
34 qmlRegisterType<VerticalJournal>(uri, 0, 1, "VerticalJournal");35 qmlRegisterType<VerticalJournal>(uri, 0, 1, "VerticalJournal");
36 qmlRegisterType<CroppedImageSizer>(uri, 0, 1, "CroppedImageSizer");
35}37}
3638
=== modified file 'qml/Components/ResponsiveVerticalJournal.qml'
--- qml/Components/ResponsiveVerticalJournal.qml 2014-10-02 11:08:26 +0000
+++ qml/Components/ResponsiveVerticalJournal.qml 2015-01-13 15:16:16 +0000
@@ -45,6 +45,7 @@
45 property alias rowSpacing: verticalJournalView.rowSpacing45 property alias rowSpacing: verticalJournalView.rowSpacing
46 property alias model: verticalJournalView.model46 property alias model: verticalJournalView.model
47 property alias delegate: verticalJournalView.delegate47 property alias delegate: verticalJournalView.delegate
48 property alias cacheBuffer: verticalJournalView.cacheBuffer
48 property alias displayMarginBeginning: verticalJournalView.displayMarginBeginning49 property alias displayMarginBeginning: verticalJournalView.displayMarginBeginning
49 property alias displayMarginEnd: verticalJournalView.displayMarginEnd50 property alias displayMarginEnd: verticalJournalView.displayMarginEnd
5051
5152
=== modified file 'qml/Dash/CardCarousel.qml'
--- qml/Dash/CardCarousel.qml 2014-09-12 09:31:56 +0000
+++ qml/Dash/CardCarousel.qml 2015-01-13 15:16:16 +0000
@@ -52,6 +52,7 @@
52 function pressAndHold() { cardCarousel.pressAndHold(index, model.result, model) }52 function pressAndHold() { cardCarousel.pressAndHold(index, model.result, model) }
5353
54 sourceComponent: cardTool.cardComponent54 sourceComponent: cardTool.cardComponent
55 asynchronous: true
55 onLoaded: {56 onLoaded: {
56 item.fixedHeaderHeight = Qt.binding(function() { return carousel.headerHeight; });57 item.fixedHeaderHeight = Qt.binding(function() { return carousel.headerHeight; });
57 item.height = Qt.binding(function() { return cardTool.cardHeight; });58 item.height = Qt.binding(function() { return cardTool.cardHeight; });
5859
=== modified file 'qml/Dash/CardGrid.qml'
--- qml/Dash/CardGrid.qml 2014-09-30 09:23:23 +0000
+++ qml/Dash/CardGrid.qml 2015-01-13 15:16:16 +0000
@@ -50,12 +50,11 @@
50 model: root.model50 model: root.model
51 displayMarginBeginning: root.displayMarginBeginning51 displayMarginBeginning: root.displayMarginBeginning
52 displayMarginEnd: root.displayMarginEnd52 displayMarginEnd: root.displayMarginEnd
53 cacheBuffer: 053 cacheBuffer: root.cacheBuffer
54 interactive: false54 interactive: false
55 delegate: Item {55 delegate: Item {
56 width: grid.cellWidth56 width: grid.cellWidth
57 height: grid.cellHeight57 height: grid.cellHeight
58 visible: y + height >= root.visibleRangeBegin && y <= root.visibleRangeEnd
59 Loader {58 Loader {
60 id: loader59 id: loader
61 sourceComponent: cardTool.cardComponent60 sourceComponent: cardTool.cardComponent
6261
=== modified file 'qml/Dash/CardHorizontalList.qml'
--- qml/Dash/CardHorizontalList.qml 2014-10-23 11:59:22 +0000
+++ qml/Dash/CardHorizontalList.qml 2015-01-13 15:16:16 +0000
@@ -42,6 +42,7 @@
42 sourceComponent: cardTool.cardComponent42 sourceComponent: cardTool.cardComponent
43 anchors { top: parent.top; bottom: parent.bottom }43 anchors { top: parent.top; bottom: parent.bottom }
44 width: cardTool.cardWidth44 width: cardTool.cardWidth
45 asynchronous: true
45 onLoaded: {46 onLoaded: {
46 item.objectName = "delegate" + index;47 item.objectName = "delegate" + index;
47 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });48 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
4849
=== modified file 'qml/Dash/CardVerticalJournal.qml'
--- qml/Dash/CardVerticalJournal.qml 2014-10-15 15:03:51 +0000
+++ qml/Dash/CardVerticalJournal.qml 2015-01-13 15:16:16 +0000
@@ -59,6 +59,7 @@
59 rowSpacing: minimumColumnSpacing59 rowSpacing: minimumColumnSpacing
60 columnWidth: cardTool.cardWidth60 columnWidth: cardTool.cardWidth
6161
62 cacheBuffer: root.cacheBuffer
62 displayMarginBeginning: root.displayMarginBeginning63 displayMarginBeginning: root.displayMarginBeginning
63 displayMarginEnd: root.displayMarginEnd64 displayMarginEnd: root.displayMarginEnd
6465
@@ -66,7 +67,6 @@
66 id: loader67 id: loader
67 sourceComponent: cardTool.cardComponent68 sourceComponent: cardTool.cardComponent
68 width: cardTool.cardWidth69 width: cardTool.cardWidth
69 visible: y + height >= root.visibleRangeBegin && y <= root.visibleRangeEnd
70 onLoaded: {70 onLoaded: {
71 item.objectName = "delegate" + index;71 item.objectName = "delegate" + index;
72 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });72 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
7373
=== modified file 'qml/Dash/DashContent.qml'
--- qml/Dash/DashContent.qml 2014-12-12 11:25:10 +0000
+++ qml/Dash/DashContent.qml 2015-01-13 15:16:16 +0000
@@ -163,6 +163,7 @@
163163
164 delegate:164 delegate:
165 Loader {165 Loader {
166 id: loader
166 width: ListView.view.width167 width: ListView.view.width
167 height: ListView.view.height168 height: ListView.view.height
168 opacity: { // hide delegate if offscreen169 opacity: { // hide delegate if offscreen
@@ -191,6 +192,7 @@
191 dashContent.scopeLoaded(item.scope.id)192 dashContent.scopeLoaded(item.scope.id)
192 item.paginationCount = Qt.binding(function() { return dashContentList.count } )193 item.paginationCount = Qt.binding(function() { return dashContentList.count } )
193 item.paginationIndex = Qt.binding(function() { return dashContentList.currentIndex } )194 item.paginationIndex = Qt.binding(function() { return dashContentList.currentIndex } )
195 item.visibleToParent = Qt.binding(function() { return loader.opacity != 0 });
194 item.holdingList = dashContentList;196 item.holdingList = dashContentList;
195 item.forceNonInteractive = Qt.binding(function() { return dashContent.forceNonInteractive } )197 item.forceNonInteractive = Qt.binding(function() { return dashContent.forceNonInteractive } )
196 }198 }
197199
=== modified file 'qml/Dash/DashRenderer.qml'
--- qml/Dash/DashRenderer.qml 2014-10-02 09:53:26 +0000
+++ qml/Dash/DashRenderer.qml 2015-01-13 15:16:16 +0000
@@ -23,14 +23,12 @@
2323
24 property int collapsedItemCount: -124 property int collapsedItemCount: -1
2525
26 property int cacheBuffer: 0
27
26 property int displayMarginBeginning: 028 property int displayMarginBeginning: 0
2729
28 property int displayMarginEnd: 030 property int displayMarginEnd: 0
2931
30 property int visibleRangeBegin: 0
31
32 property int visibleRangeEnd: 0
33
34 property real originY: 032 property real originY: 0
3533
36 // The model to renderer34 // The model to renderer
3735
=== modified file 'qml/Dash/GenericScopeView.qml'
--- qml/Dash/GenericScopeView.qml 2014-12-15 23:02:35 +0000
+++ qml/Dash/GenericScopeView.qml 2015-01-13 15:16:16 +0000
@@ -38,8 +38,10 @@
38 readonly property alias subPageShown: subPageLoader.subPageShown38 readonly property alias subPageShown: subPageLoader.subPageShown
39 property int paginationCount: 039 property int paginationCount: 0
40 property int paginationIndex: 040 property int paginationIndex: 0
41 property bool visibleToParent: false
41 property alias pageHeaderTotallyVisible: categoryView.pageHeaderTotallyVisible42 property alias pageHeaderTotallyVisible: categoryView.pageHeaderTotallyVisible
42 property var holdingList: null43 property var holdingList: null
44 property bool wasCurrentOnMoveStart: false
4345
44 property var scopeStyle: ScopeStyle {46 property var scopeStyle: ScopeStyle {
45 style: scope ? scope.customizations : {}47 style: scope ? scope.customizations : {}
@@ -115,6 +117,9 @@
115 }117 }
116118
117 onIsCurrentChanged: {119 onIsCurrentChanged: {
120 if (!holdingList || !holdingList.moving) {
121 wasCurrentOnMoveStart = scopeView.isCurrent;
122 }
118 if (pageHeaderLoader.item && showPageHeader) {123 if (pageHeaderLoader.item && showPageHeader) {
119 pageHeaderLoader.item.resetSearch();124 pageHeaderLoader.item.resetSearch();
120 }125 }
@@ -141,6 +146,15 @@
141 onHideDash: subPageLoader.closeSubPage()146 onHideDash: subPageLoader.closeSubPage()
142 }147 }
143148
149 Connections {
150 target: holdingList
151 onMovingChanged: {
152 if (!moving) {
153 wasCurrentOnMoveStart = scopeView.isCurrent;
154 }
155 }
156 }
157
144 Rectangle {158 Rectangle {
145 anchors.fill: parent159 anchors.fill: parent
146 color: scopeView.scopeStyle ? scopeView.scopeStyle.background : "transparent"160 color: scopeView.scopeStyle ? scopeView.scopeStyle.background : "transparent"
@@ -357,6 +371,7 @@
357 Connections {371 Connections {
358 target: scopeView372 target: scopeView
359 onIsCurrentChanged: rendererLoader.updateRanges();373 onIsCurrentChanged: rendererLoader.updateRanges();
374 onVisibleToParentChanged: rendererLoader.updateRanges();
360 }375 }
361 Connections {376 Connections {
362 target: holdingList377 target: holdingList
@@ -364,7 +379,13 @@
364 }379 }
365380
366 function updateRanges() {381 function updateRanges() {
367 if (holdingList && holdingList.moving) {382 // Don't want to create stress by requesting more items during scope
383 // changes so unless you're not part of the visible scopes just return.
384 // For the visible scopes we need to do some work, the previously non visible
385 // scope needs to adjust its ranges so that we define the new visible range,
386 // that still means no creation/destruction of delegates, it's just about changing
387 // the culling of the items so they are actually visible
388 if (holdingList && holdingList.moving && !scopeView.visibleToParent) {
368 return;389 return;
369 }390 }
370391
@@ -379,31 +400,61 @@
379 }400 }
380 }401 }
381402
382 if (item && item.hasOwnProperty("visibleRangeBegin")) {
383 item.visibleRangeBegin = Math.max(-baseItem.y, 0)
384 item.visibleRangeEnd = item.visibleRangeBegin + Math.min(categoryView.height, rendererLoader.height)
385 }
386
387 if (item && item.hasOwnProperty("displayMarginBeginning")) {403 if (item && item.hasOwnProperty("displayMarginBeginning")) {
388 // TODO do we need item.originY here, test 1300302 once we have a silo404 // A item view creates its delegates synchronously from
389 // and we can run it on the phone405 // -displayMarginBeginning
390 if (scopeView.isCurrent) {406 // to
391 // 1073741823 is s^30 -1. A quite big number so that you have "infinite" display margin, but not so407 // height + displayMarginEnd
392 // big so that if you add if with itself you're outside the 2^31 int range408 // Around that area it adds the cacheBuffer area where delegates are created async
393 item.displayMarginBeginning = 1073741823;409 //
394 item.displayMarginEnd = 1073741823;410 // We adjust displayMarginBeginning and displayMarginEnd so
395 } else if (baseItem.y + baseItem.height <= 0) {411 // * In non visible scopes nothing is considered visible and we set cacheBuffer
396 // Not visible (item at top of the list viewport)412 // so that creates the items that would be in the viewport asynchronously
397 item.displayMarginBeginning = -baseItem.height;413 // * For the current scope set the visible range to the viewport and then
398 item.displayMarginEnd = 0;414 // use cacheBuffer to create extra items for categoryView.height * 1.5
399 } else if (baseItem.y >= categoryView.height) {415 // to make scrolling nicer by mantaining a higher number of
400 // Not visible (item at bottom of the list viewport)416 // cached items
401 item.displayMarginBeginning = 0;417 // * For non current but visible scopes (i.e. when the user changes from one scope
402 item.displayMarginEnd = -baseItem.height;418 // to the next, we set the visible range to the viewport so
419 // items are not culled (invisible) but still use no cacheBuffer
420 // (it will be set once the scope is the current one)
421 var displayMarginBeginning = baseItem.y;
422 displayMarginBeginning = -Math.max(-displayMarginBeginning, 0);
423 displayMarginBeginning = -Math.min(-displayMarginBeginning, baseItem.height);
424 displayMarginBeginning = Math.round(displayMarginBeginning);
425 var displayMarginEnd = -baseItem.height + seeAll.height + categoryView.height - baseItem.y;
426 displayMarginEnd = -Math.max(-displayMarginEnd, 0);
427 displayMarginEnd = -Math.min(-displayMarginEnd, baseItem.height);
428 displayMarginEnd = Math.round(displayMarginEnd);
429 if (scopeView.isCurrent || scopeView.visibleToParent) {
430 item.displayMarginBeginning = displayMarginBeginning;
431 item.displayMarginEnd = displayMarginEnd;
432 if (holdingList && holdingList.moving) {
433 // If we are moving we need to reset the cache buffer of the
434 // view that was not visible (i.e. !wasCurrentOnMoveStart) to 0 since
435 // otherwise the cache buffer we had set to preload the items of the
436 // visible range will trigger some item creations and we want move to
437 // be as smooth as possible meaning no need creations
438 if (!wasCurrentOnMoveStart) {
439 item.cacheBuffer = 0;
440 }
441 } else {
442 item.cacheBuffer = categoryView.height * 1.5;
443 }
403 } else {444 } else {
404 item.displayMarginBeginning = Math.round(-Math.max(-baseItem.y, 0));445 var visibleRange = baseItem.height + displayMarginEnd + displayMarginBeginning;
405 item.displayMarginEnd = -Math.round(Math.max(baseItem.height - seeAll.height -446 if (visibleRange < 0) {
406 categoryView.height + baseItem.y, 0));447 item.displayMarginBeginning = displayMarginBeginning;
448 item.displayMarginEnd = displayMarginEnd;
449 item.cacheBuffer = 0;
450 } else {
451 // This should be visibleRange/2 in each of the properties
452 // but some item views still (like GridView) like creating sync delegates even if
453 // the visible range is 0 so let's make sure the visible range is negative
454 item.displayMarginBeginning = displayMarginBeginning - visibleRange;
455 item.displayMarginEnd = displayMarginEnd - visibleRange;
456 item.cacheBuffer = visibleRange;
457 }
407 }458 }
408 }459 }
409 }460 }
410461
=== modified file 'qml/Dash/Previews/PreviewZoomableImage.qml'
--- qml/Dash/Previews/PreviewZoomableImage.qml 2014-10-22 17:35:15 +0000
+++ qml/Dash/Previews/PreviewZoomableImage.qml 2015-01-13 15:16:16 +0000
@@ -40,6 +40,7 @@
40 }40 }
41 scaleTo: "height"41 scaleTo: "height"
42 source: widgetData["source"]42 source: widgetData["source"]
43 asynchronous: true
4344
44 borderSource: mouseArea.pressed ? "radius_pressed.sci" : "radius_idle.sci"45 borderSource: mouseArea.pressed ? "radius_pressed.sci" : "radius_idle.sci"
4546
4647
=== modified file 'qml/Dash/ScopeListView.qml'
--- qml/Dash/ScopeListView.qml 2014-10-23 11:59:22 +0000
+++ qml/Dash/ScopeListView.qml 2015-01-13 15:16:16 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2013 Canonical, Ltd.2 * Copyright (C) 2014 Canonical, Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by5 * it under the terms of the GNU General Public License as published by
@@ -20,5 +20,7 @@
20ListViewWithPageHeader {20ListViewWithPageHeader {
21 maximumFlickVelocity: height * 1021 maximumFlickVelocity: height * 10
22 flickDeceleration: height * 222 flickDeceleration: height * 2
23 cacheBuffer: Number.MAX_VALUE23 // 1073741823 is s^30 -1. A quite big number so that you have "infinite" cache, but not so
24 // big so that if you add if with itself you're outside the 2^31 int range
25 cacheBuffer: 1073741823
24}26}
2527
=== modified file 'qml/Greeter/Infographics.qml'
--- qml/Greeter/Infographics.qml 2014-11-05 00:19:41 +0000
+++ qml/Greeter/Infographics.qml 2015-01-13 15:16:16 +0000
@@ -127,7 +127,7 @@
127127
128 index: model.index128 index: model.index
129 count: pastCircles.count129 count: pastCircles.count
130 radius: parent.width / 2130 radius: dataCircle.width / 2
131 halfSize: pastCircle.width / 2131 halfSize: pastCircle.width / 2
132 posOffset: 0.0132 posOffset: 0.0
133133
@@ -187,7 +187,7 @@
187187
188 index: model.index188 index: model.index
189 count: presentCircles.count189 count: presentCircles.count
190 radius: parent.width / 2190 radius: dataCircle.width / 2
191 halfSize: presentCircle.width / 2191 halfSize: presentCircle.width / 2
192 posOffset: 0.0192 posOffset: 0.0
193193
@@ -255,14 +255,16 @@
255 interval: animDuration * 0.5; running: false; repeat: true255 interval: animDuration * 0.5; running: false; repeat: true
256 onTriggered: {256 onTriggered: {
257 if (dotCounter < dots.count) {257 if (dotCounter < dots.count) {
258 var nextDot = dots.itemAt(dotCounter++)258 var nextDot = dots.itemAt(dotCounter);
259 nextDot.unlockAnimation.start()259 if (nextDot) {
260 nextDot.unlockAnimation.start();
261 if (++dotCounter == Math.round(dots.count / 2)) {
262 circleChangeAnimTimer.startFromBeginning();
263 }
264 }
260 } else {265 } else {
261 stop()266 stop()
262 }267 }
263 if (dotCounter == Math.round(dots.count / 2)) {
264 circleChangeAnimTimer.startFromBeginning()
265 }
266 }268 }
267269
268 function startFromBeginning() {270 function startFromBeginning() {
269271
=== modified file 'qml/Shell.qml'
--- qml/Shell.qml 2014-12-05 16:27:27 +0000
+++ qml/Shell.qml 2015-01-13 15:16:16 +0000
@@ -353,7 +353,7 @@
353353
354 function maybeShow() {354 function maybeShow() {
355 if (!shell.forcedUnlock) {355 if (!shell.forcedUnlock) {
356 show()356 showNow();
357 }357 }
358 }358 }
359359
@@ -557,6 +557,15 @@
557 enabled = true;557 enabled = true;
558 }558 }
559559
560 Timer {
561 // See powerConnection for why this is useful
562 id: showGreeterDelayed
563 interval: 1
564 onTriggered: {
565 greeter.showNow();
566 }
567 }
568
560 onShownChanged: {569 onShownChanged: {
561 if (shown) {570 if (shown) {
562 // Disable everything so that user can't swipe greeter or571 // Disable everything so that user can't swipe greeter or
@@ -622,7 +631,16 @@
622 onStatusChanged: {631 onStatusChanged: {
623 if (Powerd.status === Powerd.Off && reason !== Powerd.Proximity &&632 if (Powerd.status === Powerd.Off && reason !== Powerd.Proximity &&
624 !callManager.hasCalls && !edgeDemo.running) {633 !callManager.hasCalls && !edgeDemo.running) {
625 greeter.showNow()634 // We don't want to simply call greeter.showNow() here, because
635 // that will take too long. Qt will delay button event
636 // handling until the greeter is done loading and may think the
637 // user held down the power button the whole time, leading to a
638 // power dialog being shown. Instead, delay showing the
639 // greeter until we've finished handling the event. We could
640 // make the greeter load asynchronously instead, but that
641 // introduces a whole host of timing issues, especially with
642 // its animations. So this is simpler.
643 showGreeterDelayed.start();
626 }644 }
627 }645 }
628 }646 }
629647
=== renamed file 'qml/graphics/applicationIcons/dash@18.png' => 'qml/graphics/applicationIcons/dash.png'
=== modified file 'tests/autopilot/unity8/shell/emulators/dash.py'
--- tests/autopilot/unity8/shell/emulators/dash.py 2014-10-30 14:38:28 +0000
+++ tests/autopilot/unity8/shell/emulators/dash.py 2015-01-13 15:16:16 +0000
@@ -204,7 +204,7 @@
204204
205 """205 """
206 category_element = self._get_category_element(category)206 category_element = self._get_category_element(category)
207 icon = category_element.select_single('AbstractButton', title=title)207 icon = category_element.wait_select_single('AbstractButton', title=title)
208 self.pointing_device.click_object(icon)208 self.pointing_device.click_object(icon)
209209
210 def _get_category_element(self, category):210 def _get_category_element(self, category):
211211
=== modified file 'tests/plugins/Dash/CMakeLists.txt'
--- tests/plugins/Dash/CMakeLists.txt 2014-09-01 09:13:08 +0000
+++ tests/plugins/Dash/CMakeLists.txt 2015-01-13 15:16:16 +0000
@@ -80,3 +80,4 @@
80add_qml_test(. ScopeStyle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)80add_qml_test(. ScopeStyle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
81add_qml_test(. ListViewWithPageHeaderQML IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)81add_qml_test(. ListViewWithPageHeaderQML IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
82add_qml_test(. CardAttributes IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)82add_qml_test(. CardAttributes IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
83add_qml_test(. CroppedImageMinimumSourceSize IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
8384
=== modified file 'tests/plugins/Dash/cardcreator/1.res'
--- tests/plugins/Dash/cardcreator/1.res 2014-10-20 20:51:10 +0000
+++ tests/plugins/Dash/cardcreator/1.res 2015-01-13 15:16:16 +0000
@@ -46,16 +46,16 @@
46 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });46 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });
47 } 47 }
48 } 48 }
49 image: CroppedImageMinimumSourceSize {49 CroppedImageMinimumSourceSize {
50 id: artImage;
50 objectName: "artImage"; 51 objectName: "artImage";
51 property bool doLoadSource: !NetworkingStatus.limitedBandwith;52 source: cardData && cardData["art"] || "";
52 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["art"] || ""; }
53 cache: true;
54 asynchronous: root.asynchronous; 53 asynchronous: root.asynchronous;
55 visible: false; 54 visible: false;
56 width: root.width; 55 width: root.width;
57 height: width / artShape.aspect; 56 height: width / artShape.aspect;
58 } 57 }
58 image: artImage.image;
59 } 59 }
60 } 60 }
61 }61 }
6262
=== modified file 'tests/plugins/Dash/cardcreator/2.res'
--- tests/plugins/Dash/cardcreator/2.res 2014-10-20 20:51:10 +0000
+++ tests/plugins/Dash/cardcreator/2.res 2015-01-13 15:16:16 +0000
@@ -68,13 +68,12 @@
68 id: mascotImage; 68 id: mascotImage;
69 objectName: "mascotImage"; 69 objectName: "mascotImage";
70 anchors { verticalCenter: parent.verticalCenter; } 70 anchors { verticalCenter: parent.verticalCenter; }
71 property bool doLoadSource: !NetworkingStatus.limitedBandwith;71 source: cardData && cardData["mascot"] || "";
72 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["mascot"] || ""; }
73 width: units.gu(6); 72 width: units.gu(6);
74 height: units.gu(5.625); 73 height: units.gu(5.625);
75 horizontalAlignment: Image.AlignHCenter; 74 horizontalAlignment: Image.AlignHCenter;
76 verticalAlignment: Image.AlignVCenter; 75 verticalAlignment: Image.AlignVCenter;
77 visible: showHeader && resized;76 visible: showHeader;
78 }77 }
79,Item { 78,Item {
80 id: headerTitleContainer; 79 id: headerTitleContainer;
8180
=== modified file 'tests/plugins/Dash/cardcreator/3.res'
--- tests/plugins/Dash/cardcreator/3.res 2014-10-20 20:51:10 +0000
+++ tests/plugins/Dash/cardcreator/3.res 2015-01-13 15:16:16 +0000
@@ -46,16 +46,16 @@
46 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });46 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });
47 }47 }
48 } 48 }
49 image: CroppedImageMinimumSourceSize {49 CroppedImageMinimumSourceSize {
50 objectName: "artImage"; 50 id: artImage;
51 property bool doLoadSource: !NetworkingStatus.limitedBandwith;51 objectName: "artImage";
52 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["art"] || ""; }52 source: cardData && cardData["art"] || "";
53 cache: true;53 asynchronous: root.asynchronous;
54 asynchronous: root.asynchronous; 54 visible: false;
55 visible: false; 55 width: root.width;
56 width: root.width; 56 height: width / artShape.aspect;
57 height: width / artShape.aspect; 57 }
58 } 58 image: artImage.image;
59 } 59 }
60 } 60 }
61 }61 }
6262
=== modified file 'tests/plugins/Dash/cardcreator/4.res'
--- tests/plugins/Dash/cardcreator/4.res 2014-10-20 20:51:10 +0000
+++ tests/plugins/Dash/cardcreator/4.res 2015-01-13 15:16:16 +0000
@@ -35,11 +35,11 @@
35 id: mascotShapeLoader; 35 id: mascotShapeLoader;
36 objectName: "mascotShapeLoader"; 36 objectName: "mascotShapeLoader";
37 asynchronous: root.asynchronous; 37 asynchronous: root.asynchronous;
38 active: mascotImage.status === Image.Ready; 38 active: mascotImage.image.status === Image.Ready;
39 visible: showHeader && active && status == Loader.Ready; 39 visible: showHeader && active && status == Loader.Ready;
40 width: units.gu(6); 40 width: units.gu(6);
41 height: units.gu(5.625); 41 height: units.gu(5.625);
42 sourceComponent: UbuntuShape { image: mascotImage } 42 sourceComponent: UbuntuShape { image: mascotImage.image }
43 anchors { verticalCenter: parent.verticalCenter; }43 anchors { verticalCenter: parent.verticalCenter; }
44 }44 }
4545
@@ -47,8 +47,7 @@
47 id: mascotImage; 47 id: mascotImage;
48 objectName: "mascotImage"; 48 objectName: "mascotImage";
49 anchors { verticalCenter: parent.verticalCenter; }49 anchors { verticalCenter: parent.verticalCenter; }
50 property bool doLoadSource: !NetworkingStatus.limitedBandwith;50 source: cardData && cardData["mascot"] || "";
51 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["mascot"] || ""; }
52 width: units.gu(6);51 width: units.gu(6);
53 height: units.gu(5.625); 52 height: units.gu(5.625);
54 horizontalAlignment: Image.AlignHCenter; 53 horizontalAlignment: Image.AlignHCenter;
5554
=== modified file 'tests/plugins/Dash/cardcreator/5.res'
--- tests/plugins/Dash/cardcreator/5.res 2014-10-20 20:51:10 +0000
+++ tests/plugins/Dash/cardcreator/5.res 2015-01-13 15:16:16 +0000
@@ -46,16 +46,16 @@
46 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });46 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height });
47 }47 }
48 } 48 }
49 image: CroppedImageMinimumSourceSize {49 CroppedImageMinimumSourceSize {
50 objectName: "artImage"; 50 id: artImage;
51 property bool doLoadSource: !NetworkingStatus.limitedBandwith;51 objectName: "artImage";
52 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["art"] || ""; }52 source: cardData && cardData["art"] || "";
53 cache: true;53 asynchronous: root.asynchronous;
54 asynchronous: root.asynchronous; 54 visible: false;
55 visible: false; 55 width: root.width;
56 width: root.width; 56 height: width / artShape.aspect;
57 height: width / artShape.aspect; 57 }
58 } 58 image: artImage.image;
59 } 59 }
60 }60 }
61 }61 }
6262
=== modified file 'tests/plugins/Dash/cardcreator/7.res'
--- tests/plugins/Dash/cardcreator/7.res 2014-10-20 20:51:10 +0000
+++ tests/plugins/Dash/cardcreator/7.res 2015-01-13 15:16:16 +0000
@@ -68,13 +68,12 @@
68 id: mascotImage; 68 id: mascotImage;
69 objectName: "mascotImage"; 69 objectName: "mascotImage";
70 anchors { verticalCenter: parent.verticalCenter; } 70 anchors { verticalCenter: parent.verticalCenter; }
71 property bool doLoadSource: !NetworkingStatus.limitedBandwith;71 source: cardData && cardData["mascot"] || "";
72 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["mascot"] || ""; }
73 width: units.gu(6);72 width: units.gu(6);
74 height: units.gu(5.625); 73 height: units.gu(5.625);
75 horizontalAlignment: Image.AlignHCenter; 74 horizontalAlignment: Image.AlignHCenter;
76 verticalAlignment: Image.AlignVCenter; 75 verticalAlignment: Image.AlignVCenter;
77 visible: showHeader && resized;76 visible: showHeader;
78 }77 }
7978
80,Item { 79,Item {
8180
=== modified file 'tests/plugins/Dash/horizontaljournaltest.qml'
--- tests/plugins/Dash/horizontaljournaltest.qml 2014-04-30 10:06:33 +0000
+++ tests/plugins/Dash/horizontaljournaltest.qml 2015-01-13 15:16:16 +0000
@@ -25,6 +25,7 @@
25 rowHeight: 15025 rowHeight: 150
26 columnSpacing: 1026 columnSpacing: 10
27 rowSpacing: 1027 rowSpacing: 10
28 cacheBuffer: Math.max(0, (height + displayMarginEnd + displayMarginBeginning) / 2)
2829
29 delegate: Rectangle {30 delegate: Rectangle {
30 property real randomValue: Math.random()31 property real randomValue: Math.random()
3132
=== modified file 'tests/plugins/Dash/listviewwithpageheadertest.cpp'
--- tests/plugins/Dash/listviewwithpageheadertest.cpp 2014-08-26 08:41:02 +0000
+++ tests/plugins/Dash/listviewwithpageheadertest.cpp 2015-01-13 15:16:16 +0000
@@ -1920,7 +1920,7 @@
19201920
1921 void testAllCacheBuffer()1921 void testAllCacheBuffer()
1922 {1922 {
1923 lvwph->setCacheBuffer(std::numeric_limits<qreal>::max());1923 lvwph->setCacheBuffer(std::numeric_limits<int>::max());
1924 QTRY_COMPARE(lvwph->m_visibleItems.count(), 6);1924 QTRY_COMPARE(lvwph->m_visibleItems.count(), 6);
1925 QCOMPARE(lvwph->m_firstVisibleIndex, 0);1925 QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1926 verifyItem(0, 50., 150., false);1926 verifyItem(0, 50., 150., false);
19271927
=== modified file 'tests/plugins/Dash/organicgridtest.qml'
--- tests/plugins/Dash/organicgridtest.qml 2014-04-30 10:06:33 +0000
+++ tests/plugins/Dash/organicgridtest.qml 2015-01-13 15:16:16 +0000
@@ -27,6 +27,7 @@
27 rowSpacing: 1027 rowSpacing: 10
28 smallDelegateSize: Qt.size(90, 90)28 smallDelegateSize: Qt.size(90, 90)
29 bigDelegateSize: Qt.size(180, 180)29 bigDelegateSize: Qt.size(180, 180)
30 cacheBuffer: Math.max(0, (height + displayMarginEnd + displayMarginBeginning) / 2)
3031
31 delegate: Rectangle {32 delegate: Rectangle {
32 property real randomValue: Math.random()33 property real randomValue: Math.random()
3334
=== added file 'tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qml'
--- tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qml 1970-01-01 00:00:00 +0000
+++ tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qml 2015-01-13 15:16:16 +0000
@@ -0,0 +1,56 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.3
18import QtTest 1.0
19import Ubuntu.Components 1.1
20import Dash 0.1
21
22Rectangle {
23 width: 500
24 height: 300
25
26 color: "red"
27
28 CroppedImageMinimumSourceSize {
29 id: cimss
30 x: 100
31 y: 100
32 width: 100
33 height: 100
34 source: Qt.resolvedUrl("../../qmltests/Dash/artwork/music-player-design.png")
35 asynchronous: true
36 }
37
38 TestCase {
39 id: testCase
40 name: "ScopeStyle"
41 when: windowShown
42
43 function test_croppedSource() {
44 tryCompare(cimss.image.sourceSize, "width", 100);
45 tryCompare(cimss.image.sourceSize, "height", 0);
46
47 cimss.width = 40;
48 tryCompare(cimss.image.sourceSize, "width", 0);
49 tryCompare(cimss.image.sourceSize, "height", 100);
50
51 cimss.width = 100;
52 tryCompare(cimss.image.sourceSize, "width", 100);
53 tryCompare(cimss.image.sourceSize, "height", 0);
54 }
55 }
56}
057
=== modified file 'tests/plugins/Dash/verticaljournaltest.qml'
--- tests/plugins/Dash/verticaljournaltest.qml 2014-04-30 10:06:33 +0000
+++ tests/plugins/Dash/verticaljournaltest.qml 2015-01-13 15:16:16 +0000
@@ -26,6 +26,7 @@
26 columnWidth: 15026 columnWidth: 150
27 columnSpacing: 1027 columnSpacing: 10
28 rowSpacing: 1028 rowSpacing: 10
29 cacheBuffer: Math.max(0, (height + displayMarginEnd + displayMarginBeginning) / 2)
2930
30 delegate: Rectangle {31 delegate: Rectangle {
31 property real randomValue: Math.random()32 property real randomValue: Math.random()
3233
=== modified file 'tests/qmltests/Dash/tst_Card.qml'
--- tests/qmltests/Dash/tst_Card.qml 2014-10-14 15:44:00 +0000
+++ tests/qmltests/Dash/tst_Card.qml 2015-01-13 15:16:16 +0000
@@ -17,7 +17,6 @@
17import QtQuick 2.017import QtQuick 2.0
18import QtTest 1.018import QtTest 1.0
19import Ubuntu.Components 0.119import Ubuntu.Components 0.1
20import Ubuntu.Connectivity 1.0
21import Unity.Test 0.1 as UT20import Unity.Test 0.1 as UT
22import "../../../qml/Dash"21import "../../../qml/Dash"
23import "CardHelpers.js" as Helpers22import "CardHelpers.js" as Helpers
@@ -221,7 +220,6 @@
221220
222 function init() {221 function init() {
223 loader.visible = true;222 loader.visible = true;
224 NetworkingStatus.limitedBandwith = false;
225 }223 }
226224
227 function cleanup() {225 function cleanup() {
@@ -585,25 +583,5 @@
585 verify((card.width - titleToCard.x - titleToCard.width) === units.gu(1));583 verify((card.width - titleToCard.x - titleToCard.width) === units.gu(1));
586 }584 }
587 }585 }
588
589 function test_load_images_visibility_network_data() {
590 return [
591 { tag: "Visible, network", visible: true, limitedBandwith: false },
592 { tag: "Visible, no network", visible: true, limitedBandwith: true },
593 { tag: "Not Visible, network", visible: false, limitedBandwith: false },
594 { tag: "Not Visible, no network", visible: false, limitedBandwith: true }
595 ];
596 }
597
598 function test_load_images_visibility_network(data) {
599 loader.visible = data.visible;
600 NetworkingStatus.limitedBandwith = data.limitedBandwith;
601
602 selector.selectedIndex = 0;
603 waitForRendering(selector);
604 waitForRendering(card);
605
606 verify(data.visible || !data.limitedBandwith || artImage.source == "");
607 }
608 }586 }
609}587}
610588
=== modified file 'tests/qmltests/Dash/tst_DashContent.qml'
--- tests/qmltests/Dash/tst_DashContent.qml 2014-12-16 18:29:37 +0000
+++ tests/qmltests/Dash/tst_DashContent.qml 2015-01-13 15:16:16 +0000
@@ -516,5 +516,62 @@
516516
517 compare(categoryListView.pageHeader.item.searchHint, "Search People");517 compare(categoryListView.pageHeader.item.searchHint, "Search People");
518 }518 }
519
520 function compareArrays(a, b) {
521 if (a.length != b.length) return false;
522 for (var i in a) {
523 if (a[i] != b[i]) return false;
524 }
525 return true;
526 }
527
528 function getSettledButtons() {
529 var buttons = findChildsByType(dashContent, "AbstractButton");
530 wait(2500);
531 var aux = findChildsByType(dashContent, "AbstractButton");
532 while (!compareArrays(aux, buttons)) {
533 buttons = aux;
534 wait(2500);
535 aux = findChildsByType(dashContent, "AbstractButton");
536 }
537 return buttons;
538 }
539
540 function test_noDelegateCreationDestructionOnMove() {
541 // Our cards are of type AbstractButton as defined in CardCreator.js
542 // This gives also other things that are not cards but for our purpose it
543 // does not matter
544
545 // Wait for the buttons to settle
546 var buttons = getSettledButtons();
547
548 // Move the scopes so that the item on the right is the current one
549 // without releasing the button
550 mouseFlick(dashContent, dashContent.width - units.gu(1), units.gu(1), units.gu(1), units.gu(1), true, false);
551
552 // Make sure we have changed to a new scope
553 compare(dashContent.currentIndex, 1);
554
555 // Wait for the buttons to settle
556 var buttons2 = getSettledButtons();
557
558 // Verify we have exactly the same buttons as before starting to move
559 verify(compareArrays(buttons2, buttons));
560
561 // Release the mouse
562 mouseRelease(dashContent, units.gu(1), units.gu(1));
563
564 // Wait for the scopes list to stop moving
565 var dashContentList = findChild(dashContent, "dashContentList");
566 tryCompare(dashContentList, "moving", false);
567 compare(dashContent.currentIndex, 1);
568
569 // Wait for the buttons to settle
570 var buttons3 = getSettledButtons();
571
572 // Verify we have a different set of buttons now
573 expectFail("", "There has to be new cards after releasing the list is not moving anymore");
574 verify(compareArrays(buttons3, buttons));
575 }
519 }576 }
520}577}
521578
=== modified file 'tests/qmltests/Dash/tst_GenericScopeView.qml'
--- tests/qmltests/Dash/tst_GenericScopeView.qml 2014-12-15 23:02:35 +0000
+++ tests/qmltests/Dash/tst_GenericScopeView.qml 2015-01-13 15:16:16 +0000
@@ -59,6 +59,7 @@
59 GenericScopeView {59 GenericScopeView {
60 id: genericScopeView60 id: genericScopeView
61 anchors.fill: parent61 anchors.fill: parent
62 visibleToParent: true
6263
63 UT.UnityTestCase {64 UT.UnityTestCase {
64 id: testCase65 id: testCase
@@ -293,6 +294,7 @@
293 },294 },
294 true);295 true);
295 var tile = findChild(findChild(genericScopeView, "dashCategory"+category), "delegate"+delegate);296 var tile = findChild(findChild(genericScopeView, "dashCategory"+category), "delegate"+delegate);
297 waitForRendering(tile);
296 mouseClick(tile, tile.width / 2, tile.height / 2);298 mouseClick(tile, tile.width / 2, tile.height / 2);
297 tryCompare(testCase.subPageLoader, "open", true);299 tryCompare(testCase.subPageLoader, "open", true);
298 tryCompare(testCase.subPageLoader, "x", 0);300 tryCompare(testCase.subPageLoader, "x", 0);
299301
=== modified file 'tests/utils/modules/Unity/Test/UnityTestCase.qml'
--- tests/utils/modules/Unity/Test/UnityTestCase.qml 2014-10-14 08:43:38 +0000
+++ tests/utils/modules/Unity/Test/UnityTestCase.qml 2015-01-13 15:16:16 +0000
@@ -109,6 +109,18 @@
109 return null;109 return null;
110 }110 }
111111
112 function findChildsByType(obj, typeName) {
113 var res = new Array(0);
114 for (var i in obj.children) {
115 var c = obj.children[i];
116 if (UT.Util.isInstanceOf(c, typeName)) {
117 res.push(c)
118 }
119 res = res.concat(findChildsByType(c, typeName));
120 }
121 return res;
122 }
123
112 // Type a full string instead of keyClick letter by letter124 // Type a full string instead of keyClick letter by letter
113 // TODO: this is not ugly, this is uber-ugly and does not support125 // TODO: this is not ugly, this is uber-ugly and does not support
114 // any special character. Remove the keyMap once keyClick(obj, char)126 // any special character. Remove the keyMap once keyClick(obj, char)

Subscribers

People subscribed via source and target branches

to all changes: