This file is indexed.

/usr/share/unity8/Components/Carousel.qml is in unity8-common 8.12+16.04.20160401-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/*
 * Copyright (C) 2013-2015 Canonical, Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import QtQuick 2.4
import Ubuntu.Components 1.3
import "carousel.js" as CarouselJS

/*! The Carousel component presents the items of a model in a carousel view. It's similar to a
    cover flow. But it stops at it's boundaries (therefore no PathView is used).
  */
Item {
    id: carousel

    clip: true // Don't leak horizontally to other dashes

    /// The component to be used as delegate. This component has to be derived from BaseCarouselDelegate
    property Component itemComponent
    /// Model for the Carousel, which has to be a model usable by a ListView
    property alias model: listView.model
    /// A minimal width of a tile can be set here. Per default a best fit will be calculated
    property alias minimumTileWidth: listView.minimumTileWidth
    /// Sets the number of tiles that are visible
    property alias pathItemCount: listView.pathItemCount
    /// Aspect ratio of the tiles width/height
    property alias tileAspectRatio: listView.tileAspectRatio
    /// Used to cache some delegates for performance reasons. See the ListView documentation for details
    property alias cacheBuffer: listView.cacheBuffer
    property alias displayMarginBeginning: listView.displayMarginBeginning
    property alias displayMarginEnd: listView.displayMarginEnd
    /// Width of the "draw buffer" in pixel. The drawBuffer is an additional area at start/end where
    /// items drawn, even if it is not in the visible area.
    /// cacheBuffer controls only the to retain delegates outside the visible area (and is used on top of the drawBuffer)
    /// see https://bugreports.qt-project.org/browse/QTBUG-29173
    property int drawBuffer: width / pathItemCount // an "ok" value - but values used from the listView cause loops
    /// The selected item can be shown in a different size controlled by selectedItemScaleFactor
    property real selectedItemScaleFactor: 1.1
    /// The extra margin at the bottom
    property real extraBottomMargin: 0
    /// The index of the item that should be highlighted
    property alias highlightIndex: listView.highlightIndex
    /// exposes the delegate of the currentItem
    readonly property alias currentItem: listView.currentItem
    /// exposes the distance to the next row (only one row in carousel, so it's the topMargins)
    readonly property alias verticalSpacing: listView.verticalMargin
    /// the width of the internal list
    readonly property alias innerWidth: listView.width

    implicitHeight: listView.tileHeight * selectedItemScaleFactor
    opacity: listView.highlightIndex === -1 ? 1 : 0.6

    /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
       One drawback is, that more delegates have to be drawn than usually. As some items are moved from the
       invisible to the visible area. Setting the cacheBuffer does not fix this.
       See https://bugreports.qt-project.org/browse/QTBUG-29173
       Therefore the ListView has negative left and right anchors margins, and in addition a header
       and footer item to compensate that.

       The scaling of the items is controlled by the variable continuousIndex, described below. */
    ListView {
        id: listView
        objectName: "listView"

        property int highlightIndex: -1
        property real minimumTileWidth: 0
        property real newContentX: disabledNewContentX
        property real pathItemCount: referenceWidth / referenceTileWidth
        property real tileAspectRatio: 1

        /* The positioning and scaling of the items in the carousel is based on the variable
           'continuousIndex', a continuous real variable between [0, 'carousel.model.count'],
           roughly representing the index of the item that is prioritised over the others.
           'continuousIndex' is not linear, but is weighted depending on if it is close
           to the beginning of the content (beginning phase), in the middle (middle phase)
           or at the end (end phase).
           Each tile is scaled and transformed in proportion to the difference between
           its own index and continuousIndex.
           To efficiently calculate continuousIndex, we have these values:
            - 'gapToMiddlePhase' gap in pixels between beginning and middle phase
            - 'gapToEndPhase' gap in pixels between middle and end phase
            - 'kGapEnd' constant used to calculate 'continuousIndex' in end phase
            - 'kMiddleIndex' constant used to calculate 'continuousIndex' in middle phase
            - 'kXBeginningEnd' constant used to calculate 'continuousIndex' in beginning and end phase
            - 'realContentWidth' the width of all the delegates only (without header/footer)
            - 'realContentX' the 'contentX' of the listview ignoring the 'drawBuffer'
            - 'realWidth' the 'width' of the listview, as it is used as component. */

        readonly property real gapToMiddlePhase: Math.min(realWidth / 2 - tileWidth / 2, (realContentWidth - realWidth) / 2)
        readonly property real gapToEndPhase: realContentWidth - realWidth - gapToMiddlePhase
        readonly property real kGapEnd: kMiddleIndex * (1 - gapToEndPhase / gapToMiddlePhase)
        readonly property real kMiddleIndex: (realWidth / 2) / tileWidth - 0.5
        readonly property real kXBeginningEnd: 1 / tileWidth + kMiddleIndex / gapToMiddlePhase
        readonly property real maximumItemTranslation: (listView.tileWidth * 3) / listView.scaleFactor
        readonly property real disabledNewContentX: -carousel.drawBuffer - 1
        readonly property real realContentWidth: contentWidth - 2 * carousel.drawBuffer
        readonly property real realContentX: contentX + carousel.drawBuffer
        readonly property real realPathItemCount: Math.min(realWidth / tileWidth, pathItemCount)
        readonly property real realWidth: carousel.width
        readonly property real referenceGapToMiddlePhase: realWidth / 2 - tileWidth / 2
        readonly property real referencePathItemCount: referenceWidth / referenceTileWidth
        readonly property real referenceWidth: 848
        readonly property real referenceTileWidth: 175
        readonly property real scaleFactor: tileWidth / referenceTileWidth
        readonly property real tileWidth: Math.max(realWidth / pathItemCount, minimumTileWidth)
        readonly property real tileHeight: tileWidth / tileAspectRatio
        readonly property real translationXViewFactor: 0.2 * (referenceGapToMiddlePhase / gapToMiddlePhase)
        readonly property real verticalMargin: (parent.height - tileHeight - carousel.extraBottomMargin) / 2
        readonly property real visibleTilesScaleFactor: realPathItemCount / referencePathItemCount

        anchors {
            fill: parent
            topMargin: verticalMargin
            bottomMargin: verticalMargin + carousel.extraBottomMargin
            // extending the "drawing area"
            leftMargin: -carousel.drawBuffer
            rightMargin: -carousel.drawBuffer
        }

        /* The header and footer help to "extend" the area, the listview draws items.
           This together with anchors.leftMargin and anchors.rightMargin. */
        header: Item {
            width: carousel.drawBuffer
            height: listView.tileHeight
        }
        footer: Item {
            width: carousel.drawBuffer
            height: listView.tileHeight
        }

        boundsBehavior: Flickable.DragOverBounds
        cacheBuffer: carousel.cacheBuffer
        flickDeceleration: Math.max(1500 * Math.pow(realWidth / referenceWidth, 1.5), 1500) // 1500 is platform default
        maximumFlickVelocity: Math.max(2500 * Math.pow(realWidth / referenceWidth, 1.5), 2500) // 2500 is platform default
        orientation: ListView.Horizontal

        function getXFromContinuousIndex(index) {
            return CarouselJS.getXFromContinuousIndex(index,
                                                       realWidth,
                                                       footerItem.x,
                                                       tileWidth,
                                                       gapToMiddlePhase,
                                                       gapToEndPhase,
                                                       carousel.drawBuffer)
        }

        function itemClicked(index, delegateItem) {
            listView.currentIndex = index
            var x = getXFromContinuousIndex(index);

            if (Math.abs(x - contentX) < 1 && delegateItem !== undefined) {
                /* We're clicking the selected item and
                   we're in the neighbourhood of radius 1 pixel from it.
                   Let's emit the clicked signal. */
                delegateItem.clicked()
                return
            }

            stepAnimation.stop()
            newContentXAnimation.stop()

            newContentX = x
            newContentXAnimation.start()
        }

        function itemPressAndHold(index, delegateItem) {
            var x = getXFromContinuousIndex(index);

            if (Math.abs(x - contentX) < 1 && delegateItem !== undefined) {
                /* We're pressAndHold the selected item and
                   we're in the neighbourhood of radius 1 pixel from it.
                   Let's emit the pressAndHold signal. */
                delegateItem.pressAndHold();
                return;
            }

            stepAnimation.stop();
            newContentXAnimation.stop();

            newContentX = x;
            newContentXAnimation.start();
        }

        onHighlightIndexChanged: {
            if (highlightIndex != -1) {
                itemClicked(highlightIndex)
            }
        }

        onMovementStarted: {
            stepAnimation.stop()
            newContentXAnimation.stop()
            newContentX = disabledNewContentX
        }
        onMovementEnded: {
            if (realContentX > 0)
                stepAnimation.start()
        }

        SmoothedAnimation {
            id: stepAnimation
            objectName: "stepAnimation"

            target: listView
            property: "contentX"
            to: listView.getXFromContinuousIndex(listView.selectedIndex)
            duration: 450
            velocity: 200
            easing.type: Easing.InOutQuad
        }

        SequentialAnimation {
            id: newContentXAnimation

            NumberAnimation {
                target: listView
                property: "contentX"
                from: listView.contentX
                to: listView.newContentX
                duration: 300
                easing.type: Easing.InOutQuad
            }
            ScriptAction {
                script: listView.newContentX = listView.disabledNewContentX
            }
        }

        readonly property int selectedIndex: Math.round(continuousIndex)
        readonly property real continuousIndex: CarouselJS.getContinuousIndex(listView.realContentX,
                                                                              listView.tileWidth,
                                                                              listView.gapToMiddlePhase,
                                                                              listView.gapToEndPhase,
                                                                              listView.kGapEnd,
                                                                              listView.kMiddleIndex,
                                                                              listView.kXBeginningEnd)

        property real viewTranslation: CarouselJS.getViewTranslation(listView.realContentX,
                                                                     listView.tileWidth,
                                                                     listView.gapToMiddlePhase,
                                                                     listView.gapToEndPhase,
                                                                     listView.translationXViewFactor)

        delegate: tileWidth > 0 && tileHeight > 0 ? loaderComponent : null

        Component {
            id: loaderComponent

            Loader {
                property bool explicitlyScaled: explicitScaleFactor == carousel.selectedItemScaleFactor
                property real explicitScaleFactor: explicitScale ? carousel.selectedItemScaleFactor : 1.0
                readonly property bool explicitScale: (!listView.moving ||
                                                    listView.realContentX <= 0 ||
                                                    listView.realContentX >= listView.realContentWidth - listView.realWidth) &&
                                                    listView.newContentX === listView.disabledNewContentX &&
                                                    index === listView.selectedIndex
                readonly property real cachedTiles: listView.realPathItemCount + carousel.drawBuffer / listView.tileWidth
                readonly property real distance: listView.continuousIndex - index
                readonly property real itemTranslationScale: CarouselJS.getItemScale(0.5,
                                                                                    (index + 0.5), // good approximation of scale while changing selected item
                                                                                    listView.count,
                                                                                    listView.visibleTilesScaleFactor)
                readonly property real itemScale: CarouselJS.getItemScale(distance,
                                                                        listView.continuousIndex,
                                                                        listView.count,
                                                                        listView.visibleTilesScaleFactor)
                readonly property real translationX: CarouselJS.getItemTranslation(index,
                                                                                listView.selectedIndex,
                                                                                distance,
                                                                                itemScale,
                                                                                itemTranslationScale,
                                                                                listView.maximumItemTranslation)

                readonly property real xTransform: listView.viewTranslation + translationX * listView.scaleFactor
                readonly property real center: x - listView.contentX + xTransform - drawBuffer + (width/2)

                width: listView.tileWidth
                height: listView.tileHeight
                scale: itemScale * explicitScaleFactor
                sourceComponent: itemComponent
                z: cachedTiles - Math.abs(index - listView.selectedIndex)

                transform: Translate {
                    x: xTransform
                }

                Behavior on explicitScaleFactor {
                    SequentialAnimation {
                        ScriptAction {
                            script: if (!explicitScale)
                                        explicitlyScaled = false
                        }
                        NumberAnimation {
                            duration: explicitScaleFactor === 1.0 ? 250 : 150
                            easing.type: Easing.InOutQuad
                        }
                        ScriptAction {
                            script: if (explicitScale)
                                        explicitlyScaled = true
                        }
                    }
                }

                onLoaded: {
                    item.explicitlyScaled = Qt.binding(function() { return explicitlyScaled; });
                    item.index = Qt.binding(function() { return index; });
                    item.model = Qt.binding(function() { return model; });
                }

                MouseArea {
                    id: mouseArea

                    anchors.fill: parent

                    onClicked: {
                        listView.itemClicked(index, item)
                    }

                    onPressAndHold: {
                        listView.itemPressAndHold(index, item)
                    }
                }
            }
        }
    }
}