|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <HbInstance> |
|
19 |
|
20 #include "hsdomainmodeldatastructures.h" |
|
21 #include "hspage.h" |
|
22 #include "hspagetoucharea.h" |
|
23 #include "hspagenewwidgetlayout.h" |
|
24 #include "hsscene.h" |
|
25 #include "hswidgethost.h" |
|
26 #include "hswidgethostvisual.h" |
|
27 #include "hswallpaper.h" |
|
28 #include "hswidgetpositioningonwidgetadd.h" |
|
29 #include "hswidgetpositioningonorientationchange.h" |
|
30 #include "hsconfiguration.h" |
|
31 #include "hspagevisual.h" |
|
32 #include "hsgui.h" |
|
33 /*! |
|
34 \class HsPage |
|
35 \ingroup group_hsdomainmodel |
|
36 \brief Represents a page in the framework. |
|
37 HsPage contains group of widgets. HsPage can have a wallpaper. |
|
38 */ |
|
39 |
|
40 /*! |
|
41 Constructor. |
|
42 |
|
43 \a parent Owner. |
|
44 \a aFlags Window flags. |
|
45 */ |
|
46 HsPage::HsPage(QObject* parent) |
|
47 : QObject(parent), |
|
48 mDatabaseId(-1), |
|
49 mPageVisual(new HsPageVisual), |
|
50 mWallpaper(0), |
|
51 mRemovable(true), |
|
52 mPageMargin(0.0) |
|
53 { |
|
54 //Page margin |
|
55 mPageMargin = HSCONFIGURATION_GET(pageMargin); |
|
56 connect(HsConfiguration::instance(), SIGNAL(propertyChanged(QString)), SLOT(onPageMarginChanged(QString))); |
|
57 } |
|
58 |
|
59 /*! |
|
60 Destructor. |
|
61 */ |
|
62 HsPage::~HsPage() |
|
63 { |
|
64 delete mWallpaper; |
|
65 delete mPageVisual; |
|
66 } |
|
67 |
|
68 /*! |
|
69 Returns the database id. |
|
70 */ |
|
71 int HsPage::databaseId() const |
|
72 { |
|
73 return mDatabaseId; |
|
74 } |
|
75 |
|
76 /*! |
|
77 Sets the database id to \a id. |
|
78 */ |
|
79 void HsPage::setDatabaseId(int id) |
|
80 { |
|
81 mDatabaseId = id; |
|
82 } |
|
83 |
|
84 |
|
85 /*! |
|
86 Loads widgets. |
|
87 */ |
|
88 bool HsPage::load() |
|
89 { |
|
90 if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) { |
|
91 mWallpaper = new HsPageWallpaper(this); |
|
92 } |
|
93 |
|
94 HsWidgetHost *widget = new HsWidgetHost(-1); |
|
95 mWidgets.append(widget); |
|
96 connectWidget(widget); |
|
97 widget->setPage(this); |
|
98 widget->startWidget(); |
|
99 return true; |
|
100 } |
|
101 |
|
102 /*! |
|
103 Return wallpaper. |
|
104 */ |
|
105 HsWallpaper *HsPage::wallpaper() const |
|
106 { |
|
107 return mWallpaper; |
|
108 } |
|
109 /*! |
|
110 Add given existing \a widgetHost to a page. Returns true if successful |
|
111 */ |
|
112 bool HsPage::addExistingWidget(HsWidgetHost *widgetHost) |
|
113 { |
|
114 if (!widgetHost) { |
|
115 return false; |
|
116 } |
|
117 |
|
118 if (mWidgets.contains(widgetHost)) { |
|
119 return true; |
|
120 } |
|
121 |
|
122 if (!widgetHost->setPage(this)) { |
|
123 return false; |
|
124 } |
|
125 |
|
126 connectWidget(widgetHost); |
|
127 mWidgets << widgetHost; |
|
128 |
|
129 return true; |
|
130 } |
|
131 |
|
132 /*! |
|
133 Remove given \a widgetHost from a page. Widget is not deleted. |
|
134 Returns true if successful |
|
135 */ |
|
136 bool HsPage::removeWidget(HsWidgetHost *widgetHost) |
|
137 { |
|
138 if (!widgetHost || !widgetHost->setPage(0)) { |
|
139 return false; |
|
140 } |
|
141 |
|
142 disconnectWidget(widgetHost); |
|
143 mWidgets.removeOne(widgetHost); |
|
144 |
|
145 return true; |
|
146 } |
|
147 |
|
148 /*! |
|
149 Returns list of new widgets belonging to a page. Widgets which are |
|
150 not yet layouted are considered as new widgets. |
|
151 */ |
|
152 QList<HsWidgetHost *> HsPage::newWidgets() |
|
153 { |
|
154 return mNewWidgets; |
|
155 } |
|
156 |
|
157 /*! |
|
158 Adds new widget into a page. Returns true if successfull. |
|
159 */ |
|
160 bool HsPage::addNewWidget(HsWidgetHost* widgetHost, const QPointF &touchPoint) |
|
161 { |
|
162 Q_UNUSED(touchPoint) |
|
163 if (!widgetHost || mWidgets.contains(widgetHost)) { |
|
164 return false; |
|
165 } |
|
166 |
|
167 if (mNewWidgets.contains(widgetHost)) { |
|
168 return true; |
|
169 } |
|
170 |
|
171 HsWidgetPresentationData presentation; |
|
172 presentation.orientation = HsGui::instance()->orientation(); |
|
173 if (!widgetHost->getPresentation(presentation)) { |
|
174 presentation.orientation = HsGui::instance()->orientation(); |
|
175 presentation.setPos(QPointF()); |
|
176 presentation.zValue = 0; |
|
177 widgetHost->savePresentation(presentation); |
|
178 } |
|
179 |
|
180 connectWidget(widgetHost); |
|
181 mNewWidgets << widgetHost; |
|
182 |
|
183 return true; |
|
184 } |
|
185 |
|
186 /*! |
|
187 Layouts all the new widgets |
|
188 */ |
|
189 void HsPage::layoutNewWidgets() |
|
190 { |
|
191 if (mNewWidgets.isEmpty()) { |
|
192 return; |
|
193 } |
|
194 |
|
195 updateZValues(); |
|
196 HsWidgetHost *widget = 0; |
|
197 for (int i = 0; i < mNewWidgets.count(); ++i) { |
|
198 widget = mNewWidgets.at(i); |
|
199 widget->setPage(this); |
|
200 widget->showWidget(); |
|
201 } |
|
202 mWidgets << mNewWidgets; |
|
203 mNewWidgets.clear(); |
|
204 } |
|
205 |
|
206 /*! |
|
207 Clears new widgets list and resets layout. |
|
208 */ |
|
209 void HsPage::resetNewWidgets() |
|
210 { |
|
211 mNewWidgets.clear(); |
|
212 } |
|
213 |
|
214 /*! |
|
215 Remove page and all it's contained widgets from database |
|
216 */ |
|
217 bool HsPage::deleteFromDatabase() |
|
218 { |
|
219 //Not used in mock |
|
220 return true; |
|
221 } |
|
222 |
|
223 /*! |
|
224 Return list of widgets belonging to a page |
|
225 */ |
|
226 QList<HsWidgetHost *> HsPage::widgets() const |
|
227 { |
|
228 return mWidgets; |
|
229 } |
|
230 |
|
231 /*! |
|
232 Returns true if the page can be removed. Otherwise, |
|
233 returns false. |
|
234 */ |
|
235 bool HsPage::isRemovable() const |
|
236 { |
|
237 return mRemovable; |
|
238 } |
|
239 |
|
240 /*! |
|
241 Sets removable flag to \a removable. |
|
242 */ |
|
243 void HsPage::setRemovable(bool removable) |
|
244 { |
|
245 mRemovable = removable; |
|
246 } |
|
247 |
|
248 /*! |
|
249 Return true if page is default page. |
|
250 */ |
|
251 bool HsPage::isDefaultPage() const |
|
252 { |
|
253 return mDatabaseId == HSCONFIGURATION_GET(defaultPageId); |
|
254 } |
|
255 |
|
256 /*! |
|
257 Return true if page is active page. |
|
258 */ |
|
259 bool HsPage::isActivePage() const |
|
260 { |
|
261 return this == HsScene::instance()->activePage(); |
|
262 } |
|
263 |
|
264 /*! |
|
265 Create page into database and return instance of a new page. |
|
266 */ |
|
267 HsPage *HsPage::createInstance(const HsPageData &pageData) |
|
268 { |
|
269 Q_UNUSED(pageData); |
|
270 HsPage *page = new HsPage; |
|
271 return page; |
|
272 } |
|
273 |
|
274 /*! |
|
275 The widget is bounded in the rectangle which is smaller by PageMargin on all sides of page. |
|
276 */ |
|
277 QPointF HsPage::adjustedWidgetPosition(const QRectF &origWidgetRect) |
|
278 { |
|
279 QRectF widgetAreaRect = contentGeometry(); |
|
280 qreal widgetX = qBound(widgetAreaRect.left(), origWidgetRect.x(), widgetAreaRect.right() - origWidgetRect.width()); |
|
281 qreal widgetY = qBound(widgetAreaRect.top(), origWidgetRect.y(), widgetAreaRect.bottom() - origWidgetRect.height()); |
|
282 |
|
283 return QPointF(widgetX, widgetY); |
|
284 } |
|
285 |
|
286 /*! |
|
287 Returns rect of rectangular where widgets are allowed to be placed in the page. |
|
288 */ |
|
289 QRectF HsPage::contentGeometry() |
|
290 { |
|
291 return contentGeometry(HsGui::instance()->orientation()); |
|
292 } |
|
293 |
|
294 /*! |
|
295 Returns rect of rectangular where widgets are allowed to be placed in the page. |
|
296 */ |
|
297 QRectF HsPage::contentGeometry(Qt::Orientation orientation) |
|
298 { |
|
299 QRectF pageRect; |
|
300 //pageRect = rect(); |
|
301 |
|
302 if (orientation != HsGui::instance()->orientation()) { |
|
303 qreal width = pageRect.width(); |
|
304 qreal height = pageRect.height(); |
|
305 pageRect.setWidth(height); |
|
306 pageRect.setHeight(width); |
|
307 } |
|
308 |
|
309 //Take care of chrome in both orientation |
|
310 pageRect.setTop(64); |
|
311 |
|
312 //Shrink by page margins at each side |
|
313 return pageRect.adjusted(mPageMargin, mPageMargin, -mPageMargin, -mPageMargin); |
|
314 } |
|
315 |
|
316 /*! |
|
317 Returns rect of rectangular where widgets are allowed to be placed in the page. |
|
318 */ |
|
319 QRectF HsPage::contentRect() |
|
320 { |
|
321 return contentRect(HsGui::instance()->orientation()); |
|
322 } |
|
323 |
|
324 /*! |
|
325 Returns rect of rectangular where widgets are allowed to be placed in the page. |
|
326 */ |
|
327 QRectF HsPage::contentRect(Qt::Orientation orientation) |
|
328 { |
|
329 QRectF rect = contentGeometry(orientation); |
|
330 rect.moveTopLeft(QPointF(0,0)); |
|
331 return rect; |
|
332 } |
|
333 |
|
334 /*! |
|
335 Calls onShow() for contained widgets. |
|
336 */ |
|
337 void HsPage::showWidgets() |
|
338 { |
|
339 } |
|
340 |
|
341 /*! |
|
342 Calls onHide() for contained widgets. |
|
343 */ |
|
344 void HsPage::hideWidgets() |
|
345 { |
|
346 } |
|
347 |
|
348 /*! |
|
349 Propagate online state to widgets. |
|
350 */ |
|
351 void HsPage::setOnline(bool online) |
|
352 { |
|
353 foreach (HsWidgetHost *widget, mNewWidgets) { |
|
354 widget->setOnline(online); |
|
355 } |
|
356 foreach (HsWidgetHost *widget, mWidgets) { |
|
357 widget->setOnline(online); |
|
358 } |
|
359 } |
|
360 |
|
361 /*! |
|
362 Update widgets z-values and persist those. Active widget has top most |
|
363 z-value. |
|
364 */ |
|
365 void HsPage::updateZValues() |
|
366 { |
|
367 |
|
368 } |
|
369 |
|
370 /*! |
|
371 Return this page's index. |
|
372 */ |
|
373 int HsPage::pageIndex() |
|
374 { |
|
375 return HsScene::instance()->pages().indexOf(this); |
|
376 } |
|
377 |
|
378 /*! |
|
379 Utility to connect widget signals to page. |
|
380 */ |
|
381 void HsPage::connectWidget(HsWidgetHost *widget) |
|
382 { |
|
383 connect(widget, SIGNAL(finished()), SLOT(onWidgetFinished())); |
|
384 connect(widget, SIGNAL(faulted()), SLOT(onWidgetFaulted())); |
|
385 connect(widget->visual(), SIGNAL(resized()), SLOT(onWidgetResized())); |
|
386 connect(widget, SIGNAL(available()), SLOT(onWidgetAvailable())); |
|
387 connect(widget, SIGNAL(unavailable()), SLOT(onWidgetUnavailable())); |
|
388 } |
|
389 /*! |
|
390 Disconnect widget signals from page |
|
391 */ |
|
392 void HsPage::disconnectWidget(HsWidgetHost *widget) |
|
393 { |
|
394 widget->disconnect(this); |
|
395 } |
|
396 /*! |
|
397 Disconnect and remove widget |
|
398 */ |
|
399 void HsPage::onWidgetFinished() |
|
400 { |
|
401 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
402 |
|
403 // It can be in new widget list if we haven't layouted it yet |
|
404 // or layouted new widget and widget list |
|
405 if (!mNewWidgets.removeOne(widget)) { |
|
406 mWidgets.removeOne(widget); |
|
407 } |
|
408 |
|
409 disconnectWidget(widget); |
|
410 widget->remove(); |
|
411 } |
|
412 /*! |
|
413 Remove widget if it faulted |
|
414 */ |
|
415 void HsPage::onWidgetFaulted() |
|
416 { |
|
417 onWidgetFinished(); |
|
418 } |
|
419 |
|
420 /*! |
|
421 Calculates new widget position on page when widget size changes. If page has layout then there are new widgets |
|
422 and we use layout to calculate new widget positions. |
|
423 */ |
|
424 void HsPage::onWidgetResized() |
|
425 { |
|
426 } |
|
427 /*! |
|
428 Show widget if it came available |
|
429 */ |
|
430 void HsPage::onWidgetAvailable() |
|
431 { |
|
432 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
433 |
|
434 mUnavailableWidgets.removeOne(widget); |
|
435 mWidgets.append(widget); |
|
436 |
|
437 widget->startWidget(isActivePage()); |
|
438 } |
|
439 /*! |
|
440 Update internal bookkeeping and hide widget |
|
441 */ |
|
442 void HsPage::onWidgetUnavailable() |
|
443 { |
|
444 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
445 |
|
446 if (mWidgets.contains(widget)) { |
|
447 mWidgets.removeOne(widget); |
|
448 } else if (mNewWidgets.contains(widget)) { |
|
449 mNewWidgets.removeOne(widget); |
|
450 } else { |
|
451 return; |
|
452 } |
|
453 |
|
454 mUnavailableWidgets.append(widget); |
|
455 } |
|
456 |
|
457 /*! |
|
458 Run positioning algorithm for widgets which don't have position on |
|
459 target orientation. Otherwise set orientation positions for widgets. |
|
460 */ |
|
461 void HsPage::onOrientationChanged(Qt::Orientation orientation) |
|
462 { |
|
463 Q_UNUSED(orientation) |
|
464 } |
|
465 |
|
466 void HsPage::onPageMarginChanged(const QString &value) |
|
467 { |
|
468 if (value == "pageMargin") { |
|
469 mPageMargin = HSCONFIGURATION_GET(pageMargin); |
|
470 |
|
471 if (!mWidgets.isEmpty()) { |
|
472 foreach (HsWidgetHost *widget, mWidgets) { |
|
473 widget->savePresentation(); |
|
474 } |
|
475 } |
|
476 |
|
477 if (!mNewWidgets.isEmpty()) { |
|
478 foreach (HsWidgetHost *widget, mNewWidgets) { |
|
479 widget->savePresentation(); |
|
480 } |
|
481 } |
|
482 } |
|
483 } |
|
484 HsPageVisual *HsPage::visual() const |
|
485 { |
|
486 return mPageVisual; |
|
487 } |