1 import QMLContactManagerAsync 1.0 |
1 /**************************************************************************** |
2 import QmlContact 1.0 |
2 ** |
|
3 ** Copyright (C) 2010 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 Mobility Components. |
|
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 QmlContactModel 1.0 |
3 import Qt 4.6 |
42 import Qt 4.6 |
|
43 import "contents" |
4 |
44 |
5 Rectangle { |
45 Rectangle { |
6 id: topItem |
46 id: topItem |
7 width: 320 |
47 width: 360 |
8 height: 480 |
48 height: 640 |
9 x: 0 |
49 x: 0 |
10 y: 0 |
50 y: 0 |
11 |
51 |
12 color: "#080808"; |
52 color: "#080808"; |
13 |
53 |
14 Script { |
54 QmlContactModel { |
15 function startup() { |
55 id: "myModel" |
16 manager.contacts(); |
|
17 } |
|
18 function gotContacts(c) { |
|
19 if(c == undefined){ |
|
20 return; |
|
21 } |
|
22 |
|
23 var q = c.values("Presence"); |
|
24 |
|
25 nameModel.append({"name": c.name, |
|
26 "presence": "Status: " + q.Presence, |
|
27 "email": c.email, |
|
28 "avatarSource": c.avatar ? c.avatar : "qrc:/default.svg", |
|
29 "hasThumbnail" : c.hasThumbnail, |
|
30 "avatarImage": c.thumbnail, |
|
31 "interestLabel" : c.interestLabel, |
|
32 "interest" : c.interest}); |
|
33 |
|
34 } |
|
35 } |
|
36 |
|
37 Component.onCompleted: startup(); |
|
38 |
|
39 QMLContactManagerAsync { |
|
40 id: "manager" |
|
41 |
|
42 manager: "memory" |
56 manager: "memory" |
43 onDataChanged: print("Data changed!"); |
|
44 onContactsAdded: print("Contacts added: " + contactIds); |
|
45 onContactsLoaded: gotContacts(contact); |
|
46 } |
57 } |
47 |
58 |
48 Component { |
59 Component { |
49 id: listdelegate |
60 id: listdelegate |
50 Rectangle { |
61 Rectangle { |
51 id: wrapper |
62 id: wrapper |
52 border.width: 2 |
63 border.width: 2 |
53 height: mainLabel.height; |
64 height: 36; |
54 width: mainList.width; |
65 width: mainList.width; |
55 |
66 |
56 property color topColor: "#333333"; |
67 property color topColor: "#999999"; |
57 property color bottomColor: "#111111"; |
68 property color bottomColor: "#444444"; |
58 property real detailsOpacity: 0 |
69 property real detailsOpacity: 1 |
|
70 property int littleDetailsMode: 0; |
|
71 property int bigDetailsMode: 0; |
59 |
72 |
60 gradient: Gradient { |
73 gradient: Gradient { |
61 GradientStop { position: 0.0; color: topColor } |
74 GradientStop { position: 0.0; color: topColor } |
62 GradientStop { position: 1.0; color: bottomColor } |
75 GradientStop { position: 1.0; color: bottomColor } |
|
76 } |
|
77 |
|
78 MouseArea { |
|
79 id: mr |
|
80 width: topItem.width; |
|
81 height: wrapper.height; |
|
82 anchors.centerIn: parent; |
|
83 onClicked: { littleDetailsMode = !littleDetailsMode; mainList.currentIndex = index; } |
63 } |
84 } |
64 |
85 |
65 Row { |
86 Row { |
66 spacing: 2 |
87 spacing: 2 |
67 Item { |
88 Item { |
106 opacity: wrapper.detailsOpacity |
127 opacity: wrapper.detailsOpacity |
107 height: childrenRect.height + 6; |
128 height: childrenRect.height + 6; |
108 width: childrenRect.width; |
129 width: childrenRect.width; |
109 Column { |
130 Column { |
110 Text { |
131 Text { |
111 text: interestLabel + interest |
132 text: model.interestLabel + ": " + model.interest |
112 color: details.textColor; |
133 color: details.textColor; |
113 } |
134 } |
114 Text { |
135 Text { |
115 text: presence |
136 text: model.presenceAvailable ? model.presenceText + " [" + model.presenceMessage + "]" : " "; |
116 color: details.textColor; |
137 color: details.textColor; |
|
138 } |
|
139 } |
|
140 } |
|
141 } |
|
142 |
|
143 Item { |
|
144 id: "buttonBox" |
|
145 x: wrapper.width - 6 - childrenRect.width; |
|
146 y: 4; |
|
147 height:childrenRect.height |
|
148 opacity: details.opacity; |
|
149 Column { |
|
150 // Buttons |
|
151 MediaButton { |
|
152 id: dialButton; |
|
153 text: "Dial"; |
|
154 } |
|
155 MediaButton { |
|
156 id: textButton |
|
157 text: "Send Text"; |
|
158 } |
|
159 Item { |
|
160 height:childrenRect.height |
|
161 width: childrenRect.width |
|
162 MediaButton { |
|
163 id: viewButton |
|
164 text: "More..." |
|
165 opacity: 0; |
|
166 onClicked: wrapper.bigDetailsMode = 1; |
|
167 } |
|
168 MediaButton { |
|
169 id: smallAgainButton |
|
170 text: "Back"; |
|
171 anchors.top:viewButton.top; |
|
172 opacity: 0; |
|
173 onClicked: wrapper.bigDetailsMode = 0; |
117 } |
174 } |
118 } |
175 } |
119 } |
176 } |
120 } |
177 } |
121 } |
178 } |
122 |
179 |
123 states: State { |
180 states: [ |
124 name: "Details" |
181 State { |
125 when: wrapper.ListView.isCurrentItem; |
182 name: "List"; |
126 PropertyChanges { target: wrapper; detailsOpacity: 1; } |
183 when: mainList.currentIndex != index || wrapper.littleDetailsMode == 0 |
127 PropertyChanges { target: wrapper; topColor: "#999999"; } |
184 PropertyChanges { target: wrapper; detailsOpacity: 0; } |
128 PropertyChanges { target: wrapper; bottomColor: "#444444"; } |
185 PropertyChanges { target: wrapper; topColor: "#333333"; } |
129 PropertyChanges { target: wrapper; height: mainLabel.height + details.height + 4; } |
186 PropertyChanges { target: wrapper; bottomColor: "#111111"; } |
130 } |
187 PropertyChanges { target: buttonBox; x: wrapper.width + 6; } |
|
188 }, |
|
189 State { |
|
190 name: "MiniDetails" |
|
191 when: (mainList.currentIndex == index) && (wrapper.littleDetailsMode == 1) && (wrapper.bigDetailsMode == 0); |
|
192 PropertyChanges { target: viewButton; opacity: 1; } |
|
193 PropertyChanges { target: smallAgainButton; opacity: 0; } |
|
194 PropertyChanges { target: wrapper; height: Math.max(mainLabel.height + details.height + 4, buttonBox.height + 8); } |
|
195 PropertyChanges { target: mainList; explicit: true; contentY: wrapper.y } // XXX I don't think this should be here |
|
196 }, |
|
197 State { |
|
198 name: "Details" |
|
199 when: (mainList.currentIndex == index) && (wrapper.bigDetailsMode == 1); |
|
200 PropertyChanges { target: wrapper; height: mainList.height; } |
|
201 PropertyChanges { target: viewButton; opacity: 0; } |
|
202 PropertyChanges { target: smallAgainButton; opacity: 1; } |
|
203 PropertyChanges { target: mainAvatar; height: 96; } |
|
204 PropertyChanges { target: mainList; explicit: true; contentY: wrapper.y } |
|
205 PropertyChanges { target: mainList; interactive: false; } |
|
206 } |
|
207 ] |
131 |
208 |
132 transitions: [ |
209 transitions: [ |
133 Transition { |
210 Transition { |
134 from: "" |
211 from: "List" |
135 to: "Details" |
212 to: "MiniDetails" |
136 reversible: false |
213 reversible: false |
137 SequentialAnimation { |
214 SequentialAnimation { |
138 NumberAnimation { duration: 100; properties: "detailsOpacity,height" } |
215 NumberAnimation { duration: 100; properties: "detailsOpacity,height" } |
139 ColorAnimation { duration: 100; properties: "topColor, bottomColor";} |
216 ParallelAnimation { |
|
217 ColorAnimation { duration: 100; properties: "topColor, bottomColor";} |
|
218 NumberAnimation { duration: 150; properties: "x"; } |
|
219 } |
140 } |
220 } |
141 }, |
221 }, |
142 Transition { |
222 Transition { |
143 to: "" |
223 from: "MiniDetails" |
|
224 to: "Details" |
|
225 reversible: false |
|
226 ParallelAnimation { |
|
227 NumberAnimation { duration: 250; properties: "contentY,opacity"; } |
|
228 SequentialAnimation { |
|
229 NumberAnimation { duration: 100; properties: "detailsOpacity,height" } |
|
230 ParallelAnimation { |
|
231 ColorAnimation { duration: 100; properties: "topColor, bottomColor";} |
|
232 NumberAnimation { duration: 150; properties: "x"; } |
|
233 } |
|
234 } |
|
235 } |
|
236 }, |
|
237 Transition { |
144 from: "Details" |
238 from: "Details" |
|
239 to: "MiniDetails" |
|
240 reversible: false |
|
241 ParallelAnimation { |
|
242 NumberAnimation { duration: 250; properties: "contentY,opacity"; } |
|
243 SequentialAnimation { |
|
244 ParallelAnimation { |
|
245 NumberAnimation { duration: 150; properties: "x"; } |
|
246 ColorAnimation { duration: 200; properties: "topColor, bottomColor";} |
|
247 } |
|
248 NumberAnimation { duration: 200; properties: "detailsOpacity,height" } |
|
249 } |
|
250 } |
|
251 }, |
|
252 Transition { |
|
253 from: "MiniDetails" |
|
254 to: "List" |
145 reversible: false |
255 reversible: false |
146 SequentialAnimation { |
256 SequentialAnimation { |
147 NumberAnimation { duration: 100; properties: "detailsOpacity,height" } |
257 NumberAnimation { duration: 100; properties: "x"; } |
148 ColorAnimation { duration: 100; properties: "topColor, bottomColor";} |
258 ParallelAnimation{ |
|
259 NumberAnimation { duration: 150; properties: "detailsOpacity,height" } |
|
260 ColorAnimation { duration: 150; properties: "topColor, bottomColor";} |
|
261 } |
149 } |
262 } |
150 } |
263 } |
151 ] |
264 ] |
152 MouseArea { |
|
153 id: mr |
|
154 width: topItem.width; |
|
155 height: wrapper.height; |
|
156 anchors.centerIn: parent; |
|
157 onClicked: mainList.currentIndex = index; |
|
158 } |
|
159 } |
265 } |
160 } |
266 } |
161 |
267 |
162 ListView { |
268 ListView { |
163 id: mainList |
269 id: mainList |
164 model: nameModel |
270 model: myModel |
165 width: parent.width; height: parent.height |
271 width: parent.width; height: parent.height |
166 delegate: listdelegate |
272 delegate: listdelegate |
167 highlightFollowsCurrentItem: false |
273 highlightFollowsCurrentItem: false |
168 focus: true |
274 focus: true |
169 anchors.fill: parent |
275 anchors.fill: parent |
170 highlightMoveSpeed: 5000 |
|
171 keyNavigationWraps: true |
276 keyNavigationWraps: true |
172 } |
|
173 |
|
174 ListModel { |
|
175 id: nameModel |
|
176 } |
277 } |
177 |
278 |
178 // Attach scrollbar to the right edge of the view. |
279 // Attach scrollbar to the right edge of the view. |
179 ScrollBar { |
280 ScrollBar { |
180 id: verticalScrollBar |
281 id: verticalScrollBar |