~ubuntu-branches/ubuntu/wily/ubuntu-ui-toolkit/wily-proposed

« back to all changes in this revision

Viewing changes to modules/Ubuntu/Components/1.3/AppHeader.qml

  • Committer: Package Import Robot
  • Author(s): CI Train Bot, Florian Boucault, Loïc Molinari, Benjamin Zeller, Richard Huddie, Tim Peeters, Zsombor Egri, Timo Jyrinki, Christian Dywan, Albert Astals Cid
  • Date: 2015-07-30 13:04:18 UTC
  • mfrom: (1.1.126)
  • Revision ID: package-import@ubuntu.com-20150730130418-nxjr780u6wqcdqeh
Tags: 1.3.1584+15.10.20150730-0ubuntu1
[ Florian Boucault ]
* New BottomEdgeHint component to represent extra features available from the 
  bottom edge of an application.

[ Loïc Molinari ]
* [UbuntuShape] Added a big radius.
* [UbuntuShape] Added relative radius support. Fixes LP: #1478124.
* Ensured components, styles, examples and tests use the new UbuntuShape 
  properties (not deprecated). Fixes LP: #1437412.

[ Benjamin Zeller ]
* Make use of the official qt build macros to blend into the Qt buildprocess.
* Fix debug builds, optimization is always enabled by the system qt build.

[ Richard Huddie ]
* Fix for autopilot bug lp:1476715. Don't throw an exception if maliit-server
  is not found. Fixes LP: #1476715.

[ Tim Peeters ]
* Clean up the MainView docs.
* Set theme version for Sections component.
* Implement AdaptivePageLayout.

[ Zsombor Egri ]
* Fix width for trailing and leading actions of a ListItem. Fixes LP: #1465582.
* Button and Haptics import wrong toolkit versions, thus they break style 
  versioning. Moving Icon and ProgressBar to 1.0 and 1.1 version source folder.
* SuruDark theme for ListItem style. Fixes LP: #1451225.
* Swiping ListItem when no actions are defined for the gesture breaks 
  selectMode. Fixes LP: #1468100.
* Fixing selected connection with the ListItem's select mode checkbox state. 
  Fixes LP: #1461501, LP: #1469471.

[ Timo Jyrinki ]
* Fix ucstylehints.cpp compilation with Qt 5.5. Fixes LP: #1473873.
* Add PageHeadStyle 1.3 reference to fix install_plugins_qmltypes failure with 
  Qt 5.5. Fixes LP: #1466484.

[ Christian Dywan ]
* Avoid hard-coded skipping of members by name "type" can be a property name 
  regardless of also being a field in the JSON description of a property.
* Add apicheck unit test for QML and Javascript.
* Remove "do cleanup" comments. Fixes LP: #1369874.
* Initialize defaultTypes later to avoid bogus types.
* Implement Action.shortcut property. Fixes LP: #1202464.
* Update text handler to 3gu assert.
* Add a deprecated note to ListItems.ThinDivider. Fixes LP: #1470951.
* Don't include overridden properties in API.
* Clean-up API check wrapper scripts.
* Track version members were introduced.
* Implement ListItemPopover on right-click. Fixes LP: #1452676.
* Move delegate's chevron into the row and size it explicitly. 
  Fixes LP: #1474418.
* Enable (Shift)Tab via activeFocusOnTab. Fixes LP: #1276797.
* Only swipe with left button and block timer otherwise. 
  Fixes LP: #1476300, LP: #1476310.
* Include Javascript libraries in QML documentation. Fixes LP: #1466058.

[ Albert Astals Cid ]
* Fix warning if there's no __propagated
* TypeError: Cannot call method 'hasOwnProperty' of null.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2015 Canonical Ltd.
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or modify
5
 
 * it under the terms of the GNU Lesser General Public License as published by
6
 
 * the Free Software Foundation; version 3.
7
 
 *
8
 
 * This program is distributed in the hope that it will be useful,
9
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
 * GNU Lesser General Public License for more details.
12
 
 *
13
 
 * You should have received a copy of the GNU Lesser General Public License
14
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
 
 */
16
 
 
17
 
import QtQuick 2.4
18
 
import Ubuntu.Components 1.3 as Components
19
 
 
20
 
/*!
21
 
    \internal
22
 
    \qmltype AppHeader
23
 
    \inqmlmodule Ubuntu.Components 1.1
24
 
    \ingroup ubuntu
25
 
*/
26
 
Components.StyledItem {
27
 
    id: header
28
 
 
29
 
    anchors {
30
 
        left: parent.left
31
 
        right: parent.right
32
 
    }
33
 
    y: 0
34
 
 
35
 
    /*!
36
 
      Animate showing and hiding of the header.
37
 
     */
38
 
    property bool animate: true
39
 
 
40
 
    /*!
41
 
      The background color of the divider. Value set by MainView.
42
 
     */
43
 
    property color dividerColor
44
 
 
45
 
    /*!
46
 
      The background color of the panel. Value set by MainView.
47
 
     */
48
 
    property color panelColor
49
 
 
50
 
    Behavior on y {
51
 
        enabled: animate && !(header.flickable && header.flickable.moving)
52
 
        SmoothedAnimation {
53
 
            duration: Components.UbuntuAnimation.BriskDuration
54
 
        }
55
 
    }
56
 
 
57
 
    /*! \internal */
58
 
    onHeightChanged: {
59
 
        internal.checkFlickableMargins();
60
 
        internal.movementEnded();
61
 
        if (header.config.visible) {
62
 
            header.show();
63
 
        } else {
64
 
            header.hide();
65
 
        }
66
 
    }
67
 
 
68
 
    // with PageHeadConfiguration 1.2, always be visible.
69
 
    visible: title || contents || tabsModel || internal.newConfig
70
 
    onVisibleChanged: {
71
 
        internal.checkFlickableMargins();
72
 
    }
73
 
 
74
 
    /*!
75
 
      Show the header
76
 
     */
77
 
    function show() {
78
 
        if (internal.newConfig) {
79
 
            header.config.visible = true;
80
 
        }
81
 
        header.y = 0;
82
 
    }
83
 
 
84
 
    /*!
85
 
      Hide the header
86
 
     */
87
 
    function hide() {
88
 
        if (internal.newConfig) {
89
 
            header.config.visible = false;
90
 
        }
91
 
        header.y = -header.height;
92
 
    }
93
 
 
94
 
    /*!
95
 
      The text to display in the header
96
 
     */
97
 
    property string title: ""
98
 
    onTitleChanged: {
99
 
        // deprecated for new versions of PageHeadConfiguration
100
 
        if (!internal.newConfig) {
101
 
            header.show();
102
 
        }
103
 
    }
104
 
 
105
 
    /*!
106
 
      The contents of the header. If this is set, \l title will be ignored.
107
 
      DEPRECATED and replaced by Page.head.contents.
108
 
     */
109
 
    property Item contents: null
110
 
    onContentsChanged: {
111
 
        // deprecated for new versions of PageHeadConfiguration
112
 
        if (!internal.newConfig) {
113
 
            header.show();
114
 
        }
115
 
    }
116
 
 
117
 
    /*!
118
 
      A model of tabs to represent in the header.
119
 
      This is automatically set by \l Tabs.
120
 
     */
121
 
    property var tabsModel: null
122
 
 
123
 
    /*!
124
 
      If it is possible to pop this PageStack, a back button will be
125
 
      shown in the header.
126
 
     */
127
 
    property var pageStack: null
128
 
 
129
 
    /*!
130
 
      \deprecated
131
 
      \qmlproperty list<Action> actions
132
 
      The list of actions actions that will be shown in the header.
133
 
      DEPRECATED. Use Page.head.actions instead.
134
 
     */
135
 
    property var actions
136
 
    onActionsChanged: print("WARNING: Header.actions property is DEPRECATED. "+
137
 
                            "Use Page.head.actions instead.")
138
 
 
139
 
    /*!
140
 
      \internal
141
 
      \deprecated
142
 
      Action shown before the title. Setting this will disable the back
143
 
      button and tabs drawer button in the new header and replace it with a button
144
 
      representing the action below.
145
 
      DEPRECATED. Use Page.head.backAction property instead.
146
 
     */
147
 
    property var __customBackAction: null
148
 
 
149
 
    // FIXME: Currently autopilot can only get visual items, but once bug #1273956
150
 
    //  is fixed to support non-visual items, a QtObject may be used.
151
 
    //  --timp - 2014-03-20
152
 
    Item {
153
 
        // FIXME: This is a workaround to be able to get the properties of
154
 
        //  tabsModel in an autopilot test.
155
 
        objectName: "tabsModelProperties"
156
 
        property int count: tabsModel ? tabsModel.count : 0
157
 
        property int selectedIndex: tabsModel ? tabsModel.selectedIndex : -1
158
 
    }
159
 
    Item {
160
 
        // FIXME: This is a workaround to be able to get the properties of
161
 
        //  the sections in an autopilot test.
162
 
        objectName: "sectionsProperties"
163
 
        property int selectedIndex: header.config ? header.config.sections.selectedIndex : -1
164
 
    }
165
 
 
166
 
    /*!
167
 
      The flickable that controls the movement of the header.
168
 
      Will be set automatically by Pages inside a MainView, but can
169
 
      be overridden.
170
 
     */
171
 
    property Flickable flickable: null
172
 
    onFlickableChanged: {
173
 
        internal.connectFlickable();
174
 
        if (!internal.newConfig || !header.config.locked) {
175
 
            header.show();
176
 
        }
177
 
    }
178
 
 
179
 
    /*!
180
 
      Set by \l MainView
181
 
     */
182
 
    property bool useDeprecatedToolbar: true
183
 
 
184
 
    /*!
185
 
      Configuration of the header.
186
 
      FIXME: Must be of type PageHeadConfiguration. Setting that as the property type
187
 
      however will use the latest version (1.3) and a Page that uses an older
188
 
      version (1.1) will no longer work.
189
 
     */
190
 
    property QtObject config: null
191
 
    onConfigChanged: {
192
 
        // set internal.newConfig because when we rely on the binding,
193
 
        //  the value of newConfig may be updated after executing the code below.
194
 
        internal.newConfig = config && config.hasOwnProperty("visible") &&
195
 
                config.hasOwnProperty("locked");
196
 
        internal.connectFlickable();
197
 
 
198
 
        if (internal.newConfig && header.config.locked &&!header.config.visible) {
199
 
            header.hide();
200
 
        } else {
201
 
            header.show();
202
 
        }
203
 
    }
204
 
    Connections {
205
 
        target: header.config
206
 
        ignoreUnknownSignals: true // PageHeadConfiguration <1.2 lacks the signals below
207
 
        onVisibleChanged: {
208
 
            if (header.config.visible) {
209
 
                header.show();
210
 
            } else {
211
 
                header.hide();
212
 
            }
213
 
            internal.checkFlickableMargins();
214
 
        }
215
 
        onLockedChanged: {
216
 
            internal.connectFlickable();
217
 
            if (!header.config.locked) {
218
 
                internal.movementEnded();
219
 
            }
220
 
        }
221
 
    }
222
 
 
223
 
    /*!
224
 
      The header is not fully opened or fully closed.
225
 
 
226
 
      This property is true if the header is animating towards a fully
227
 
      opened or fully closed state, or if the header is moving due to user
228
 
      interaction with the flickable.
229
 
 
230
 
      The value of moving is always false when using an old version of
231
 
      PageHeadConfiguration (which does not have the visible property).
232
 
 
233
 
      Used in tst_header_locked_visible.qml.
234
 
    */
235
 
    readonly property bool moving: internal.newConfig &&
236
 
                                   ((config.visible && header.y !== 0) ||
237
 
                                    (!config.visible && header.y !== -header.height))
238
 
 
239
 
    QtObject {
240
 
        id: internal
241
 
 
242
 
        // This property is updated in header.onConfigChanged to ensure it
243
 
        //  is updated before other functions are called in onConfigChanged.
244
 
        property bool newConfig: header.config &&
245
 
                                 header.config.hasOwnProperty("locked") &&
246
 
                                 header.config.hasOwnProperty("visible")
247
 
 
248
 
        /*!
249
 
          Track the y-position inside the flickable.
250
 
         */
251
 
        property real previousContentY: 0
252
 
 
253
 
        /*!
254
 
          The previous flickable to disconnect events
255
 
         */
256
 
        property Flickable previousFlickable: null
257
 
 
258
 
        /*!
259
 
          Disconnect previous flickable, and connect the new one.
260
 
         */
261
 
        function connectFlickable() {
262
 
            // Finish the current header movement in case the current
263
 
            // flickable is disconnected while scrolling:
264
 
            internal.movementEnded();
265
 
 
266
 
            if (previousFlickable) {
267
 
                previousFlickable.contentYChanged.disconnect(internal.scrollContents);
268
 
                previousFlickable.movementEnded.disconnect(internal.movementEnded);
269
 
                previousFlickable.interactiveChanged.disconnect(internal.interactiveChanged);
270
 
                previousFlickable = null;
271
 
            }
272
 
            if (flickable && !(internal.newConfig && header.config.locked)) {
273
 
                // Connect flicking to movements of the header
274
 
                previousContentY = flickable.contentY;
275
 
                flickable.contentYChanged.connect(internal.scrollContents);
276
 
                flickable.movementEnded.connect(internal.movementEnded);
277
 
                flickable.interactiveChanged.connect(internal.interactiveChanged);
278
 
                flickable.contentHeightChanged.connect(internal.contentHeightChanged);
279
 
                previousFlickable = flickable;
280
 
            }
281
 
            internal.checkFlickableMargins();
282
 
        }
283
 
 
284
 
        /*!
285
 
          Update the position of the header to scroll with the flickable.
286
 
         */
287
 
        function scrollContents() {
288
 
            // Avoid updating header.y when rebounding or being dragged over the bounds.
289
 
            if (!flickable.atYBeginning && !flickable.atYEnd) {
290
 
                var deltaContentY = flickable.contentY - previousContentY;
291
 
                // FIXME: MathUtils.clamp  is expensive. Fix clamp, or replace it here.
292
 
                header.y = MathUtils.clamp(header.y - deltaContentY, -header.height, 0);
293
 
            }
294
 
            previousContentY = flickable.contentY;
295
 
        }
296
 
 
297
 
        /*!
298
 
          Fully show or hide the header, depending on its current y.
299
 
         */
300
 
        function movementEnded() {
301
 
            if (!(internal.newConfig && header.config.locked)) {
302
 
                if ( (flickable && flickable.contentY < 0) ||
303
 
                        (header.y > -header.height/2)) {
304
 
                    header.show();
305
 
                } else {
306
 
                    header.hide();
307
 
                }
308
 
            }
309
 
        }
310
 
 
311
 
        /*
312
 
          Content height of flickable changed
313
 
         */
314
 
        function contentHeightChanged() {
315
 
            if (flickable && flickable.height >= flickable.contentHeight) header.show();
316
 
        }
317
 
 
318
 
        /*
319
 
          Flickable became interactive or non-interactive.
320
 
         */
321
 
        function interactiveChanged() {
322
 
            if (flickable && !flickable.interactive) header.show();
323
 
        }
324
 
 
325
 
        /*
326
 
          Check the topMargin of the flickable and set it if needed to avoid
327
 
          contents becoming unavailable behind the header.
328
 
         */
329
 
        function checkFlickableMargins() {
330
 
            if (header.flickable) {
331
 
                var headerHeight = 0;
332
 
                if (header.visible && !(internal.newConfig &&
333
 
                                        header.config.locked &&
334
 
                                        !header.config.visible)) {
335
 
                    headerHeight = header.height;
336
 
                }
337
 
 
338
 
                if (flickable.topMargin !== headerHeight) {
339
 
                    var oldContentY = flickable.contentY;
340
 
                    var previousHeaderHeight = flickable.topMargin;
341
 
                    flickable.topMargin = headerHeight;
342
 
                    // push down contents when header grows,
343
 
                    // pull up contents when header shrinks.
344
 
                    flickable.contentY = oldContentY - headerHeight + previousHeaderHeight;
345
 
                }
346
 
            }
347
 
        }
348
 
    }
349
 
 
350
 
    theme.version: Components.Ubuntu.toolkitVersion
351
 
    styleName: header.useDeprecatedToolbar ? "HeaderStyle" : "PageHeadStyle"
352
 
}