Merge lp:~zsombi/ubuntu-ui-toolkit/bottomEdgePreloadsContent into lp:ubuntu-ui-toolkit/staging
- bottomEdgePreloadsContent
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Zsombor Egri |
Approved revision: | 1861 |
Merged at revision: | 1877 |
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/bottomEdgePreloadsContent |
Merge into: | lp:ubuntu-ui-toolkit/staging |
Prerequisite: | lp:~zsombi/ubuntu-ui-toolkit/asyncLoader |
Diff against target: |
1114 lines (+526/-116) 13 files modified
components.api (+3/-0) examples/ubuntu-ui-toolkit-gallery/BottomEdgePage.qml (+37/-3) src/Ubuntu/Components/Themes/Ambiance/1.3/BottomEdgeStyle.qml (+4/-23) src/Ubuntu/Components/plugin/ucbottomedge.cpp (+137/-45) src/Ubuntu/Components/plugin/ucbottomedge.h (+7/-0) src/Ubuntu/Components/plugin/ucbottomedge_p.h (+9/-3) src/Ubuntu/Components/plugin/ucbottomedgeregion.cpp (+146/-31) src/Ubuntu/Components/plugin/ucbottomedgeregion.h (+38/-7) tests/unit_x11/tst_bottomedge/AutoCollapseInPageHeader.qml (+3/-1) tests/unit_x11/tst_bottomedge/AutoCollapseInPageWithPageHeader.qml (+3/-1) tests/unit_x11/tst_bottomedge/PreloadedContent.qml (+60/-0) tests/unit_x11/tst_bottomedge/tst_bottomedge.cpp (+76/-0) tests/unit_x11/tst_bottomedge/tst_bottomedge.pro (+3/-2) |
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/bottomEdgePreloadsContent |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
ubuntu-sdk-build-bot | continuous-integration | Approve | |
Benjamin Zeller | Approve | ||
Review via email: mp+286670@code.launchpad.net |
Commit message
BorromEdge.
Description of the change
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1847
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1847
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
- 1848. By Zsombor Egri
-
adjust AsyncLoader changes
- 1849. By Zsombor Egri
-
API updated
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1847
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1847
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1849
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1849
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1849
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1849
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1849
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1850. By Zsombor Egri
-
remove enum
- 1851. By Zsombor Egri
-
make things nicer and unified
- 1852. By Zsombor Egri
-
use BottomEdge context when creating the content
- 1853. By Zsombor Egri
-
tests added, content handling fixed
- 1854. By Zsombor Egri
-
adjust tests with deprecation warning so those are not shown anymore
- 1855. By Zsombor Egri
-
prereq sync
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1855
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1855
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1855
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1855
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1855
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1856. By Zsombor Egri
-
reshape gallery page
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1856
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1856
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1856
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1856
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1856
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1857. By Zsombor Egri
-
prereq sync
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1857
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1857
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1857
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1857
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1857
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Benjamin Zeller (zeller-benjamin) wrote : | # |
Just 2 inline comments
Zsombor Egri (zsombi) wrote : | # |
See my reply below.
- 1858. By Zsombor Egri
-
prereq sync
- 1859. By Zsombor Egri
-
turn off logs
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1859
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1859
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1859
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1859
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1859
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1860. By Zsombor Egri
-
prereq sync
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1860
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1860
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1860
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1860
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1860
https:/
Executed test runs:
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1861. By Zsombor Egri
-
prereq sync
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1861
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2016-02-24 13:18:49 +0000 |
3 | +++ components.api 2016-03-01 10:46:21 +0000 |
4 | @@ -197,6 +197,7 @@ |
5 | signal collapseCompleted() |
6 | function commit() |
7 | function collapse() |
8 | + property bool preloadContent |
9 | property list<BottomEdgeRegion> regions |
10 | readonly property Status status |
11 | Ubuntu.Components.BottomEdge.DragDirection: Enum |
12 | @@ -223,6 +224,8 @@ |
13 | property url contentUrl |
14 | property bool enabled |
15 | property double from |
16 | + signal contentChanged(url url) |
17 | + signal contentComponentChanged(Component component) |
18 | signal entered() |
19 | signal exited() |
20 | signal dragEnded() |
21 | |
22 | === modified file 'examples/ubuntu-ui-toolkit-gallery/BottomEdgePage.qml' |
23 | --- examples/ubuntu-ui-toolkit-gallery/BottomEdgePage.qml 2016-01-13 16:07:58 +0000 |
24 | +++ examples/ubuntu-ui-toolkit-gallery/BottomEdgePage.qml 2016-03-01 10:46:21 +0000 |
25 | @@ -36,7 +36,7 @@ |
26 | spacing: units.gu(1) |
27 | CheckBox { |
28 | id: contentToLayout |
29 | - text: i18n.tr("push content into the layout") |
30 | + text: i18n.tr("push content into the column") |
31 | enabled: bottomEdge.hint.status >= BottomEdgeHint.Active |
32 | } |
33 | Label { |
34 | @@ -52,20 +52,38 @@ |
35 | className: "BottomEdge" |
36 | |
37 | TemplateRow { |
38 | + title: i18n.tr("Content") |
39 | + Row { |
40 | + spacing: units.gu(1) |
41 | + CheckBox { |
42 | + id: preloadContent |
43 | + text: i18n.tr("preload content") |
44 | + checked: bottomEdge.preloadContent |
45 | + onTriggered: bottomEdge.preloadContent = checked |
46 | + } |
47 | + Label { |
48 | + text: preloadContent.text |
49 | + anchors.verticalCenter: preloadContent.verticalCenter |
50 | + } |
51 | + } |
52 | + } |
53 | + |
54 | + TemplateFlow { |
55 | title: i18n.tr("Top") |
56 | Slider { |
57 | id: bottomEdgeHeight |
58 | + width: Math.min(units.gu(30), parent.width) |
59 | maximumValue: page.height |
60 | value: bottomEdge.height |
61 | onValueChanged: bottomEdge.height = value |
62 | } |
63 | } |
64 | |
65 | - TemplateRow { |
66 | + TemplateFlow { |
67 | title: i18n.tr("Regions") |
68 | Slider { |
69 | id: regionCount |
70 | - width: units.gu(20) |
71 | + width: Math.min(units.gu(20), parent.width) |
72 | maximumValue: 3.0 |
73 | live: true |
74 | } |
75 | @@ -133,12 +151,28 @@ |
76 | enabled: regionConfig.model >= 1 |
77 | to: 0.3 |
78 | property color baseColor: UbuntuColors.silk |
79 | + contentComponent: Rectangle { |
80 | + PageHeader { |
81 | + title: i18n.tr("CustomRegion #1") |
82 | + } |
83 | + width: bottomEdge.width - units.gu(10) |
84 | + height: bottomEdge.height |
85 | + color: UbuntuColors.blue |
86 | + } |
87 | }, |
88 | BottomEdgeRegion { |
89 | objectName: "CustomRegion2" |
90 | enabled: regionConfig.model >= 2 |
91 | from: 0.3 |
92 | to: 0.6 |
93 | + contentComponent: Rectangle { |
94 | + PageHeader { |
95 | + title: i18n.tr("CustomRegion #2") |
96 | + } |
97 | + width: bottomEdge.width - units.gu(30) |
98 | + height: bottomEdge.height |
99 | + color: UbuntuColors.red |
100 | + } |
101 | }, |
102 | BottomEdgeRegion { |
103 | objectName: "CustomRegion3" |
104 | |
105 | === modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/BottomEdgeStyle.qml' |
106 | --- src/Ubuntu/Components/Themes/Ambiance/1.3/BottomEdgeStyle.qml 2015-12-14 09:16:41 +0000 |
107 | +++ src/Ubuntu/Components/Themes/Ambiance/1.3/BottomEdgeStyle.qml 2016-03-01 10:46:21 +0000 |
108 | @@ -22,10 +22,12 @@ |
109 | //setup properties |
110 | property BottomEdge bottomEdge: styledItem |
111 | panel: panelItem |
112 | - contentItem: loader.item |
113 | panelAnimation: panelBehavior |
114 | revealThreshold: bottomEdge.hint.height + units.gu(2) |
115 | |
116 | + //deprecated for now |
117 | + contentItem: bottomEdge.contentItem |
118 | + |
119 | // own styling properties |
120 | property color backgroundColor: !panelItem.collapsing |
121 | ? Qt.rgba(0, 0, 0, Math.min(0.25, (height - revealThreshold - panelItem.y) / (height - revealThreshold))) |
122 | @@ -54,7 +56,7 @@ |
123 | ? -(bottomEdge.height * bottomEdge.dragProgress) |
124 | : 0 |
125 | } |
126 | - height: loader.item ? loader.item.height : 0 |
127 | + height: bottomEdge.contentItem ? bottomEdge.contentItem.height : 0 |
128 | color: panelColor |
129 | opacity: bottomEdge.status >= BottomEdge.Revealed ? 1.0 : 0.0 |
130 | |
131 | @@ -108,26 +110,5 @@ |
132 | GradientStop { position: 1.0; color: Qt.rgba(shadowColor.r, shadowColor.g, shadowColor.b, 0.1) } |
133 | } |
134 | } |
135 | - |
136 | - // content |
137 | - Loader { |
138 | - id: loader |
139 | - anchors.horizontalCenter: parent.horizontalCenter |
140 | - asynchronous: true |
141 | - source: bottomEdge.status > BottomEdge.Hidden ? bottomEdge.contentUrl : "" |
142 | - sourceComponent: bottomEdge.status > BottomEdge.Hidden ? bottomEdge.contentComponent : null |
143 | - onItemChanged: { |
144 | - if (item) { |
145 | - item.parent = panelItem; |
146 | - item.anchors.horizontalCenter = panelItem.horizontalCenter; |
147 | - } |
148 | - } |
149 | - |
150 | - Connections { |
151 | - target: bottomEdge |
152 | - onCommitStarted: loader.asynchronous = false |
153 | - onCommitCompleted: loader.asynchronous = true |
154 | - } |
155 | - } |
156 | } |
157 | } |
158 | |
159 | === modified file 'src/Ubuntu/Components/plugin/ucbottomedge.cpp' |
160 | --- src/Ubuntu/Components/plugin/ucbottomedge.cpp 2016-01-25 12:23:03 +0000 |
161 | +++ src/Ubuntu/Components/plugin/ucbottomedge.cpp 2016-03-01 10:46:21 +0000 |
162 | @@ -37,15 +37,15 @@ |
163 | #include "private/ucswipearea_p.h" |
164 | #include <QtQuick/private/qquickanimation_p.h> |
165 | |
166 | +using namespace UbuntuToolkit; |
167 | + |
168 | Q_LOGGING_CATEGORY(ucBottomEdge, "ubuntu.components.BottomEdge", QtMsgType::QtWarningMsg) |
169 | |
170 | -#define LOG qCDebug(ucBottomEdge) << "[BottomEdge]" |
171 | - |
172 | UCBottomEdgePrivate::UCBottomEdgePrivate() |
173 | : UCStyledItemBasePrivate() |
174 | + , defaultRegion(new UCBottomEdgeRegion(nullptr, true)) |
175 | , activeRegion(Q_NULLPTR) |
176 | , hint(new UCBottomEdgeHint) |
177 | - , contentComponent(Q_NULLPTR) |
178 | , bottomPanel(Q_NULLPTR) |
179 | , previousDistance(0.0) |
180 | , dragProgress(0.) |
181 | @@ -54,6 +54,7 @@ |
182 | , dragDirection(UCBottomEdge::Undefined) |
183 | , defaultRegionsReset(false) |
184 | , mousePressed(false) |
185 | + , preloadContent(false) |
186 | { |
187 | } |
188 | |
189 | @@ -67,8 +68,20 @@ |
190 | hint->setEnabled2(q->isEnabled()); |
191 | }); |
192 | |
193 | - // create default regions |
194 | - createDefaultRegions(); |
195 | + // create default region |
196 | + // for testing purposes |
197 | + defaultRegion->setObjectName("default_BottomEdgeRegion"); |
198 | + // enters in this stage when drag ratio reaches 30% of the area |
199 | + defaultRegion->m_from = 0.33; |
200 | + defaultRegion->m_to = 1.0; |
201 | + defaultRegion->attachToBottomEdge(q); |
202 | + |
203 | + QObject::connect(defaultRegion, &UCBottomEdgeRegion::contentChanged, |
204 | + q, &UCBottomEdge::contentChanged); |
205 | + QObject::connect(defaultRegion, &UCBottomEdgeRegion::contentComponentChanged, |
206 | + q, &UCBottomEdge::contentComponentChanged); |
207 | + |
208 | + regions.append(defaultRegion); |
209 | |
210 | // set the style name |
211 | styleDocument = QStringLiteral("BottomEdgeStyle"); |
212 | @@ -124,13 +137,17 @@ |
213 | |
214 | if (!defaultRegionsReset) { |
215 | defaultRegionsReset = true; |
216 | - qDeleteAll(regions); |
217 | regions.clear(); |
218 | } |
219 | |
220 | // validate the region before we append |
221 | validateRegion(region); |
222 | |
223 | + // if preload is set, load content |
224 | + if (preloadContent) { |
225 | + region->loadRegionContent(); |
226 | + } |
227 | + |
228 | // append region definition |
229 | regions.append(region); |
230 | } |
231 | @@ -146,7 +163,7 @@ |
232 | } |
233 | regions.clear(); |
234 | defaultRegionsReset = false; |
235 | - createDefaultRegions(); |
236 | + regions.append(defaultRegion); |
237 | } |
238 | |
239 | // validates an added region |
240 | @@ -186,21 +203,6 @@ |
241 | } |
242 | } |
243 | |
244 | -// creates the default region(s) |
245 | -void UCBottomEdgePrivate::createDefaultRegions() |
246 | -{ |
247 | - Q_Q(UCBottomEdge); |
248 | - // add the default stages |
249 | - UCBottomEdgeRegion *commitRegion = new UCBottomEdgeRegion(q); |
250 | - // for testing purposes |
251 | - commitRegion->setObjectName("default_BottomEdgeRegion"); |
252 | - // enters in this stage when drag ratio reaches 30% of the area |
253 | - commitRegion->m_from = 0.33; |
254 | - commitRegion->m_to = 1.0; |
255 | - |
256 | - regions.append(commitRegion); |
257 | -} |
258 | - |
259 | // update status, drag direction and activeRegion during drag |
260 | void UCBottomEdgePrivate::updateProgressionStates(qreal distance) |
261 | { |
262 | @@ -352,6 +354,8 @@ |
263 | } |
264 | break; |
265 | case UCBottomEdgePrivate::Collapsing: |
266 | + // no active region when collapsed! |
267 | + d->setActiveRegion(nullptr); |
268 | d->setStatus(UCBottomEdge::Hidden); |
269 | Q_EMIT collapseCompleted(); |
270 | break; |
271 | @@ -392,11 +396,12 @@ |
272 | void UCBottomEdgePrivate::patchContentItemHeader() |
273 | { |
274 | // ugly, as it can be, as we don't have the PageHeader in cpp to detect the type |
275 | - UCHeader *header = bottomPanel->m_contentItem ? bottomPanel->m_contentItem->findChild<UCHeader*>() : Q_NULLPTR; |
276 | + UCHeader *header = currentContentItem ? currentContentItem->findChild<UCHeader*>() : Q_NULLPTR; |
277 | if (!header || !QuickUtils::inherits(header, "PageHeader")) { |
278 | return; |
279 | } |
280 | |
281 | + LOG << "PATCH HEADER" << currentContentItem.data(); |
282 | // get the navigationActions and inject an action there |
283 | QVariant list(header->property("navigationActions")); |
284 | QQmlListProperty<UCAction> actions = list.value< QQmlListProperty<UCAction> >(); |
285 | @@ -453,14 +458,6 @@ |
286 | hint->setParentItem(bottomPanel); |
287 | // and stack it before the panel, so it is covered by the panel when revealed |
288 | hint->stackBefore(bottomPanel->m_panel); |
289 | - |
290 | - // connect style stuff |
291 | - QObject::connect(bottomPanel, &UCBottomEdgeStyle::contentItemChanged, |
292 | - q, &UCBottomEdge::contentItemChanged, Qt::DirectConnection); |
293 | - // follow contentItem change to patch the header |
294 | - QObject::connect(bottomPanel, &UCBottomEdgeStyle::contentItemChanged, [=]() { |
295 | - patchContentItemHeader(); |
296 | - }); |
297 | } |
298 | return result; |
299 | } |
300 | @@ -749,6 +746,10 @@ |
301 | { |
302 | UCStyledItemBasePrivate::completeComponentInitialization(); |
303 | Q_Q(UCBottomEdge); |
304 | + // trigger default region content loading; the default region content is |
305 | + // always pre-loaded |
306 | + defaultRegion->loadRegionContent(); |
307 | + |
308 | // fix the hint's style version as that has no qmlContext of its own |
309 | // and thus import version check will fail; setting the context for |
310 | // the hint using this component's hint won't work either as this |
311 | @@ -931,6 +932,13 @@ |
312 | } |
313 | |
314 | Q_EMIT q_func()->statusChanged(this->status); |
315 | + |
316 | + // show content |
317 | + if (status > UCBottomEdge::Hidden) { |
318 | + setCurrentContent(); |
319 | + } else { |
320 | + resetCurrentContent(nullptr); |
321 | + } |
322 | } |
323 | |
324 | /*! |
325 | @@ -941,17 +949,12 @@ |
326 | QUrl UCBottomEdge::contentUrl() const |
327 | { |
328 | Q_D(const UCBottomEdge); |
329 | - return d->contentUrl; |
330 | + return d->defaultRegion->m_url; |
331 | } |
332 | void UCBottomEdge::setContent(const QUrl &url) |
333 | { |
334 | Q_D(UCBottomEdge); |
335 | - if (d->contentUrl == url) { |
336 | - return; |
337 | - } |
338 | - |
339 | - d->contentUrl = url; |
340 | - Q_EMIT contentChanged(d->contentUrl); |
341 | + d->defaultRegion->setUrl(url); |
342 | } |
343 | |
344 | /*! |
345 | @@ -962,16 +965,12 @@ |
346 | QQmlComponent *UCBottomEdge::contentComponent() const |
347 | { |
348 | Q_D(const UCBottomEdge); |
349 | - return d->contentComponent; |
350 | + return d->defaultRegion->m_component; |
351 | } |
352 | void UCBottomEdge::setContentComponent(QQmlComponent *component) |
353 | { |
354 | Q_D(UCBottomEdge); |
355 | - if (d->contentComponent == component) { |
356 | - return; |
357 | - } |
358 | - d->contentComponent = component; |
359 | - Q_EMIT contentComponentChanged(d->contentComponent); |
360 | + d->defaultRegion->setComponent(component); |
361 | } |
362 | |
363 | /*! |
364 | @@ -983,7 +982,7 @@ |
365 | QQuickItem *UCBottomEdge::contentItem() const |
366 | { |
367 | Q_D(const UCBottomEdge); |
368 | - return d->bottomPanel ? d->bottomPanel->m_contentItem : Q_NULLPTR; |
369 | + return d->currentContentItem.data(); |
370 | } |
371 | |
372 | /*! |
373 | @@ -1082,4 +1081,97 @@ |
374 | return d->activeRegion; |
375 | } |
376 | |
377 | +/*! |
378 | + * \qmlproperty bool BottomEdge::preloadContent |
379 | + * If set, all the contents set in the component and in regions will be loaded |
380 | + * in the background, so it will be available before it is revealed. |
381 | + */ |
382 | +bool UCBottomEdge::preloadContent() const |
383 | +{ |
384 | + return d_func()->preloadContent; |
385 | +} |
386 | +void UCBottomEdge::setPreloadContent(bool value) |
387 | +{ |
388 | + Q_D(UCBottomEdge); |
389 | + if (d->preloadContent == value) { |
390 | + return; |
391 | + } |
392 | + d->preloadContent = value; |
393 | + |
394 | + if (d->preloadContent) { |
395 | + // we load all region's content, but we skip teh default one, |
396 | + // as default one is always preloaded |
397 | + for (int i = 0; i < d->regions.size(); i++) { |
398 | + UCBottomEdgeRegion *region = d->regions[i]; |
399 | + if (region == d->defaultRegion) { |
400 | + continue; |
401 | + } |
402 | + region->loadRegionContent(); |
403 | + } |
404 | + } else { |
405 | + // discard all inactive regions content, except default one |
406 | + for (int i = 0; i < d->regions.size(); i++) { |
407 | + UCBottomEdgeRegion *region = d->regions[i]; |
408 | + if (region != d->activeRegion && region != d->defaultRegion) { |
409 | + region->discardRegionContent(); |
410 | + } |
411 | + } |
412 | + } |
413 | + |
414 | + Q_EMIT preloadContentChanged(); |
415 | +} |
416 | + |
417 | +/* |
418 | + * Set the current content. The content is taken from the region if active, or foced |
419 | + * is set. If the region has no item, the logic falls back to use the default region's |
420 | + * content. |
421 | + */ |
422 | +void UCBottomEdgePrivate::setCurrentContent() |
423 | +{ |
424 | + QQuickItem *newContent = nullptr; |
425 | + if (activeRegion) { |
426 | + newContent = activeRegion->regionContent(); |
427 | + LOG << "ACTIVE REGION CONTENT" << activeRegion->objectName() << newContent; |
428 | + } |
429 | + if (!newContent) { |
430 | + newContent = defaultRegion->regionContent(); |
431 | + LOG << "USING DEFAULT" << newContent; |
432 | + } |
433 | + resetCurrentContent(newContent); |
434 | +} |
435 | +/* |
436 | + * Set the content to the default region one. |
437 | + */ |
438 | +void UCBottomEdgePrivate::resetCurrentContent(QQuickItem *newContent) |
439 | +{ |
440 | + if (newContent == currentContentItem) { |
441 | + // same content, no need to reset to |
442 | + return; |
443 | + } |
444 | + if (currentContentItem) { |
445 | + // detach current content, the content will be deleted by the exiting region |
446 | + currentContentItem->setVisible(false); |
447 | + currentContentItem->setParentItem(nullptr); |
448 | + } |
449 | + |
450 | + if (!newContent) { |
451 | + // try to use the default one |
452 | + newContent = defaultRegion->regionContent(); |
453 | + } |
454 | + |
455 | + // if it is still null, leave - we may not have default content at all! |
456 | + if (!newContent) { |
457 | + return; |
458 | + } |
459 | + |
460 | + LOG << "RESET CONTENT TO" << newContent; |
461 | + currentContentItem = newContent; |
462 | + currentContentItem->setParentItem(bottomPanel->m_panel); |
463 | + QQuickAnchors *anchors = QQuickItemPrivate::get(currentContentItem.data())->anchors(); |
464 | + anchors->setHorizontalCenter(QQuickItemPrivate::get(bottomPanel->m_panel)->horizontalCenter()); |
465 | + currentContentItem->setVisible(true); |
466 | + Q_EMIT q_func()->contentItemChanged(); |
467 | + patchContentItemHeader(); |
468 | +} |
469 | + |
470 | #include "moc_ucbottomedge.cpp" |
471 | |
472 | === modified file 'src/Ubuntu/Components/plugin/ucbottomedge.h' |
473 | --- src/Ubuntu/Components/plugin/ucbottomedge.h 2015-12-11 12:10:54 +0000 |
474 | +++ src/Ubuntu/Components/plugin/ucbottomedge.h 2016-03-01 10:46:21 +0000 |
475 | @@ -42,6 +42,7 @@ |
476 | Q_PROPERTY(QQuickItem* contentItem READ contentItem NOTIFY contentItemChanged FINAL) |
477 | Q_PROPERTY(QQmlListProperty<UCBottomEdgeRegion> regions READ regions NOTIFY regionsChanged FINAL) |
478 | Q_PROPERTY(UCBottomEdgeRegion* activeRegion READ activeRegion NOTIFY activeRegionChanged FINAL) |
479 | + Q_PROPERTY(bool preloadContent READ preloadContent WRITE setPreloadContent NOTIFY preloadContentChanged FINAL DESIGNABLE false) |
480 | |
481 | // overloaded data property to catch regions |
482 | Q_PRIVATE_PROPERTY(UCBottomEdge::d_func(), QQmlListProperty<QObject> data READ data DESIGNABLE false) |
483 | @@ -73,6 +74,8 @@ |
484 | void setFillWindow(bool fill); |
485 | QQmlListProperty<UCBottomEdgeRegion> regions(); |
486 | UCBottomEdgeRegion *activeRegion(); |
487 | + bool preloadContent() const; |
488 | + void setPreloadContent(bool value); |
489 | |
490 | Q_SIGNALS: |
491 | void dragProgressChanged(qreal dragProgress); |
492 | @@ -83,6 +86,7 @@ |
493 | void contentItemChanged(); |
494 | void regionsChanged(); |
495 | void activeRegionChanged(UCBottomEdgeRegion *activeRegion); |
496 | + void preloadContentChanged(); |
497 | |
498 | void commitStarted(); |
499 | void commitCompleted(); |
500 | @@ -109,6 +113,7 @@ |
501 | |
502 | Q_DECLARE_PRIVATE(UCBottomEdge) |
503 | |
504 | +private: |
505 | friend class tst_BottomEdge; |
506 | }; |
507 | Q_DECLARE_METATYPE(UCBottomEdge::Status) |
508 | @@ -116,4 +121,6 @@ |
509 | |
510 | Q_DECLARE_LOGGING_CATEGORY(ucBottomEdge) |
511 | |
512 | +#define LOG qCDebug(ucBottomEdge) << "[BottomEdge]" |
513 | + |
514 | #endif // UCBOTTOMEDGE_H |
515 | |
516 | === modified file 'src/Ubuntu/Components/plugin/ucbottomedge_p.h' |
517 | --- src/Ubuntu/Components/plugin/ucbottomedge_p.h 2015-12-21 17:49:59 +0000 |
518 | +++ src/Ubuntu/Components/plugin/ucbottomedge_p.h 2016-03-01 10:46:21 +0000 |
519 | @@ -23,6 +23,10 @@ |
520 | #include "ucstyleditembase_p.h" |
521 | #include "ucaction.h" |
522 | |
523 | +#include <AsyncLoader> |
524 | + |
525 | +using namespace UbuntuToolkit; |
526 | + |
527 | class UCBottomEdgeStyle; |
528 | class UCBottomEdgePrivate : public UCStyledItemBasePrivate, protected QQuickItemChangeListener |
529 | { |
530 | @@ -51,7 +55,6 @@ |
531 | |
532 | // page header manipulation |
533 | void patchContentItemHeader(); |
534 | - void createDefaultRegions(); |
535 | void updateProgressionStates(qreal distance); |
536 | bool setActiveRegion(UCBottomEdgeRegion *range); |
537 | void detectDirection(qreal currentDistance); |
538 | @@ -70,12 +73,14 @@ |
539 | void itemChildAdded(QQuickItem *item, QQuickItem *child); |
540 | void itemChildRemoved(QQuickItem *item, QQuickItem *child); |
541 | |
542 | + void setCurrentContent(); |
543 | + void resetCurrentContent(QQuickItem *newItem); |
544 | // members |
545 | - QUrl contentUrl; |
546 | QList<UCBottomEdgeRegion*> regions; |
547 | + QPointer<QQuickItem> currentContentItem; |
548 | + UCBottomEdgeRegion *defaultRegion; |
549 | UCBottomEdgeRegion *activeRegion; |
550 | UCBottomEdgeHint *hint; |
551 | - QQmlComponent *contentComponent; |
552 | UCBottomEdgeStyle *bottomPanel; |
553 | |
554 | qreal previousDistance; |
555 | @@ -93,6 +98,7 @@ |
556 | |
557 | bool defaultRegionsReset:1; |
558 | bool mousePressed:1; |
559 | + bool preloadContent:1; |
560 | |
561 | // status management |
562 | void setOperationStatus(OperationStatus s); |
563 | |
564 | === modified file 'src/Ubuntu/Components/plugin/ucbottomedgeregion.cpp' |
565 | --- src/Ubuntu/Components/plugin/ucbottomedgeregion.cpp 2015-11-26 15:49:24 +0000 |
566 | +++ src/Ubuntu/Components/plugin/ucbottomedgeregion.cpp 2016-03-01 10:46:21 +0000 |
567 | @@ -91,16 +91,19 @@ |
568 | * properties will cause unpredictable results. |
569 | */ |
570 | |
571 | -UCBottomEdgeRegion::UCBottomEdgeRegion(QObject *parent) |
572 | +UCBottomEdgeRegion::UCBottomEdgeRegion(QObject *parent, bool isDefault) |
573 | : QObject(parent) |
574 | , m_bottomEdge(qobject_cast<UCBottomEdge*>(parent)) |
575 | , m_component(Q_NULLPTR) |
576 | - , m_urlBackup(Q_NULLPTR) |
577 | - , m_componentBackup(Q_NULLPTR) |
578 | + , m_contentItem(Q_NULLPTR) |
579 | , m_from(0.0) |
580 | , m_to(-1.0) |
581 | , m_enabled(true) |
582 | + , m_active(false) |
583 | + , m_default(isDefault) |
584 | { |
585 | + connect(&m_loader, &UbuntuToolkit::AsyncLoader::loadingStatus, |
586 | + this, &UCBottomEdgeRegion::onLoaderStatusChanged); |
587 | } |
588 | |
589 | void UCBottomEdgeRegion::attachToBottomEdge(UCBottomEdge *bottomEdge) |
590 | @@ -121,41 +124,40 @@ |
591 | |
592 | void UCBottomEdgeRegion::enter() |
593 | { |
594 | + m_active = true; |
595 | Q_EMIT entered(); |
596 | - // backup url |
597 | - if (m_url.isValid()) { |
598 | - m_urlBackup = new PropertyChange(m_bottomEdge, "contentUrl"); |
599 | - QQmlProperty property(this, "contentUrl", qmlContext(this)); |
600 | - QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(property); |
601 | - if (binding) { |
602 | - PropertyChange::setBinding(m_urlBackup, binding); |
603 | - } else { |
604 | - PropertyChange::setValue(m_urlBackup, m_url); |
605 | - } |
606 | - } |
607 | - if (m_component) { |
608 | - m_componentBackup = new PropertyChange(m_bottomEdge, "contentComponent"); |
609 | - QQmlProperty property(this, "contentComponent", qmlContext(this)); |
610 | - QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(property); |
611 | - if (binding) { |
612 | - PropertyChange::setBinding(m_componentBackup, binding); |
613 | - } else { |
614 | - PropertyChange::setValue(m_componentBackup, QVariant::fromValue<QQmlComponent*>(m_component)); |
615 | - } |
616 | + |
617 | + LOG << "ENTER REGION" << objectName(); |
618 | + // if preloaded, or default(?), set the content |
619 | + if (m_bottomEdge->preloadContent() || m_default) { |
620 | + if (m_loader.status() == UbuntuToolkit::AsyncLoader::Ready) { |
621 | + LOG << "SET REGION CONTENT" << objectName(); |
622 | + UCBottomEdgePrivate::get(m_bottomEdge)->setCurrentContent(); |
623 | + } |
624 | + } else { |
625 | + // initiate loading, component has priority |
626 | + loadRegionContent(); |
627 | } |
628 | } |
629 | |
630 | void UCBottomEdgeRegion::exit() |
631 | { |
632 | - if (m_componentBackup) { |
633 | - delete m_componentBackup; |
634 | - m_componentBackup = Q_NULLPTR; |
635 | - } |
636 | - if (m_urlBackup) { |
637 | - delete m_urlBackup; |
638 | - m_urlBackup = Q_NULLPTR; |
639 | - } |
640 | + m_active = false; |
641 | Q_EMIT exited(); |
642 | + |
643 | + // detach content from BottomEdge |
644 | + LOG << "EXIT REGION" << objectName(); |
645 | + UCBottomEdgePrivate::get(m_bottomEdge)->resetCurrentContent(nullptr); |
646 | + |
647 | + // then cleanup |
648 | + if (!m_contentItem) { |
649 | + return; |
650 | + } |
651 | + LOG << "RESET REGION CONTENT" << objectName(); |
652 | + if (!m_bottomEdge->preloadContent()) { |
653 | + LOG << "DISCARD REGION CONTENT" << objectName(); |
654 | + discardRegionContent(); |
655 | + } |
656 | } |
657 | |
658 | const QRectF UCBottomEdgeRegion::rect(const QRectF &bottomEdgeRect) |
659 | @@ -166,6 +168,86 @@ |
660 | return regionRect; |
661 | } |
662 | |
663 | +void UCBottomEdgeRegion::loadRegionContent() |
664 | +{ |
665 | + if (!m_enabled) { |
666 | + return; |
667 | + } |
668 | + LOG << "LOAD REGION CONTENT" << objectName(); |
669 | + if (m_component) { |
670 | + loadContent(LoadingComponent); |
671 | + } else if (m_url.isValid()) { |
672 | + loadContent(LoadingUrl); |
673 | + } |
674 | +} |
675 | + |
676 | +void UCBottomEdgeRegion::loadContent(LoadingType type) |
677 | +{ |
678 | + // we must delete the previous content before we (re)initiate loading |
679 | + if (m_contentItem) { |
680 | + m_contentItem->deleteLater();; |
681 | + m_contentItem = nullptr; |
682 | + } |
683 | + // no need to create new context as we do not set any context properties |
684 | + // for which we would need one |
685 | + switch (type) { |
686 | + case LoadingUrl: |
687 | + m_loader.load(m_url, qmlContext(m_bottomEdge)); |
688 | + return; |
689 | + case LoadingComponent: |
690 | + m_loader.load(m_component, qmlContext(m_bottomEdge)); |
691 | + return; |
692 | + } |
693 | +} |
694 | + |
695 | +void UCBottomEdgeRegion::discardRegionContent() |
696 | +{ |
697 | + m_loader.reset(); |
698 | + if (m_contentItem) { |
699 | + LOG << "DISCARD CONTENT" << objectName(); |
700 | + m_contentItem->deleteLater(); |
701 | + } |
702 | + m_contentItem = nullptr; |
703 | +} |
704 | + |
705 | +QQuickItem *UCBottomEdgeRegion::regionContent() |
706 | +{ |
707 | + return m_contentItem; |
708 | +} |
709 | + |
710 | +void UCBottomEdgeRegion::onLoaderStatusChanged(UbuntuToolkit::AsyncLoader::LoadingStatus status, QObject *object) |
711 | +{ |
712 | + bool emitChange = false; |
713 | + LOG << "STATUS" << status << object; |
714 | + if (status == UbuntuToolkit::AsyncLoader::Ready) { |
715 | + // if we are no longer active, no need to continue, and discard content |
716 | + // this may occur when the component was still in Compiling state while |
717 | + // the region was exited, therefore reset() could not cancel the operation. |
718 | + if (!m_active && !m_default && !m_bottomEdge->preloadContent()) { |
719 | + LOG << "DELETE REGION CONTENT" << objectName(); |
720 | + object->deleteLater(); |
721 | + return; |
722 | + } |
723 | + m_contentItem = qobject_cast<QQuickItem*>(object); |
724 | + emitChange = m_active || m_default; |
725 | + } |
726 | + |
727 | + if (status == UbuntuToolkit::AsyncLoader::Reset) { |
728 | + // de-parent first |
729 | + if (m_contentItem) { |
730 | + m_contentItem->setParentItem(nullptr); |
731 | + LOG << "RESET CONTENT" << objectName(); |
732 | + m_contentItem->deleteLater(); |
733 | + } |
734 | + m_contentItem = nullptr; |
735 | + emitChange = true; |
736 | + } |
737 | + |
738 | + if (emitChange && m_bottomEdge && m_active) { |
739 | + UCBottomEdgePrivate::get(m_bottomEdge)->setCurrentContent(); |
740 | + } |
741 | +} |
742 | + |
743 | /*! |
744 | * \qmlproperty bool BottomEdgeRegion::enabled |
745 | * Enables the section. Disabled sections do not trigger nor change the BottomEdge |
746 | @@ -180,6 +262,15 @@ |
747 | if (m_bottomEdge) { |
748 | UCBottomEdgePrivate::get(m_bottomEdge)->validateRegion(this); |
749 | } |
750 | + |
751 | + // load content if preload is set |
752 | + if (m_bottomEdge->preloadContent()) { |
753 | + if (!m_enabled) { |
754 | + discardRegionContent(); |
755 | + } else { |
756 | + loadRegionContent(); |
757 | + } |
758 | + } |
759 | Q_EMIT enabledChanged(); |
760 | } |
761 | |
762 | @@ -227,6 +318,18 @@ |
763 | * when the drag gesture enters the section area. The orginal value will be restored |
764 | * once the gesture leaves the section area. |
765 | */ |
766 | +void UCBottomEdgeRegion::setUrl(const QUrl &url) |
767 | +{ |
768 | + if (m_url == url) { |
769 | + return; |
770 | + } |
771 | + m_url = url; |
772 | + Q_EMIT contentChanged(m_url); |
773 | + // invoke loader if the preload is set |
774 | + if (m_bottomEdge && (m_bottomEdge->preloadContent() || m_default) && !m_url.isValid()) { |
775 | + loadContent(LoadingUrl); |
776 | + } |
777 | +} |
778 | |
779 | /*! |
780 | * \qmlproperty Component BottomEdgeRegion::contentComponent |
781 | @@ -235,6 +338,18 @@ |
782 | * when the drag gesture enters the section area. The orginal value will be restored |
783 | * once the gesture leaves the section area. |
784 | */ |
785 | +void UCBottomEdgeRegion::setComponent(QQmlComponent *component) |
786 | +{ |
787 | + if (m_component == component) { |
788 | + return; |
789 | + } |
790 | + m_component = component; |
791 | + Q_EMIT contentComponentChanged(m_component); |
792 | + // invoke loader if the preload is set |
793 | + if (m_bottomEdge && (m_bottomEdge->preloadContent() || m_default) && m_component) { |
794 | + loadContent(LoadingComponent); |
795 | + } |
796 | +} |
797 | |
798 | /*! |
799 | * \qmlsignal void BottomEdgeRegion::entered() |
800 | |
801 | === modified file 'src/Ubuntu/Components/plugin/ucbottomedgeregion.h' |
802 | --- src/Ubuntu/Components/plugin/ucbottomedgeregion.h 2015-11-26 15:49:24 +0000 |
803 | +++ src/Ubuntu/Components/plugin/ucbottomedgeregion.h 2016-03-01 10:46:21 +0000 |
804 | @@ -23,6 +23,8 @@ |
805 | #include <QtQml/QQmlParserStatus> |
806 | #include <QtCore/QUrl> |
807 | #include <QtCore/QPointer> |
808 | +#include <QtQml/QQmlIncubator> |
809 | +#include <AsyncLoader> |
810 | |
811 | class UCBottomEdge; |
812 | class QQmlComponent; |
813 | @@ -34,13 +36,15 @@ |
814 | Q_PROPERTY(bool enabled MEMBER m_enabled WRITE setEnabled NOTIFY enabledChanged FINAL) |
815 | Q_PROPERTY(qreal from MEMBER m_from WRITE setFrom NOTIFY fromChanged FINAL) |
816 | Q_PROPERTY(qreal to MEMBER m_to WRITE setTo NOTIFY toChanged FINAL) |
817 | - Q_PROPERTY(QUrl contentUrl MEMBER m_url NOTIFY contentChanged FINAL) |
818 | - Q_PROPERTY(QQmlComponent* contentComponent MEMBER m_component NOTIFY contentComponentChanged FINAL) |
819 | + Q_PROPERTY(QUrl contentUrl MEMBER m_url WRITE setUrl NOTIFY contentChanged FINAL) |
820 | + Q_PROPERTY(QQmlComponent* contentComponent MEMBER m_component WRITE setComponent NOTIFY contentComponentChanged FINAL) |
821 | public: |
822 | - explicit UCBottomEdgeRegion(QObject *parent = 0); |
823 | + explicit UCBottomEdgeRegion(QObject *parent = 0, bool isDefault = false); |
824 | void attachToBottomEdge(UCBottomEdge *bottomEdge); |
825 | |
826 | // used internally |
827 | + void setUrl(const QUrl &url); |
828 | + void setComponent(QQmlComponent *component); |
829 | void setFrom(qreal from); |
830 | void setTo(qreal to); |
831 | void setEnabled(bool enabled); |
832 | @@ -49,30 +53,57 @@ |
833 | void exit(); |
834 | const QRectF rect(const QRectF &bottomEdgeRect); |
835 | |
836 | + // not exposed to QML |
837 | + bool isActive() |
838 | + { |
839 | + return m_active; |
840 | + } |
841 | + bool isDefault() |
842 | + { |
843 | + return m_default; |
844 | + } |
845 | + |
846 | + QQuickItem *regionContent(); |
847 | + inline const UbuntuToolkit::AsyncLoader *loader() |
848 | + { |
849 | + return const_cast<const UbuntuToolkit::AsyncLoader*>(&m_loader); |
850 | + } |
851 | + |
852 | Q_SIGNALS: |
853 | void enabledChanged(); |
854 | void fromChanged(); |
855 | void toChanged(); |
856 | - void contentChanged(); |
857 | - void contentComponentChanged(); |
858 | + void contentChanged(const QUrl &url); |
859 | + void contentComponentChanged(QQmlComponent *component); |
860 | |
861 | void entered(); |
862 | void exited(); |
863 | void dragEnded(); |
864 | |
865 | protected: |
866 | + enum LoadingType { |
867 | + LoadingUrl, |
868 | + LoadingComponent |
869 | + }; |
870 | + UbuntuToolkit::AsyncLoader m_loader; |
871 | QUrl m_url; |
872 | QPointer<UCBottomEdge> m_bottomEdge; |
873 | QQmlComponent *m_component; |
874 | - PropertyChange *m_urlBackup; |
875 | - PropertyChange *m_componentBackup; |
876 | + QQuickItem *m_contentItem; |
877 | qreal m_from; |
878 | qreal m_to; |
879 | bool m_enabled:1; |
880 | + bool m_active:1; |
881 | + const bool m_default:1; |
882 | |
883 | friend class UCBottomEdge; |
884 | friend class UCBottomEdgePrivate; |
885 | friend class tst_BottomEdge; |
886 | + |
887 | + void loadRegionContent(); |
888 | + void discardRegionContent(); |
889 | + void loadContent(LoadingType type); |
890 | + Q_SLOT void onLoaderStatusChanged(UbuntuToolkit::AsyncLoader::LoadingStatus,QObject*); |
891 | }; |
892 | |
893 | #endif // UCBOTTOMEDGEREGION_H |
894 | |
895 | === modified file 'tests/unit_x11/tst_bottomedge/AutoCollapseInPageHeader.qml' |
896 | --- tests/unit_x11/tst_bottomedge/AutoCollapseInPageHeader.qml 2015-11-26 14:50:03 +0000 |
897 | +++ tests/unit_x11/tst_bottomedge/AutoCollapseInPageHeader.qml 2016-03-01 10:46:21 +0000 |
898 | @@ -23,7 +23,9 @@ |
899 | height: units.gu(71) |
900 | |
901 | Page { |
902 | - title: "Main page" |
903 | + header: PageHeader { |
904 | + title: "Main page" |
905 | + } |
906 | |
907 | BottomEdge { |
908 | id: bottomEdge |
909 | |
910 | === modified file 'tests/unit_x11/tst_bottomedge/AutoCollapseInPageWithPageHeader.qml' |
911 | --- tests/unit_x11/tst_bottomedge/AutoCollapseInPageWithPageHeader.qml 2015-11-26 14:50:03 +0000 |
912 | +++ tests/unit_x11/tst_bottomedge/AutoCollapseInPageWithPageHeader.qml 2016-03-01 10:46:21 +0000 |
913 | @@ -23,7 +23,9 @@ |
914 | height: units.gu(71) |
915 | |
916 | Page { |
917 | - title: "Main page" |
918 | + header: PageHeader { |
919 | + title: "Main page" |
920 | + } |
921 | |
922 | BottomEdge { |
923 | id: bottomEdge |
924 | |
925 | === added file 'tests/unit_x11/tst_bottomedge/PreloadedContent.qml' |
926 | --- tests/unit_x11/tst_bottomedge/PreloadedContent.qml 1970-01-01 00:00:00 +0000 |
927 | +++ tests/unit_x11/tst_bottomedge/PreloadedContent.qml 2016-03-01 10:46:21 +0000 |
928 | @@ -0,0 +1,60 @@ |
929 | +/* |
930 | + * Copyright 2016 Canonical Ltd. |
931 | + * |
932 | + * This program is free software; you can redistribute it and/or modify |
933 | + * it under the terms of the GNU Lesser General Public License as published by |
934 | + * the Free Software Foundation; version 3. |
935 | + * |
936 | + * This program is distributed in the hope that it will be useful, |
937 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
938 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
939 | + * GNU Lesser General Public License for more details. |
940 | + * |
941 | + * You should have received a copy of the GNU Lesser General Public License |
942 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
943 | + * |
944 | + */ |
945 | + |
946 | +import QtQuick 2.4 |
947 | +import Ubuntu.Components 1.3 |
948 | + |
949 | +Item { |
950 | + id: holder |
951 | + width: units.gu(40) |
952 | + height: units.gu(71) |
953 | + |
954 | + BottomEdge { |
955 | + id: bottomEdge |
956 | + height: parent.height |
957 | + hint.text: "Test" |
958 | + objectName: "testItem" |
959 | + preloadContent: true |
960 | + contentComponent: Rectangle { |
961 | + objectName: "default" |
962 | + width: bottomEdge.width |
963 | + height: bottomEdge.height |
964 | + color: UbuntuColors.silk |
965 | + } |
966 | + |
967 | + BottomEdgeRegion { |
968 | + from: 0.2 |
969 | + to: 0.5 |
970 | + contentComponent: Rectangle { |
971 | + objectName: "region1" |
972 | + width: bottomEdge.width - units.gu(10) |
973 | + height: bottomEdge.height |
974 | + color: UbuntuColors.red |
975 | + } |
976 | + } |
977 | + BottomEdgeRegion { |
978 | + from: 0.5 |
979 | + to: 0.7 |
980 | + contentComponent: Rectangle { |
981 | + objectName: "region2" |
982 | + width: bottomEdge.width - units.gu(15) |
983 | + height: bottomEdge.height |
984 | + color: UbuntuColors.blue |
985 | + } |
986 | + } |
987 | + } |
988 | +} |
989 | |
990 | === modified file 'tests/unit_x11/tst_bottomedge/tst_bottomedge.cpp' |
991 | --- tests/unit_x11/tst_bottomedge/tst_bottomedge.cpp 2016-02-10 10:57:20 +0000 |
992 | +++ tests/unit_x11/tst_bottomedge/tst_bottomedge.cpp 2016-03-01 10:46:21 +0000 |
993 | @@ -114,6 +114,7 @@ |
994 | class tst_BottomEdge : public QObject |
995 | { |
996 | Q_OBJECT |
997 | + QStringList regionObjects; |
998 | private Q_SLOTS: |
999 | |
1000 | void initTestCase() |
1001 | @@ -121,6 +122,12 @@ |
1002 | UCTestExtras::registerTouchDevice(); |
1003 | } |
1004 | |
1005 | + void init() |
1006 | + { |
1007 | + regionObjects.clear(); |
1008 | + } |
1009 | + |
1010 | +private Q_SLOTS: |
1011 | void test_defaults() |
1012 | { |
1013 | QScopedPointer<BottomEdgeTestCase> test(new BottomEdgeTestCase("Defaults.qml")); |
1014 | @@ -137,6 +144,7 @@ |
1015 | QCOMPARE(test->regionAt("testItem", 0)->m_from, 0.33); |
1016 | QCOMPARE(test->regionAt("testItem", 0)->m_to, 1.0); |
1017 | QVERIFY(!test->testItem()->activeRegion()); |
1018 | + QVERIFY(!test->testItem()->preloadContent()); |
1019 | } |
1020 | |
1021 | void test_height_moves_when_reparented() |
1022 | @@ -880,6 +888,74 @@ |
1023 | bottomEdge->setEnabled(!bottomEdge->isEnabled()); |
1024 | QCOMPARE(bottomEdge->isEnabled(), bottomEdge->hint()->isEnabled()); |
1025 | } |
1026 | + |
1027 | + void test_preload_content() |
1028 | + { |
1029 | + QScopedPointer<BottomEdgeTestCase> test(new BottomEdgeTestCase("PreloadedContent.qml")); |
1030 | + UCBottomEdge *bottomEdge = test->testItem(); |
1031 | + |
1032 | + QPoint from(bottomEdge->width() / 2.0f, bottomEdge->height() - 5); |
1033 | + QPoint to = from + QPoint(0, -(bottomEdge->parentItem()->height() - 1)); |
1034 | + QSignalSpy spy(bottomEdge, SIGNAL(activeRegionChanged(UCBottomEdgeRegion*))); |
1035 | + |
1036 | + connect(bottomEdge, &UCBottomEdge::contentItemChanged, [=]() { |
1037 | + regionObjects.append(bottomEdge->contentItem() |
1038 | + ? bottomEdge->contentItem()->objectName() |
1039 | + : "NULL"); |
1040 | + }); |
1041 | + |
1042 | + UCTestExtras::touchPress(0, bottomEdge, from); |
1043 | + QPoint movePos(from); |
1044 | + while (movePos.y() > to.y()) { |
1045 | + QTest::qWait(20); |
1046 | + UCTestExtras::touchMove(0, bottomEdge, movePos); |
1047 | + movePos += QPoint(0, -10); |
1048 | + } |
1049 | + QTest::qWait(20); |
1050 | + UCTestExtras::touchRelease(0, bottomEdge, movePos); |
1051 | + // we should have had 3 active region changes by now |
1052 | + // null -> region #0 -> region #1 -> null |
1053 | + QCOMPARE(spy.count(), 3); |
1054 | + QCOMPARE(regionObjects.size(), 5); |
1055 | + int i = 0; |
1056 | + QCOMPARE(regionObjects[i++], QString("default")); |
1057 | + QCOMPARE(regionObjects[i++], QString("region1")); |
1058 | + QCOMPARE(regionObjects[i++], QString("default")); |
1059 | + QCOMPARE(regionObjects[i++], QString("region2")); |
1060 | + QCOMPARE(regionObjects[i++], QString("default")); |
1061 | + } |
1062 | + |
1063 | + void test_reset_preload_content() |
1064 | + { |
1065 | + QScopedPointer<BottomEdgeTestCase> test(new BottomEdgeTestCase("PreloadedContent.qml")); |
1066 | + UCBottomEdge *bottomEdge = test->testItem(); |
1067 | + |
1068 | + UCBottomEdgePrivate *d = UCBottomEdgePrivate::get(bottomEdge); |
1069 | + for (int i = 0; i < d->regions.size(); i++) { |
1070 | + QVERIFY(d->regions[i]->regionContent()); |
1071 | + } |
1072 | + |
1073 | + // set preloadContent: false |
1074 | + bottomEdge->setPreloadContent(false); |
1075 | + for (int i = 0; i < d->regions.size(); i++) { |
1076 | + QVERIFY(!d->regions[i]->regionContent()); |
1077 | + } |
1078 | + } |
1079 | + |
1080 | + void test_disabled_content_unloads() |
1081 | + { |
1082 | + QScopedPointer<BottomEdgeTestCase> test(new BottomEdgeTestCase("PreloadedContent.qml")); |
1083 | + UCBottomEdge *bottomEdge = test->testItem(); |
1084 | + |
1085 | + UCBottomEdgePrivate *d = UCBottomEdgePrivate::get(bottomEdge); |
1086 | + // disable a region |
1087 | + d->regions[0]->setEnabled(false); |
1088 | + QVERIFY(!d->regions[0]->regionContent()); |
1089 | + |
1090 | + // enable it |
1091 | + d->regions[0]->setEnabled(true); |
1092 | + QTRY_VERIFY_WITH_TIMEOUT(d->regions[0]->regionContent() != nullptr, 1000); |
1093 | + } |
1094 | }; |
1095 | |
1096 | QTEST_MAIN(tst_BottomEdge) |
1097 | |
1098 | === modified file 'tests/unit_x11/tst_bottomedge/tst_bottomedge.pro' |
1099 | --- tests/unit_x11/tst_bottomedge/tst_bottomedge.pro 2015-12-17 15:23:26 +0000 |
1100 | +++ tests/unit_x11/tst_bottomedge/tst_bottomedge.pro 2016-03-01 10:46:21 +0000 |
1101 | @@ -1,5 +1,5 @@ |
1102 | include(../test-include.pri) |
1103 | -QT += core-private qml-private quick-private gui-private UbuntuGestures UbuntuGestures_private |
1104 | +QT += core-private qml-private quick-private gui-private UbuntuGestures UbuntuGestures_private UbuntuToolkit |
1105 | |
1106 | SOURCES += \ |
1107 | tst_bottomedge.cpp |
1108 | @@ -22,4 +22,5 @@ |
1109 | AutoCollapseInPageWithPageHeader.qml \ |
1110 | LeanActiveRegionChange.qml \ |
1111 | UncoveredByRegion.qml \ |
1112 | - OverriddenHintTrigger.qml |
1113 | + OverriddenHintTrigger.qml \ |
1114 | + PreloadedContent.qml |
FAILED: Continuous integration, rev:1847 /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-amd64- stable/ 348/ /jenkins. ubuntu. com/ubuntu- sdk/job/ generic- update- mp/1040/ console
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild: /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-amd64- stable/ 348/rebuild
https:/