improved desktop UI
[mardrone] / mardrone / imports / com / nokia / meego / ToolBar.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 // The ToolBar is a container for toolbar items such as ToolItem or ToolButton.
42
43 import QtQuick 1.1
44 import "." 1.0
45
46 Item {
47     id: root
48
49     width: parent ? parent.width : 0
50     height: bgImage.height
51
52     // Dummy property to allow qt component deprecated API clients to fail more gracefully
53     property bool __hidden: false
54
55     property int privateVisibility: ToolBarVisibility.Visible
56
57     // Styling for the ToolBar
58     property Style platformStyle: ToolBarStyle {}
59
60     // Deprecated, TODO remove
61     property alias style: root.platformStyle
62
63     // Shadows:
64     Image {
65         anchors.top : bgImage.top
66         anchors.right: bgImage.left
67         anchors.bottom : bgImage.bottom
68         source: "image://theme/meegotouch-menu-shadow-left"
69     }
70     Image {
71         anchors.bottom : bgImage.top
72         anchors.left: bgImage.left
73         anchors.right : bgImage.right
74         source: "image://theme/meegotouch-menu-shadow-top"
75     }
76     Image {
77         anchors.top : bgImage.top
78         anchors.left: bgImage.right
79         anchors.bottom : bgImage.bottom
80         source: "image://theme/meegotouch-menu-shadow-right"
81     }
82     Image {
83         anchors.top : bgImage.bottom
84         anchors.left: bgImage.left
85         anchors.right : bgImage.right
86         source: "image://theme/meegotouch-menu-shadow-bottom"
87     }
88     // Toolbar background.
89     BorderImage {
90         id: bgImage
91         width: root.width
92         border.left: 10
93         border.right: 10
94         border.top: 10
95         border.bottom: 10
96         source: platformStyle.background
97
98         // Mousearea that eats clicks so they don't go through the toolbar to content
99         // that may exist below it in z-order, such as unclipped listview items.
100         MouseArea { anchors.fill: parent }
101     }
102
103     states: [
104         // Inactive state.
105         State {
106             name: "hidden"
107             when: privateVisibility == ToolBarVisibility.Hidden || tools == null
108             PropertyChanges { target: root; height: 0; }
109         },
110         State {
111             name: "HiddenImmediately"
112             when: privateVisibility == ToolBarVisibility.HiddenImmediately
113             PropertyChanges { target: root; height: 0; }
114         },
115         State {
116             name: ""
117             when: !(privateVisibility == ToolBarVisibility.Visible || tools == null)
118             PropertyChanges { target: root; height: bgImage.height }
119         }
120
121     ]
122
123     transitions: [
124         // Transition between active and inactive states.
125         Transition {
126             from: ""; to: "hidden"; reversible: true
127             ParallelAnimation {
128                 PropertyAnimation { properties: "height"; easing.type: Easing.InOutExpo; duration: platformStyle.visibilityTransitionDuration }
129             }
130         }
131     ]
132
133     // The current set of tools.
134     property Item tools: null
135
136     onToolsChanged: {
137         __performTransition(__transition || transition);
138         __transition = undefined;
139     }
140
141     // The transition type. One of the following:
142     //      set         an instantaneous change (default)
143     //      push        follows page stack push animation
144     //      pop         follows page stack pop animation
145     //      replace     follows page stack replace animation
146     property string transition: "set"
147
148     // The currently displayed container; null if none.
149     property Item __currentContainer: null
150
151     // Alternating containers used for transitions.
152     property Item __containerA: null
153     property Item __containerB: null
154
155     // The transition to perform next.
156     property variant __transition
157
158     // Sets the tools with a transition.
159     function setTools(tools, transition) {
160         __transition = transition;
161         root.tools = tools;
162     }
163
164     // Performs a transition between tools in the toolbar.
165     function __performTransition(transition) {
166         // lazily create containers if they have not been created
167         if (!__currentContainer) {
168             // Parent is bgImage because it doesn't change height when toolbar gets hidden
169             __containerA = containerComponent.createObject(bgImage);
170             __containerB = containerComponent.createObject(bgImage);
171             __currentContainer = __containerB;
172         }
173
174         // no transition if the tools are unchanged
175         if (__currentContainer.tools == tools) {
176             return;
177         }
178
179         // select container states based on the transition animation
180         var transitions = {
181             "set":      { "new": "",        "old": "hidden" },
182             "push":     { "new": "right",   "old": "left" },
183             "pop":      { "new": "left",    "old": "right" },
184             "replace":  { "new": "front",   "old": "back" }
185         };
186         var animation = transitions[transition];
187
188         // initialize the free container
189         var container = __currentContainer == __containerA ? __containerB : __containerA;
190         container.state = "hidden";
191         if (tools) {
192             container.tools = tools;
193             container.owner = tools.parent;
194             tools.parent = container;
195             tools.visible = true;
196         }
197
198         // perform transition
199         __currentContainer.state = animation["old"];
200         if (tools) {
201             container.state = animation["new"];
202             container.state = "";
203         }
204
205         __currentContainer = container;
206     }
207
208     // Component for toolbar containers.
209     Component {
210         id: containerComponent
211
212         Item {
213             id: container
214
215             width: parent ? parent.width : 0
216             height: parent ? parent.height : 0
217
218             // The states correspond to the different possible positions of the container.
219             state: "hidden"
220
221             // The tools held by this container.
222             property Item tools: null
223             // The owner of the tools.
224             property Item owner: null
225
226             states: [
227                 // Start state for pop entry, end state for push exit.
228                 State {
229                     name: "left"
230                     PropertyChanges { target: container; x: -30; opacity: 0.0 }
231                 },
232                 // Start state for push entry, end state for pop exit.
233                 State {
234                     name: "right"
235                     PropertyChanges { target: container; x: 30; opacity: 0.0 }
236                 },
237                 // Start state for replace entry.
238                 State {
239                     name: "front"
240                     PropertyChanges { target: container; scale: 1.25; opacity: 0.0 }
241                 },
242                 // End state for replace exit.
243                 State {
244                     name: "back"
245                     PropertyChanges { target: container; scale: 0.85; opacity: 0.0 }
246                 },
247                 // Inactive state.
248                 State {
249                     name: "hidden"
250                     PropertyChanges { target: container; visible: false }
251                     StateChangeScript {
252                         script: {
253                             if (container.tools) {
254                                 // re-parent back to original owner
255                                 tools.visible = false;
256                                 tools.parent = owner;
257
258                                 // reset container
259                                 container.tools = container.owner = null;
260                             }
261                         }
262                     }
263                 }
264             ]
265
266             transitions: [
267                 // Pop entry and push exit transition.
268                 Transition {
269                     from: ""; to: "left"; reversible: true
270                     SequentialAnimation {
271                         PropertyAnimation { properties: "x,opacity"; easing.type: Easing.InCubic; duration: platformStyle.contentTransitionDuration / 2 }
272                         PauseAnimation { duration: platformStyle.contentTransitionDuration / 2 }
273                         ScriptAction { script: if (state == "left") state = "hidden"; }
274                     }
275                 },
276                 // Push entry and pop exit transition.
277                 Transition {
278                     from: ""; to: "right"; reversible: true
279                     SequentialAnimation {
280                         PropertyAnimation { properties: "x,opacity"; easing.type: Easing.InCubic; duration: platformStyle.contentTransitionDuration / 2 }
281                         PauseAnimation { duration: platformStyle.contentTransitionDuration / 2 }
282                         ScriptAction { script: if (state == "right") state = "hidden"; }
283                     }
284                 },
285                 Transition {
286                     // Replace entry transition.
287                     from: "front"; to: "";
288                     SequentialAnimation {
289                         PropertyAnimation { properties: "scale,opacity"; easing.type: Easing.InOutExpo; duration: platformStyle.contentTransitionDuration }
290                     }
291                 },
292                 Transition {
293                     // Replace exit transition.
294                     from: ""; to: "back";
295                     SequentialAnimation {
296                         PropertyAnimation { properties: "scale,opacity"; easing.type: Easing.InOutExpo; duration: platformStyle.contentTransitionDuration }
297                         ScriptAction { script: if (state == "back") state = "hidden"; }
298                     }
299                 }
300             ]
301
302         }
303     }
304
305 }