improved desktop UI
[mardrone] / mardrone / imports / com / nokia / meego / AbstractMenu.qml
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the Qt Components project.
8 **
9 ** $QT_BEGIN_LICENSE:BSD$
10 ** You may use this file under the terms of the BSD license as follows:
11 **
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
14 ** met:
15 **   * Redistributions of source code must retain the above copyright
16 **     notice, this list of conditions and the following disclaimer.
17 **   * Redistributions in binary form must reproduce the above copyright
18 **     notice, this list of conditions and the following disclaimer in
19 **     the documentation and/or other materials provided with the
20 **     distribution.
21 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 **     the names of its contributors may be used to endorse or promote
23 **     products derived from this software without specific prior written
24 **     permission.
25 **
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 import QtQuick 1.1
42 import "." 1.0
43
44 Popup {
45     id: root
46
47     // Common API
48     default property alias content: contentField.children
49
50     // Common API inherited from Popup:
51     /*
52         function open()
53         function close()
54
55         property QDeclarativeItem* visualParent
56         property int status
57     */
58
59     // platformStyle API
60     property Style platformStyle: MenuStyle{}
61     property alias style: root.platformStyle // Deprecated
62     property alias platformTitle: titleBar.children
63     property alias title: titleBar.children // Deprecated
64     property alias __footer: footerBar.children
65
66     // private api
67     property int __statusBarDelta: visualParent ? 0 :
68                  __findItem( "appWindowContent") != null ? 0 :
69                  __findItem( "pageStackWindow") != null && __findItem( "pageStackWindow").showStatusBar ? 36 : 0
70
71     property string __animationChief: "abstractMenu"
72     property int __pressDelay: platformStyle.pressDelay
73     property alias __statesWrapper: statesWrapper
74     property alias __menuPane: menuPane
75
76     // This item will find the object with the given objectName ... or will return
77     function __findItem( objectName ) {
78         var next = parent;
79
80         if (next != null) {
81             while (next) {
82                 if(next.objectName == objectName){
83                     return next;
84                 }
85
86                 next = next.parent;
87             }
88         }
89
90         return null;
91     }
92
93     __dim: platformStyle.dim
94     __fadeInDuration: platformStyle.fadeInDuration
95     __fadeOutDuration: platformStyle.fadeOutDuration
96     __fadeInDelay: platformStyle.fadeInDelay
97     __fadeOutDelay: platformStyle.fadeOutDelay
98     __faderBackground: platformStyle.faderBackground
99     __fadeInEasingType: platformStyle.fadeInEasingType
100     __fadeOutEasingType: platformStyle.fadeOutEasingType
101
102     anchors.fill: parent
103
104     // When application is minimized menu is closed.
105     Connections {
106         target: platformWindow
107         onActiveChanged: {
108             if(!platformWindow.active)
109                 close()
110         }
111     }
112
113     // This is needed for menus which are not instantiated inside the
114     // content window of the PageStackWindow:
115     Item {
116         id: roundedCorners
117         visible: root.status != DialogStatus.Closed && !visualParent
118                  && __findItem( "pageStackWindow") != null && __findItem( "pageStackWindow").platformStyle.cornersVisible
119         anchors.left: parent.left
120         anchors.right: parent.right
121         anchors.bottom: parent.bottom
122         height: parent.height - __statusBarDelta - 2
123         z: 10001
124
125         // compensate for the widening of the edges of the fader (which avoids artefacts during rotation)
126         anchors.topMargin:    +1
127         anchors.rightMargin:  +1
128         anchors.bottomMargin: +1
129         anchors.leftMargin:   +1
130
131         Image {
132             anchors.top : parent.top
133             anchors.left: parent.left
134             source: "image://theme/meegotouch-applicationwindow-corner-top-left"
135         }
136         Image {
137             anchors.top: parent.top
138             anchors.right: parent.right
139             source: "image://theme/meegotouch-applicationwindow-corner-top-right"
140         }
141         Image {
142             anchors.bottom : parent.bottom
143             anchors.left: parent.left
144             source: "image://theme/meegotouch-applicationwindow-corner-bottom-left"
145         }
146         Image {
147             anchors.bottom : parent.bottom
148             anchors.right: parent.right
149             source: "image://theme/meegotouch-applicationwindow-corner-bottom-right"
150         }
151     }
152
153     // Shadows:
154     Image {
155         anchors.top : menuPane.top
156         anchors.right: menuPane.left
157         anchors.bottom : menuPane.bottom
158         source: "image://theme/meegotouch-menu-shadow-left"
159         visible: root.status != DialogStatus.Closed
160     }
161     Image {
162         anchors.bottom : menuPane.top
163         anchors.left: menuPane.left
164         anchors.right : menuPane.right
165         source: "image://theme/meegotouch-menu-shadow-top"
166         visible: root.status != DialogStatus.Closed
167     }
168     Image {
169         anchors.top : menuPane.top
170         anchors.left: menuPane.right
171         anchors.bottom : menuPane.bottom
172         source: "image://theme/meegotouch-menu-shadow-right"
173         visible: root.status != DialogStatus.Closed
174     }
175     Image {
176         anchors.top : menuPane.bottom
177         anchors.left: menuPane.left
178         anchors.right : menuPane.right
179         source: "image://theme/meegotouch-menu-shadow-bottom"
180         visible: root.status != DialogStatus.Closed
181     }
182
183     Item {
184         id: menuPane
185         //ToDo: add support for layoutDirection Qt::RightToLeft
186         x: platformStyle.leftMargin
187         width:  parent.width  - platformStyle.leftMargin - platformStyle.rightMargin  // ToDo: better width heuristic
188         height: (screen.currentOrientation == 1) || (screen.currentOrientation == 4) ?
189                 /* Portrait  */ titleBar.height + flickableContent.height + footerBar.height :
190                 /* Landscape */ parent.height - platformStyle.topMargin - platformStyle.bottomMargin - __statusBarDelta
191         anchors.bottom: parent.bottom
192         anchors.right: parent.right
193
194         state: __statesWrapper.state
195
196         BorderImage {
197            id: backgroundImage
198            source: // !enabled ? root.platformStyle.disabledBackground :
199                    root.platformStyle.background
200            anchors.fill : parent
201            border { left: 22; top: theme.inverted ? 124 : 22;
202                     right: 22; bottom: theme.inverted ? 2 : 22 }
203         }
204
205         // this item contains the whole menu (content rectangle)
206         Item {
207             id: backgroundRect
208             anchors.fill: parent
209
210                 Item {
211                     id: titleBar
212                     anchors.left: parent.left
213                     anchors.right: parent.right
214
215                     height: childrenRect.height
216                 }
217
218                 Item {
219                     // Required to have the ScrollDecorator+Flickable handled
220                     // by the column as a single item while keeping the
221                     // ScrollDecorator working
222                     id: flickableContent
223                     anchors.left: parent.left
224                     anchors.right: parent.right
225
226                     anchors.top: backgroundRect.top
227                     anchors.topMargin: titleBar.height
228                     property int maxHeight : visualParent
229                                              ? visualParent.height - platformStyle.topMargin - __statusBarDelta
230                                                - footerBar.height - titleBar.height
231                                              : root.parent
232                                                      ? root.parent.height - platformStyle.topMargin - __statusBarDelta
233                                                        - footerBar.height - titleBar.height
234                                                      : 350
235
236                     height: contentField.childrenRect.height + platformStyle.topPadding + platformStyle.bottomPadding < maxHeight
237                             ? contentField.childrenRect.height + platformStyle.topPadding + platformStyle.bottomPadding
238                             : maxHeight
239
240                     Flickable {
241                         id: flickable
242                         anchors.fill: parent
243                         contentWidth: parent.width
244                         contentHeight: contentField.childrenRect.height + platformStyle.topPadding + platformStyle.bottomPadding
245                         interactive: contentHeight > flickable.height
246                         flickableDirection: Flickable.VerticalFlick
247                         pressDelay: __pressDelay
248                         clip: true
249
250                         Item {
251                             id: contentRect
252                             height: contentField.childrenRect.height
253
254                             anchors.top: parent.top
255                             anchors.left: parent.left
256                             anchors.right: parent.right
257                             anchors.topMargin: platformStyle.topPadding
258                             anchors.bottomMargin: platformStyle.bottomPadding
259                             anchors.leftMargin: platformStyle.leftPadding
260                             anchors.rightMargin: platformStyle.rightPadding
261
262                             Item {
263                                 id: contentField
264                                 anchors.fill: contentRect
265
266                                 function closeMenu() { root.close(); }
267                             }
268                         }
269                     }
270                     ScrollDecorator {
271                         id: scrollDecorator
272                         flickableItem: flickable
273                     }
274                 }
275
276                 Item {
277                     id: footerBar
278                     anchors.left: parent.left
279                     anchors.right: parent.right
280
281                     anchors.top: backgroundRect.top
282                     anchors.topMargin: titleBar.height + flickableContent.height
283                     height: childrenRect.height
284                 }
285
286         }
287     }
288
289     onPrivateClicked: close() // "reject()"
290
291     StateGroup {
292         id: statesWrapper
293
294         state: "hidden"
295
296         states: [
297             State {
298                 name: "visible"
299                 when: root.__animationChief == "abstractMenu" && (root.status == DialogStatus.Opening || root.status == DialogStatus.Open)
300                 PropertyChanges {
301                     target: __menuPane
302                     opacity: 1.0
303                 }
304             },
305             State {
306                 name: "hidden"
307                 when: root.__animationChief == "abstractMenu" && (root.status == DialogStatus.Closing || root.status == DialogStatus.Closed)
308                 PropertyChanges {
309                     target: __menuPane
310                     opacity: 0.0
311                 }
312             }
313         ]
314
315     }
316 }