15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 #include <QStateMachine> |
18 #include <QStateMachine> |
19 #include <QGraphicsSceneMouseEvent> |
19 #include <QGraphicsSceneMouseEvent> |
20 #include <QGraphicsLinearLayout> |
|
21 #include <QParallelAnimationGroup> |
|
22 #include <QPropertyAnimation> |
20 #include <QPropertyAnimation> |
23 #include <QApplication> |
21 #include <QApplication> |
24 #include <QDir> |
22 #include <QVariantHash> |
25 |
23 |
26 #include <HbMainWindow> |
24 #include <HbMainWindow> |
27 #include <HbView> |
25 #include <HbView> |
28 #include <HbMenu> |
26 #include <HbMenu> |
29 #include <HbAction> |
27 #include <HbAction> |
30 #include <HbIcon> |
|
31 #include <HbMessageBox> |
28 #include <HbMessageBox> |
32 #include <HbLabel> |
29 #include <HbLabel> |
33 #include <HbInstantFeedback> |
30 #include <HbInstantFeedback> |
34 #include <HbContinuousFeedback> |
31 #include <HbContinuousFeedback> |
|
32 #include <HbPanGesture> |
|
33 #include <HbTapAndHoldGesture> |
|
34 |
35 #ifdef Q_OS_SYMBIAN |
35 #ifdef Q_OS_SYMBIAN |
36 #include <XQSettingsManager> |
36 #include <XQSettingsManager> |
37 #include <startupdomainpskeys.h> |
37 #include <startupdomainpskeys.h> |
38 #endif |
38 #endif |
|
39 |
39 #include "hsidlestate.h" |
40 #include "hsidlestate.h" |
40 #include "hsidlewidget.h" |
41 #include "hsidlewidget.h" |
41 #include "hsdomainmodeldatastructures.h" |
42 #include "hsdomainmodeldatastructures.h" |
42 #include "hsscene.h" |
43 #include "hsscene.h" |
43 #include "hspage.h" |
44 #include "hspage.h" |
44 #include "hswidgethost.h" |
45 #include "hswidgethost.h" |
45 #include "hswallpaper.h" |
46 #include "hswallpaper.h" |
46 #include "hsselectbackgroundstate.h" |
47 #include "hswallpaperselectionstate.h" |
47 #include "hstrashbinwidget.h" |
48 #include "hstrashbinwidget.h" |
48 #include "hspageindicator.h" |
49 #include "hspageindicator.h" |
49 #include "hsmenueventfactory.h" |
50 #include "hsmenueventfactory.h" |
50 #include "hshomescreenstatecommon.h" |
51 #include "hshomescreenstatecommon.h" |
51 #include "hstitleresolver.h" |
52 #include "hstitleresolver.h" |
112 \brief Controller part of the home screen idle state. |
104 \brief Controller part of the home screen idle state. |
113 |
105 |
114 Controls the home screen idle state execution. See the |
106 Controls the home screen idle state execution. See the |
115 state chart below for the state structure. |
107 state chart below for the state structure. |
116 |
108 |
117 \image html hsidlestate_statechart.png |
109 \imageDEPRECATED html hsidlestate_statechart.png |
118 */ |
110 */ |
119 |
111 |
120 /*! |
112 /*! |
121 Constructs a new idle state with the given \a parent. |
113 Constructs a new idle state with the given \a parent. |
122 */ |
114 */ |
123 HsIdleState::HsIdleState(QState *parent) |
115 HsIdleState::HsIdleState(QState *parent) |
124 : QState(parent), |
116 : QState(parent), |
125 mNavigationAction(0), mUiWidget(0), |
117 mNavigationAction(0), mUiWidget(0), |
126 mTitleResolver(0), |
118 mTitleResolver(0), |
127 mZoneAnimation(0), |
119 mZoneAnimation(0), |
128 mPageChanged(false), |
120 mAllowZoneAnimation(false), |
129 mAllowZoneAnimation(true), |
|
130 mPageChangeAnimation(0), |
121 mPageChangeAnimation(0), |
131 mContinuousFeedback(0), |
122 mContinuousFeedback(0), |
132 mTrashBinFeedbackAlreadyPlayed(false), |
123 mTrashBinFeedbackAlreadyPlayed(false), |
133 mDeltaX(0), |
124 mDeltaX(0), |
134 mSceneMenu(0) |
125 mSceneMenu(0), |
|
126 mSnapBorderGap(0.0) |
135 #ifdef Q_OS_SYMBIAN |
127 #ifdef Q_OS_SYMBIAN |
136 ,mSettingsMgr(0) |
128 ,mSettingsMgr(0) |
137 #endif |
129 #endif |
138 { |
130 { |
139 setupStates(); |
131 setupStates(); |
140 mTimer.setSingleShot(true); |
|
141 mTitleResolver = new HsTitleResolver(this); |
132 mTitleResolver = new HsTitleResolver(this); |
142 |
133 |
143 // TODO: Uncomment when updated API available |
134 // TODO: Uncomment when updated API available |
144 //mContinuousFeedback = new HbContinuousFeedback; |
135 //mContinuousFeedback = new HbContinuousFeedback; |
145 //mContinuousFeedback->setContinuousEffect(HbFeedback::ContinuousSmooth); |
136 //mContinuousFeedback->setContinuousEffect(HbFeedback::ContinuousSmooth); |
146 //mContinuousFeedback->setIntensity(HbFeedback::IntensityFull ); |
137 //mContinuousFeedback->setIntensity(HbFeedback::IntensityFull ); |
|
138 |
|
139 mVerticalSnapLineTimer.setSingleShot(true); |
|
140 mHorizontalSnapLineTimer.setSingleShot(true); |
147 } |
141 } |
148 |
142 |
149 /*! |
143 /*! |
150 Destroys this idle state. |
144 Destroys this idle state. |
151 */ |
145 */ |
249 { |
224 { |
250 // States |
225 // States |
251 |
226 |
252 QState *state_waitInput = new QState(this); |
227 QState *state_waitInput = new QState(this); |
253 setInitialState(state_waitInput); |
228 setInitialState(state_waitInput); |
254 QState *state_widgetInteraction = new QState(this); |
|
255 QState *state_sceneInteraction = new QState(this); |
|
256 QState *state_moveWidget = new QState(this); |
229 QState *state_moveWidget = new QState(this); |
257 QState *state_moveScene = new QState(this); |
230 QState *state_moveScene = new QState(this); |
258 QState *state_sceneMenu = new QState(this); |
231 HsWallpaperSelectionState *state_wallpaperSelectionState = |
259 HsSelectBackgroundState *state_selectSceneWallpaper = |
232 new HsWallpaperSelectionState(this); |
260 new HsSelectBackgroundState(this); |
|
261 QState *state_addPage = new QState(this); |
233 QState *state_addPage = new QState(this); |
262 QState *state_removePage = new QState(this); |
234 QState *state_removePage = new QState(this); |
263 QState *state_toggleConnection = new QState(this); |
235 QState *state_toggleConnection = new QState(this); |
264 |
236 |
265 // Transitions |
237 // Transitions |
266 |
238 |
267 state_waitInput->addTransition( |
|
268 this, SIGNAL(event_widgetInteraction()), state_widgetInteraction); |
|
269 state_waitInput->addTransition( |
|
270 this, SIGNAL(event_sceneInteraction()), state_sceneInteraction); |
|
271 state_waitInput->addTransition( |
239 state_waitInput->addTransition( |
272 this, SIGNAL(event_addPage()), state_addPage); |
240 this, SIGNAL(event_addPage()), state_addPage); |
273 state_waitInput->addTransition( |
241 state_waitInput->addTransition( |
274 this, SIGNAL(event_removePage()), state_removePage); |
242 this, SIGNAL(event_removePage()), state_removePage); |
275 state_waitInput->addTransition( |
243 state_waitInput->addTransition( |
276 this, SIGNAL(event_toggleConnection()), state_toggleConnection); |
244 this, SIGNAL(event_toggleConnection()), state_toggleConnection); |
277 state_waitInput->addTransition( |
245 state_waitInput->addTransition( |
278 this, SIGNAL(event_selectSceneWallpaper()), state_selectSceneWallpaper); |
246 this, SIGNAL(event_selectWallpaper()), state_wallpaperSelectionState); |
279 |
247 state_waitInput->addTransition( |
280 state_widgetInteraction->addTransition( |
248 this, SIGNAL(event_moveScene()), state_moveScene); |
281 this, SIGNAL(event_waitInput()), state_waitInput); |
249 state_waitInput->addTransition( |
282 state_widgetInteraction->addTransition( |
|
283 this, SIGNAL(event_moveWidget()), state_moveWidget); |
250 this, SIGNAL(event_moveWidget()), state_moveWidget); |
284 state_widgetInteraction->addTransition( |
|
285 this, SIGNAL(event_moveScene()), state_moveScene); |
|
286 |
|
287 state_sceneInteraction->addTransition( |
|
288 this, SIGNAL(event_waitInput()), state_waitInput); |
|
289 state_sceneInteraction->addTransition( |
|
290 this, SIGNAL(event_moveScene()), state_moveScene); |
|
291 state_sceneInteraction->addTransition( |
|
292 this, SIGNAL(event_sceneMenu()), state_sceneMenu); |
|
293 |
251 |
294 state_moveWidget->addTransition( |
252 state_moveWidget->addTransition( |
295 this, SIGNAL(event_waitInput()), state_waitInput); |
253 this, SIGNAL(event_waitInput()), state_waitInput); |
296 |
254 |
297 state_moveScene->addTransition( |
255 state_moveScene->addTransition( |
298 this, SIGNAL(event_waitInput()), state_waitInput); |
256 this, SIGNAL(event_waitInput()), state_waitInput); |
299 |
257 |
300 state_sceneMenu->addTransition( |
258 state_wallpaperSelectionState->addTransition( |
301 this, SIGNAL(event_waitInput()), state_waitInput); |
259 state_wallpaperSelectionState, SIGNAL(event_waitInput()), state_waitInput); |
302 state_sceneMenu->addTransition( |
|
303 this, SIGNAL(event_selectSceneWallpaper()), state_selectSceneWallpaper); |
|
304 state_sceneMenu->addTransition( |
|
305 this, SIGNAL(event_addPage()), state_addPage); |
|
306 |
|
307 state_selectSceneWallpaper->addTransition( |
|
308 state_selectSceneWallpaper, SIGNAL(event_waitInput()), state_waitInput); |
|
309 |
260 |
310 state_addPage->addTransition(state_waitInput); |
261 state_addPage->addTransition(state_waitInput); |
311 |
262 |
312 state_removePage->addTransition(state_waitInput); |
263 state_removePage->addTransition(state_waitInput); |
313 |
264 |
325 EXIT_ACTION(this, action_idle_cleanupView) |
276 EXIT_ACTION(this, action_idle_cleanupView) |
326 EXIT_ACTION(this, action_idle_disconnectOrientationChangeEventHandler) |
277 EXIT_ACTION(this, action_idle_disconnectOrientationChangeEventHandler) |
327 EXIT_ACTION(this, action_idle_uninstallEventFilter) |
278 EXIT_ACTION(this, action_idle_uninstallEventFilter) |
328 |
279 |
329 ENTRY_ACTION(state_waitInput, action_waitInput_updateOptionsMenu) |
280 ENTRY_ACTION(state_waitInput, action_waitInput_updateOptionsMenu) |
330 ENTRY_ACTION(state_waitInput, action_waitInput_connectMouseEventHandlers) |
281 ENTRY_ACTION(state_waitInput, action_waitInput_connectGestureHandlers) |
331 ENTRY_ACTION(state_waitInput, action_waitInput_publishIdleKey) |
282 ENTRY_ACTION(state_waitInput, action_waitInput_publishIdleKey) |
332 EXIT_ACTION(state_waitInput, action_waitInput_disconnectMouseEventHandlers) |
283 EXIT_ACTION(state_waitInput, action_waitInput_disconnectGestureHandlers) |
333 |
284 EXIT_ACTION(state_waitInput, action_waitInput_resetNewWidgets) |
334 ENTRY_ACTION(state_widgetInteraction, action_widgetInteraction_connectMouseEventHandlers) |
|
335 ENTRY_ACTION(state_widgetInteraction, action_widgetInteraction_connectGestureTimers) |
|
336 EXIT_ACTION(state_widgetInteraction, action_widgetInteraction_disconnectMouseEventHandlers) |
|
337 EXIT_ACTION(state_widgetInteraction, action_widgetInteraction_disconnectGestureTimers) |
|
338 |
|
339 ENTRY_ACTION(state_sceneInteraction, action_sceneInteraction_connectMouseEventHandlers) |
|
340 ENTRY_ACTION(state_sceneInteraction, action_sceneInteraction_connectGestureTimers) |
|
341 EXIT_ACTION(state_sceneInteraction, action_sceneInteraction_disconnectMouseEventHandlers) |
|
342 EXIT_ACTION(state_sceneInteraction, action_sceneInteraction_disconnectGestureTimers) |
|
343 |
285 |
344 ENTRY_ACTION(state_moveWidget, action_moveWidget_reparentToControlLayer) |
286 ENTRY_ACTION(state_moveWidget, action_moveWidget_reparentToControlLayer) |
345 ENTRY_ACTION(state_moveWidget, action_moveWidget_startWidgetDragEffect) |
287 ENTRY_ACTION(state_moveWidget, action_moveWidget_startWidgetDragEffect) |
346 ENTRY_ACTION(state_moveWidget, action_moveWidget_connectMouseEventHandlers) |
288 ENTRY_ACTION(state_moveWidget, action_moveWidget_connectGestureHandlers) |
|
289 ENTRY_ACTION(state_moveWidget, action_moveWidget_setWidgetSnap) |
347 |
290 |
348 EXIT_ACTION(state_moveWidget, action_moveWidget_reparentToPage) |
291 EXIT_ACTION(state_moveWidget, action_moveWidget_reparentToPage) |
349 EXIT_ACTION(state_moveWidget, action_moveWidget_startWidgetDropEffect) |
292 EXIT_ACTION(state_moveWidget, action_moveWidget_startWidgetDropEffect) |
350 EXIT_ACTION(state_moveWidget, action_moveWidget_disconnectMouseEventHandlers) |
293 EXIT_ACTION(state_moveWidget, action_moveWidget_disconnectGestureHandlers) |
351 |
294 EXIT_ACTION(state_moveWidget, action_moveWidget_preventZoneAnimation) |
352 ENTRY_ACTION(state_moveScene, action_moveScene_connectMouseEventHandlers) |
295 EXIT_ACTION(state_moveWidget, action_moveWidget_deleteWidgetSnap) |
|
296 |
|
297 ENTRY_ACTION(state_moveScene, action_moveScene_connectGestureHandlers) |
353 EXIT_ACTION(state_moveScene, action_moveScene_moveToNearestPage) |
298 EXIT_ACTION(state_moveScene, action_moveScene_moveToNearestPage) |
354 EXIT_ACTION(state_moveScene, action_moveScene_disconnectMouseEventHandlers) |
299 EXIT_ACTION(state_moveScene, action_moveScene_disconnectGestureHandlers) |
355 |
300 |
356 ENTRY_ACTION(state_sceneMenu, action_sceneMenu_showMenu) |
|
357 |
|
358 ENTRY_ACTION(state_addPage, action_disableUserInteraction) |
|
359 ENTRY_ACTION(state_addPage, action_addPage_addPage) |
301 ENTRY_ACTION(state_addPage, action_addPage_addPage) |
360 EXIT_ACTION(state_addPage, action_enableUserInteraction) |
302 |
361 |
|
362 ENTRY_ACTION(state_removePage, action_disableUserInteraction) |
|
363 ENTRY_ACTION(state_removePage, action_removePage_removePage) |
303 ENTRY_ACTION(state_removePage, action_removePage_removePage) |
364 EXIT_ACTION(state_removePage, action_enableUserInteraction) |
304 |
365 |
|
366 ENTRY_ACTION(state_toggleConnection, action_disableUserInteraction) |
|
367 ENTRY_ACTION(state_toggleConnection, action_toggleConnection_toggleConnection) |
305 ENTRY_ACTION(state_toggleConnection, action_toggleConnection_toggleConnection) |
368 EXIT_ACTION(state_toggleConnection, action_enableUserInteraction) |
|
369 } |
306 } |
370 |
307 |
371 /*! |
308 /*! |
372 Computes the page layer x position based on the given \a pageIndex. |
309 Computes the page layer x position based on the given \a pageIndex. |
373 */ |
310 */ |
374 qreal HsIdleState::pageLayerXPos(int pageIndex) const |
311 qreal HsIdleState::pageLayerXPos(int pageIndex) const |
375 { |
312 { |
376 return -pageIndex * HsScene::mainWindow()->layoutRect().width() - 0.5; |
313 return -pageIndex * HsScene::mainWindow()->layoutRect().width(); |
377 } |
314 } |
378 |
315 |
379 /*! |
316 /*! |
380 Starts the page change animation based on the given \a targetPageIndex |
317 Starts the page change animation based on the given \a targetPageIndex |
381 and \a duration. |
318 and \a duration. |
382 */ |
319 */ |
383 void HsIdleState::startPageChangeAnimation(int targetPageIndex, int duration) |
320 void HsIdleState::startPageChangeAnimation(int targetPageIndex, int duration) |
384 { |
321 { |
385 if (!mPageChangeAnimation) { |
322 if (!mPageChangeAnimation) { |
386 mPageChangeAnimation = new QParallelAnimationGroup(this); |
323 mPageChangeAnimation = new QPropertyAnimation(mUiWidget, "sceneX"); |
387 |
324 } |
388 QPropertyAnimation *animation = new QPropertyAnimation(mUiWidget->pageLayer(), "x"); |
325 else if (mPageChangeAnimation->state() != QAbstractAnimation::Stopped) { |
389 animation->setEndValue(pageLayerXPos(targetPageIndex)); |
326 mPageChangeAnimation->stop(); |
390 animation->setDuration(duration); |
327 } |
391 mPageChangeAnimation->addAnimation(animation); |
328 |
392 |
329 mPageChangeAnimation->setEndValue(pageLayerXPos(targetPageIndex)); |
393 animation = new QPropertyAnimation(mUiWidget->sceneLayer(), "x"); |
330 mPageChangeAnimation->setDuration(duration); |
394 animation->setEndValue((parallaxFactor() * pageLayerXPos(targetPageIndex)) - HsConfiguration::bounceEffect() / 2); |
331 connect(mPageChangeAnimation, |
395 animation->setDuration(duration); |
332 SIGNAL(finished()), |
396 mPageChangeAnimation->addAnimation(animation); |
333 SLOT(pageChangeAnimationFinished()), |
397 } |
334 Qt::UniqueConnection); |
398 else { |
|
399 if (QAbstractAnimation::Stopped != mPageChangeAnimation->state()) { |
|
400 mPageChangeAnimation->stop(); |
|
401 } |
|
402 QAbstractAnimation *animation = mPageChangeAnimation->animationAt(0); |
|
403 |
|
404 qobject_cast<QPropertyAnimation*>(animation)->setEndValue(pageLayerXPos(targetPageIndex)); |
|
405 qobject_cast<QPropertyAnimation*>(animation)->setDuration(duration); |
|
406 |
|
407 animation = mPageChangeAnimation->animationAt(1); |
|
408 qobject_cast<QPropertyAnimation*>(animation)->setEndValue((parallaxFactor() * pageLayerXPos(targetPageIndex)) - HsConfiguration::bounceEffect() / 2); |
|
409 qobject_cast<QPropertyAnimation*>(animation)->setDuration(duration); |
|
410 } |
|
411 mPageChangeAnimation->start(); |
335 mPageChangeAnimation->start(); |
412 HbInstantFeedback::play(HsConfiguration::pageChangeFeedbackType()); |
336 |
|
337 HbInstantFeedback::play(HSCONFIGURATION_GET(pageChangeFeedbackEffect)); |
|
338 |
413 mUiWidget->showPageIndicator(); |
339 mUiWidget->showPageIndicator(); |
414 mUiWidget->setActivePage(targetPageIndex); |
340 mUiWidget->setActivePage(targetPageIndex); |
415 } |
341 } |
416 |
342 |
417 /*! |
343 /*! |
424 int targetPageIndex = scene->activePageIndex(); |
350 int targetPageIndex = scene->activePageIndex(); |
425 |
351 |
426 if (isInLeftPageChangeZone() && 0 < targetPageIndex) { |
352 if (isInLeftPageChangeZone() && 0 < targetPageIndex) { |
427 --targetPageIndex; |
353 --targetPageIndex; |
428 } else if (isInRightPageChangeZone() && |
354 } else if (isInRightPageChangeZone() && |
429 targetPageIndex < scene->maximumPageCount()-1) { |
355 targetPageIndex < HSCONFIGURATION_GET(maximumPageCount) - 1) { |
430 ++targetPageIndex; |
356 ++targetPageIndex; |
431 } else { |
357 } else { |
432 mAllowZoneAnimation = true; |
|
433 return; |
358 return; |
434 } |
359 } |
435 |
360 |
436 if (targetPageIndex == scene->pages().count() |
|
437 && scene->pages().last()->widgets().isEmpty()) { |
|
438 mAllowZoneAnimation = true; |
|
439 return; |
|
440 } |
|
441 |
|
442 if (!mZoneAnimation) { |
361 if (!mZoneAnimation) { |
443 mZoneAnimation = new QPropertyAnimation(mUiWidget->sceneLayer(), "x"); |
362 mZoneAnimation = new QPropertyAnimation(mUiWidget, "sceneX"); |
444 } |
363 } |
445 |
364 |
446 int bounceEffect = HsConfiguration::bounceEffect(); |
365 int bounceEffect = HSCONFIGURATION_GET(bounceEffect); |
447 |
366 |
448 if (isInLeftPageChangeZone()) { |
367 if (isInLeftPageChangeZone()) { |
449 mZoneAnimation->setEndValue(((parallaxFactor() * pageLayerXPos(scene->activePageIndex()))-bounceEffect/2)+bounceEffect/2); |
368 mZoneAnimation->setEndValue(pageLayerXPos(scene->activePageIndex()) + bounceEffect); |
450 } else { |
369 } else { |
451 mZoneAnimation->setEndValue(((parallaxFactor() * pageLayerXPos(scene->activePageIndex()))-bounceEffect/2)-bounceEffect/2); |
370 mZoneAnimation->setEndValue(pageLayerXPos(scene->activePageIndex()) - bounceEffect); |
452 } |
371 } |
453 mZoneAnimation->setDuration(duration); |
372 mZoneAnimation->setDuration(duration); |
454 mZoneAnimation->setDirection(QAbstractAnimation::Forward); |
373 mZoneAnimation->setDirection(QAbstractAnimation::Forward); |
455 |
374 |
456 connect(mZoneAnimation, |
375 connect(mZoneAnimation, |
457 SIGNAL(finished()), |
376 SIGNAL(finished()), |
458 SLOT(zoneAnimationFinished())); |
377 SLOT(zoneAnimationFinished())); |
|
378 |
459 mZoneAnimation->start(); |
379 mZoneAnimation->start(); |
460 mPageChanged = true; |
|
461 } |
380 } |
462 |
381 |
463 /*! |
382 /*! |
464 Checks if the active widget is located inside the left or right |
383 Checks if the active widget is located inside the left or right |
465 page change zone. |
384 page change zone. |
501 HsScene::instance()->addPage(page); |
420 HsScene::instance()->addPage(page); |
502 mUiWidget->insertPage(pageIndex, page); |
421 mUiWidget->insertPage(pageIndex, page); |
503 } |
422 } |
504 |
423 |
505 /*! |
424 /*! |
506 Computes the parallax factor based on the current scene and |
|
507 page layer widths, and page count. |
|
508 */ |
|
509 qreal HsIdleState::parallaxFactor() const |
|
510 { |
|
511 qreal clw = mUiWidget->controlLayer()->size().width(); |
|
512 qreal slw = mUiWidget->sceneLayer()->size().width() - HsConfiguration::bounceEffect(); |
|
513 int n = HsScene::instance()->pages().count(); |
|
514 if (n < 2) { |
|
515 return 1; |
|
516 } else { |
|
517 return (slw - clw) / ((n - 1) * clw); |
|
518 } |
|
519 } |
|
520 |
|
521 /*! |
|
522 Checks if page change zone animation needs to be started or stopped |
425 Checks if page change zone animation needs to be started or stopped |
523 */ |
426 */ |
524 void HsIdleState::updateZoneAnimation() |
427 void HsIdleState::updateZoneAnimation() |
525 { |
428 { |
526 if (isInPageChangeZone() && mAllowZoneAnimation) { |
429 if (isInPageChangeZone() && mAllowZoneAnimation) { |
527 if (!mZoneAnimation) { |
430 if (!mZoneAnimation && (!mPageChangeAnimation |
528 /* We don't want to create another animation |
431 || mPageChangeAnimation->state() == QAbstractAnimation::Stopped )) { |
529 before previous is finished */ |
432 startPageChangeZoneAnimation(HSCONFIGURATION_GET(pageChangeZoneAnimationDuration)); |
530 mAllowZoneAnimation = false; |
433 } |
531 startPageChangeZoneAnimation(HsConfiguration::pageChangeZoneAnimationDuration()); |
434 } else if (mZoneAnimation && !isInPageChangeZone()) { |
532 } |
|
533 } |
|
534 else if (mZoneAnimation && !isInPageChangeZone()) { |
|
535 if (mZoneAnimation->state() == QAbstractAnimation::Running) { |
435 if (mZoneAnimation->state() == QAbstractAnimation::Running) { |
536 if (mZoneAnimation->direction() == QAbstractAnimation::Forward) { |
436 if (mZoneAnimation->direction() == QAbstractAnimation::Forward) { |
537 mPageChanged = false; |
437 mZoneAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration)); |
538 mZoneAnimation->setDuration(HsConfiguration::pageChangeZoneReverseAnimationDuration()); |
438 mZoneAnimation->setDirection(QAbstractAnimation::Backward); |
539 mZoneAnimation->setDirection(QAbstractAnimation::Backward); |
|
540 } |
439 } |
541 } |
440 } else { |
542 else { |
|
543 // Out of the page change zone. Delete animation. |
441 // Out of the page change zone. Delete animation. |
544 delete mZoneAnimation; |
442 deleteZoneAnimation(); |
545 mZoneAnimation = NULL; |
443 } |
546 mAllowZoneAnimation = true; |
444 } else if (!isInPageChangeZone()) { |
547 } |
445 if (mZoneAnimation) { |
548 } |
446 mZoneAnimation->stop(); |
549 else if (!isInPageChangeZone()) { |
447 } |
550 /* Zone animation finished and deleted. |
|
551 New animation can be launched. */ |
|
552 mAllowZoneAnimation = true; |
|
553 } |
448 } |
554 } |
449 } |
555 |
450 |
556 /*! |
451 /*! |
557 Selects which trash bin icon is shown or not shown at all |
452 Selects which trash bin icon is shown or not shown at all |
558 */ |
453 */ |
559 void HsIdleState::showTrashBin() |
454 void HsIdleState::showTrashBin() |
560 { |
455 { |
561 if (mUiWidget->trashBin()->isUnderMouse()) { |
456 if (mUiWidget->trashBin()->isUnderMouse()) { |
562 if (!mTrashBinFeedbackAlreadyPlayed) { |
457 if (!mTrashBinFeedbackAlreadyPlayed) { |
563 HbInstantFeedback::play(HsConfiguration::widgetOverTrashbinFeedbackType()); |
458 HbInstantFeedback::play(HSCONFIGURATION_GET(widgetOverTrashbinFeedbackEffect)); |
564 mTrashBinFeedbackAlreadyPlayed = true; |
459 mTrashBinFeedbackAlreadyPlayed = true; |
565 } |
460 } |
566 mUiWidget->trashBin()->activate(); |
461 mUiWidget->trashBin()->activate(); |
567 } else { |
462 } else { |
568 mUiWidget->trashBin()->deactivate(); |
463 mUiWidget->trashBin()->deactivate(); |
584 |
479 |
585 int pageIndex = scene->activePageIndex(); |
480 int pageIndex = scene->activePageIndex(); |
586 |
481 |
587 mUiWidget->removePage(pageIndex); |
482 mUiWidget->removePage(pageIndex); |
588 scene->removePage(page); |
483 scene->removePage(page); |
|
484 |
|
485 if (page->wallpaper()) { |
|
486 page->wallpaper()->remove(); |
|
487 } |
589 delete page; |
488 delete page; |
590 |
489 |
591 pageIndex = pageIndex == 0 ? 0 : pageIndex - 1; |
490 pageIndex = pageIndex == 0 ? 0 : pageIndex - 1; |
592 scene->setActivePageIndex(pageIndex); |
491 scene->setActivePageIndex(pageIndex); |
593 |
492 |
594 startPageChangeAnimation(pageIndex, HsConfiguration::pageRemovedAnimationDuration()); |
493 startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageRemovedAnimationDuration)); |
595 |
494 |
596 mUiWidget->pageIndicator()->removeItem(pageIndex); |
495 mUiWidget->pageIndicator()->removeItem(pageIndex); |
597 mUiWidget->setActivePage(pageIndex); |
496 mUiWidget->setActivePage(pageIndex); |
598 mUiWidget->showPageIndicator(); |
497 mUiWidget->showPageIndicator(); |
599 } |
498 } |
600 |
499 |
601 /*! |
500 /*! |
602 Disables the main window user interaction. |
501 Deletes page change zone animation. |
603 */ |
502 */ |
604 void HsIdleState::action_disableUserInteraction() |
503 void HsIdleState::deleteZoneAnimation() |
605 { |
504 { |
606 HsScene::mainWindow()->setInteractive(false); |
505 delete mZoneAnimation; |
607 } |
506 mZoneAnimation = NULL; |
608 |
|
609 /*! |
|
610 Enables the main window user interaction. |
|
611 */ |
|
612 void HsIdleState::action_enableUserInteraction() |
|
613 { |
|
614 HsScene::mainWindow()->setInteractive(true); |
|
615 } |
507 } |
616 |
508 |
617 /*! |
509 /*! |
618 If called for the first time, setups the idle view. |
510 If called for the first time, setups the idle view. |
619 Updates the soft key action and sets the idle view |
511 Updates the soft key action and sets the idle view |
664 } |
557 } |
665 |
558 |
666 /*! |
559 /*! |
667 |
560 |
668 */ |
561 */ |
669 void HsIdleState::onAddContentActionTriggered() |
562 void HsIdleState::onAddContentFromContextMenuActionTriggered() |
670 { |
563 { |
|
564 /* include position information in homescreen data, |
|
565 which passed around in applib and returned when adding content |
|
566 */ |
|
567 QVariant homescreenData(mPageHotSpot); |
671 machine()->postEvent( |
568 machine()->postEvent( |
672 HsMenuEventFactory::createOpenAppLibraryEvent(AddHsMenuMode)); |
569 HsMenuEventFactory::createOpenAppLibraryEvent(AddHsMenuMode, homescreenData)); |
|
570 mPageHotSpot = QPointF(); |
|
571 } |
|
572 |
|
573 /*! |
|
574 |
|
575 */ |
|
576 void HsIdleState::onAddContentFromOptionsMenuActionTriggered() |
|
577 { |
|
578 machine()->postEvent( |
|
579 HsMenuEventFactory::createOpenAppLibraryEvent(AddHsMenuMode)); |
673 } |
580 } |
674 |
581 |
675 /*! |
582 /*! |
676 Disconnects the idle view's title. |
583 Disconnects the idle view's title. |
677 */ |
584 */ |
678 void HsIdleState::action_idle_cleanupTitle() |
585 void HsIdleState::action_idle_cleanupTitle() |
679 { |
586 { |
680 mTitleResolver->disconnect(this); |
587 mTitleResolver->disconnect(this); |
|
588 } |
|
589 |
|
590 #ifdef COVERAGE_MEASUREMENT |
|
591 #pragma CTC SKIP |
|
592 #endif //COVERAGE_MEASUREMENT |
|
593 /*! |
|
594 |
|
595 */ |
|
596 void HsIdleState::onPageTapAndHoldFinished(QGestureEvent *event) |
|
597 { |
|
598 mPageHotSpot = qobject_cast<HbTapAndHoldGesture *>( |
|
599 event->gesture(Qt::TapAndHoldGesture))->scenePosition(); |
|
600 |
|
601 mSceneMenu = new HbMenu(); |
|
602 mSceneMenu->setObjectName("hs_ctx_menu"); |
|
603 mSceneMenu->setAttribute(Qt::WA_DeleteOnClose); |
|
604 |
|
605 HbAction *action = mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent), this, |
|
606 SLOT(onAddContentFromContextMenuActionTriggered())); |
|
607 action->setObjectName("action_add_content_ctx_menu"); |
|
608 |
|
609 HsScene *scene = HsScene::instance(); |
|
610 if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) { |
|
611 action = mSceneMenu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage), this, SIGNAL(event_addPage())); |
|
612 action->setObjectName("action_add_page_ctx_menu"); |
|
613 } |
|
614 |
|
615 action = mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper), this, SIGNAL(event_selectWallpaper())); |
|
616 action->setObjectName("action_change_wallpaper_ctx_menu"); |
|
617 mSceneMenu->setPreferredPos(mPageHotSpot); |
|
618 mSceneMenu->open(); |
|
619 } |
|
620 #ifdef COVERAGE_MEASUREMENT |
|
621 #pragma CTC ENDSKIP |
|
622 #endif //COVERAGE_MEASUREMENT |
|
623 |
|
624 void HsIdleState::onPagePanStarted(QGestureEvent *event) |
|
625 { |
|
626 Q_UNUSED(event) |
|
627 emit event_moveScene(); |
|
628 } |
|
629 |
|
630 void HsIdleState::onPagePanUpdated(QGestureEvent *event) |
|
631 { |
|
632 HbPanGesture *gesture = qobject_cast<HbPanGesture *>( |
|
633 event->gesture(Qt::PanGesture)); |
|
634 |
|
635 mDeltaX = gesture->sceneOffset().x(); |
|
636 |
|
637 HsScene *scene = HsScene::instance(); |
|
638 int bounceEffect = HSCONFIGURATION_GET(bounceEffect); |
|
639 qreal x = qBound(pageLayerXPos(scene->pages().count() - 1) - bounceEffect / 2 / mUiWidget->parallaxFactor(), |
|
640 pageLayerXPos(scene->activePageIndex()) + mDeltaX, |
|
641 pageLayerXPos(0) + (bounceEffect / 2 / mUiWidget->parallaxFactor())); |
|
642 |
|
643 mUiWidget->setSceneX(x); |
|
644 } |
|
645 |
|
646 void HsIdleState::onPagePanFinished(QGestureEvent *event) |
|
647 { |
|
648 HbPanGesture *gesture = qobject_cast<HbPanGesture *>( |
|
649 event->gesture(Qt::PanGesture)); |
|
650 mDeltaX = gesture->sceneOffset().x(); |
|
651 emit event_waitInput(); |
|
652 } |
|
653 |
|
654 void HsIdleState::onWidgetTapStarted(HsWidgetHost *widget) |
|
655 { |
|
656 HsScene *scene = HsScene::instance(); |
|
657 scene->setActiveWidget(widget); |
|
658 HsPage *page = scene->activePage(); |
|
659 QMetaObject::invokeMethod(page, "updateZValues", Qt::QueuedConnection); |
|
660 } |
|
661 |
|
662 void HsIdleState::onWidgetTapAndHoldFinished(QGestureEvent *event, HsWidgetHost *widget) |
|
663 { |
|
664 HsScene *scene = HsScene::instance(); |
|
665 scene->setActiveWidget(widget); |
|
666 |
|
667 mWidgetHotSpot = qobject_cast<HbTapAndHoldGesture *>( |
|
668 event->gesture(Qt::TapAndHoldGesture))->scenePosition(); |
|
669 mWidgetHotSpotOffset = mWidgetHotSpot - widget->pos(); |
|
670 |
|
671 emit event_moveWidget(); |
|
672 } |
|
673 |
|
674 void HsIdleState::onWidgetMoveUpdated(const QPointF &scenePos, HsWidgetHost *widget) |
|
675 { |
|
676 HsScene *scene = HsScene::instance(); |
|
677 QRectF widgetRect = widget->geometry(); |
|
678 |
|
679 // Move widget to new position. |
|
680 mWidgetHotSpot = scenePos; |
|
681 |
|
682 widgetRect.moveTopLeft(mWidgetHotSpot - mWidgetHotSpotOffset); |
|
683 |
|
684 // Widget can be moved over the pages left border. |
|
685 qreal lowerBoundX = -widgetRect.width(); |
|
686 HsPage *page = scene->activePage(); |
|
687 QRectF pageRect = HsGui::idleView()->rect(); |
|
688 // Widget can be moved over the pages right border. |
|
689 qreal upperBoundX = pageRect.width(); |
|
690 |
|
691 // Notice that chrome height is 64 pixels. |
|
692 qreal lowerBoundY = qreal(64) - widgetRect.height(); |
|
693 // Widget can be moved over the pages down border. |
|
694 qreal upperBoundY = pageRect.height(); |
|
695 |
|
696 qreal widgetX = qBound(lowerBoundX, widgetRect.x(), upperBoundX); |
|
697 qreal widgetY = qBound(lowerBoundY, widgetRect.y(), upperBoundY); |
|
698 // If using ItemClipsChildrenToShape-flag in widgethost then |
|
699 // setPos does not update position here, however setGeometry does it, QT bug? |
|
700 widget->setGeometry(widgetX, widgetY, widgetRect.width(), widgetRect.height()); |
|
701 |
|
702 if (HSCONFIGURATION_GET(isSnapEnabled)) { |
|
703 mSnapResult = HsWidgetPositioningOnWidgetMove::instance()->run(widget->sceneBoundingRect()); |
|
704 |
|
705 if (HSCONFIGURATION_GET(isSnapEffectsEnabled)) { |
|
706 if (mSnapResult.hasHorizontalSnap) { |
|
707 showVerticalLine(); |
|
708 } |
|
709 else { |
|
710 hideVerticalLine(); |
|
711 } |
|
712 if (mSnapResult.hasVerticalSnap) { |
|
713 showHorizontalLine(); |
|
714 } |
|
715 else { |
|
716 hideHorizontalLine(); |
|
717 } |
|
718 } |
|
719 |
|
720 mPreviousSnapResult = mSnapResult; |
|
721 } |
|
722 |
|
723 |
|
724 int bounceFeedbackEffectDistance = HSCONFIGURATION_GET(bounceFeedbackEffectDistance); |
|
725 // Handle effects: |
|
726 // User is indicated by a tactile feedback if he/she is trying to move |
|
727 // widget over the first or the last page. |
|
728 if( (page == scene->pages().first() && mWidgetHotSpot.x() < bounceFeedbackEffectDistance ) || |
|
729 (page == scene->pages().last() && scene->pages().count() == HSCONFIGURATION_GET(maximumPageCount) |
|
730 && mWidgetHotSpot.x() > pageRect.width() - bounceFeedbackEffectDistance)) { |
|
731 HbInstantFeedback::play(HSCONFIGURATION_GET(widgetMoveBlockedFeedbackEffect)); |
|
732 // TODO: use code below when Orbit has updated ContinuousFeedback API |
|
733 //if (!mContinuousFeedback->isPlaying()) { |
|
734 // mContinuousFeedback->play(); |
|
735 //} |
|
736 } |
|
737 else /*if (mContinuousFeedback->isPlaying())*/ { |
|
738 //mContinuousFeedback->stop(); |
|
739 } |
|
740 |
|
741 updateZoneAnimation(); |
|
742 showTrashBin(); |
|
743 } |
|
744 |
|
745 void HsIdleState::onWidgetMoveFinished(const QPointF &scenePos, HsWidgetHost *widget) |
|
746 { |
|
747 Q_UNUSED(scenePos) |
|
748 Q_UNUSED(widget) |
|
749 emit event_waitInput(); |
681 } |
750 } |
682 |
751 |
683 /*! |
752 /*! |
684 Lays out the active page's new widgets that were added |
753 Lays out the active page's new widgets that were added |
685 from the application library. |
754 from the application library. |
796 void HsIdleState::action_waitInput_updateOptionsMenu() |
872 void HsIdleState::action_waitInput_updateOptionsMenu() |
797 { |
873 { |
798 HsScene *scene = HsScene::instance(); |
874 HsScene *scene = HsScene::instance(); |
799 |
875 |
800 HbMenu *menu = new HbMenu(); |
876 HbMenu *menu = new HbMenu(); |
801 |
877 menu->setObjectName("hs_menu"); |
802 // Task switcher |
878 // Task switcher |
803 menu->addAction(hbTrId(hsLocTextId_OptionsMenu_TaskSwitcher), |
879 HbAction *action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_TaskSwitcher), |
804 this, SLOT(openTaskSwitcher())); |
880 this, SLOT(openTaskSwitcher())); |
805 |
881 action->setObjectName("action_open_task_switcher"); |
806 // Add content |
882 // Add content |
807 menu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent), |
883 action = menu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent), |
808 this, SLOT(onAddContentActionTriggered())); |
884 this, SLOT(onAddContentFromOptionsMenuActionTriggered())); |
809 |
885 action->setObjectName("action_add_content"); |
810 // Add page |
886 // Add page |
811 if (scene->pages().count() < scene->maximumPageCount()) { |
887 if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) { |
812 menu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage), |
888 action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage), |
813 this, SIGNAL(event_addPage())); |
889 this, SIGNAL(event_addPage())); |
|
890 action->setObjectName("action_add_page"); |
|
891 |
814 } |
892 } |
815 |
893 |
816 // Change wallpaper |
894 // Change wallpaper |
817 menu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper), |
895 action = menu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper), |
818 this, SIGNAL(event_selectSceneWallpaper())); |
896 this, SIGNAL(event_selectWallpaper())); |
819 |
897 action->setObjectName("action_change_wallpaper"); |
820 // Remove page |
898 // Remove page |
821 if (scene->activePage()->isRemovable()) { |
899 if (scene->activePage()->isRemovable()) { |
822 menu->addAction(hbTrId(hsLocTextId_OptionsMenu_RemovePage), |
900 action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_RemovePage), |
823 this, SIGNAL(event_removePage())); |
901 this, SIGNAL(event_removePage())); |
|
902 action->setObjectName("action_remove_page"); |
824 } |
903 } |
825 |
904 |
826 // Online / Offline |
905 // Online / Offline |
827 if (scene->isOnline()) { |
906 if (scene->isOnline()) { |
828 menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOffline), |
907 action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOffline), |
829 this, SIGNAL(event_toggleConnection())); |
908 this, SIGNAL(event_toggleConnection())); |
|
909 action->setObjectName("action_to_offline"); |
830 } else { |
910 } else { |
831 menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOnline), |
911 action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOnline), |
832 this, SIGNAL(event_toggleConnection())); |
912 this, SIGNAL(event_toggleConnection())); |
|
913 action->setObjectName("action_to_online"); |
833 } |
914 } |
834 |
915 |
835 HsGui::idleView()->setMenu(menu); |
916 HsGui::idleView()->setMenu(menu); |
836 } |
917 } |
837 |
918 |
838 /*! |
919 void HsIdleState::action_waitInput_connectGestureHandlers() |
839 Connects the waitInput state's mouse event handlers. |
920 { |
840 */ |
921 HsScene *scene = HsScene::instance(); |
841 void HsIdleState::action_waitInput_connectMouseEventHandlers() |
922 |
842 { |
923 connect(scene, |
843 CONNECT_MOUSE_EVENT_HANDLER(mousePressed, waitInput_onMousePressed) |
924 SIGNAL(pageTapAndHoldFinished(QGestureEvent*)), |
844 } |
925 SLOT(onPageTapAndHoldFinished(QGestureEvent*)), |
845 |
926 Qt::UniqueConnection); |
846 /*! |
927 |
847 Disconnects the waitInput state's mouse event handlers. |
928 connect(scene, |
848 */ |
929 SIGNAL(pagePanStarted(QGestureEvent*)), |
849 void HsIdleState::action_waitInput_disconnectMouseEventHandlers() |
930 SLOT(onPagePanStarted(QGestureEvent*)), |
850 { |
931 Qt::UniqueConnection); |
851 DISCONNECT_MOUSE_EVENT_HANDLER(mousePressed, waitInput_onMousePressed) |
932 |
852 } |
933 connect(scene, |
853 |
934 SIGNAL(widgetTapStarted(HsWidgetHost*)), |
854 /*! |
935 SLOT(onWidgetTapStarted(HsWidgetHost*)), |
855 Connects the widgetInteraction state's mouse event handlers. |
936 Qt::UniqueConnection); |
856 */ |
937 |
857 void HsIdleState::action_widgetInteraction_connectMouseEventHandlers() |
938 connect(scene, |
858 { |
939 SIGNAL(widgetTapAndHoldFinished(QGestureEvent*,HsWidgetHost*)), |
859 CONNECT_MOUSE_EVENT_HANDLER(mouseMoved, widgetInteraction_onMouseMoved) |
940 SLOT(onWidgetTapAndHoldFinished(QGestureEvent*,HsWidgetHost*)), |
860 CONNECT_MOUSE_EVENT_HANDLER(mouseReleased, widgetInteraction_onMouseReleased) |
941 Qt::UniqueConnection); |
861 } |
942 } |
862 |
943 |
863 /*! |
944 void HsIdleState::action_waitInput_disconnectGestureHandlers() |
864 Connects the widgetInteraction state's gesture timers. |
945 { |
865 */ |
946 HsScene *scene = HsScene::instance(); |
866 void HsIdleState::action_widgetInteraction_connectGestureTimers() |
947 scene->disconnect(this); |
867 { |
948 } |
868 mTimer.setInterval(HsConfiguration::widgetTapAndHoldTimeout()); |
949 |
869 connect(&mTimer, SIGNAL(timeout()), |
950 /*! |
870 SLOT(widgetInteraction_onTapAndHoldTimeout())); |
951 Resets new widget layout. |
871 mTimer.start(); |
952 */ |
872 } |
953 void HsIdleState::action_waitInput_resetNewWidgets() |
873 |
954 { |
874 /*! |
955 HsScene::instance()->activePage()->resetNewWidgets(); |
875 Disconnects the widgetInteraction state's mouse event handlers. |
|
876 */ |
|
877 void HsIdleState::action_widgetInteraction_disconnectMouseEventHandlers() |
|
878 { |
|
879 DISCONNECT_MOUSE_EVENT_HANDLER(mouseMoved, widgetInteraction_onMouseMoved) |
|
880 DISCONNECT_MOUSE_EVENT_HANDLER(mouseReleased, widgetInteraction_onMouseReleased) |
|
881 } |
|
882 |
|
883 /*! |
|
884 Disconnects the widgetInteraction state's gesture timers. |
|
885 */ |
|
886 void HsIdleState::action_widgetInteraction_disconnectGestureTimers() |
|
887 { |
|
888 disconnect(&mTimer, SIGNAL(timeout()), |
|
889 this, SLOT(widgetInteraction_onTapAndHoldTimeout())); |
|
890 } |
|
891 |
|
892 /*! |
|
893 Connects the sceneInteraction state's mouse event handlers. |
|
894 */ |
|
895 void HsIdleState::action_sceneInteraction_connectMouseEventHandlers() |
|
896 { |
|
897 CONNECT_MOUSE_EVENT_HANDLER(mouseMoved, sceneInteraction_onMouseMoved) |
|
898 CONNECT_MOUSE_EVENT_HANDLER(mouseReleased, sceneInteraction_onMouseReleased) |
|
899 } |
|
900 |
|
901 /*! |
|
902 Connects the sceneInteraction state's gesture timers. |
|
903 */ |
|
904 void HsIdleState::action_sceneInteraction_connectGestureTimers() |
|
905 { |
|
906 mTimer.setInterval(HsConfiguration::sceneTapAndHoldTimeout()); |
|
907 connect(&mTimer, SIGNAL(timeout()), |
|
908 SLOT(sceneInteraction_onTapAndHoldTimeout())); |
|
909 mTimer.start(); |
|
910 } |
|
911 |
|
912 /*! |
|
913 Disconnects the sceneInteraction state's mouse event handlers. |
|
914 */ |
|
915 void HsIdleState::action_sceneInteraction_disconnectMouseEventHandlers() |
|
916 { |
|
917 DISCONNECT_MOUSE_EVENT_HANDLER(mouseMoved, sceneInteraction_onMouseMoved) |
|
918 DISCONNECT_MOUSE_EVENT_HANDLER(mouseReleased, sceneInteraction_onMouseReleased) |
|
919 } |
|
920 |
|
921 /*! |
|
922 Disconnects the sceneInteraction state's gesture timers. |
|
923 */ |
|
924 void HsIdleState::action_sceneInteraction_disconnectGestureTimers() |
|
925 { |
|
926 disconnect(&mTimer, SIGNAL(timeout()), |
|
927 this, SLOT(sceneInteraction_onTapAndHoldTimeout())); |
|
928 } |
956 } |
929 |
957 |
930 /*! |
958 /*! |
931 Reparents the active widget to the control layer. |
959 Reparents the active widget to the control layer. |
932 */ |
960 */ |
945 void HsIdleState::action_moveWidget_startWidgetDragEffect() |
973 void HsIdleState::action_moveWidget_startWidgetDragEffect() |
946 { |
974 { |
947 HsWidgetHost *widget = HsScene::instance()->activeWidget(); |
975 HsWidgetHost *widget = HsScene::instance()->activeWidget(); |
948 Q_ASSERT(widget); |
976 Q_ASSERT(widget); |
949 widget->startDragEffect(); |
977 widget->startDragEffect(); |
950 } |
978 mAllowZoneAnimation = true; |
951 |
979 } |
952 /*! |
980 |
953 Connects the moveWidget state's mouse event handlers. |
981 void HsIdleState::action_moveWidget_connectGestureHandlers() |
954 */ |
982 { |
955 void HsIdleState::action_moveWidget_connectMouseEventHandlers() |
983 HsScene *scene = HsScene::instance(); |
956 { |
984 |
957 CONNECT_MOUSE_EVENT_HANDLER(mouseMoved, moveWidget_onMouseMoved) |
985 connect(scene, |
958 CONNECT_MOUSE_EVENT_HANDLER(mouseReleased, moveWidget_onMouseReleased) |
986 SIGNAL(widgetMoveUpdated(const QPointF&,HsWidgetHost*)), |
|
987 SLOT(onWidgetMoveUpdated(const QPointF&,HsWidgetHost*)), |
|
988 Qt::UniqueConnection); |
|
989 |
|
990 connect(scene, |
|
991 SIGNAL(widgetMoveFinished(const QPointF&,HsWidgetHost*)), |
|
992 SLOT(onWidgetMoveFinished(const QPointF&,HsWidgetHost*)), |
|
993 Qt::UniqueConnection); |
|
994 } |
|
995 |
|
996 /*! |
|
997 Initializes the presentation to the snapping algorithm |
|
998 Connects the SIGNAL for changing the presentation on active page changed |
|
999 Connects the timer for showing the snap lines |
|
1000 */ |
|
1001 void HsIdleState::action_moveWidget_setWidgetSnap() |
|
1002 { |
|
1003 if (HSCONFIGURATION_GET(isSnapEnabled)) { |
|
1004 mSnapBorderGap = HSCONFIGURATION_GET(snapBorderGap); |
|
1005 |
|
1006 QVariantHash snapConfiguration; |
|
1007 snapConfiguration[SNAPENABLED] = QString::number(HSCONFIGURATION_GET(isSnapEnabled)); |
|
1008 snapConfiguration[SNAPFORCE] = QString::number(HSCONFIGURATION_GET(snapForce)); |
|
1009 snapConfiguration[SNAPGAP] = QString::number(HSCONFIGURATION_GET(snapGap)); |
|
1010 snapConfiguration[SNAPBORDERGAP] = mSnapBorderGap; |
|
1011 HsWidgetPositioningOnWidgetMove::instance()->setConfiguration(snapConfiguration); |
|
1012 |
|
1013 |
|
1014 updatePagePresentationToWidgetSnap(); |
|
1015 |
|
1016 connect(HsScene::instance(), SIGNAL(activePageChanged()), |
|
1017 SLOT(onActivePageChanged())); |
|
1018 |
|
1019 if (HSCONFIGURATION_GET(isSnapEffectsEnabled)) { |
|
1020 mVerticalSnapLineTimer.setInterval(HSCONFIGURATION_GET(snapTimeout)); |
|
1021 mHorizontalSnapLineTimer.setInterval(HSCONFIGURATION_GET(snapTimeout)); |
|
1022 |
|
1023 connect(&mVerticalSnapLineTimer, SIGNAL(timeout()), |
|
1024 SLOT(onVerticalSnapLineTimerTimeout())); |
|
1025 connect(&mHorizontalSnapLineTimer, SIGNAL(timeout()), |
|
1026 SLOT(onHorizontalSnapLineTimerTimeout())); |
|
1027 |
|
1028 } |
|
1029 } |
|
1030 } |
|
1031 |
|
1032 /*! |
|
1033 Create the list of inactive rectangles on the page. |
|
1034 */ |
|
1035 QList<QRectF> HsIdleState::createInactiveWidgetRects() |
|
1036 { |
|
1037 HsScene *scene = HsScene::instance(); |
|
1038 HsPage *activePage = scene->activePage(); |
|
1039 HsWidgetHost *activeWidget = scene->activeWidget(); |
|
1040 |
|
1041 QList<QRectF> incativeWidgetRects; |
|
1042 |
|
1043 foreach (HsWidgetHost* widget, activePage->widgets()) { |
|
1044 //If the above function returns the active widget, skip over it as widget and mMovingRect represent same widget. |
|
1045 if (widget == activeWidget) { |
|
1046 continue; |
|
1047 } |
|
1048 QRectF widgetRect = widget->geometry(); |
|
1049 incativeWidgetRects.append(widgetRect); |
|
1050 } |
|
1051 return incativeWidgetRects; |
959 } |
1052 } |
960 |
1053 |
961 /*! |
1054 /*! |
962 Reparents the active widget to the active page. |
1055 Reparents the active widget to the active page. |
963 */ |
1056 */ |
964 void HsIdleState::action_moveWidget_reparentToPage() |
1057 void HsIdleState::action_moveWidget_reparentToPage() |
965 { |
1058 { |
966 mTimer.stop(); |
|
967 |
|
968 if (mZoneAnimation |
1059 if (mZoneAnimation |
969 && mZoneAnimation->state() == QAbstractAnimation::Running |
1060 && mZoneAnimation->state() == QAbstractAnimation::Running |
970 && mZoneAnimation->direction() == QAbstractAnimation::Forward) { |
1061 && mZoneAnimation->direction() == QAbstractAnimation::Forward) { |
971 mPageChanged = false; |
1062 mZoneAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration)); |
972 mZoneAnimation->setDuration(HsConfiguration::pageChangeZoneReverseAnimationDuration()); |
|
973 mZoneAnimation->setDirection(QAbstractAnimation::Backward); |
1063 mZoneAnimation->setDirection(QAbstractAnimation::Backward); |
974 } |
1064 } |
975 |
1065 |
976 HsScene *scene = HsScene::instance(); |
1066 HsScene *scene = HsScene::instance(); |
977 HsPage *page = scene->activePage(); |
1067 HsPage *page = scene->activePage(); |
978 HsWidgetHost *widget = scene->activeWidget(); |
1068 HsWidgetHost *widget = scene->activeWidget(); |
979 |
1069 |
980 if (mUiWidget->trashBin()->isUnderMouse()) { |
1070 if (mUiWidget->trashBin()->isUnderMouse()) { |
981 HbInstantFeedback::play(HsConfiguration::widgetDropToTrashbinFeedbackType()); |
1071 HbInstantFeedback::play(HSCONFIGURATION_GET(widgetDropToTrashbinFeedbackEffect)); |
982 widget->page()->removeWidget(widget); |
1072 widget->page()->removeWidget(widget); |
983 widget->remove(); |
1073 widget->remove(); |
984 scene->setActiveWidget(0); |
1074 scene->setActiveWidget(0); |
985 } else { |
1075 } else { |
986 if (widget->page() != page) { |
1076 if (widget->page() != page) { |
993 } |
1083 } |
994 } |
1084 } |
995 |
1085 |
996 QRectF widgetRect = widget->geometry(); |
1086 QRectF widgetRect = widget->geometry(); |
997 QRectF pageRect = page->rect(); |
1087 QRectF pageRect = page->rect(); |
998 qreal widgetX = qBound(qreal(0), widgetRect.x(), pageRect.width() - widgetRect.width()); |
1088 |
999 qreal widgetY = qBound(qreal(64), widgetRect.y(), pageRect.height() - widgetRect.height()); |
1089 //Set the snap position of the widget and save the position |
|
1090 if (mSnapResult.hasHorizontalSnap) { |
|
1091 widgetRect.moveLeft(mSnapResult.horizontalSnapPosition); |
|
1092 } |
|
1093 if (mSnapResult.hasVerticalSnap) { |
|
1094 widgetRect.moveTop(mSnapResult.verticalSnapPosition); |
|
1095 } |
|
1096 |
|
1097 //if snapBorderGap is defined, the widget is bounded in the rectangle which is smaller by snapBorderGap on all sides |
|
1098 qreal widgetX = qBound(qreal(0) + mSnapBorderGap, widgetRect.x(), (pageRect.width() - mSnapBorderGap) - widgetRect.width()); |
|
1099 qreal widgetY = qBound(qreal(64) + mSnapBorderGap, widgetRect.y(), (pageRect.height() - mSnapBorderGap) - widgetRect.height()); |
1000 |
1100 |
1001 // play feedback effect if user drops widget between pages and it needs to be repositioned back to original page |
1101 // play feedback effect if user drops widget between pages and it needs to be repositioned back to original page |
1002 if( widgetX != widgetRect.x() || widgetY != widgetRect.y()) { |
1102 if( widgetX != widgetRect.x() || widgetY != widgetRect.y()) { |
1003 HbInstantFeedback::play(HsConfiguration::widgetRepositionFeedbackType()); |
1103 HbInstantFeedback::play(HSCONFIGURATION_GET(widgetRepositionFeedbackEffect)); |
1004 } |
1104 } |
1005 widget->setPos(widgetX, widgetY); |
1105 widget->setPos(widgetX, widgetY); |
1006 |
1106 |
1007 widget->savePresentation(); |
1107 widget->savePresentation(); |
1008 page->updateZValues(); |
1108 page->updateZValues(); |
1009 } |
1109 } |
1010 mAllowZoneAnimation = true; |
|
1011 |
1110 |
1012 widget->setParentItem(HsScene::instance()->activePage()); |
1111 widget->setParentItem(HsScene::instance()->activePage()); |
1013 |
1112 |
1014 mUiWidget->showPageIndicator(); |
1113 mUiWidget->showPageIndicator(); |
1015 } |
1114 } |
1023 if (widget) { |
1122 if (widget) { |
1024 widget->startDropEffect(); |
1123 widget->startDropEffect(); |
1025 } |
1124 } |
1026 } |
1125 } |
1027 |
1126 |
1028 /*! |
1127 void HsIdleState::action_moveWidget_disconnectGestureHandlers() |
1029 Disconnects the moveWidget state's mouse event handlers. |
1128 { |
1030 */ |
1129 HsScene *scene = HsScene::instance(); |
1031 void HsIdleState::action_moveWidget_disconnectMouseEventHandlers() |
1130 scene->disconnect(this); |
1032 { |
1131 } |
1033 DISCONNECT_MOUSE_EVENT_HANDLER(mouseMoved, moveWidget_onMouseMoved) |
1132 |
1034 DISCONNECT_MOUSE_EVENT_HANDLER(mouseReleased, moveWidget_onMouseReleased) |
1133 /*! |
1035 } |
1134 Resets the snap position |
1036 |
1135 Disconnect the Active Page Changed SIGNAL |
1037 /*! |
1136 Disconnects the timers to show snap lines |
1038 Connects the moveScene state's mouse event handlers. |
1137 */ |
1039 */ |
1138 void HsIdleState::action_moveWidget_deleteWidgetSnap() |
1040 void HsIdleState::action_moveScene_connectMouseEventHandlers() |
1139 { |
1041 { |
1140 if (HSCONFIGURATION_GET(isSnapEnabled)) { |
1042 CONNECT_MOUSE_EVENT_HANDLER(mouseMoved, moveScene_onMouseMoved) |
1141 resetSnapPosition(); |
1043 CONNECT_MOUSE_EVENT_HANDLER(mouseReleased, moveScene_onMouseReleased) |
1142 |
|
1143 disconnect(HsScene::instance(), SIGNAL(activePageChanged()), |
|
1144 this, SLOT(onActivePageChanged())); |
|
1145 |
|
1146 if (HSCONFIGURATION_GET(isSnapEffectsEnabled)) { |
|
1147 disconnect(&mVerticalSnapLineTimer, SIGNAL(timeout()), |
|
1148 this, SLOT(onVerticalSnapLineTimerTimeout())); |
|
1149 disconnect(&mHorizontalSnapLineTimer, SIGNAL(timeout()), |
|
1150 this, SLOT(onHorizontalSnapLineTimerTimeout())); |
|
1151 } |
|
1152 } |
|
1153 } |
|
1154 |
|
1155 /*! |
|
1156 Prevents page change zone animation. |
|
1157 */ |
|
1158 void HsIdleState::action_moveWidget_preventZoneAnimation() |
|
1159 { |
|
1160 mAllowZoneAnimation = false; |
|
1161 } |
|
1162 |
|
1163 void HsIdleState::action_moveScene_connectGestureHandlers() |
|
1164 { |
|
1165 HsScene *scene = HsScene::instance(); |
|
1166 |
|
1167 connect(scene, |
|
1168 SIGNAL(pagePanUpdated(QGestureEvent*)), |
|
1169 SLOT(onPagePanUpdated(QGestureEvent*)), |
|
1170 Qt::UniqueConnection); |
|
1171 |
|
1172 connect(scene, |
|
1173 SIGNAL(pagePanFinished(QGestureEvent*)), |
|
1174 SLOT(onPagePanFinished(QGestureEvent*)), |
|
1175 Qt::UniqueConnection); |
1044 } |
1176 } |
1045 |
1177 |
1046 /*! |
1178 /*! |
1047 Moves to the nearest page. |
1179 Moves to the nearest page. |
1048 */ |
1180 */ |
1051 QList<HsPage *> pages = HsScene::instance()->pages(); |
1183 QList<HsPage *> pages = HsScene::instance()->pages(); |
1052 QSizeF pageSize = pages.first()->size(); |
1184 QSizeF pageSize = pages.first()->size(); |
1053 |
1185 |
1054 int pageIndex = HsScene::instance()->activePageIndex(); |
1186 int pageIndex = HsScene::instance()->activePageIndex(); |
1055 |
1187 |
1056 if (mDeltaX < -HsConfiguration::pageChangePanDistanceInPixels()) { |
1188 if (mDeltaX < -HSCONFIGURATION_GET(pageChangePanDistanceInPixels)) { |
1057 pageIndex = qMin(pageIndex + 1, pages.count() - 1); |
1189 pageIndex = qMin(pageIndex + 1, pages.count() - 1); |
1058 } else if (HsConfiguration::pageChangePanDistanceInPixels() < mDeltaX) { |
1190 } else if (HSCONFIGURATION_GET(pageChangePanDistanceInPixels) < mDeltaX) { |
1059 pageIndex = qMax(pageIndex - 1, 0); |
1191 pageIndex = qMax(pageIndex - 1, 0); |
1060 } |
1192 } |
1061 |
1193 |
1062 HsScene::instance()->setActivePageIndex(pageIndex); |
1194 HsScene::instance()->setActivePageIndex(pageIndex); |
1063 |
1195 |
1064 startPageChangeAnimation(pageIndex, HsConfiguration::pageChangeAnimationDuration()); |
1196 startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration)); |
1065 } |
1197 } |
1066 |
1198 |
1067 /*! |
1199 void HsIdleState::action_moveScene_disconnectGestureHandlers() |
1068 Disconnects the moveScene state's mouse event handlers. |
1200 { |
1069 */ |
1201 HsScene *scene = HsScene::instance(); |
1070 void HsIdleState::action_moveScene_disconnectMouseEventHandlers() |
1202 scene->disconnect(this); |
1071 { |
1203 } |
1072 DISCONNECT_MOUSE_EVENT_HANDLER(mouseMoved, moveScene_onMouseMoved) |
|
1073 DISCONNECT_MOUSE_EVENT_HANDLER(mouseReleased, moveScene_onMouseReleased) |
|
1074 } |
|
1075 |
|
1076 #ifdef COVERAGE_MEASUREMENT |
|
1077 #pragma CTC SKIP |
|
1078 #endif //COVERAGE_MEASUREMENT |
|
1079 /*! |
|
1080 Shows the scene menu. |
|
1081 */ |
|
1082 void HsIdleState::action_sceneMenu_showMenu() |
|
1083 { |
|
1084 mSceneMenu = new HbMenu(); |
|
1085 mSceneMenu->setAttribute(Qt::WA_DeleteOnClose); |
|
1086 mSceneMenu->setDismissPolicy(HbDialog::TapOutside); |
|
1087 //This is used to check if any action is not triggered ( == menu is dismissed by user or timeout). |
|
1088 connect(mSceneMenu, SIGNAL(aboutToClose()), this, SLOT(onSceneMenuAboutToClose())); |
|
1089 |
|
1090 mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent), this, SLOT(onAddContentActionTriggered())); |
|
1091 |
|
1092 HsScene *scene = HsScene::instance(); |
|
1093 if (scene->pages().count() < scene->maximumPageCount()) { |
|
1094 mSceneMenu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage), this, SIGNAL(event_addPage())); |
|
1095 } |
|
1096 |
|
1097 mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper), this, SIGNAL(event_selectSceneWallpaper())); |
|
1098 mSceneMenu->setPreferredPos(mTouchScenePos); |
|
1099 mSceneMenu->open(this, SLOT(onSceneMenuTriggered(HbAction *))); |
|
1100 } |
|
1101 #ifdef COVERAGE_MEASUREMENT |
|
1102 #pragma CTC ENDSKIP |
|
1103 #endif //COVERAGE_MEASUREMENT |
|
1104 |
1204 |
1105 /*! |
1205 /*! |
1106 Adds a new page to the scene. |
1206 Adds a new page to the scene. |
1107 */ |
1207 */ |
1108 void HsIdleState::action_addPage_addPage() |
1208 void HsIdleState::action_addPage_addPage() |
1109 { |
1209 { |
1110 HsScene *scene = HsScene::instance(); |
1210 HsScene *scene = HsScene::instance(); |
1111 int pageIndex = scene->activePageIndex() + 1; |
1211 int pageIndex = scene->activePageIndex() + 1; |
1112 addPageToScene(pageIndex); |
1212 addPageToScene(pageIndex); |
1113 scene->setActivePageIndex(pageIndex); |
1213 scene->setActivePageIndex(pageIndex); |
1114 startPageChangeAnimation(pageIndex, HsConfiguration::newPageAddedAnimationDuration()); |
1214 startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(newPageAddedAnimationDuration)); |
1115 mUiWidget->pageIndicator()->addItem(pageIndex); |
1215 mUiWidget->pageIndicator()->addItem(pageIndex); |
1116 mUiWidget->showPageIndicator(); |
1216 mUiWidget->showPageIndicator(); |
1117 } |
1217 } |
1118 |
1218 |
1119 /*! |
1219 /*! |
1152 */ |
1250 */ |
1153 void HsIdleState::action_toggleConnection_toggleConnection() |
1251 void HsIdleState::action_toggleConnection_toggleConnection() |
1154 { |
1252 { |
1155 HsScene *scene = HsScene::instance(); |
1253 HsScene *scene = HsScene::instance(); |
1156 scene->setOnline(!scene->isOnline()); |
1254 scene->setOnline(!scene->isOnline()); |
1157 } |
|
1158 |
|
1159 /*! |
|
1160 Handles mouse press events for the waitInput state. |
|
1161 Filters events for the item \a watched. \a event is the |
|
1162 filtered event. Sets the \a filtered true if the event |
|
1163 was filtered by this handler. |
|
1164 */ |
|
1165 void HsIdleState::waitInput_onMousePressed( |
|
1166 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1167 { |
|
1168 filtered = true; |
|
1169 |
|
1170 HsScene *scene = HsScene::instance(); |
|
1171 HsPage *page = scene->activePage(); |
|
1172 QList<HsWidgetHost *> widgets = page->widgets(); |
|
1173 |
|
1174 if (mUiWidget->controlLayer() == watched || |
|
1175 mUiWidget->controlLayer()->isAncestorOf(watched)) { |
|
1176 filtered = false; |
|
1177 return; |
|
1178 } |
|
1179 |
|
1180 mUiWidget->captureDelayedPress(event); |
|
1181 |
|
1182 foreach (HsWidgetHost *widget, widgets) { |
|
1183 if (widget == watched || widget->isAncestorOf(watched)) { |
|
1184 scene->setActiveWidget(widget); |
|
1185 emit event_widgetInteraction(); |
|
1186 return; |
|
1187 } |
|
1188 } |
|
1189 |
|
1190 mTouchScenePos = event->scenePos(); |
|
1191 emit event_sceneInteraction(); |
|
1192 } |
|
1193 |
|
1194 /*! |
|
1195 Handles mouse move events for the widgetInteraction state. |
|
1196 Filters events for the item \a watched. \a event is the |
|
1197 filtered event. Sets the \a filtered true if the event |
|
1198 was filtered by this handler. |
|
1199 */ |
|
1200 void HsIdleState::widgetInteraction_onMouseMoved( |
|
1201 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1202 { |
|
1203 Q_UNUSED(watched) |
|
1204 Q_UNUSED(filtered) |
|
1205 |
|
1206 if (!mTimer.isActive()) { |
|
1207 return; |
|
1208 } |
|
1209 |
|
1210 filtered = true; |
|
1211 |
|
1212 QPointF point = |
|
1213 event->scenePos() - event->buttonDownScenePos(Qt::LeftButton); |
|
1214 if (HsConfiguration::tapAndHoldDistance() < point.manhattanLength()) { |
|
1215 // Threshold area for tap exceeded. This is pan or swipe |
|
1216 mTimer.stop(); |
|
1217 if (HsScene::instance()->activeWidget()->isPannable(event)) { |
|
1218 // let widget get first press |
|
1219 mUiWidget->sendDelayedPress(); |
|
1220 } else { |
|
1221 // Widget doesn't consume pan or swipe gestures |
|
1222 mUiWidget->clearDelayedPress(); |
|
1223 emit event_moveScene(); |
|
1224 } |
|
1225 } |
|
1226 |
|
1227 } |
|
1228 |
|
1229 /*! |
|
1230 Handles mouse release events for the widgetInteraction state. |
|
1231 Filters events for the item \a watched. \a event is the |
|
1232 filtered event. Sets the \a filtered true if the event |
|
1233 was filtered by this handler. |
|
1234 */ |
|
1235 void HsIdleState::widgetInteraction_onMouseReleased( |
|
1236 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1237 { |
|
1238 Q_UNUSED(watched) |
|
1239 Q_UNUSED(event) |
|
1240 Q_UNUSED(filtered) |
|
1241 |
|
1242 if (mTimer.isActive()) { |
|
1243 mTimer.stop(); |
|
1244 mUiWidget->sendDelayedPress(); |
|
1245 } |
|
1246 |
|
1247 HsPage *page = HsScene::instance()->activePage(); |
|
1248 QMetaObject::invokeMethod(page, "updateZValues", Qt::QueuedConnection); |
|
1249 |
|
1250 emit event_waitInput(); |
|
1251 } |
|
1252 |
|
1253 /*! |
|
1254 Handles mouse move events for the sceneInteraction state. |
|
1255 Filters events for the item \a watched. \a event is the |
|
1256 filtered event. Sets the \a filtered true if the event |
|
1257 was filtered by this handler. |
|
1258 */ |
|
1259 void HsIdleState::sceneInteraction_onMouseMoved( |
|
1260 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1261 { |
|
1262 Q_UNUSED(watched) |
|
1263 Q_UNUSED(filtered) |
|
1264 |
|
1265 mTouchScenePos = event->scenePos(); |
|
1266 |
|
1267 if (!mTimer.isActive()) { |
|
1268 return; |
|
1269 } |
|
1270 |
|
1271 filtered = true; |
|
1272 |
|
1273 QPointF point = |
|
1274 event->scenePos() - event->buttonDownScenePos(Qt::LeftButton); |
|
1275 if (HsConfiguration::tapAndHoldDistance() < point.manhattanLength()) { |
|
1276 mTimer.stop(); |
|
1277 mUiWidget->clearDelayedPress(); |
|
1278 emit event_moveScene(); |
|
1279 } |
|
1280 } |
|
1281 |
|
1282 /*! |
|
1283 Handles mouse release events for the sceneInteraction state. |
|
1284 Filters events for the item \a watched. \a event is the |
|
1285 filtered event. Sets the \a filtered true if the event |
|
1286 was filtered by this handler. |
|
1287 */ |
|
1288 void HsIdleState::sceneInteraction_onMouseReleased( |
|
1289 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1290 { |
|
1291 Q_UNUSED(watched) |
|
1292 Q_UNUSED(event) |
|
1293 Q_UNUSED(filtered) |
|
1294 |
|
1295 filtered = true; |
|
1296 |
|
1297 if (mTimer.isActive()) { |
|
1298 mTimer.stop(); |
|
1299 mUiWidget->clearDelayedPress(); |
|
1300 } |
|
1301 |
|
1302 emit event_waitInput(); |
|
1303 } |
|
1304 |
|
1305 /*! |
|
1306 Handles mouse move events for the moveWidget state. |
|
1307 Filters events for the item \a watched. \a event is the |
|
1308 filtered event. Sets the \a filtered true if the event |
|
1309 was filtered by this handler. |
|
1310 */ |
|
1311 void HsIdleState::moveWidget_onMouseMoved( |
|
1312 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1313 { |
|
1314 Q_UNUSED(watched) |
|
1315 |
|
1316 HsScene *scene = HsScene::instance(); |
|
1317 HsWidgetHost *widget = scene->activeWidget(); |
|
1318 QRectF widgetRect = widget->geometry(); |
|
1319 |
|
1320 //Move widget to new position: |
|
1321 mTouchScenePos = event->scenePos(); |
|
1322 QPointF delta(event->scenePos() - event->lastScenePos()); |
|
1323 widgetRect.moveTopLeft(widgetRect.topLeft() + delta); |
|
1324 |
|
1325 //Widget can be moved over the pages left border |
|
1326 qreal lowerBoundX = -widgetRect.width(); |
|
1327 HsPage *page = scene->activePage(); |
|
1328 QRectF pageRect = HsGui::idleView()->rect(); |
|
1329 //Widget can be moved over the pages right border |
|
1330 qreal upperBoundX = pageRect.width(); |
|
1331 |
|
1332 //Notice that chrome height is 64 pixels |
|
1333 qreal lowerBoundY = qreal(64) - widgetRect.height(); |
|
1334 //Widget can be moved over the pages down border |
|
1335 qreal upperBoundY = pageRect.height(); |
|
1336 |
|
1337 qreal widgetX = qBound(lowerBoundX, widgetRect.x(), upperBoundX); |
|
1338 qreal widgetY = qBound(lowerBoundY, widgetRect.y(), upperBoundY); |
|
1339 /* if using ItemClipsChildrenToShape-flag in widgethost then |
|
1340 setPos does not update position here, however setGeometry does it, QT bug? |
|
1341 */ |
|
1342 widget->setGeometry(widgetX, widgetY, widgetRect.width(), widgetRect.height()); |
|
1343 |
|
1344 int bounceFeedbackEffectDistance = HsConfiguration::bounceFeedbackEffectDistance(); |
|
1345 //Handle effects: |
|
1346 //User is indicated by a tactile feedback if he/she is trying to move |
|
1347 //widget over the first or the last page. |
|
1348 if( (page == scene->pages().first() && mTouchScenePos.x() < bounceFeedbackEffectDistance ) || |
|
1349 (page == scene->pages().last() && scene->pages().count() == scene->maximumPageCount() |
|
1350 && mTouchScenePos.x() > pageRect.width() - bounceFeedbackEffectDistance)) { |
|
1351 HbInstantFeedback::play(HsConfiguration::widgetMoveBlockedFeedbackType()); |
|
1352 // TODO: use code below when Orbit has updated ContinuousFeedback API |
|
1353 //if (!mContinuousFeedback->isPlaying()) { |
|
1354 // mContinuousFeedback->play(); |
|
1355 //} |
|
1356 } |
|
1357 else /*if (mContinuousFeedback->isPlaying())*/ { |
|
1358 //mContinuousFeedback->stop(); |
|
1359 } |
|
1360 |
|
1361 updateZoneAnimation(); |
|
1362 showTrashBin(); |
|
1363 |
|
1364 filtered = true; |
|
1365 } |
|
1366 |
|
1367 /*! |
|
1368 Handles mouse release events for the moveWidget state. |
|
1369 Filters events for the item \a watched. \a event is the |
|
1370 filtered event. Sets the \a filtered true if the event |
|
1371 was filtered by this handler. |
|
1372 */ |
|
1373 void HsIdleState::moveWidget_onMouseReleased( |
|
1374 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1375 { |
|
1376 Q_UNUSED(watched) |
|
1377 Q_UNUSED(event) |
|
1378 |
|
1379 filtered = true; |
|
1380 emit event_waitInput(); |
|
1381 } |
|
1382 |
|
1383 /*! |
|
1384 Handles mouse move events for the moveScene state. |
|
1385 Filters events for the item \a watched. \a event is the |
|
1386 filtered event. Sets the \a filtered true if the event |
|
1387 was filtered by this handler. |
|
1388 */ |
|
1389 void HsIdleState::moveScene_onMouseMoved( |
|
1390 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1391 { |
|
1392 Q_UNUSED(watched) |
|
1393 Q_UNUSED(filtered) |
|
1394 |
|
1395 filtered = true; |
|
1396 |
|
1397 HsScene *scene = HsScene::instance(); |
|
1398 mDeltaX = event->scenePos().x() - event->buttonDownScenePos(Qt::LeftButton).x(); |
|
1399 |
|
1400 int bounceEffect = HsConfiguration::bounceEffect(); |
|
1401 |
|
1402 qreal x = qBound(pageLayerXPos(scene->pages().count() - 1) - bounceEffect / 2 / parallaxFactor(), |
|
1403 pageLayerXPos(scene->activePageIndex()) + mDeltaX, |
|
1404 pageLayerXPos(0) + (bounceEffect / 2 / parallaxFactor()) - qreal(0.5)); |
|
1405 |
|
1406 mUiWidget->pageLayer()->setX(x); |
|
1407 mUiWidget->sceneLayer()->setX((parallaxFactor() * x) - bounceEffect / 2); |
|
1408 } |
|
1409 |
|
1410 /*! |
|
1411 Handles mouse release events for the moveScene state. |
|
1412 Filters events for the item \a watched. \a event is the |
|
1413 filtered event. Sets the \a filtered true if the event |
|
1414 was filtered by this handler. |
|
1415 */ |
|
1416 void HsIdleState::moveScene_onMouseReleased( |
|
1417 QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered) |
|
1418 { |
|
1419 Q_UNUSED(watched) |
|
1420 Q_UNUSED(filtered) |
|
1421 filtered = true; |
|
1422 |
|
1423 mDeltaX = event->scenePos().x() - event->buttonDownScenePos(Qt::LeftButton).x(); |
|
1424 |
|
1425 emit event_waitInput(); |
|
1426 } |
|
1427 |
|
1428 /*! |
|
1429 Handles tap-and-hold events for the widgetInteraction state. |
|
1430 */ |
|
1431 void HsIdleState::widgetInteraction_onTapAndHoldTimeout() |
|
1432 { |
|
1433 mUiWidget->clearDelayedPress(); |
|
1434 emit event_moveWidget(); |
|
1435 } |
|
1436 |
|
1437 /*! |
|
1438 Handles tap-and-hold events for the sceneInteraction state. |
|
1439 */ |
|
1440 void HsIdleState::sceneInteraction_onTapAndHoldTimeout() |
|
1441 { |
|
1442 mUiWidget->clearDelayedPress(); |
|
1443 emit event_sceneMenu(); |
|
1444 } |
1255 } |
1445 |
1256 |
1446 #ifdef COVERAGE_MEASUREMENT |
1257 #ifdef COVERAGE_MEASUREMENT |
1447 #pragma CTC SKIP |
1258 #pragma CTC SKIP |
1448 #endif //COVERAGE_MEASUREMENT |
1259 #endif //COVERAGE_MEASUREMENT |
1465 void HsIdleState::zoneAnimationFinished() |
1276 void HsIdleState::zoneAnimationFinished() |
1466 { |
1277 { |
1467 HsScene *scene = HsScene::instance(); |
1278 HsScene *scene = HsScene::instance(); |
1468 int pageIndex = scene->activePageIndex(); |
1279 int pageIndex = scene->activePageIndex(); |
1469 |
1280 |
1470 if (mPageChanged) { |
1281 if (mZoneAnimation->direction() == QAbstractAnimation::Forward) { |
1471 if (isInLeftPageChangeZone() && |
1282 if (isInLeftPageChangeZone() && |
1472 0 < pageIndex) { |
1283 0 < pageIndex) { |
1473 --pageIndex; |
1284 --pageIndex; |
1474 } |
1285 } else if (isInRightPageChangeZone() && |
1475 else if (isInRightPageChangeZone() && |
1286 pageIndex < scene->pages().count()) { |
1476 pageIndex < scene->pages().count()) { |
|
1477 ++pageIndex; |
1287 ++pageIndex; |
1478 } |
1288 } |
1479 else { |
|
1480 delete mZoneAnimation; |
|
1481 mZoneAnimation = NULL; |
|
1482 mAllowZoneAnimation = true; |
|
1483 return; |
|
1484 } |
|
1485 |
|
1486 if (pageIndex == scene->pages().count()) { |
1289 if (pageIndex == scene->pages().count()) { |
1487 if (scene->pages().last()->widgets().isEmpty()) { |
1290 if (pageIndex < HSCONFIGURATION_GET(maximumPageCount)) { |
1488 delete mZoneAnimation; |
|
1489 mZoneAnimation = NULL; |
|
1490 mAllowZoneAnimation = true; |
|
1491 return; |
|
1492 } |
|
1493 else if (scene->pages().count() < scene->maximumPageCount()) { |
|
1494 addPageToScene(pageIndex); |
1291 addPageToScene(pageIndex); |
1495 mUiWidget->showPageIndicator(); |
1292 mUiWidget->showPageIndicator(); |
1496 mUiWidget->pageIndicator()->addItem(pageIndex); |
1293 mUiWidget->pageIndicator()->addItem(pageIndex); |
1497 } |
1294 } |
1498 else { |
|
1499 delete mZoneAnimation; |
|
1500 mZoneAnimation = NULL; |
|
1501 mAllowZoneAnimation = true; |
|
1502 return; |
|
1503 } |
|
1504 } |
1295 } |
1505 scene->setActivePageIndex(pageIndex); |
1296 scene->setActivePageIndex(pageIndex); |
1506 startPageChangeAnimation(pageIndex, HsConfiguration::pageChangeAnimationDuration()); |
1297 startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration)); |
1507 } |
1298 } else { |
1508 else { |
|
1509 scene->setActivePageIndex(pageIndex); |
1299 scene->setActivePageIndex(pageIndex); |
1510 mUiWidget->setActivePage(pageIndex); |
1300 mUiWidget->setActivePage(pageIndex); |
1511 mAllowZoneAnimation = true; |
1301 } |
1512 } |
1302 |
1513 |
1303 deleteZoneAnimation(); |
1514 delete mZoneAnimation; |
1304 } |
1515 mZoneAnimation = NULL; |
1305 |
1516 } |
1306 /*! |
1517 |
1307 Page change animation has been finished. |
1518 /*! |
1308 */ |
1519 Handles the close of the scene menu when menu is dismissed. |
1309 void HsIdleState::pageChangeAnimationFinished() |
1520 While dismissed menu should be triggered with NULL action. |
1310 { |
1521 Actions on menu are connected stright to desired slot or signal. |
1311 updateZoneAnimation(); |
1522 */ |
|
1523 void HsIdleState::onSceneMenuTriggered(HbAction *action) |
|
1524 { |
|
1525 //We check if menu was dismissed either by user tap in outside of the menu, |
|
1526 //menu's dismiss timer timeouts or state_sceneMenu was exited by any other reason |
|
1527 //than triggered action, e.g. applib activated while context menu is active. |
|
1528 if(!action) { |
|
1529 emit event_waitInput(); |
|
1530 } |
|
1531 } |
1312 } |
1532 |
1313 |
1533 /*! |
1314 /*! |
1534 Handles the close of remove page confirmation dialog for page having content. |
1315 Handles the close of remove page confirmation dialog for page having content. |
1535 */ |
1316 */ |
1537 { |
1318 { |
1538 removeActivePage(); |
1319 removeActivePage(); |
1539 } |
1320 } |
1540 |
1321 |
1541 /*! |
1322 /*! |
1542 Handles the close of the scene menu. |
1323 Provides the page presentation to the Widget Snap algorithm |
1543 |
1324 */ |
1544 This workaround is needed since HbMenu does not trigger empty action in case of |
1325 void HsIdleState::updatePagePresentationToWidgetSnap() |
1545 dismission of menu dialog. That functionality will be added in near future. Thereafter |
1326 { |
1546 onSceneMenuTriggered() can handle dismissions (HbMenu::triggered() emitted with NULL |
1327 QRectF containerRect = HsScene::instance()->activePage()->rect(); |
1547 action). This workaround can be removed at that time. |
1328 containerRect.setTop(qreal(64)); |
1548 */ |
1329 HsWidgetHost *activeWidget = HsScene::instance()->activeWidget(); |
1549 void HsIdleState::onSceneMenuAboutToClose() { |
1330 HsWidgetPositioningOnWidgetMove::instance()->setPagePresentation(containerRect, createInactiveWidgetRects(), activeWidget->geometry()); |
1550 //We need to check if menu is dismissed either by user tap in outside of the menu or |
1331 } |
1551 //menu's dismiss timer timeouts. There is active action if any action tapped otherwise |
1332 |
1552 //menu was dissmised. |
1333 /*! |
1553 HbMenu *menu = static_cast<HbMenu*>(sender()); |
1334 Reset Snap position, hide the snap lines |
1554 if(!menu->activeAction()) { |
1335 */ |
1555 //mSceneMenu = 0; //Menu deletes itself at the close |
1336 void HsIdleState::resetSnapPosition() |
1556 emit event_waitInput(); |
1337 { |
1557 } |
1338 mSnapResult = HsWidgetPositioningOnWidgetMove::Result(); |
1558 } |
1339 mPreviousSnapResult = HsWidgetPositioningOnWidgetMove::Result(); |
|
1340 hideVerticalLine(); |
|
1341 hideHorizontalLine(); |
|
1342 } |
|
1343 |
|
1344 /*! |
|
1345 Show the Vertical line for Snap guidance |
|
1346 */ |
|
1347 void HsIdleState::showVerticalLine() |
|
1348 { |
|
1349 if (mPreviousSnapResult.verticalSnapLine.x1() != mSnapResult.verticalSnapLine.x1()) { |
|
1350 hideVerticalLine(); |
|
1351 mVerticalSnapLineTimer.start(); |
|
1352 } |
|
1353 else { |
|
1354 //As the Vertical Line position is at the same place, |
|
1355 //the timer was started when vertical line positions were at different locations |
|
1356 //the line will be shown when the timer expires. |
|
1357 //If timer has already expired, just show the line, which is redrawn to new geometry. |
|
1358 if (!mVerticalSnapLineTimer.isActive()) { |
|
1359 mUiWidget->showVerticalSnapLine(mSnapResult.verticalSnapLine); |
|
1360 } |
|
1361 } |
|
1362 } |
|
1363 |
|
1364 /*! |
|
1365 Timer for showing the Vertical line expires |
|
1366 */ |
|
1367 void HsIdleState::onVerticalSnapLineTimerTimeout() |
|
1368 { |
|
1369 mUiWidget->showVerticalSnapLine(mSnapResult.verticalSnapLine); |
|
1370 } |
|
1371 |
|
1372 /*! |
|
1373 Hide the Vertical line for Snap guidance |
|
1374 */ |
|
1375 void HsIdleState::hideVerticalLine() |
|
1376 { |
|
1377 mUiWidget->hideVerticalSnapLine(); |
|
1378 mVerticalSnapLineTimer.stop(); |
|
1379 } |
|
1380 |
|
1381 /*! |
|
1382 Show the Horizontal line for Snap guidance |
|
1383 */ |
|
1384 void HsIdleState::showHorizontalLine() |
|
1385 { |
|
1386 if (mPreviousSnapResult.horizontalSnapLine.y1() != mSnapResult.horizontalSnapLine.y1()) { |
|
1387 hideHorizontalLine(); |
|
1388 mHorizontalSnapLineTimer.start(); |
|
1389 } |
|
1390 else { |
|
1391 if (!mHorizontalSnapLineTimer.isActive()) { |
|
1392 mUiWidget->showHorizontalSnapLine(mSnapResult.horizontalSnapLine); |
|
1393 } |
|
1394 } |
|
1395 } |
|
1396 |
|
1397 /*! |
|
1398 Timer for showing the Horizontal line expires |
|
1399 */ |
|
1400 void HsIdleState::onHorizontalSnapLineTimerTimeout() |
|
1401 { |
|
1402 mUiWidget->showHorizontalSnapLine(mSnapResult.horizontalSnapLine); |
|
1403 } |
|
1404 |
|
1405 /*! |
|
1406 Hide the Horizontal line for Snap guidance |
|
1407 */ |
|
1408 void HsIdleState::hideHorizontalLine() |
|
1409 { |
|
1410 mUiWidget->hideHorizontalSnapLine(); |
|
1411 mHorizontalSnapLineTimer.stop(); |
|
1412 } |
|
1413 |
|
1414 /*! |
|
1415 Handles updating the Snap algorithm with page presentation on page change |
|
1416 */ |
|
1417 void HsIdleState::onActivePageChanged() |
|
1418 { |
|
1419 updatePagePresentationToWidgetSnap(); |
|
1420 resetSnapPosition(); |
|
1421 } |