~elopio/unity8/wait_for_category

« back to all changes in this revision

Viewing changes to Dash/GenericScopeView.qml

reset after completely messing up merging

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
ScopeView {
23
23
    id: scopeView
24
 
    readonly property alias previewShown: previewLoader.onScreen
 
24
    readonly property alias previewShown: previewListView.onScreen
25
25
 
26
26
    onIsCurrentChanged: {
27
27
        pageHeader.resetSearch();
28
 
        previewLoader.open = false;
 
28
        previewListView.open = false;
29
29
    }
30
30
 
31
31
    onMovementStarted: categoryView.showHeader()
52
52
 
53
53
    Connections {
54
54
        target: scopeView.scope
55
 
        onShowDash: previewLoader.open = false;
56
 
        onHideDash: previewLoader.open = false;
 
55
        onShowDash: previewListView.open = false;
 
56
        onHideDash: previewListView.open = false;
57
57
    }
58
58
 
59
59
    ScopeListView {
60
60
        id: categoryView
61
61
        anchors.fill: parent
62
62
        model: scopeView.categories
63
 
        forceNoClip: previewLoader.onScreen
 
63
        forceNoClip: previewListView.onScreen
64
64
 
65
65
        onAtYEndChanged: if (atYEnd) endReached()
66
66
        onMovingChanged: if (moving && atYEnd) endReached()
67
67
 
68
68
        property string expandedCategoryId: ""
 
69
        signal correctExpandedCategory();
 
70
 
 
71
        Behavior on contentY {
 
72
            enabled: previewListView.open
 
73
            UbuntuNumberAnimation {}
 
74
        }
69
75
 
70
76
        delegate: ListItems.Base {
 
77
            id: rendererDelegate
71
78
            highlightWhenPressed: false
72
79
 
73
80
            readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
104
111
                Connections {
105
112
                    target: rendererLoader.item
106
113
                    onClicked: {
 
114
                        // Prepare the preview in case activate() triggers a preview only
107
115
                        effect.positionPx = mapToItem(categoryView, 0, itemY).y
108
 
                        scopeView.scope.activate(delegateItem.model.uri,
109
 
                                                 delegateItem.model.icon,
110
 
                                                 delegateItem.model.category,
111
 
                                                 0,
112
 
                                                 delegateItem.model.mimetype,
113
 
                                                 delegateItem.model.title,
114
 
                                                 delegateItem.model.comment,
115
 
                                                 delegateItem.model.dndUri,
116
 
                                                 delegateItem.model.metadata)
 
116
                        previewListView.categoryId = categoryId
 
117
                        previewListView.categoryDelegate = rendererLoader.item
 
118
                        previewListView.model = model;
 
119
                        previewListView.init = true;
 
120
                        previewListView.currentIndex = index;
 
121
 
 
122
                        var item = model.get(index);
 
123
 
 
124
                        if ((scopeView.scope.id == "applications.scope" && categoryId == "installed")
 
125
                                || (scopeView.scope.id == "home.scope" && categoryId == "applications.scope")) {
 
126
                            scopeView.scope.activate(item.uri, item.icon, item.category, 0, item.mimetype, item.title,
 
127
                                                     item.comment, item.dndUri, item.metadata)
 
128
                        } else {
 
129
                            previewListView.open = true
 
130
 
 
131
                            scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
 
132
                                                     item.comment, item.dndUri, item.metadata)
 
133
                        }
117
134
                    }
118
135
                    onPressAndHold: {
119
136
                        effect.positionPx = mapToItem(categoryView, 0, itemY).y
120
 
                        scopeView.scope.preview( delegateItem.model.uri,
121
 
                                                 delegateItem.model.icon,
122
 
                                                 delegateItem.model.category,
123
 
                                                 0,
124
 
                                                 delegateItem.model.mimetype,
125
 
                                                 delegateItem.model.title,
126
 
                                                 delegateItem.model.comment,
127
 
                                                 delegateItem.model.dndUri,
128
 
                                                 delegateItem.model.metadata)
 
137
                        previewListView.categoryId = categoryId
 
138
                        previewListView.categoryDelegate = rendererLoader.item
 
139
                        previewListView.model = model;
 
140
                        previewListView.init = true;
 
141
                        previewListView.currentIndex = index;
 
142
                        previewListView.open = true
 
143
 
 
144
                        var item = model.get(index)
 
145
                        scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
 
146
                                                item.comment, item.dndUri, item.metadata)
129
147
                    }
130
148
                }
131
149
                Connections {
132
150
                    target: categoryView
133
151
                    onExpandedCategoryIdChanged: {
 
152
                        collapseAllButExpandedCategory();
 
153
                    }
 
154
                    onCorrectExpandedCategory: {
 
155
                        collapseAllButExpandedCategory();
 
156
                    }
 
157
                    function collapseAllButExpandedCategory() {
134
158
                        var item = rendererLoader.item;
135
159
                        if (item.expandable) {
136
160
                            var shouldFilter = categoryId != categoryView.expandedCategoryId;
138
162
                                // If the filter animation will be seen start it, otherwise, just flip the switch
139
163
                                var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
140
164
                                var growingVisible = !shouldFilter && y + height < categoryView.height;
141
 
                                if (shrinkingVisible || growingVisible) {
142
 
                                    item.startFilterAnimation(shouldFilter)
143
 
                                } else {
144
 
                                    item.filter = shouldFilter;
145
 
                                }
146
 
                                if (!shouldFilter) {
147
 
                                    categoryView.maximizeVisibleArea(index, item.uncollapsedHeight);
 
165
                                if (!previewListView.open || !shouldFilter) {
 
166
                                    if (shrinkingVisible || growingVisible) {
 
167
                                        item.startFilterAnimation(shouldFilter)
 
168
                                    } else {
 
169
                                        item.filter = shouldFilter;
 
170
                                    }
 
171
                                    if (!shouldFilter && !previewListView.open) {
 
172
                                        categoryView.maximizeVisibleArea(index, item.uncollapsedHeight);
 
173
                                    }
148
174
                                }
149
175
                            }
150
176
                        }
222
248
        topOpacity: (1 - gap * 1.2)
223
249
        bottomGapPx: positionPx + gap * (targetBottomGapPx - positionPx)
224
250
        bottomOverflow: units.gu(20)
225
 
        bottomOpacity: 1 - (gap * 0.8)
 
251
        live: true
226
252
 
227
253
        property int targetBottomGapPx: height - units.gu(8) - bottomOverflow
228
 
        property real gap: previewLoader.open ? 1.0 : 0.0
 
254
        property real gap: previewListView.open ? 1.0 : 0.0
229
255
 
230
256
        Behavior on gap {
231
257
            NumberAnimation {
232
258
                duration: 200
233
259
                easing.type: Easing.InOutQuad
234
260
                onRunningChanged: {
235
 
                    if (!previewLoader.open && !running) {
236
 
                        previewLoader.onScreen = false
 
261
                    if (!previewListView.open && !running) {
 
262
                        previewListView.onScreen = false
237
263
                    }
238
264
                }
239
265
            }
243
269
    Connections {
244
270
        target: scopeView.scope
245
271
        onPreviewReady: {
246
 
            previewLoader.previewData = preview
247
 
            previewLoader.open = true
 
272
            if (previewListView.init) {
 
273
                // Preview was triggered because of a click on the item. Need to expand now.
 
274
                if (!previewListView.open) {
 
275
                    previewListView.open = true
 
276
                }
 
277
 
 
278
                var index = previewListView.currentIndex
 
279
                previewListView.currentIndex = -1
 
280
                previewListView.currentIndex = index
 
281
                previewListView.init = false
 
282
            }
 
283
            previewListView.currentItem.previewData = preview
248
284
        }
249
285
    }
250
286
 
252
288
        id: previewDelegateMapper
253
289
    }
254
290
 
255
 
    Connections {
256
 
        ignoreUnknownSignals: true
257
 
        target: previewLoader.valid ? previewLoader.item : null
258
 
        onClose: {
259
 
            previewLoader.open = false
260
 
        }
261
 
    }
262
 
 
263
 
    Loader {
264
 
        objectName: "previewLoader"
265
 
        id: previewLoader
266
 
        property var previewData
 
291
    ListView  {
 
292
        id: previewListView
 
293
        objectName: "previewListView"
267
294
        height: effect.bottomGapPx - effect.topGapPx
268
295
        anchors {
269
296
            top: parent.top
271
298
            left: parent.left
272
299
            right: parent.right
273
300
        }
274
 
        source: onScreen ? previewDelegateMapper.map(previewLoader.previewData.rendererName) : ""
 
301
        orientation: ListView.Horizontal
 
302
        highlightRangeMode: ListView.StrictlyEnforceRange
 
303
        snapMode: ListView.SnapOneItem
 
304
        boundsBehavior: Flickable.DragAndOvershootBounds
 
305
        highlightMoveDuration: 250
 
306
        flickDeceleration: units.gu(625)
 
307
        maximumFlickVelocity: width * 5
 
308
        cacheBuffer: 0
 
309
 
 
310
        // To be set before opening the preview
 
311
        property string categoryId: ""
 
312
        property var categoryDelegate
 
313
 
 
314
        // because the ListView is built asynchronous, setting the
 
315
        // currentIndex directly won't work. We need to refresh it
 
316
        // when the first preview is ready to be displayed.
 
317
        property bool init: true
 
318
 
 
319
        // Used internally
 
320
        property int oldRow: -1
 
321
        property bool categoryWasFiltered: false
 
322
        property int initialContenY: 0
 
323
 
 
324
        onCurrentIndexChanged: {
 
325
            var row = Math.floor(currentIndex / categoryDelegate.columns);
 
326
            if (!init && model !== undefined) {
 
327
                var item = model.get(currentIndex)
 
328
                scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title, item.comment, item.dndUri, item.metadata)
 
329
                if (oldRow != -1) {
 
330
                    if (row < oldRow) {
 
331
                        categoryView.contentY -= categoryDelegate.cellHeight
 
332
                    } else if (row > oldRow){
 
333
                        categoryView.contentY += categoryDelegate.cellHeight
 
334
                    }
 
335
                }
 
336
            }
 
337
            oldRow = row;
 
338
            if (categoryDelegate.collapsedRowCount <= row) {
 
339
                categoryView.expandedCategoryId = categoryId
 
340
            }
 
341
 
 
342
            if (open) {
 
343
                categoryDelegate.highlightIndex = currentIndex
 
344
            }
 
345
        }
275
346
 
276
347
        property bool open: false
277
348
        property bool onScreen: false
278
 
        property bool valid: item !== null
279
349
 
280
350
        onOpenChanged: {
281
351
            if (open) {
282
352
                onScreen = true
283
 
            }
284
 
        }
285
 
 
286
 
        onLoaded: {
287
 
            item.previewData = Qt.binding(function() { return previewLoader.previewData })
288
 
        }
 
353
                categoryDelegate.highlightIndex = currentIndex
 
354
            } else {
 
355
                model = undefined
 
356
                categoryView.correctExpandedCategory();
 
357
                categoryDelegate.highlightIndex = -1
 
358
            }
 
359
        }
 
360
 
 
361
        Rectangle {
 
362
            anchors.fill: parent
 
363
            color: Qt.rgba(0, 0, 0, .3)
 
364
        }
 
365
 
 
366
        delegate: Loader {
 
367
            id: previewLoader
 
368
            objectName: "previewLoader"
 
369
            height: previewListView.height
 
370
            width: previewListView.width
 
371
            asynchronous: true
 
372
            source: previewListView.onScreen ?
 
373
                         (previewData !== undefined ? previewDelegateMapper.map(previewData.rendererName) : "DashPreviewPlaceholder.qml") : ""
 
374
 
 
375
            onPreviewDataChanged: {
 
376
                if (previewData !== undefined && source.toString().indexOf("DashPreviewPlaceholder.qml") != -1) {
 
377
                    previewLoader.opacity = 0;
 
378
                }
 
379
            }
 
380
 
 
381
            onSourceChanged: {
 
382
                if (previewData !== undefined) {
 
383
                    fadeIn.start()
 
384
                }
 
385
            }
 
386
 
 
387
            PropertyAnimation {
 
388
                id: fadeIn
 
389
                target: previewLoader
 
390
                property: "opacity"
 
391
                from: 0.0
 
392
                to: 1.0
 
393
                duration: UbuntuAnimation.BriskDuration
 
394
            }
 
395
 
 
396
            property var previewData
 
397
            property bool valid: item !== null
 
398
 
 
399
            onLoaded: {
 
400
                if (previewListView.onScreen && previewData !== undefined) {
 
401
                    item.previewData = Qt.binding(function() { return previewData })
 
402
                }
 
403
            }
 
404
 
 
405
            Connections {
 
406
                ignoreUnknownSignals: true
 
407
                target: item
 
408
                onClose: {
 
409
                    previewListView.open = false
 
410
                }
 
411
            }
 
412
        }
 
413
    }
 
414
 
 
415
    Image {
 
416
        anchors {
 
417
            top: previewListView.bottom
 
418
            left: parent.left
 
419
            leftMargin: previewListView.categoryDelegate.highlightCentered ?
 
420
                            (parent.width - width) / 2 :
 
421
                            (highlightColumn * cellWidth) + (-width + cellWidth + margins) / 2
 
422
            Behavior on leftMargin {
 
423
                UbuntuNumberAnimation {}
 
424
            }
 
425
        }
 
426
        height: units.gu(1)
 
427
        width: units.gu(2)
 
428
        property int columns: previewListView.categoryDelegate ? previewListView.categoryDelegate.columns : 1
 
429
        property int highlightColumn: previewListView.currentIndex % columns
 
430
        property int cellWidth: previewListView.categoryDelegate ? previewListView.categoryDelegate.cellWidth : 0
 
431
        property int margins: previewListView.categoryDelegate ? previewListView.categoryDelegate.margins : 0
 
432
        opacity: previewListView.open ? .5 : 0
 
433
 
 
434
        source: "graphics/tooltip_arrow.png"
289
435
    }
290
436
 
291
437
    // TODO: Move as InverseMouseArea to DashPreview
292
438
    MouseArea {
293
 
        enabled: previewLoader.onScreen
 
439
        enabled: previewListView.onScreen
294
440
        anchors {
295
441
            fill: parent
296
442
            topMargin: effect.bottomGapPx
297
443
        }
298
444
        onClicked: {
299
 
            previewLoader.open = false;
 
445
            previewListView.open = false;
300
446
        }
301
447
    }
302
448
}