Merge lp:~mrqtros/component-store/bottom-edge-tabs into lp:component-store
- bottom-edge-tabs
- Merge into trunk.14.10
Status: | Merged |
---|---|
Approved by: | Nekhelesh Ramananthan |
Approved revision: | 52 |
Merged at revision: | 50 |
Proposed branch: | lp:~mrqtros/component-store/bottom-edge-tabs |
Merge into: | lp:component-store |
Diff against target: |
738 lines (+680/-0) 8 files modified
curated-store/ComponentStore/BottomEdgeTabs/BottomEdgeTabs.qml (+427/-0) curated-store/ComponentStore/BottomEdgeTabs/FakeHeader.qml (+39/-0) curated-store/ComponentStore/BottomEdgeTabs/ubuntu_component_store.json (+6/-0) curated-store/GallerySRC/BottomEdgeTabsWidget.qml (+69/-0) curated-store/GallerySRC/WidgetsModel.qml (+5/-0) docs/_components/bottomedgetabs.rst (+129/-0) docs/index.rst (+1/-0) docs/release.rst (+4/-0) |
To merge this branch: | bzr merge lp:~mrqtros/component-store/bottom-edge-tabs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nekhelesh Ramananthan | Approve | ||
Review via email: mp+256041@code.launchpad.net |
Commit message
New component - BottomEdgeTabs (something like PageWithBottomEdge, but for Tabs).
Description of the change
New component - BottomEdgeTabs (something like PageWithBottomEdge, but for Tabs).
P.S. I think that PageWithBottomEdge also should use my method of displaying live preview (use ShaderEffectSource instead of manual creating and reparenting).
Roman Shchekin (mrqtros) wrote : | # |
Nekhelesh Ramananthan (nik90) wrote : | # |
The only warning I see is,
QML UbuntuShape: Binding Loop Detected for property "hidden".. I guess that's fine.
1. Merge https:/
2. This is your component, so please maintain it as and when required :-)
Nice Work!
- 52. By Roman Shchekin
-
Merged with correct docs (thanks Nekhelesh).
Roman Shchekin (mrqtros) wrote : | # |
1. Merged with your branch!
2. Yes I will :)
BTW, binding loop can be caused by this bug https:/
Preview Diff
1 | === added directory 'curated-store/ComponentStore/BottomEdgeTabs' | |||
2 | === added file 'curated-store/ComponentStore/BottomEdgeTabs/BottomEdgeTabs.qml' | |||
3 | --- curated-store/ComponentStore/BottomEdgeTabs/BottomEdgeTabs.qml 1970-01-01 00:00:00 +0000 | |||
4 | +++ curated-store/ComponentStore/BottomEdgeTabs/BottomEdgeTabs.qml 2015-04-14 06:07:01 +0000 | |||
5 | @@ -0,0 +1,427 @@ | |||
6 | 1 | /* | ||
7 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
8 | 3 | * | ||
9 | 4 | * This program is free software; you can redistribute it and/or modify | ||
10 | 5 | * it under the terms of the GNU General Public License as published by | ||
11 | 6 | * the Free Software Foundation; version 3. | ||
12 | 7 | * | ||
13 | 8 | * This program is distributed in the hope that it will be useful, | ||
14 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | 11 | * GNU General Public License for more details. | ||
17 | 12 | * | ||
18 | 13 | * You should have received a copy of the GNU General Public License | ||
19 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | 15 | */ | ||
21 | 16 | |||
22 | 17 | /* | ||
23 | 18 | Example: | ||
24 | 19 | |||
25 | 20 | MainView { | ||
26 | 21 | objectName: "mainView" | ||
27 | 22 | |||
28 | 23 | applicationName: "com.ubuntu.developer.qtros.tabsbottomedge" | ||
29 | 24 | |||
30 | 25 | width: units.gu(50) | ||
31 | 26 | height: units.gu(75) | ||
32 | 27 | useDeprecatedToolbar: false | ||
33 | 28 | |||
34 | 29 | PageStack { | ||
35 | 30 | id: stack | ||
36 | 31 | Component.onCompleted: push(tabs) | ||
37 | 32 | } | ||
38 | 33 | |||
39 | 34 | BottomEdgeTabs { | ||
40 | 35 | id: tabs | ||
41 | 36 | |||
42 | 37 | bottomEdgePage: secondPage | ||
43 | 38 | bottomEdgeTitle: "Violet page" | ||
44 | 39 | |||
45 | 40 | Tab { | ||
46 | 41 | title: "First tab" | ||
47 | 42 | page: Page { | ||
48 | 43 | Label { | ||
49 | 44 | anchors.centerIn: parent | ||
50 | 45 | text: "Content of first tab" | ||
51 | 46 | } | ||
52 | 47 | } | ||
53 | 48 | } | ||
54 | 49 | |||
55 | 50 | Tab { | ||
56 | 51 | title: "Second tab" | ||
57 | 52 | page: Page { | ||
58 | 53 | Label { | ||
59 | 54 | anchors.centerIn: parent | ||
60 | 55 | text: "Centered label" | ||
61 | 56 | } | ||
62 | 57 | } | ||
63 | 58 | } | ||
64 | 59 | } // BottomEdgeTabs | ||
65 | 60 | |||
66 | 61 | Page { | ||
67 | 62 | id: secondPage | ||
68 | 63 | title: "Violet page" | ||
69 | 64 | visible: false | ||
70 | 65 | |||
71 | 66 | Rectangle { | ||
72 | 67 | anchors.fill: parent | ||
73 | 68 | color: "darkviolet" | ||
74 | 69 | } | ||
75 | 70 | } | ||
76 | 71 | } | ||
77 | 72 | |||
78 | 73 | */ | ||
79 | 74 | |||
80 | 75 | import QtQuick 2.3 | ||
81 | 76 | import Ubuntu.Components 1.1 | ||
82 | 77 | |||
83 | 78 | Tabs { | ||
84 | 79 | id: page | ||
85 | 80 | |||
86 | 81 | property Page bottomEdgePage: null | ||
87 | 82 | property alias bottomEdgeTitle: tipLabel.text | ||
88 | 83 | property color bottomEdgeBackgroundColor: Theme.palette.normal.background | ||
89 | 84 | property color bottomEdgeTipColor: Theme.palette.normal.background | ||
90 | 85 | property bool bottomEdgeEnabled: true | ||
91 | 86 | property bool bottomEdgeHeaderHidden: true | ||
92 | 87 | property bool bottomEdgeUseHeaderInCalculations: true | ||
93 | 88 | property real bottomEdgeExpandThreshold: 0.2 | ||
94 | 89 | |||
95 | 90 | readonly property bool isReady: bottomEdgePageLoaded && bottomEdgePage.active && bottomEdge.y === __pageStartY | ||
96 | 91 | readonly property bool isCollapsed: (bottomEdge.y === page.height) | ||
97 | 92 | readonly property bool bottomEdgePageLoaded: bottomEdgePage != null | ||
98 | 93 | |||
99 | 94 | readonly property int __pageStartY: bottomEdgeUseHeaderInCalculations ? fakeHeader.height : 0 | ||
100 | 95 | |||
101 | 96 | signal bottomEdgeReleased() | ||
102 | 97 | signal bottomEdgeDismissed() | ||
103 | 98 | |||
104 | 99 | function __pushPage() { | ||
105 | 100 | if (bottomEdgePageLoaded) { | ||
106 | 101 | bottomEdgePage.active = true | ||
107 | 102 | if (bottomEdgePage.hasOwnProperty("isDirty")) // TODO | ||
108 | 103 | bottomEdgePage.isDirty = true | ||
109 | 104 | page.pageStack.push(bottomEdgePage) | ||
110 | 105 | if (bottomEdgePage.flickable) { | ||
111 | 106 | bottomEdgePage.flickable.contentY = -page.header.height | ||
112 | 107 | bottomEdgePage.flickable.returnToBounds() | ||
113 | 108 | } | ||
114 | 109 | if (bottomEdgePage.ready) | ||
115 | 110 | bottomEdgePage.ready() | ||
116 | 111 | } | ||
117 | 112 | } | ||
118 | 113 | |||
119 | 114 | onActiveChanged: { | ||
120 | 115 | if (active) { | ||
121 | 116 | bottomEdge.state = "collapsed" | ||
122 | 117 | } | ||
123 | 118 | } | ||
124 | 119 | |||
125 | 120 | onBottomEdgePageChanged: { | ||
126 | 121 | tip.forceActiveFocus() | ||
127 | 122 | if (page.isReady && bottomEdgePageLoaded && !bottomEdgePage.active) { | ||
128 | 123 | page.__pushPage() | ||
129 | 124 | } | ||
130 | 125 | } | ||
131 | 126 | |||
132 | 127 | Rectangle { | ||
133 | 128 | id: bgVisual | ||
134 | 129 | |||
135 | 130 | color: "black" | ||
136 | 131 | anchors { | ||
137 | 132 | fill: parent | ||
138 | 133 | topMargin: __pageStartY | ||
139 | 134 | } | ||
140 | 135 | opacity: 0.7 * ((page.height - bottomEdge.y) / page.height) | ||
141 | 136 | z: 1 | ||
142 | 137 | } | ||
143 | 138 | |||
144 | 139 | UbuntuShape { | ||
145 | 140 | id: tip | ||
146 | 141 | objectName: "bottomEdgeTip" | ||
147 | 142 | |||
148 | 143 | property bool hidden: !activeFocus || (bottomEdge.y - units.gu(1) < tip.y) | ||
149 | 144 | |||
150 | 145 | enabled: bottomEdgePageLoaded | ||
151 | 146 | visible: bottomEdgeEnabled | ||
152 | 147 | anchors { | ||
153 | 148 | bottom: parent.bottom | ||
154 | 149 | horizontalCenter: bottomEdge.horizontalCenter | ||
155 | 150 | bottomMargin: hidden ? - height + units.gu(1) : -units.gu(1) | ||
156 | 151 | Behavior on bottomMargin { | ||
157 | 152 | SequentialAnimation { | ||
158 | 153 | // wait some msecs in case of the focus change again, to avoid flickering | ||
159 | 154 | PauseAnimation { | ||
160 | 155 | duration: 300 | ||
161 | 156 | } | ||
162 | 157 | UbuntuNumberAnimation { | ||
163 | 158 | duration: UbuntuAnimation.SnapDuration | ||
164 | 159 | } | ||
165 | 160 | } | ||
166 | 161 | } | ||
167 | 162 | } | ||
168 | 163 | |||
169 | 164 | z: 1 | ||
170 | 165 | width: tipLabel.paintedWidth + units.gu(6) | ||
171 | 166 | height: bottomEdge.tipHeight + units.gu(1) | ||
172 | 167 | color: bottomEdgeTipColor //color: "#C9C9C9" | ||
173 | 168 | |||
174 | 169 | Label { | ||
175 | 170 | id: tipLabel | ||
176 | 171 | |||
177 | 172 | anchors { | ||
178 | 173 | top: parent.top | ||
179 | 174 | left: parent.left | ||
180 | 175 | right: parent.right | ||
181 | 176 | } | ||
182 | 177 | height: bottomEdge.tipHeight | ||
183 | 178 | verticalAlignment: Text.AlignVCenter | ||
184 | 179 | horizontalAlignment: Text.AlignHCenter | ||
185 | 180 | opacity: tip.hidden ? 0.0 : 1.0 | ||
186 | 181 | Behavior on opacity { | ||
187 | 182 | UbuntuNumberAnimation { | ||
188 | 183 | duration: UbuntuAnimation.SnapDuration | ||
189 | 184 | } | ||
190 | 185 | } | ||
191 | 186 | } | ||
192 | 187 | } // UbuntuShape | ||
193 | 188 | |||
194 | 189 | Rectangle { | ||
195 | 190 | id: shadow | ||
196 | 191 | |||
197 | 192 | anchors { | ||
198 | 193 | left: parent.left | ||
199 | 194 | right: parent.right | ||
200 | 195 | bottom: bottomEdge.top | ||
201 | 196 | } | ||
202 | 197 | height: units.gu(1) | ||
203 | 198 | z: 1 | ||
204 | 199 | opacity: 0.0 | ||
205 | 200 | gradient: Gradient { | ||
206 | 201 | GradientStop { position: 0.0; color: "transparent" } | ||
207 | 202 | GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.2) } | ||
208 | 203 | } | ||
209 | 204 | } | ||
210 | 205 | |||
211 | 206 | MouseArea { | ||
212 | 207 | id: mouseArea | ||
213 | 208 | |||
214 | 209 | property real previousY: -1 | ||
215 | 210 | property string dragDirection: "None" | ||
216 | 211 | |||
217 | 212 | preventStealing: true | ||
218 | 213 | drag { | ||
219 | 214 | axis: Drag.YAxis | ||
220 | 215 | target: bottomEdge | ||
221 | 216 | minimumY: __pageStartY | ||
222 | 217 | maximumY: page.height | ||
223 | 218 | } | ||
224 | 219 | enabled: bottomEdgePageLoaded | ||
225 | 220 | visible: page.bottomEdgeEnabled | ||
226 | 221 | |||
227 | 222 | anchors { | ||
228 | 223 | left: parent.left | ||
229 | 224 | right: parent.right | ||
230 | 225 | bottom: parent.bottom | ||
231 | 226 | } | ||
232 | 227 | height: bottomEdge.tipHeight | ||
233 | 228 | z: 1 | ||
234 | 229 | |||
235 | 230 | onReleased: { | ||
236 | 231 | page.bottomEdgeReleased() | ||
237 | 232 | if ((dragDirection === "BottomToTop") && | ||
238 | 233 | bottomEdge.y < (page.height - page.height * bottomEdgeExpandThreshold - bottomEdge.tipHeight)) { | ||
239 | 234 | bottomEdge.state = "expanded" | ||
240 | 235 | } else { | ||
241 | 236 | bottomEdge.state = "collapsed" | ||
242 | 237 | } | ||
243 | 238 | previousY = -1 | ||
244 | 239 | dragDirection = "None" | ||
245 | 240 | } | ||
246 | 241 | |||
247 | 242 | onPressed: { | ||
248 | 243 | previousY = mouse.y | ||
249 | 244 | tip.forceActiveFocus() | ||
250 | 245 | } | ||
251 | 246 | |||
252 | 247 | onMouseYChanged: { | ||
253 | 248 | var yOffset = previousY - mouseY | ||
254 | 249 | // skip if was a small move | ||
255 | 250 | if (Math.abs(yOffset) <= units.gu(2)) | ||
256 | 251 | return | ||
257 | 252 | |||
258 | 253 | previousY = mouseY | ||
259 | 254 | dragDirection = yOffset > 0 ? "BottomToTop" : "TopToBottom" | ||
260 | 255 | } | ||
261 | 256 | } | ||
262 | 257 | |||
263 | 258 | FakeHeader { | ||
264 | 259 | id: fakeHeader | ||
265 | 260 | visible: bottomEdgeEnabled && !bottomEdgeHeaderHidden | ||
266 | 261 | |||
267 | 262 | anchors { | ||
268 | 263 | left: parent.left | ||
269 | 264 | right: parent.right | ||
270 | 265 | } | ||
271 | 266 | y: -fakeHeader.height + (fakeHeader.height * (page.height - bottomEdge.y)) / (page.height - fakeHeader.height) | ||
272 | 267 | z: bgVisual.z + 1 | ||
273 | 268 | |||
274 | 269 | Behavior on y { | ||
275 | 270 | UbuntuNumberAnimation { | ||
276 | 271 | duration: UbuntuAnimation.SnapDuration | ||
277 | 272 | } | ||
278 | 273 | } | ||
279 | 274 | } | ||
280 | 275 | |||
281 | 276 | Rectangle { | ||
282 | 277 | id: bottomEdge | ||
283 | 278 | objectName: "bottomEdge" | ||
284 | 279 | |||
285 | 280 | readonly property int tipHeight: units.gu(3) | ||
286 | 281 | |||
287 | 282 | |||
288 | 283 | z: 1 | ||
289 | 284 | color: bottomEdgeBackgroundColor | ||
290 | 285 | clip: true | ||
291 | 286 | anchors { | ||
292 | 287 | left: parent.left | ||
293 | 288 | right: parent.right | ||
294 | 289 | } | ||
295 | 290 | height: page.height | ||
296 | 291 | y: height | ||
297 | 292 | |||
298 | 293 | visible: !page.isCollapsed | ||
299 | 294 | state: "collapsed" | ||
300 | 295 | states: [ | ||
301 | 296 | State { | ||
302 | 297 | name: "collapsed" | ||
303 | 298 | PropertyChanges { | ||
304 | 299 | target: bottomEdge | ||
305 | 300 | y: bottomEdge.height | ||
306 | 301 | } | ||
307 | 302 | PropertyChanges { | ||
308 | 303 | target: fakeHeader | ||
309 | 304 | y: -fakeHeader.height | ||
310 | 305 | } | ||
311 | 306 | }, | ||
312 | 307 | State { | ||
313 | 308 | name: "expanded" | ||
314 | 309 | PropertyChanges { | ||
315 | 310 | target: bottomEdge | ||
316 | 311 | y: __pageStartY | ||
317 | 312 | } | ||
318 | 313 | PropertyChanges { | ||
319 | 314 | target: fakeHeader | ||
320 | 315 | y: 0 | ||
321 | 316 | } | ||
322 | 317 | }, | ||
323 | 318 | State { | ||
324 | 319 | name: "floating" | ||
325 | 320 | when: mouseArea.drag.active | ||
326 | 321 | PropertyChanges { | ||
327 | 322 | target: shadow | ||
328 | 323 | opacity: 1.0 | ||
329 | 324 | } | ||
330 | 325 | } | ||
331 | 326 | ] | ||
332 | 327 | |||
333 | 328 | transitions: [ | ||
334 | 329 | Transition { | ||
335 | 330 | to: "expanded" | ||
336 | 331 | SequentialAnimation { | ||
337 | 332 | alwaysRunToEnd: true | ||
338 | 333 | ParallelAnimation { | ||
339 | 334 | SmoothedAnimation { | ||
340 | 335 | target: bottomEdge | ||
341 | 336 | property: "y" | ||
342 | 337 | duration: UbuntuAnimation.FastDuration | ||
343 | 338 | easing.type: Easing.Linear | ||
344 | 339 | } | ||
345 | 340 | SmoothedAnimation { | ||
346 | 341 | target: fakeHeader | ||
347 | 342 | property: "y" | ||
348 | 343 | duration: UbuntuAnimation.FastDuration | ||
349 | 344 | easing.type: Easing.Linear | ||
350 | 345 | } | ||
351 | 346 | } | ||
352 | 347 | SmoothedAnimation { | ||
353 | 348 | target: shaderSource | ||
354 | 349 | property: "anchors.topMargin" | ||
355 | 350 | to: - units.gu(4) | ||
356 | 351 | duration: UbuntuAnimation.FastDuration | ||
357 | 352 | easing.type: Easing.Linear | ||
358 | 353 | } | ||
359 | 354 | SmoothedAnimation { | ||
360 | 355 | target: shaderSource | ||
361 | 356 | property: "anchors.topMargin" | ||
362 | 357 | to: 0 | ||
363 | 358 | duration: UbuntuAnimation.FastDuration | ||
364 | 359 | easing: UbuntuAnimation.StandardEasing | ||
365 | 360 | } | ||
366 | 361 | ScriptAction { | ||
367 | 362 | script: page.__pushPage() | ||
368 | 363 | } | ||
369 | 364 | } | ||
370 | 365 | }, | ||
371 | 366 | Transition { | ||
372 | 367 | from: "expanded" | ||
373 | 368 | to: "collapsed" | ||
374 | 369 | SequentialAnimation { | ||
375 | 370 | alwaysRunToEnd: true | ||
376 | 371 | |||
377 | 372 | ScriptAction { | ||
378 | 373 | script: { | ||
379 | 374 | Qt.inputMethod.hide() | ||
380 | 375 | bottomEdgePage.active = false | ||
381 | 376 | } | ||
382 | 377 | } | ||
383 | 378 | ParallelAnimation { | ||
384 | 379 | SmoothedAnimation { | ||
385 | 380 | target: bottomEdge | ||
386 | 381 | property: "y" | ||
387 | 382 | duration: UbuntuAnimation.SlowDuration | ||
388 | 383 | } | ||
389 | 384 | SmoothedAnimation { | ||
390 | 385 | target: fakeHeader | ||
391 | 386 | property: "y" | ||
392 | 387 | duration: UbuntuAnimation.SlowDuration | ||
393 | 388 | } | ||
394 | 389 | } | ||
395 | 390 | ScriptAction { | ||
396 | 391 | script: { | ||
397 | 392 | // notify | ||
398 | 393 | page.bottomEdgeDismissed() | ||
399 | 394 | bottomEdgePage.active = true | ||
400 | 395 | } | ||
401 | 396 | } | ||
402 | 397 | } | ||
403 | 398 | }, | ||
404 | 399 | Transition { | ||
405 | 400 | from: "floating" | ||
406 | 401 | to: "collapsed" | ||
407 | 402 | UbuntuNumberAnimation { | ||
408 | 403 | target: bottomEdge | ||
409 | 404 | property: "opacity" | ||
410 | 405 | } | ||
411 | 406 | } | ||
412 | 407 | ] | ||
413 | 408 | |||
414 | 409 | ShaderEffectSource { | ||
415 | 410 | id: shaderSource | ||
416 | 411 | sourceItem: bottomEdgePage | ||
417 | 412 | anchors { | ||
418 | 413 | top: parent.top | ||
419 | 414 | left: parent.left | ||
420 | 415 | right: parent.right | ||
421 | 416 | } | ||
422 | 417 | height: page.height - fakeHeader.height | ||
423 | 418 | |||
424 | 419 | Binding { | ||
425 | 420 | target: bottomEdgePageLoaded ? shaderSource : null | ||
426 | 421 | property: "anchors.topMargin" | ||
427 | 422 | value: bottomEdgePage && bottomEdgePage.flickable ? bottomEdgePage.flickable.contentY : 0 | ||
428 | 423 | when: !page.isReady | ||
429 | 424 | } | ||
430 | 425 | } | ||
431 | 426 | } // Rectanlgle | ||
432 | 427 | } | ||
433 | 0 | 428 | ||
434 | === added file 'curated-store/ComponentStore/BottomEdgeTabs/FakeHeader.qml' | |||
435 | --- curated-store/ComponentStore/BottomEdgeTabs/FakeHeader.qml 1970-01-01 00:00:00 +0000 | |||
436 | +++ curated-store/ComponentStore/BottomEdgeTabs/FakeHeader.qml 2015-04-14 06:07:01 +0000 | |||
437 | @@ -0,0 +1,39 @@ | |||
438 | 1 | /* | ||
439 | 2 | * Copyright (C) 2014 Canonical Ltd | ||
440 | 3 | * | ||
441 | 4 | * This file is part of Ubuntu Clock App | ||
442 | 5 | * | ||
443 | 6 | * Ubuntu Clock App is free software: you can redistribute it and/or modify | ||
444 | 7 | * it under the terms of the GNU General Public License version 3 as | ||
445 | 8 | * published by the Free Software Foundation. | ||
446 | 9 | * | ||
447 | 10 | * Ubuntu Clock App is distributed in the hope that it will be useful, | ||
448 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
449 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
450 | 13 | * GNU General Public License for more details. | ||
451 | 14 | * | ||
452 | 15 | * You should have received a copy of the GNU General Public License | ||
453 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
454 | 17 | */ | ||
455 | 18 | |||
456 | 19 | import QtQuick 2.3 | ||
457 | 20 | import Ubuntu.Components 1.1 | ||
458 | 21 | |||
459 | 22 | Column { | ||
460 | 23 | id: fakeHeader | ||
461 | 24 | |||
462 | 25 | height: units.gu(9) | ||
463 | 26 | |||
464 | 27 | Rectangle { | ||
465 | 28 | height: units.gu(7) | ||
466 | 29 | width: parent.width | ||
467 | 30 | color: Theme.palette.normal.background | ||
468 | 31 | } | ||
469 | 32 | |||
470 | 33 | Rectangle { | ||
471 | 34 | color: "#C9C9C9" | ||
472 | 35 | height: units.gu(2) | ||
473 | 36 | anchors.left: parent.left | ||
474 | 37 | anchors.right: parent.right | ||
475 | 38 | } | ||
476 | 39 | } | ||
477 | 0 | 40 | ||
478 | === added file 'curated-store/ComponentStore/BottomEdgeTabs/ubuntu_component_store.json' | |||
479 | --- curated-store/ComponentStore/BottomEdgeTabs/ubuntu_component_store.json 1970-01-01 00:00:00 +0000 | |||
480 | +++ curated-store/ComponentStore/BottomEdgeTabs/ubuntu_component_store.json 2015-04-14 06:07:01 +0000 | |||
481 | @@ -0,0 +1,6 @@ | |||
482 | 1 | { | ||
483 | 2 | "name": "BottomEdgeTabs", | ||
484 | 3 | "description": "This component adds a bottom edge page to Tabs.", | ||
485 | 4 | "version": "1.0", | ||
486 | 5 | "documentation_url": "http://ubuntu-component-store.readthedocs.org/en/latest/_components/bottomedgetabs.html" | ||
487 | 6 | } | ||
488 | 0 | 7 | ||
489 | === added file 'curated-store/GallerySRC/BottomEdgeTabsWidget.qml' | |||
490 | --- curated-store/GallerySRC/BottomEdgeTabsWidget.qml 1970-01-01 00:00:00 +0000 | |||
491 | +++ curated-store/GallerySRC/BottomEdgeTabsWidget.qml 2015-04-14 06:07:01 +0000 | |||
492 | @@ -0,0 +1,69 @@ | |||
493 | 1 | import QtQuick 2.0 | ||
494 | 2 | import Ubuntu.Components 1.1 | ||
495 | 3 | import Ubuntu.Components.ListItems 1.0 as ListItems | ||
496 | 4 | import "../ComponentStore/BottomEdgeTabs" | ||
497 | 5 | |||
498 | 6 | TemplateWidgetPage { | ||
499 | 7 | id: bottomEdgeTabsWidget | ||
500 | 8 | |||
501 | 9 | title: "Tabs With Bottom Edge" | ||
502 | 10 | author: "Roman Shchekin" | ||
503 | 11 | email: "mrqtros@gmail.com" | ||
504 | 12 | license: "GNU General Public License v3.0" | ||
505 | 13 | description: "Tabs component with the ability to setting bottom edge page." | ||
506 | 14 | |||
507 | 15 | Component { | ||
508 | 16 | id: pageComponent | ||
509 | 17 | |||
510 | 18 | PageStack { | ||
511 | 19 | id: stack | ||
512 | 20 | Component.onCompleted: push(tabs) | ||
513 | 21 | |||
514 | 22 | BottomEdgeTabs { | ||
515 | 23 | id: tabs | ||
516 | 24 | |||
517 | 25 | bottomEdgePage: secondPage | ||
518 | 26 | bottomEdgeTitle: "Violet page" | ||
519 | 27 | |||
520 | 28 | Tab { | ||
521 | 29 | title: "First tab" | ||
522 | 30 | page: Page { | ||
523 | 31 | Label { | ||
524 | 32 | anchors.centerIn: parent | ||
525 | 33 | text: "Content of first tab" | ||
526 | 34 | } | ||
527 | 35 | } | ||
528 | 36 | } | ||
529 | 37 | |||
530 | 38 | Tab { | ||
531 | 39 | title: "Second tab" | ||
532 | 40 | page: Page { | ||
533 | 41 | Label { | ||
534 | 42 | anchors.centerIn: parent | ||
535 | 43 | text: "Centered label" | ||
536 | 44 | } | ||
537 | 45 | } | ||
538 | 46 | } | ||
539 | 47 | } // BottomEdgeTabs | ||
540 | 48 | |||
541 | 49 | Page { | ||
542 | 50 | id: secondPage | ||
543 | 51 | title: "Violet page" | ||
544 | 52 | visible: false | ||
545 | 53 | |||
546 | 54 | Rectangle { | ||
547 | 55 | anchors.fill: parent | ||
548 | 56 | color: "darkviolet" | ||
549 | 57 | } | ||
550 | 58 | } | ||
551 | 59 | } | ||
552 | 60 | } | ||
553 | 61 | |||
554 | 62 | content: Button { | ||
555 | 63 | text: "Preview BottomEdgeTabs Component" | ||
556 | 64 | color: "Green" | ||
557 | 65 | height: units.gu(6) | ||
558 | 66 | onClicked: stack.push(pageComponent) | ||
559 | 67 | anchors.centerIn: parent | ||
560 | 68 | } | ||
561 | 69 | } | ||
562 | 0 | 70 | ||
563 | === modified file 'curated-store/GallerySRC/WidgetsModel.qml' | |||
564 | --- curated-store/GallerySRC/WidgetsModel.qml 2015-03-03 13:16:09 +0000 | |||
565 | +++ curated-store/GallerySRC/WidgetsModel.qml 2015-04-14 06:07:01 +0000 | |||
566 | @@ -37,4 +37,9 @@ | |||
567 | 37 | label: "Welcome Wizard" | 37 | label: "Welcome Wizard" |
568 | 38 | source: "GallerySRC/WelcomeWizardWidget.qml" | 38 | source: "GallerySRC/WelcomeWizardWidget.qml" |
569 | 39 | } | 39 | } |
570 | 40 | |||
571 | 41 | ListElement { | ||
572 | 42 | label: "Tabs With Bottom Edge" | ||
573 | 43 | source: "GallerySRC/BottomEdgeTabsWidget.qml" | ||
574 | 44 | } | ||
575 | 40 | } | 45 | } |
576 | 41 | 46 | ||
577 | === added file 'docs/_components/bottomedgetabs.rst' | |||
578 | --- docs/_components/bottomedgetabs.rst 1970-01-01 00:00:00 +0000 | |||
579 | +++ docs/_components/bottomedgetabs.rst 2015-04-14 06:07:01 +0000 | |||
580 | @@ -0,0 +1,129 @@ | |||
581 | 1 | Bottom Edge Tabs | ||
582 | 2 | ================ | ||
583 | 3 | |||
584 | 4 | +----------+----------------------------------------+ | ||
585 | 5 | | Author | Roman Shchekin | | ||
586 | 6 | +----------+-------------+--------------------------+ | ||
587 | 7 | | License | GNU General Public License v3.0 | | ||
588 | 8 | +----------+----------------------------------------+ | ||
589 | 9 | | Contact | mrqtros@gmail.com | | ||
590 | 10 | +----------+----------------------------------------+ | ||
591 | 11 | | Framework| ubuntu-sdk-14.10 | | ||
592 | 12 | +----------+----------------------------------------+ | ||
593 | 13 | |||
594 | 14 | BottomEdgeTabs is very similar to PageWithBottomEdge but uses Tabs as root component instead of Page. Check it's documentation. | ||
595 | 15 | |||
596 | 16 | Example: | ||
597 | 17 | |||
598 | 18 | .. code-block:: qml | ||
599 | 19 | |||
600 | 20 | MainView { | ||
601 | 21 | objectName: "mainView" | ||
602 | 22 | |||
603 | 23 | applicationName: "com.ubuntu.developer.qtros.tabsbottomedge" | ||
604 | 24 | |||
605 | 25 | width: units.gu(50) | ||
606 | 26 | height: units.gu(75) | ||
607 | 27 | useDeprecatedToolbar: false | ||
608 | 28 | |||
609 | 29 | PageStack { | ||
610 | 30 | id: stack | ||
611 | 31 | Component.onCompleted: push(tabs) | ||
612 | 32 | |||
613 | 33 | BottomEdgeTabs { | ||
614 | 34 | id: tabs | ||
615 | 35 | |||
616 | 36 | bottomEdgePage: secondPage | ||
617 | 37 | bottomEdgeTitle: "Violet page" | ||
618 | 38 | |||
619 | 39 | Tab { | ||
620 | 40 | title: "First tab" | ||
621 | 41 | page: Page { | ||
622 | 42 | Label { | ||
623 | 43 | anchors.centerIn: parent | ||
624 | 44 | text: "Content of first tab" | ||
625 | 45 | } | ||
626 | 46 | } | ||
627 | 47 | } | ||
628 | 48 | |||
629 | 49 | Tab { | ||
630 | 50 | title: "Second tab" | ||
631 | 51 | page: Page { | ||
632 | 52 | Label { | ||
633 | 53 | anchors.centerIn: parent | ||
634 | 54 | text: "Centered label" | ||
635 | 55 | } | ||
636 | 56 | } | ||
637 | 57 | } | ||
638 | 58 | } // BottomEdgeTabs | ||
639 | 59 | |||
640 | 60 | Page { | ||
641 | 61 | id: secondPage | ||
642 | 62 | title: "Violet page" | ||
643 | 63 | visible: false | ||
644 | 64 | |||
645 | 65 | Rectangle { | ||
646 | 66 | anchors.fill: parent | ||
647 | 67 | color: "darkviolet" | ||
648 | 68 | } | ||
649 | 69 | } | ||
650 | 70 | } | ||
651 | 71 | } | ||
652 | 72 | |||
653 | 73 | .. image:: ../_images/bottomedgetabs.png | ||
654 | 74 | :align: center | ||
655 | 75 | |||
656 | 76 | Properties | ||
657 | 77 | ---------- | ||
658 | 78 | |||
659 | 79 | - :ref:`bottomEdgeTitle`: string | ||
660 | 80 | - :ref:`bottomEdgePage`: Page | ||
661 | 81 | - :ref:`bottomEdgeEnabled`: boolean | ||
662 | 82 | |||
663 | 83 | Signals | ||
664 | 84 | ------- | ||
665 | 85 | |||
666 | 86 | - :ref:`bottomEdgeReleased()` | ||
667 | 87 | - :ref:`bottomEdgeDismissed()` | ||
668 | 88 | |||
669 | 89 | Property Documentation | ||
670 | 90 | ---------------------- | ||
671 | 91 | |||
672 | 92 | .. _bottomEdgeTitle: | ||
673 | 93 | |||
674 | 94 | bottomEdgeTitle | ||
675 | 95 | ^^^^^^^^^^^^^^^ | ||
676 | 96 | |||
677 | 97 | The text to be displayed in the bottom edge action. | ||
678 | 98 | |||
679 | 99 | .. _bottomEdgePage: | ||
680 | 100 | |||
681 | 101 | bottomEdgePage | ||
682 | 102 | ^^^^^^^^^^^^^^ | ||
683 | 103 | |||
684 | 104 | The page to be shown when swiping the bottom edge up. | ||
685 | 105 | |||
686 | 106 | .. _bottomEdgeEnabled: | ||
687 | 107 | |||
688 | 108 | bottomEdgeEnabled | ||
689 | 109 | ^^^^^^^^^^^^^^^^^ | ||
690 | 110 | |||
691 | 111 | Boolean property to enable/disable the bottom edge | ||
692 | 112 | |||
693 | 113 | Signal Documentation | ||
694 | 114 | -------------------- | ||
695 | 115 | |||
696 | 116 | .. _bottomEdgeReleased(): | ||
697 | 117 | |||
698 | 118 | bottomEdgeReleased() | ||
699 | 119 | ^^^^^^^^^^^^^^^^^^^^ | ||
700 | 120 | |||
701 | 121 | This handler is called when the bottom edge is let go. | ||
702 | 122 | |||
703 | 123 | .. _bottomEdgeDismissed(): | ||
704 | 124 | |||
705 | 125 | bottomEdgeDismissed() | ||
706 | 126 | ^^^^^^^^^^^^^^^^^^^^^ | ||
707 | 127 | |||
708 | 128 | Called when the bottom edge is dismissed (hidden). | ||
709 | 129 | |||
710 | 0 | 130 | ||
711 | === added file 'docs/_images/bottomedgetabs.png' | |||
712 | 1 | Binary files docs/_images/bottomedgetabs.png 1970-01-01 00:00:00 +0000 and docs/_images/bottomedgetabs.png 2015-04-14 06:07:01 +0000 differ | 131 | Binary files docs/_images/bottomedgetabs.png 1970-01-01 00:00:00 +0000 and docs/_images/bottomedgetabs.png 2015-04-14 06:07:01 +0000 differ |
713 | === modified file 'docs/index.rst' | |||
714 | --- docs/index.rst 2015-04-13 17:45:49 +0000 | |||
715 | +++ docs/index.rst 2015-04-14 06:07:01 +0000 | |||
716 | @@ -50,6 +50,7 @@ | |||
717 | 50 | .. toctree:: | 50 | .. toctree:: |
718 | 51 | :maxdepth: 1 | 51 | :maxdepth: 1 |
719 | 52 | 52 | ||
720 | 53 | _components/bottomedgetabs | ||
721 | 53 | _components/circleimage | 54 | _components/circleimage |
722 | 54 | _components/emptystate | 55 | _components/emptystate |
723 | 55 | _components/fastscroll | 56 | _components/fastscroll |
724 | 56 | 57 | ||
725 | === modified file 'docs/release.rst' | |||
726 | --- docs/release.rst 2015-03-23 14:32:46 +0000 | |||
727 | +++ docs/release.rst 2015-04-14 06:07:01 +0000 | |||
728 | @@ -1,6 +1,10 @@ | |||
729 | 1 | Release Notes | 1 | Release Notes |
730 | 2 | ============= | 2 | ============= |
731 | 3 | 3 | ||
732 | 4 | **13th April 2015** | ||
733 | 5 | |||
734 | 6 | * Added Bottom Edge Tabs component | ||
735 | 7 | |||
736 | 4 | **23rd March 2015** | 8 | **23rd March 2015** |
737 | 5 | 9 | ||
738 | 6 | * Added haptic feedback to radial action buttons | 10 | * Added haptic feedback to radial action buttons |
Btw, you maybe will see warning message about message loop - it's result of hosting one PageStack in another, in real use case there are no any warnings.
And feel free to change docs & other staff - my English is not good.