~dobey/unity8/fix-cross

« back to all changes in this revision

Viewing changes to qml/Dash/GenericScopeView.qml

  • Committer: Rodney Dawes
  • Date: 2014-12-19 15:38:10 UTC
  • mfrom: (1263.1.256 unity8)
  • Revision ID: rodney.dawes@canonical.com-20141219153810-40tiwfea7eeotril
[ Ubuntu daily release ]
* New rebuild forced
[ Albert Astals ]
* Need to wait until loaded is true to use the count property
* Manage Dash: Ellide properly
[ Albert Astals Cid ]
* ScopesList: Use the default scope style for the header
[ Daniel d'Andrada ]
* Refactor Dialogs.qml to use proper in-scene dialogs
* Make Greeter nicely handle being resized
[ Albert Astals ]
* Rework how we set the ranges so we get some more asynchronousity
  from item views (LP: #1384374)
* clickscope is back to being unfavoritable (LP: #1400762)
* Fix clicking on the manage dash list after having moved the current
  scope
* Make the drag range be a multiple of the drag "rate" value.
  Workarounds https://bugs.launchpad.net/mir/+bug/1399690
[ Gerry Boland ]
* MockAppMan: emit SIGSTOP so AP test apps are run (LP: #1394208)
[ Ubuntu daily release ]
* New rebuild forced
[ Albert Astals ]
* Make Navigation work when "jumping" to the non root
[ Michał Sawicz ]
* Bump version due to new Manage Dash
[ Gerry Boland ]
* [indicators] Fix positioning on panel resize.
[ Nick Dedekind ]
* [indicators] Fix positioning on panel resize.
[ Albert Astals ]
* Fix the Dash Header hamburger menu background color
* Fix tests (LP: #1400449)
* Allow pulling manage dash if there's no favorite scopes (LP:
  #1400774)
* Manage Dash: Make store button work even if you have no favorites
  (LP: #1400771)
* Make pot_file
[ CI Train Bot ]
* Resync trunk
[ Andrea Cimitan ]
* Remove dismiss timer in Launcher (LP: #1368778)
[ Michael Zanetti ]
* decrease opacity changes in spread, move it to a separate surface.
* Add an initial, rudimentary DesktopStage to get started
* Uninvert Launcher in Desktop Mode
* Add support for Wallpaper in Desktop stage
* Add window control buttons to panel for fullscreen applications
[ Rodney Dawes ]
* Add dependency on gir1.2-notify-0.7 to unity8-autopilot package.
  (LP: #1400437)
[ CI Train Bot ]
* Resync trunk
[ Albert Astals ]
* Replace Scopes Overview by the new Manage Dash (LP: #1386698,
  #1368670)
[ Michael Terry ]
* Import wizard code from ubuntu-system-settings.
* Convert the welcome wizard from a separate executable into a qml
  plugin (with a small C++ plugin for support).
* Add tests for welcome wizard.
[ Michael Terry ]
* Make sure that there is no window of opportunity for swiping away
  greeter before the lockscreen appears.
* Don't allow dragging the greeter out from the left edge if it's
  hidden there. (LP: #1372952)
[ Michał Sawicz ]
* Move from Theme colour to direct UbuntuColors.orange for activity
  indicator and preview buttons
[ Albert Astals ]
* Use QImageReader not to load the image into memory twice (LP:
  #1384374)
* Don't create the whole current scope delegates, just height * 3 (LP:
  #1384393, #1384374)
* Make CroppedImageSizer async
* Use ubuntu::connectivity::NetworkingStatus instead of
  QNetworkConfigurationManager
* Compile with Qt 5.4 (LP: #1395636)
[ Michael Zanetti ]
* close previews and temp scopes on left edge/BFB (LP: #1391798)
* make spread reversible (LP: #1368668, #1355284, #1368677)
[ Andrea Cimitan ]
* Different drag behaviour for not closable apps in spread (LP:
  #1368287)
[ Daniel d'Andrada ]
* Make UnityTestCase.touchFlick properly map event coordinates
[ Michael Zanetti ]
* improve snapping after dragging
* Make the launcher BFB rounded on one end (LP: #1382596)
* disable swipeToClose while some snapping is happening (LP: #1378938)
* increase threshold and avoid jumping in SpreadDelegate dragging (LP:
  #1352842, #1350803)
[ Ying-Chun Liu ]
* Notifications should be on right side when wide. (LP: 1379384) (LP:
  #1379384)
[ Albert Astals ]
* Fix qml warnings
* Fix some qmluitests
[ Lars Uebernickel ]
* Use Icon instead of StatusIcon
[ josharenson ]
* Return focus to the application after a tusted session overlay is
  closing. (LP: #1381292)
[ Josh Arenson ]
* Return focus to the application after a tusted session overlay is
  closing. (LP: #1381292)
[ Albert Astals ]
* Remove unused ResponsiveFlowView
* Fix a few cmake warnings when running ./build.sh in a clean checkout
[ Mirco Müller ]
* Make sure non-square icons are not cropped. (LP: #1378417)
[ Michael Terry ]
* Drop the "EARLY ALPHA" scare label when running in testing mode.
[ Michael Zanetti ]
* unify Greeter and Lockscreen wallpaper again
* hide quicklist when launcher hides (LP: #1387088)
* Keep applications suspended while lockscreen is shown (LP: #1378126)
* change spread background color to 111111
[ Omer Akram ]
* show password when tapped on the 'Show password' label, not just the
  checkbox. (LP: #1389832)
* No-change rebuild against Qt 5.3.2.
[ Michael Terry ]
* Skip second SIM unlock dialog if user presses Emergency Call on
  first one (LP: #1387925)
[ Michael Zanetti ]
* fix positive/negative answer order on the new swipe notification
  (LP: #1358343)
* Update PageHeader to use new SDK api
* antialias surfaces when in spread (LP: #1351559)
[ Albert Astals ]
* Remove Hud
[ Mirco Müller ]
* Replace ComboButton in snap-decision notifications, used for
  additional actions (> 3 actions), with custom widget immune to
  accidental taps. (LP: #1384730)
[ Sebastien Bacher ]
* Drop workaround, it's not needed and create issues for desktop-next
  (LP: #1387671)
[ Albert Astals ]
* Do not append integer to char *
* Remove unused end() function
* Update build.sh
* Fix i18n
[ Michael Zanetti ]
* rework launcher quicklist visuals to fit new design (LP: #1368660)
* Fix DBusVariant conversion for launcher emblems (LP: #1387261)
* Fix desktop file encoding in launcher (LP: #1387083)
* Add a hinting animation to indicate changes in the backend (LP:
  #1376707)
[ Alberto Aguirre ]
* Add audioRole to QtMultimedia mock
* Add a plugin to take screenshots on vol up + vol down
[ CI bot ]
* Fix relative time formatter when using non-UTC timezone. (LP:
  #1378821)
[ Leo Arias ]
* Removed the tests for the alternate paths of the autopilot helpers.
[ Nick Dedekind ]
* Fix relative time formatter when using non-UTC timezone. (LP:
  #1378821)
* Reset current item selection on deleted. (LP: #1378462)
* Added timer to re-assert server value after indicator menu item
  activation. (LP: #1336715)
[ Mirco Müller ]
* Added dedicated swipe-to-act button for snap-decisions, which avoids
  accidental taps/button-presses. (LP: #1358343)
[ Chris Gagnon ]
* add missing unity-scope-click dependancy to unity8-autopilot package
  (LP: #1336276)
[ Michael Terry ]
* Don't lock phone if user tries to switch back to an active call.
  (LP: #1388156)
[ Daniel d'Andrada ]
* DirectionalDragArea: Update TODO comment in light of new events
* TouchDispatcher: synthesize MouseButtonDblClick events
[ Leonardo Arias Fonseca ]
* Removed the tests for the alternate paths of the autopilot helpers.
[ Michael Terry ]
* Provide 'passphrase' as a field of Components.Lockscreen
* Fix a race between Qml loading and DBus registration that caused
  problems when jenkins tried to unlock the phone.
* Set domain explicitly for the Dialogs component because the welcome
  wizard wants to import it. (LP: #1381731)
* When greeter or lockscreen has focus, show active call panel. (LP:
  #1378872)
[ Ted Gould ]
* Set the default OOM score for the dash (LP: #1379786)
[ Michał Sawicz ]
* Revert lp:~unity-team/unity8/flickables-speed-workaround to avoid
  risk in RTM.
* Updated behaviour for zoomable image, workaround for sourcesize (LP:
  #1333187)
[ Michael Frey ]
* Added a check for Proximity to determine if we show the lock screen.
  (LP: #1378012)
[ Ying-Chun Liu ]
* Add non-interactive code into GenericScopeView. (LP: #1384441)
[ Mirco Müller ]
* Also use modal nature of snap-decision notifications when
  greeter/lockscreen is shown. This fixes LP: #1378827. (LP: #1378827)
[ Michael Zanetti ]
* Make the launcher update on dconf changes (LP: #1376707)
* exit spread on background tap (LP: #1368261)
* Use an index instead of a scope id in DashCommunicator (LP:
  #1376044)
[ Andrea Cimitan ]
* Updated behaviour for zoomable image, workaround for sourcesize (LP:
  #1333187)
[ Daniel d'Andrada ]
* Make TouchGate synthesize QMouseEvents for mouse-based target items
* Don't specify a distanceThreshold as it conflicts with
  hintDisplacment
[ josharenson ]
* Fix lp:1370240 by making stages interactive when a snap decision is
  dismissed. (LP: #1370240)
[ Nick Dedekind ]
* remove qml ownership confusion for caching unitymenumodels (LP:
  #1368856)
* Implementation of expandable panel design (LP: #1368856)
[ Albert Astals ]
* CardAttributes: Specify column and row since the gridlayout gets
  confused sometimes (LP: #1381092)
* Reset VerticalJournal until the cardTool settles (LP: #1381255)
[ Mirco Müller ]
* Added synchronous/confirmation notification support to unity8. (LP:
  #1232633)
[ Michael Zanetti ]
* Fix lp:1370240 by making stages interactive when a snap decision is
  dismissed. (LP: #1370240)
* Drop all visual indication of "pinning" (LP: #1381054)
[ Antti Kaijanmäki ]
* Unlock all modems on boot. (LP: #1333121)
[ Michael Terry ]
* Don't show initial lockscreen during the edge demo. The user just
  set up their phone with a password, it's pointless to ask them
  again. (LP: #1358283)
* Distinguish between incoming calls and other dialer-app opens. (LP:
  #1378218) (LP: #1378218)
[ Andrea Cimitan ]
* Fix flickable speed to be resolution independent, by subclassing
  components (LP: #1348557)
[ Michał Sawicz ]
* Fix the ShellWithPin test and some functionality.
[ Albert Astals ]
* Move Base.qml to DashCategoryBase
* Fix first item positioning when m_clipItem->y() is not 0 (LP:
  #1251597)
* Fix some small qml warnings
[ Daniel d'Andrada ]
* Add touch ownership logic on top of qt input handling
[ Michał Sawicz ]
* Rename datetime indicator in test
[ Albert Astals ]
* Close overview temp scope on show dash (LP: #1373819)
* Enable QT_STRICT_ITERATORS
* Make Base not clickable, since we don't use it in anywhere clickable
  (we only use it for Category delegates in the LVWPH) (LP: #1300709)
* Hide preview if it was visible when going to a scope (LP: #1374548)
* Remove contentScale variable
[ Andrea Cimitan ]
* Fix card implicitHeight when summary is declared, but its text is
  empty. Also fixes vertical journal height and clipping (LP:
  #1362160)
* Redesign for pinned apps. Remove thindivider on top of ubuntu dash
  button (not needed anymore) (LP: #1377100)
[ Ying-Chun Liu ]
* Fix run_on_device.sh to let it run again.
[ Nick Dedekind ]
* Fixed indicator menu bindings to server toggle value broken by user
  interaction. (LP: #1336715)
* Force rendering so we don't get stuck in "waitForRendering" loop in
  tests.
[ Daniel d'Andrada ]
* PhoneStage: focus the new topmost app after the current one closes
  itself (LP: #1375267)
[ Michael Terry ]
* Fix some security issues with the tablet greeter, which allowed the
  lockscreen to be bypassed. (LP: #1367715) (LP: #1367715)
[ Michael Zanetti ]
* scale down errorText label if necessary (LP: #1378848)
[ Michael Zanetti ]
* Dual SIM pin unlocking. Hook up the UI to the backend. (LP:
  #1267135)
[ Antti Kaijanmäki ]
* Dual SIM pin unlocking. Hook up the UI to the backend. (LP:
  #1267135)
[ Ubuntu daily release ]
* New rebuild forced
[ Andrea Cimitan ]
* Tweak card header to match the spec
* Add preview image slideshow (LP: #1351537)
[ Michał Sawicz ]
* Cache more things in memory, so flicking scopes should be faster
  (LP: #1336724)
* Tweak card header to match the spec
* Save texture memory by limiting sourceSize (LP: #1338430)
[ Ying-Chun Liu ]
* Add attributes to Preview. (LP: #1282460)
[ Albert Astals ]
* Update pot
* Cache more things in memory, so flicking scopes should be faster
  (LP: #1336724)
* Save texture memory by limiting sourceSize (LP: #1338430)
* Clip the settings list
* Fix unlocking from the left again
* Add wait_ makes tests more reliable
[ Michael Zanetti ]
* fix fading out the launcher instead of sliding it out on left-edge
  minimizing an app.
* Make the DashCommunicator async and more flexible to handle a
  lifecycle-suspended dash (LP: #1339883)
[ Michael Terry ]
* Retry unlock-device script if it fails, as there is always a risk of
  a small race with boot-up. (LP: #1370644)
* Add pull-to-refresh functionality to scopes. (LP: #1368336)
[ CI bot ]
* Resync trunk
[ Alexandros Frantzis ]
* Remove stale trusted socket before starting unity8 from upstart (LP:
  #1371597) (LP: #1371597)
[ CI bot ]
* Resync trunk
[ Andrea Cimitan ]
* Move activity indicator on top of keyboard (LP: #1354519)
[ Gerry Boland ]
* Cleanup: Remove unused member and fix small syntax error in
  OrientationLock
[ josharenson ]
* Fix lp:1367894 by correcting how the minute value is calculated in
  the panel. (LP: #1367894)
[ Nick Dedekind ]
* Fixed DefaultIndicatorPage test. Fixed warnings from test.
[ Ying-Chun Liu ]
* Remove maxLineCount in preview. (LP: 1328513) (LP: #1328513)
[ Michael Terry ]
* Fix some code that accidentally landed in trunk before it got
  cleaned up. The current code just has some duplication to it that
  should be unified.
* Implement latest visual designs for passphrase lockscreen.
* Make it easier to use the Lockscreen component from the welcome
  wizard.
* Limit how much memory we reserve for the greeter background image,
  allowing giant images to appear correctly.
[ Daniel d'Andrada ]
* Add gdbTestComponentName build targets
[ CI bot ]
* Resync trunk
[ Nick Dedekind ]
* Visual changes for indicator RTM polishing (LP: #1329289)
[ Ubuntu daily release ]
* New rebuild forced
[ Michael Zanetti ]
* fix swiping away the launcher from the left edge
* fix indicators AP test
[ Florian Boucault ]
* New Splash screen implementation that fakes real app
[ Albert Astals ]
* We need this in build-depends so that qmluitests pass in CI
[ Daniel d'Andrada ]
* New Splash screen implementation that fakes real app
[ Michael Terry ]
* Fix LC_ALL and test harder by making both manual runs of
  timeformattertest and the whole test suite use the same locale
  settings.
[ CI bot ]
* Resync trunk
[ Michał Sawicz ]
* Add -windowgeometry option to the Dash and drop any user-visible
  mentions of Dash
* Dash: Fix issue when expanding a category and collapsing another one
  at the same time.
[ Albert Astals ]
* Dash: Fix issue when expanding a category and collapsing another one
  at the same time.
* Make the categoryView invisible when we are in the preview mode (LP:
  #1341205)
* Pixel pushing in the dash header (LP: #1365929)
[ Ying-Chun Liu ]
* Re-add restart button for power menu. (LP: 1358197) (LP: #1358197)
[ Marcus Tomlinson ]
* Don't show a preview if a null response is returned from
  scope.preview(result)
[ Mirco Müller ]
* Don't limit the number of text-lines for body-text. (LP: #1369438)
[ Michael Zanetti ]
* Don't hide launcher when nothing happens on long left edge swipes
  (LP: #1357333)
* Rework LauncherBackend
[ Michael Terry ]
* When running qmluitests, make sure that they use LANGUAGE=C, fixing
  a test failure when running locally in the US.
[ Daniel d'Andrada ]
* Some ApplicationWindow test improvements
[ Rodney Dawes ]
* Check purchase state to determine if purchase was cancelled and hide
  progress. (LP: #1362622)
[ Michael Zanetti ]
* Focus first app if there are already some running when we're
  starting up (LP: #1339883)
[ Michał Sawicz ]
* Don't play empty urls in Notification.qml
[ Daniel d'Andrada ]
* Improve tst_Shell
* Build without any warnings
* Make tst_Card work from outside the source tree (LP:1359201) (LP:
  #1359201)

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 */
16
16
 
17
17
import QtQuick 2.0
18
 
import Ubuntu.Components 0.1
 
18
import Ubuntu.Components 1.1
19
19
import Utils 0.1
20
20
import Unity 0.2
21
21
import Dash 0.1
26
26
    id: scopeView
27
27
 
28
28
    readonly property bool navigationShown: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].openList : false
 
29
    property bool forceNonInteractive: false
29
30
    property var scope: null
30
31
    property SortFilterProxyModel categories: categoryFilter
31
32
    property bool isCurrent: false
37
38
    readonly property alias subPageShown: subPageLoader.subPageShown
38
39
    property int paginationCount: 0
39
40
    property int paginationIndex: 0
 
41
    property bool visibleToParent: false
40
42
    property alias pageHeaderTotallyVisible: categoryView.pageHeaderTotallyVisible
 
43
    property var holdingList: null
41
44
 
42
45
    property var scopeStyle: ScopeStyle {
43
46
        style: scope ? scope.customizations : {}
47
50
 
48
51
    signal backClicked()
49
52
 
 
53
    onScopeChanged: {
 
54
        floatingSeeLess.companionBase = null;
 
55
    }
 
56
 
50
57
    function positionAtBeginning() {
51
58
        categoryView.positionAtBeginning()
52
59
    }
66
73
            // so it's not implemented
67
74
            scope.activate(result)
68
75
        } else {
69
 
            openPreview(index, resultsModel, limitedCategoryItemCount);
 
76
            if (scope.preview(result)) {
 
77
                openPreview(index, resultsModel, limitedCategoryItemCount);
 
78
            }
70
79
        }
71
80
    }
72
81
 
73
 
    function itemPressedAndHeld(index, itemModel, resultsModel, limitedCategoryItemCount) {
 
82
    function itemPressedAndHeld(index, result, itemModel, resultsModel, limitedCategoryItemCount) {
74
83
        if (itemModel.uri.indexOf("scope://") !== 0) {
75
 
            openPreview(index, resultsModel, limitedCategoryItemCount);
 
84
            if (scope.preview(result)) {
 
85
                openPreview(index, resultsModel, limitedCategoryItemCount);
 
86
            }
76
87
        }
77
88
    }
78
89
 
140
151
    ScopeListView {
141
152
        id: categoryView
142
153
        objectName: "categoryListView"
 
154
        interactive: !forceNonInteractive
143
155
 
144
156
        x: subPageLoader.open ? -width : 0
 
157
        visible: x != -width
145
158
        Behavior on x { UbuntuNumberAnimation { } }
146
159
        width: parent.width
147
160
        height: floatingSeeLess.visible ? parent.height - floatingSeeLess.height + floatingSeeLess.yOffset
152
165
        forceNoClip: subPageLoader.open
153
166
        pixelAligned: true
154
167
 
155
 
        property Item expandedCategoryItem: null
 
168
        property string expandedCategoryId: ""
 
169
        property int runMaximizeAfterSizeChanges: 0
156
170
 
157
171
        readonly property bool pageHeaderTotallyVisible: scopeView.showPageHeader &&
158
172
            ((headerItemShownHeight == 0 && categoryView.contentY <= categoryView.originY) || (headerItemShownHeight == pageHeaderLoader.item.height))
159
173
 
160
 
        delegate: ListItems.Base {
 
174
        onExpandedCategoryIdChanged: {
 
175
            var firstCreated = firstCreatedIndex();
 
176
            var shrinkingAny = false;
 
177
            var shrinkHeightDifference = 0;
 
178
            for (var i = 0; i < createdItemCount(); ++i) {
 
179
                var baseItem = item(firstCreated + i);
 
180
                if (baseItem.expandable) {
 
181
                    var shouldExpand = baseItem.category === expandedCategoryId;
 
182
                    if (shouldExpand != baseItem.expanded) {
 
183
                        var animate = false;
 
184
                        if (!subPageLoader.open) {
 
185
                            var animateShrinking = !shouldExpand && baseItem.y + baseItem.item.collapsedHeight + baseItem.seeAllButton.height < categoryView.height;
 
186
                            var animateGrowing = shouldExpand && baseItem.y + baseItem.height < categoryView.height;
 
187
                            animate = shrinkingAny || animateShrinking || animateGrowing;
 
188
                        }
 
189
 
 
190
                        if (!shouldExpand) {
 
191
                            shrinkingAny = true;
 
192
                            shrinkHeightDifference = baseItem.item.expandedHeight - baseItem.item.collapsedHeight;
 
193
                        }
 
194
 
 
195
                        if (shouldExpand && !subPageLoader.open) {
 
196
                            if (!shrinkingAny) {
 
197
                                categoryView.maximizeVisibleArea(firstCreated + i, baseItem.item.expandedHeight + baseItem.seeAllButton.height);
 
198
                            } else {
 
199
                                // If the space that shrinking is smaller than the one we need to grow we'll call maximizeVisibleArea
 
200
                                // after the shrink/grow animation ends
 
201
                                var growHeightDifference = baseItem.item.expandedHeight - baseItem.item.collapsedHeight;
 
202
                                if (growHeightDifference > shrinkHeightDifference) {
 
203
                                    runMaximizeAfterSizeChanges = 2;
 
204
                                } else {
 
205
                                    runMaximizeAfterSizeChanges = 0;
 
206
                                }
 
207
                            }
 
208
                        }
 
209
 
 
210
                        baseItem.expand(shouldExpand, animate);
 
211
                    }
 
212
                }
 
213
            }
 
214
        }
 
215
 
 
216
        delegate: DashCategoryBase {
161
217
            id: baseItem
162
218
            objectName: "dashCategory" + category
163
 
            highlightWhenPressed: false
164
 
            showDivider: false
165
219
 
166
220
            property Item seeAllButton: seeAll
167
221
 
184
238
            CardTool {
185
239
                id: cardTool
186
240
                objectName: "cardTool"
187
 
                count: results.count
 
241
                count: results ? results.count : 0
188
242
                template: model.renderer
189
243
                components: model.components
190
244
                viewWidth: parent.width
194
248
                // This can happen with the VJ that doesn't know how height it will be on creation
195
249
                // so doesn't set expandable until a bit too late for onLoaded
196
250
                if (expandable) {
197
 
                    var shouldExpand = baseItem === categoryView.expandedCategoryItem;
 
251
                    var shouldExpand = baseItem.category === categoryView.expandedCategoryId;
198
252
                    baseItem.expand(shouldExpand, false /*animate*/);
199
253
                }
200
254
            }
201
255
 
202
 
            onHeightChanged: rendererLoader.updateDelegateCreationRange();
203
 
            onYChanged: rendererLoader.updateDelegateCreationRange();
 
256
            onHeightChanged: rendererLoader.updateRanges();
 
257
            onYChanged: rendererLoader.updateRanges();
204
258
 
205
259
            Loader {
206
260
                id: rendererLoader
215
269
                    id: heightBehaviour
216
270
                    enabled: false
217
271
                    animation: UbuntuNumberAnimation {
 
272
                        duration: UbuntuAnimation.FastDuration
218
273
                        onRunningChanged: {
219
274
                            if (!running) {
220
275
                                heightBehaviour.enabled = false
 
276
                                if (categoryView.runMaximizeAfterSizeChanges > 0) {
 
277
                                    categoryView.runMaximizeAfterSizeChanges--;
 
278
                                    if (categoryView.runMaximizeAfterSizeChanges == 0) {
 
279
                                        var firstCreated = categoryView.firstCreatedIndex();
 
280
                                        for (var i = 0; i < categoryView.createdItemCount(); ++i) {
 
281
                                            var baseItem = categoryView.item(firstCreated + i);
 
282
                                            if (baseItem.category === categoryView.expandedCategoryId) {
 
283
                                                categoryView.maximizeVisibleArea(firstCreated + i, baseItem.item.expandedHeight + baseItem.seeAllButton.height);
 
284
                                                break;
 
285
                                            }
 
286
                                        }
 
287
                                    }
 
288
                                }
221
289
                            }
222
290
                        }
223
291
                    }
245
313
                    item.objectName = Qt.binding(function() { return categoryId })
246
314
                    item.scopeStyle = scopeView.scopeStyle;
247
315
                    if (baseItem.expandable) {
248
 
                        var shouldExpand = baseItem === categoryView.expandedCategoryItem;
 
316
                        var shouldExpand = baseItem.category === categoryView.expandedCategoryId;
249
317
                        baseItem.expand(shouldExpand, false /*animate*/);
250
318
                    }
251
 
                    updateDelegateCreationRange();
 
319
                    updateRanges();
252
320
                    if (scope && scope.id === "clickscope" && (categoryId === "predefined" || categoryId === "local")) {
253
321
                        // Yeah, hackish :/
254
322
                        cardTool.artShapeSize = Qt.size(units.gu(8), units.gu(7.5));
269
337
                    }
270
338
 
271
339
                    onPressAndHold: {
272
 
                        scopeView.itemPressedAndHeld(index, itemModel, target.model, categoryItemCount());
 
340
                        scopeView.itemPressedAndHeld(index, result, itemModel, target.model, categoryItemCount());
273
341
                    }
274
342
 
275
343
                    function categoryItemCount() {
282
350
                }
283
351
                Connections {
284
352
                    target: categoryView
285
 
                    onExpandedCategoryItemChanged: {
286
 
                        collapseAllButExpandedCategory();
287
 
                    }
288
 
                    function collapseAllButExpandedCategory() {
289
 
                        var item = rendererLoader.item;
290
 
                        if (baseItem.expandable) {
291
 
                            var shouldExpand = baseItem === categoryView.expandedCategoryItem;
292
 
                            if (shouldExpand != baseItem.expanded) {
293
 
                                // If the filter animation will be seen start it, otherwise, just flip the switch
294
 
                                var shrinkingVisible = !shouldExpand && y + item.collapsedHeight + seeAll.height < categoryView.height;
295
 
                                var growingVisible = shouldExpand && y + height < categoryView.height;
296
 
                                if (!subPageLoader.open || shouldExpand) {
297
 
                                    var animate = shrinkingVisible || growingVisible;
298
 
                                    baseItem.expand(shouldExpand, animate)
299
 
                                    if (shouldExpand && !subPageLoader.open) {
300
 
                                        categoryView.maximizeVisibleArea(index, item.expandedHeight + seeAll.height);
301
 
                                    }
302
 
                                }
303
 
                            }
304
 
                        }
305
 
                    }
306
 
                    onOriginYChanged: rendererLoader.updateDelegateCreationRange();
307
 
                    onContentYChanged: rendererLoader.updateDelegateCreationRange();
308
 
                    onHeightChanged: rendererLoader.updateDelegateCreationRange();
309
 
                    onContentHeightChanged: rendererLoader.updateDelegateCreationRange();
310
 
                }
311
 
 
312
 
                function updateDelegateCreationRange() {
 
353
                    onOriginYChanged: rendererLoader.updateRanges();
 
354
                    onContentYChanged: rendererLoader.updateRanges();
 
355
                    onHeightChanged: rendererLoader.updateRanges();
 
356
                    onContentHeightChanged: rendererLoader.updateRanges();
 
357
                }
 
358
                Connections {
 
359
                    target: scopeView
 
360
                    onIsCurrentChanged: rendererLoader.updateRanges();
 
361
                    onVisibleToParentChanged: rendererLoader.updateRanges();
 
362
                }
 
363
                Connections {
 
364
                    target: holdingList
 
365
                    onMovingChanged: if (!moving) rendererLoader.updateRanges();
 
366
                }
 
367
 
 
368
                function updateRanges() {
 
369
                    // Don't want to create stress by requesting more items during scope
 
370
                    // changes so unless you're not part of the visible scopes just return
 
371
                    if (holdingList && holdingList.moving && !scopeView.visibleToParent) {
 
372
                        return;
 
373
                    }
 
374
 
313
375
                    if (categoryView.moving) {
314
376
                        // Do not update the range if we are overshooting up or down, since we'll come back
315
377
                        // to the stable position and delete/create items without any reason
322
384
                    }
323
385
 
324
386
                    if (item && item.hasOwnProperty("displayMarginBeginning")) {
325
 
                        // TODO do we need item.originY here, test 1300302 once we have a silo
326
 
                        // and we can run it on the phone
327
 
                        if (baseItem.y + baseItem.height <= 0) {
328
 
                            // Not visible (item at top of the list viewport)
329
 
                            item.displayMarginBeginning = -baseItem.height;
330
 
                            item.displayMarginEnd = 0;
331
 
                        } else if (baseItem.y >= categoryView.height) {
332
 
                            // Not visible (item at bottom of the list viewport)
333
 
                            item.displayMarginBeginning = 0;
334
 
                            item.displayMarginEnd = -baseItem.height;
 
387
                        // A item view creates its delegates synchronously from
 
388
                        //     -displayMarginBeginning
 
389
                        // to
 
390
                        //     height + displayMarginEnd
 
391
                        // Around that area it adds the cacheBuffer area where delegates are created async
 
392
                        //
 
393
                        // We adjust displayMarginBeginning and displayMarginEnd so
 
394
                        //   * In non visible scopes nothing is considered visible and we set cacheBuffer
 
395
                        //     so that creates the items that would be in the viewport asynchronously
 
396
                        //   * For the current scope set the visible range to the viewport and then
 
397
                        //     use cacheBuffer to create extra items for categoryView.height * 1.5
 
398
                        //     to make scrolling nicer by mantaining a higher number of
 
399
                        //     cached items
 
400
                        //   * For non current but visible scopes (i.e. when the user changes from one scope
 
401
                        //     to the next, we set the visible range to the viewport so
 
402
                        //     items are not culled (invisible) but still use no cacheBuffer
 
403
                        //     (it will be set once the scope is the current one)
 
404
                        var displayMarginBeginning = baseItem.y;
 
405
                        displayMarginBeginning = -Math.max(-displayMarginBeginning, 0);
 
406
                        displayMarginBeginning = -Math.min(-displayMarginBeginning, baseItem.height);
 
407
                        displayMarginBeginning = Math.round(displayMarginBeginning);
 
408
                        var displayMarginEnd = -baseItem.height + seeAll.height + categoryView.height - baseItem.y;
 
409
                        displayMarginEnd = -Math.max(-displayMarginEnd, 0);
 
410
                        displayMarginEnd = -Math.min(-displayMarginEnd, baseItem.height);
 
411
                        displayMarginEnd = Math.round(displayMarginEnd);
 
412
                        if (scopeView.isCurrent || scopeView.visibleToParent) {
 
413
                            item.displayMarginBeginning = displayMarginBeginning;
 
414
                            item.displayMarginEnd = displayMarginEnd;
 
415
                            item.cacheBuffer = scopeView.isCurrent ? categoryView.height * 1.5 : 0;
335
416
                        } else {
336
 
                            item.displayMarginBeginning = -Math.max(-baseItem.y, 0);
337
 
                            item.displayMarginEnd = -Math.max(baseItem.height - seeAll.height
338
 
                                                              - categoryView.height + baseItem.y, 0)
 
417
                            var visibleRange = baseItem.height + displayMarginEnd + displayMarginBeginning;
 
418
                            if (visibleRange < 0) {
 
419
                                item.displayMarginBeginning = displayMarginBeginning;
 
420
                                item.displayMarginEnd = displayMarginEnd;
 
421
                                item.cacheBuffer = 0;
 
422
                            } else {
 
423
                                // This should be visibleRange/2 in each of the properties
 
424
                                // but some item views still (like GridView) like creating sync delegates even if
 
425
                                // the visible range is 0 so let's make sure the visible range is negative
 
426
                                item.displayMarginBeginning = displayMarginBeginning - visibleRange;
 
427
                                item.displayMarginEnd = displayMarginEnd - visibleRange;
 
428
                                item.cacheBuffer = visibleRange;
 
429
                            }
339
430
                        }
340
431
                    }
341
432
                }
349
440
                    left: parent.left
350
441
                    right: parent.right
351
442
                }
352
 
                height: seeAllLabel.visible ? seeAllLabel.font.pixelSize + units.gu(4) : 0
 
443
                height: baseItem.expandable && !baseItem.headerLink ? seeAllLabel.font.pixelSize + units.gu(4) : 0
 
444
                visible: height != 0
353
445
 
354
446
                onClicked: {
355
 
                    if (categoryView.expandedCategoryItem !== baseItem) {
356
 
                        categoryView.expandedCategoryItem = baseItem;
 
447
                    if (categoryView.expandedCategoryId !== baseItem.category) {
 
448
                        categoryView.expandedCategoryId = baseItem.category;
 
449
                        floatingSeeLess.companionBase = baseItem;
357
450
                    } else {
358
 
                        categoryView.expandedCategoryItem = null;
 
451
                        categoryView.expandedCategoryId = "";
359
452
                    }
360
453
                }
361
454
 
369
462
                    fontSize: "small"
370
463
                    font.weight: Font.Bold
371
464
                    color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
372
 
                    visible: baseItem.expandable && !baseItem.headerLink
373
465
                }
374
466
            }
375
467
 
450
542
        }
451
543
    }
452
544
 
 
545
    Item {
 
546
        id: pullToRefreshClippingItem
 
547
        anchors.left: parent.left
 
548
        anchors.right: parent.right
 
549
        anchors.bottom: parent.bottom
 
550
        height: parent.height - pullToRefresh.contentY + (pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].height - pageHeaderLoader.item.height : 0)
 
551
        clip: true
 
552
 
 
553
        PullToRefresh {
 
554
            id: pullToRefresh
 
555
            objectName: "pullToRefresh"
 
556
            target: categoryView
 
557
 
 
558
            readonly property real contentY: categoryView.contentY - categoryView.originY
 
559
            y: -contentY - units.gu(5)
 
560
 
 
561
            onRefresh: {
 
562
                refreshing = true
 
563
                scopeView.scope.refresh()
 
564
            }
 
565
            anchors.left: parent.left
 
566
            anchors.right: parent.right
 
567
 
 
568
            Connections {
 
569
                target: scopeView
 
570
                onProcessingChanged: if (!scopeView.processing) pullToRefresh.refreshing = false
 
571
            }
 
572
 
 
573
            style: PullToRefreshScopeStyle {
 
574
                anchors.fill: parent
 
575
                activationThreshold: units.gu(14)
 
576
            }
 
577
        }
 
578
    }
 
579
 
453
580
    AbstractButton {
454
581
        id: floatingSeeLess
455
582
        objectName: "floatingSeeLess"
456
583
 
457
584
        property Item companionTo: companionBase ? companionBase.seeAllButton : null
458
 
        property Item companionBase: categoryView.expandedCategoryItem
 
585
        property Item companionBase: null
459
586
        property bool showBecausePosition: false
460
587
        property real yOffset: 0
461
588
 
467
594
        height: seeLessLabel.font.pixelSize + units.gu(4)
468
595
        visible: companionTo && showBecausePosition
469
596
 
470
 
        onClicked: categoryView.expandedCategoryItem = null;
 
597
        onClicked: categoryView.expandedCategoryId = "";
471
598
 
472
599
        function updateVisibility() {
473
600
            var companionPos = companionTo.mapToItem(floatingSeeLess, 0, 0);
476
603
            var posToBase = floatingSeeLess.mapToItem(companionBase, 0, -yOffset).y;
477
604
            yOffset = Math.max(0, companionBase.item.collapsedHeight - posToBase);
478
605
            yOffset = Math.min(yOffset, height);
 
606
 
 
607
            if (!showBecausePosition && categoryView.expandedCategoryId === "") {
 
608
                companionBase = null;
 
609
            }
479
610
        }
480
611
 
481
612
        Label {