homescreenapp/stateplugins/hshomescreenstateplugin/src/hsidlestate.cpp
changeset 61 2b1b11a301d2
parent 60 30f14686fb04
child 77 4b195f3bea29
equal deleted inserted replaced
60:30f14686fb04 61:2b1b11a301d2
    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"
    57 #define ENTRY_ACTION(state, action) \
    58 #define ENTRY_ACTION(state, action) \
    58     connect(state, SIGNAL(entered()), SLOT(action()));
    59     connect(state, SIGNAL(entered()), SLOT(action()));
    59 #define EXIT_ACTION(state, action) \
    60 #define EXIT_ACTION(state, action) \
    60     connect(state, SIGNAL(exited()), SLOT(action()));
    61     connect(state, SIGNAL(exited()), SLOT(action()));
    61 
    62 
    62 // Helper macros for connecting and disconnecting mouse event handlers.
       
    63 #define CONNECT_MOUSE_EVENT_HANDLER(signal, slot) \
       
    64     connect(mUiWidget, SIGNAL(signal(QGraphicsItem*,QGraphicsSceneMouseEvent*,bool&)), \
       
    65         SLOT(slot(QGraphicsItem*,QGraphicsSceneMouseEvent*,bool&)));
       
    66 #define DISCONNECT_MOUSE_EVENT_HANDLER(signal, slot) \
       
    67     disconnect(mUiWidget, SIGNAL(signal(QGraphicsItem*,QGraphicsSceneMouseEvent*,bool&)), \
       
    68         this, SLOT(slot(QGraphicsItem*,QGraphicsSceneMouseEvent*,bool&)));
       
    69 
       
    70 
       
    71 namespace
    63 namespace
    72 {
    64 {
    73     const char gApplicationLibraryIconName[] = "qtg_mono_applications_all";
    65     const char gApplicationLibraryIconName[] = "qtg_mono_applications_all";
    74 
    66 
    75     //User adds a new page to home screen
    67     //User adds a new page to home screen
   128     mAllowZoneAnimation(false),
   120     mAllowZoneAnimation(false),
   129     mPageChangeAnimation(0),
   121     mPageChangeAnimation(0),
   130     mContinuousFeedback(0),
   122     mContinuousFeedback(0),
   131     mTrashBinFeedbackAlreadyPlayed(false),
   123     mTrashBinFeedbackAlreadyPlayed(false),
   132     mDeltaX(0),
   124     mDeltaX(0),
   133     mSceneMenu(0)
   125     mSceneMenu(0),
       
   126     mSnapBorderGap(0.0)
   134 #ifdef Q_OS_SYMBIAN
   127 #ifdef Q_OS_SYMBIAN
   135     ,mSettingsMgr(0)
   128     ,mSettingsMgr(0)
   136 #endif
   129 #endif
   137 {
   130 {
   138     setupStates();
   131     setupStates();
   139     mTimer.setSingleShot(true);
       
   140     mTitleResolver = new HsTitleResolver(this);
   132     mTitleResolver = new HsTitleResolver(this);
   141 	
   133 
   142     // TODO: Uncomment when updated API available
   134     // TODO: Uncomment when updated API available
   143     //mContinuousFeedback = new HbContinuousFeedback;
   135     //mContinuousFeedback = new HbContinuousFeedback;
   144     //mContinuousFeedback->setContinuousEffect(HbFeedback::ContinuousSmooth);
   136     //mContinuousFeedback->setContinuousEffect(HbFeedback::ContinuousSmooth);
   145     //mContinuousFeedback->setIntensity(HbFeedback::IntensityFull );
   137     //mContinuousFeedback->setIntensity(HbFeedback::IntensityFull );
       
   138 
       
   139     mVerticalSnapLineTimer.setSingleShot(true);
       
   140     mHorizontalSnapLineTimer.setSingleShot(true);
   146 }
   141 }
   147 
   142 
   148 /*!
   143 /*!
   149     Destroys this idle state.
   144     Destroys this idle state.
   150 */
   145 */
   163     switch (event->type()) {
   158     switch (event->type()) {
   164         case QEvent::ApplicationActivate:
   159         case QEvent::ApplicationActivate:
   165             action_idle_layoutNewWidgets();
   160             action_idle_layoutNewWidgets();
   166             break;
   161             break;
   167         case QEvent::ApplicationDeactivate:
   162         case QEvent::ApplicationDeactivate:
   168             mUiWidget->clearDelayedPress();
       
   169             emit event_waitInput();
   163             emit event_waitInput();
   170             break;
   164             break;
   171         default:
   165         default:
   172             break;
   166             break;
   173     }
   167     }
   185 
   179 
   186     This signal initiates a transition to the waitInput state.
   180     This signal initiates a transition to the waitInput state.
   187 */
   181 */
   188 
   182 
   189 /*!
   183 /*!
   190     \fn HsIdleState::event_widgetInteraction()
       
   191 
       
   192     This signal initiates a transition to the widgetInteraction state.
       
   193 */
       
   194 
       
   195 /*!
       
   196     \fn HsIdleState::event_sceneInteraction()
       
   197 
       
   198     This signal initiates a transition to the sceneInteraction state.
       
   199 */
       
   200 
       
   201 /*!
       
   202     \fn HsIdleState::event_moveWidget()
   184     \fn HsIdleState::event_moveWidget()
   203 
   185 
   204     This signal initiates a transition to the moveWidget state.
   186     This signal initiates a transition to the moveWidget state.
   205 */
   187 */
   206 
   188 
   207 /*!
   189 /*!
   208     \fn HsIdleState::event_moveScene()
   190     \fn HsIdleState::event_moveScene()
   209 
   191 
   210     This signal initiates a transition to the moveScene state.
   192     This signal initiates a transition to the moveScene state.
   211 */
       
   212 
       
   213 /*!
       
   214     \fn HsIdleState::event_sceneMenu()
       
   215 
       
   216     This signal initiates a transition to the sceneMenu state.
       
   217 */
   193 */
   218 
   194 
   219 /*!
   195 /*!
   220     \fn HsIdleState::event_selectWallpaper()
   196     \fn HsIdleState::event_selectWallpaper()
   221 
   197 
   248 {
   224 {
   249     // States
   225     // States
   250 
   226 
   251     QState *state_waitInput = new QState(this);
   227     QState *state_waitInput = new QState(this);
   252     setInitialState(state_waitInput);
   228     setInitialState(state_waitInput);
   253     QState *state_widgetInteraction = new QState(this);
       
   254     QState *state_sceneInteraction = new QState(this);
       
   255     QState *state_moveWidget = new QState(this);
   229     QState *state_moveWidget = new QState(this);
   256     QState *state_moveScene = new QState(this);
   230     QState *state_moveScene = new QState(this);
   257     QState *state_sceneMenu = new QState(this);
       
   258     HsWallpaperSelectionState *state_wallpaperSelectionState =
   231     HsWallpaperSelectionState *state_wallpaperSelectionState =
   259         new HsWallpaperSelectionState(this);
   232         new HsWallpaperSelectionState(this);
   260     QState *state_addPage = new QState(this);
   233     QState *state_addPage = new QState(this);
   261     QState *state_removePage = new QState(this);
   234     QState *state_removePage = new QState(this);
   262     QState *state_toggleConnection = new QState(this);
   235     QState *state_toggleConnection = new QState(this);
   263 
   236 
   264     // Transitions
   237     // Transitions
   265 
   238 
   266     state_waitInput->addTransition(
       
   267         this, SIGNAL(event_widgetInteraction()), state_widgetInteraction);
       
   268     state_waitInput->addTransition(
       
   269         this, SIGNAL(event_sceneInteraction()), state_sceneInteraction);
       
   270     state_waitInput->addTransition(
   239     state_waitInput->addTransition(
   271         this, SIGNAL(event_addPage()), state_addPage);
   240         this, SIGNAL(event_addPage()), state_addPage);
   272     state_waitInput->addTransition(
   241     state_waitInput->addTransition(
   273         this, SIGNAL(event_removePage()), state_removePage);
   242         this, SIGNAL(event_removePage()), state_removePage);
   274     state_waitInput->addTransition(
   243     state_waitInput->addTransition(
   275         this, SIGNAL(event_toggleConnection()), state_toggleConnection);
   244         this, SIGNAL(event_toggleConnection()), state_toggleConnection);
   276     state_waitInput->addTransition(
   245     state_waitInput->addTransition(
   277         this, SIGNAL(event_selectWallpaper()), state_wallpaperSelectionState);
   246         this, SIGNAL(event_selectWallpaper()), state_wallpaperSelectionState);
   278 
   247     state_waitInput->addTransition(
   279     state_widgetInteraction->addTransition(
   248         this, SIGNAL(event_moveScene()), state_moveScene);
   280         this, SIGNAL(event_waitInput()), state_waitInput);
   249     state_waitInput->addTransition(
   281     state_widgetInteraction->addTransition(
       
   282         this, SIGNAL(event_moveWidget()), state_moveWidget);
   250         this, SIGNAL(event_moveWidget()), state_moveWidget);
   283     state_widgetInteraction->addTransition(
       
   284         this, SIGNAL(event_moveScene()), state_moveScene);
       
   285 
       
   286     state_sceneInteraction->addTransition(
       
   287         this, SIGNAL(event_waitInput()), state_waitInput);
       
   288     state_sceneInteraction->addTransition(
       
   289         this, SIGNAL(event_moveScene()), state_moveScene);
       
   290     state_sceneInteraction->addTransition(
       
   291         this, SIGNAL(event_sceneMenu()), state_sceneMenu);
       
   292 
   251 
   293     state_moveWidget->addTransition(
   252     state_moveWidget->addTransition(
   294         this, SIGNAL(event_waitInput()), state_waitInput);
   253         this, SIGNAL(event_waitInput()), state_waitInput);
   295 
   254 
   296     state_moveScene->addTransition(
   255     state_moveScene->addTransition(
   297         this, SIGNAL(event_waitInput()), state_waitInput);
   256         this, SIGNAL(event_waitInput()), state_waitInput);
   298 
       
   299     state_sceneMenu->addTransition(
       
   300         this, SIGNAL(event_waitInput()), state_waitInput);
       
   301     state_sceneMenu->addTransition(
       
   302         this, SIGNAL(event_selectWallpaper()), state_wallpaperSelectionState);
       
   303     state_sceneMenu->addTransition(
       
   304         this, SIGNAL(event_addPage()), state_addPage);
       
   305 
   257 
   306     state_wallpaperSelectionState->addTransition(
   258     state_wallpaperSelectionState->addTransition(
   307         state_wallpaperSelectionState, SIGNAL(event_waitInput()), state_waitInput);
   259         state_wallpaperSelectionState, SIGNAL(event_waitInput()), state_waitInput);
   308 
   260 
   309     state_addPage->addTransition(state_waitInput);
   261     state_addPage->addTransition(state_waitInput);
   324     EXIT_ACTION(this, action_idle_cleanupView)
   276     EXIT_ACTION(this, action_idle_cleanupView)
   325     EXIT_ACTION(this, action_idle_disconnectOrientationChangeEventHandler)
   277     EXIT_ACTION(this, action_idle_disconnectOrientationChangeEventHandler)
   326     EXIT_ACTION(this, action_idle_uninstallEventFilter)
   278     EXIT_ACTION(this, action_idle_uninstallEventFilter)
   327 
   279 
   328     ENTRY_ACTION(state_waitInput, action_waitInput_updateOptionsMenu)
   280     ENTRY_ACTION(state_waitInput, action_waitInput_updateOptionsMenu)
   329     ENTRY_ACTION(state_waitInput, action_waitInput_connectMouseEventHandlers)
   281     ENTRY_ACTION(state_waitInput, action_waitInput_connectGestureHandlers)
   330     ENTRY_ACTION(state_waitInput, action_waitInput_publishIdleKey)
   282     ENTRY_ACTION(state_waitInput, action_waitInput_publishIdleKey)
   331     EXIT_ACTION(state_waitInput, action_waitInput_disconnectMouseEventHandlers)
   283     EXIT_ACTION(state_waitInput, action_waitInput_disconnectGestureHandlers)
   332     EXIT_ACTION(state_waitInput, action_waitInput_resetNewWidgets)
   284     EXIT_ACTION(state_waitInput, action_waitInput_resetNewWidgets)
   333 
       
   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     EXIT_ACTION(state_moveWidget, action_moveWidget_preventZoneAnimation)
   294     EXIT_ACTION(state_moveWidget, action_moveWidget_preventZoneAnimation)
   352 
   295     EXIT_ACTION(state_moveWidget, action_moveWidget_deleteWidgetSnap)
   353     ENTRY_ACTION(state_moveScene, action_moveScene_connectMouseEventHandlers)
   296 
       
   297     ENTRY_ACTION(state_moveScene, action_moveScene_connectGestureHandlers)
   354     EXIT_ACTION(state_moveScene, action_moveScene_moveToNearestPage)
   298     EXIT_ACTION(state_moveScene, action_moveScene_moveToNearestPage)
   355     EXIT_ACTION(state_moveScene, action_moveScene_disconnectMouseEventHandlers)
   299     EXIT_ACTION(state_moveScene, action_moveScene_disconnectGestureHandlers)
   356 
   300     
   357     ENTRY_ACTION(state_sceneMenu, action_sceneMenu_showMenu)
       
   358 
       
   359     ENTRY_ACTION(state_addPage, action_disableUserInteraction)
       
   360     ENTRY_ACTION(state_addPage, action_addPage_addPage)
   301     ENTRY_ACTION(state_addPage, action_addPage_addPage)
   361     EXIT_ACTION(state_addPage, action_enableUserInteraction)
   302 
   362 
       
   363     ENTRY_ACTION(state_removePage, action_disableUserInteraction)
       
   364     ENTRY_ACTION(state_removePage, action_removePage_removePage)
   303     ENTRY_ACTION(state_removePage, action_removePage_removePage)
   365     EXIT_ACTION(state_removePage, action_enableUserInteraction)
   304 
   366 
       
   367     ENTRY_ACTION(state_toggleConnection, action_disableUserInteraction)
       
   368     ENTRY_ACTION(state_toggleConnection, action_toggleConnection_toggleConnection)
   305     ENTRY_ACTION(state_toggleConnection, action_toggleConnection_toggleConnection)
   369     EXIT_ACTION(state_toggleConnection, action_enableUserInteraction)
       
   370 }
   306 }
   371 
   307 
   372 /*!
   308 /*!
   373     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.
   374 */
   310 */
   392     
   328     
   393     mPageChangeAnimation->setEndValue(pageLayerXPos(targetPageIndex));
   329     mPageChangeAnimation->setEndValue(pageLayerXPos(targetPageIndex));
   394     mPageChangeAnimation->setDuration(duration);
   330     mPageChangeAnimation->setDuration(duration);
   395     connect(mPageChangeAnimation,
   331     connect(mPageChangeAnimation,
   396             SIGNAL(finished()),
   332             SIGNAL(finished()),
   397             SLOT(pageChangeAnimationFinished()));
   333             SLOT(pageChangeAnimationFinished()), 
       
   334             Qt::UniqueConnection);
   398     mPageChangeAnimation->start();
   335     mPageChangeAnimation->start();
   399     
   336     
   400     HbInstantFeedback::play(HSCONFIGURATION_GET(pageChangeFeedbackEffect));
   337     HbInstantFeedback::play(HSCONFIGURATION_GET(pageChangeFeedbackEffect));
   401     
   338     
   402     mUiWidget->showPageIndicator();
   339     mUiWidget->showPageIndicator();
   419         ++targetPageIndex;
   356         ++targetPageIndex;
   420     } else {
   357     } else {
   421         return;
   358         return;
   422     }
   359     }
   423 
   360 
   424     if (targetPageIndex >= HSCONFIGURATION_GET(maximumPageCount)){
       
   425         return;
       
   426     }
       
   427 
       
   428     if (!mZoneAnimation) {
   361     if (!mZoneAnimation) {
   429         mZoneAnimation = new QPropertyAnimation(mUiWidget, "sceneX");
   362         mZoneAnimation = new QPropertyAnimation(mUiWidget, "sceneX");
   430     }
   363     }
   431 
   364 
   432     int bounceEffect = HSCONFIGURATION_GET(bounceEffect);
   365     int bounceEffect = HSCONFIGURATION_GET(bounceEffect);
   440     mZoneAnimation->setDirection(QAbstractAnimation::Forward);
   373     mZoneAnimation->setDirection(QAbstractAnimation::Forward);
   441 
   374 
   442     connect(mZoneAnimation,
   375     connect(mZoneAnimation,
   443             SIGNAL(finished()),
   376             SIGNAL(finished()),
   444             SLOT(zoneAnimationFinished()));
   377             SLOT(zoneAnimationFinished()));
       
   378     
   445     mZoneAnimation->start();
   379     mZoneAnimation->start();
   446 }
   380 }
   447 
   381 
   448 /*!
   382 /*!
   449     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
   459     Checks if touch point in the active widget is located inside the left
   393     Checks if touch point in the active widget is located inside the left
   460     page change zone.
   394     page change zone.
   461 */
   395 */
   462 bool HsIdleState::isInLeftPageChangeZone()
   396 bool HsIdleState::isInLeftPageChangeZone()
   463 {
   397 {
   464     return mTouchScenePos.x() < HSCONFIGURATION_GET(pageChangeZoneWidth);
   398     return mWidgetHotSpot.x() < HSCONFIGURATION_GET(pageChangeZoneWidth);
   465 }
   399 }
   466 
   400 
   467 /*!
   401 /*!
   468     Checks if touch point in the active widget is located inside the right
   402     Checks if touch point in the active widget is located inside the right
   469     page change zone.
   403     page change zone.
   470 */
   404 */
   471 bool HsIdleState::isInRightPageChangeZone()
   405 bool HsIdleState::isInRightPageChangeZone()
   472 {
   406 {
   473     qreal pageWidth = HsScene::mainWindow()->layoutRect().width();
   407     qreal pageWidth = HsScene::mainWindow()->layoutRect().width();
   474     return mTouchScenePos.x() > pageWidth - HSCONFIGURATION_GET(pageChangeZoneWidth);
   408     return mWidgetHotSpot.x() > pageWidth - HSCONFIGURATION_GET(pageChangeZoneWidth);
   475 }
   409 }
   476 
   410 
   477 /*!
   411 /*!
   478     Inserts new page at index position \a pageIndex in the scene.
   412     Inserts new page at index position \a pageIndex in the scene.
   479 */
   413 */
   491     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
   492 */
   426 */
   493 void HsIdleState::updateZoneAnimation()
   427 void HsIdleState::updateZoneAnimation()
   494 {
   428 {
   495     if (isInPageChangeZone() && mAllowZoneAnimation) {
   429     if (isInPageChangeZone() && mAllowZoneAnimation) {
   496         if (!mZoneAnimation
   430         if (!mZoneAnimation && (!mPageChangeAnimation
   497             && ( !mPageChangeAnimation
   431             || mPageChangeAnimation->state() == QAbstractAnimation::Stopped )) {
   498                  || mPageChangeAnimation->state() == QAbstractAnimation::Stopped )) {
       
   499             startPageChangeZoneAnimation(HSCONFIGURATION_GET(pageChangeZoneAnimationDuration));
   432             startPageChangeZoneAnimation(HSCONFIGURATION_GET(pageChangeZoneAnimationDuration));
   500         }
   433         }
   501     }
   434     } else if (mZoneAnimation && !isInPageChangeZone()) {
   502     else if (mZoneAnimation && !isInPageChangeZone()) {
       
   503         if (mZoneAnimation->state() == QAbstractAnimation::Running) {
   435         if (mZoneAnimation->state() == QAbstractAnimation::Running) {
   504             if (mZoneAnimation->direction() == QAbstractAnimation::Forward) {
   436             if (mZoneAnimation->direction() == QAbstractAnimation::Forward) {
   505                     mZoneAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration));
   437                 mZoneAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration));
   506                     mZoneAnimation->setDirection(QAbstractAnimation::Backward);
   438                 mZoneAnimation->setDirection(QAbstractAnimation::Backward);
   507             }
   439             }
   508         }
   440         } else {
   509         else {
       
   510             // Out of the page change zone. Delete animation.
   441             // Out of the page change zone. Delete animation.
   511             deleteZoneAnimation();
   442             deleteZoneAnimation();
   512         }
   443         }
   513     }
   444     } else if (!isInPageChangeZone()) {
   514     else if (!isInPageChangeZone()) {
       
   515         if (mZoneAnimation) {
   445         if (mZoneAnimation) {
   516             mZoneAnimation->stop();
   446             mZoneAnimation->stop();
   517         }
   447         }
   518     }
   448     }
   519 }
   449 }
   575     delete mZoneAnimation;
   505     delete mZoneAnimation;
   576     mZoneAnimation = NULL;
   506     mZoneAnimation = NULL;
   577 }
   507 }
   578 
   508 
   579 /*!
   509 /*!
   580     Disables the main window user interaction.
       
   581 */
       
   582 void HsIdleState::action_disableUserInteraction()
       
   583 {
       
   584     HsScene::mainWindow()->setInteractive(false);
       
   585 }
       
   586 
       
   587 /*!
       
   588     Enables the main window user interaction.
       
   589 */
       
   590 void HsIdleState::action_enableUserInteraction()
       
   591 {
       
   592     HsScene::mainWindow()->setInteractive(true);
       
   593 }
       
   594 
       
   595 /*!
       
   596     If called for the first time, setups the idle view.
   510     If called for the first time, setups the idle view.
   597     Updates the soft key action and sets the idle view
   511     Updates the soft key action and sets the idle view
   598     as the current view to the main window.
   512     as the current view to the main window.
   599 */
   513 */
   600 void HsIdleState::action_idle_setupView()
   514 void HsIdleState::action_idle_setupView()
   605         idleView = HsScene::mainWindow()->addView(mUiWidget);
   519         idleView = HsScene::mainWindow()->addView(mUiWidget);
   606         idleView->setContentFullScreen();
   520         idleView->setContentFullScreen();
   607 
   521 
   608         mNavigationAction = new HbAction(this);
   522         mNavigationAction = new HbAction(this);
   609         mNavigationAction->setIcon(HbIcon(gApplicationLibraryIconName));
   523         mNavigationAction->setIcon(HbIcon(gApplicationLibraryIconName));
       
   524         mNavigationAction->setObjectName("applib_navigation_action");
   610         connect(mNavigationAction, SIGNAL(triggered()), SIGNAL(event_applicationLibrary()));
   525         connect(mNavigationAction, SIGNAL(triggered()), SIGNAL(event_applicationLibrary()));
   611         idleView->setNavigationAction(mNavigationAction);
   526         idleView->setNavigationAction(mNavigationAction);
   612 
   527 
   613         HsGui::setIdleView(idleView);
   528         HsGui::setIdleView(idleView);
   614 
   529 
   623 
   538 
   624 /*!
   539 /*!
   625     Sets the idle view's title.
   540     Sets the idle view's title.
   626 */
   541 */
   627 void HsIdleState::action_idle_setupTitle()
   542 void HsIdleState::action_idle_setupTitle()
   628 {
   543 {    
   629     qDebug() << "HsIdleState::action_idle_setupTitle() - ENTRY";
       
   630     onTitleChanged(mTitleResolver->title());
   544     onTitleChanged(mTitleResolver->title());
   631     connect(mTitleResolver, SIGNAL(titleChanged(QString)), SLOT(onTitleChanged(QString)));
   545     connect(mTitleResolver, 
   632     qDebug() << "HsIdleState::action_idle_setupTitle() - EXIT";
   546         SIGNAL(titleChanged(QString)), 
       
   547         SLOT(onTitleChanged(QString)));
   633 }
   548 }
   634 
   549 
   635 /*!
   550 /*!
   636     Updates the idle view's title.
   551     Updates the idle view's title.
   637 */
   552 */
   642 }
   557 }
   643 
   558 
   644 /*!
   559 /*!
   645 
   560 
   646 */
   561 */
   647 void HsIdleState::onAddContentActionTriggered()
   562 void HsIdleState::onAddContentFromContextMenuActionTriggered()
   648 {
   563 {
       
   564     /* include position information in homescreen data,
       
   565        which passed around in applib and returned when adding content
       
   566     */
       
   567     QVariant homescreenData(mPageHotSpot);
   649     machine()->postEvent(
   568     machine()->postEvent(
   650         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));
   651 }
   580 }
   652 
   581 
   653 /*!
   582 /*!
   654     Disconnects the idle view's title.
   583     Disconnects the idle view's title.
   655 */
   584 */
   656 void HsIdleState::action_idle_cleanupTitle()
   585 void HsIdleState::action_idle_cleanupTitle()
   657 {
   586 {
   658     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();
   659 }
   750 }
   660 
   751 
   661 /*!
   752 /*!
   662     Lays out the active page's new widgets that were added
   753     Lays out the active page's new widgets that were added
   663     from the application library.
   754     from the application library.
   685 /*!
   776 /*!
   686     Moves the scene and page layers so that the active
   777     Moves the scene and page layers so that the active
   687     page is shown.
   778     page is shown.
   688 */
   779 */
   689 void HsIdleState::action_idle_showActivePage()
   780 void HsIdleState::action_idle_showActivePage()
   690 {    
   781 {   
   691     HsScene *scene = HsScene::instance();
   782     HsScene *scene = HsScene::instance();
   692     QApplication::instance()->installEventFilter(scene);
   783     QApplication::instance()->installEventFilter(scene);
   693     scene->activePage()->showWidgets();
   784     scene->activePage()->showWidgets();
   694     qreal x = pageLayerXPos(scene->activePageIndex());
   785     qreal x = pageLayerXPos(scene->activePageIndex());
   695     mUiWidget->setSceneX(x);
   786     mUiWidget->setSceneX(x);
   700 */
   791 */
   701 void HsIdleState::action_idle_connectOrientationChangeEventHandler()
   792 void HsIdleState::action_idle_connectOrientationChangeEventHandler()
   702 {
   793 {
   703     connect(HsScene::mainWindow(),
   794     connect(HsScene::mainWindow(),
   704         SIGNAL(orientationChanged(Qt::Orientation)),
   795         SIGNAL(orientationChanged(Qt::Orientation)),
   705         SLOT(action_idle_showActivePage()));
   796         SLOT(action_idle_orientationChanged()));
       
   797 }
       
   798 
       
   799 void HsIdleState::action_idle_orientationChanged()
       
   800 {
       
   801     HsScene::instance()->activePage()->resetNewWidgets();
       
   802     action_idle_showActivePage();
   706 }
   803 }
   707 
   804 
   708 /*!
   805 /*!
   709     Installs the event filter.
   806     Installs the event filter.
   710 */
   807 */
   740 {
   837 {
   741     HsScene *scene = HsScene::instance();
   838     HsScene *scene = HsScene::instance();
   742     QApplication::instance()->removeEventFilter(scene);
   839     QApplication::instance()->removeEventFilter(scene);
   743     scene->activePage()->hideWidgets();
   840     scene->activePage()->hideWidgets();
   744 
   841 
   745     if (mUiWidget) {
       
   746         mUiWidget->clearDelayedPress();
       
   747     }
       
   748 
       
   749     //Close options menu on view change
   842     //Close options menu on view change
   750     HsGui::idleView()->setMenu(NULL);
   843     HsGui::idleView()->setMenu(NULL);
   751 
   844 
   752     //Close context menu on view change
   845     //Close context menu on view change
   753     if (mSceneMenu) {
   846     if (mSceneMenu) {
   754         disconnect(mSceneMenu, SIGNAL(aboutToClose()), this, SLOT(onSceneMenuAboutToClose()));
       
   755         mSceneMenu->close();
   847         mSceneMenu->close();
   756     }
   848     }
   757 }
   849 }
   758 
   850 
   759 /*!
   851 /*!
   761 */
   853 */
   762 void HsIdleState::action_idle_disconnectOrientationChangeEventHandler()
   854 void HsIdleState::action_idle_disconnectOrientationChangeEventHandler()
   763 {
   855 {
   764     disconnect(HsScene::mainWindow(),
   856     disconnect(HsScene::mainWindow(),
   765         SIGNAL(orientationChanged(Qt::Orientation)),
   857         SIGNAL(orientationChanged(Qt::Orientation)),
   766         this, SLOT(action_idle_showActivePage()));
   858         this, SLOT(action_idle_orientationChanged()));
   767 }
   859 }
   768 
   860 
   769 /*!
   861 /*!
   770     Disconnects the event filter.
   862     Disconnects the event filter.
   771 */
   863 */
   780 void HsIdleState::action_waitInput_updateOptionsMenu()
   872 void HsIdleState::action_waitInput_updateOptionsMenu()
   781 {
   873 {
   782     HsScene *scene = HsScene::instance();
   874     HsScene *scene = HsScene::instance();
   783 
   875 
   784     HbMenu *menu = new HbMenu();
   876     HbMenu *menu = new HbMenu();
   785 
   877     menu->setObjectName("hs_menu");
   786     // Task switcher
   878     // Task switcher
   787     menu->addAction(hbTrId(hsLocTextId_OptionsMenu_TaskSwitcher),
   879     HbAction *action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_TaskSwitcher),
   788         this, SLOT(openTaskSwitcher()));
   880         this, SLOT(openTaskSwitcher()));
   789 
   881     action->setObjectName("action_open_task_switcher");
   790     // Add content
   882     // Add content
   791     menu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent),
   883     action = menu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent),
   792         this, SLOT(onAddContentActionTriggered()));
   884         this, SLOT(onAddContentFromOptionsMenuActionTriggered()));
   793 
   885     action->setObjectName("action_add_content");
   794     // Add page
   886     // Add page
   795     if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) {
   887     if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) {
   796         menu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage),
   888         action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage),
   797             this, SIGNAL(event_addPage()));
   889             this, SIGNAL(event_addPage()));
       
   890         action->setObjectName("action_add_page");
       
   891 
   798     }
   892     }
   799 
   893 
   800     // Change wallpaper
   894     // Change wallpaper
   801     menu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper),
   895     action = menu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper),
   802         this, SIGNAL(event_selectWallpaper()));
   896         this, SIGNAL(event_selectWallpaper()));
   803 
   897     action->setObjectName("action_change_wallpaper");
   804     // Remove page
   898     // Remove page
   805     if (scene->activePage()->isRemovable()) {
   899     if (scene->activePage()->isRemovable()) {
   806         menu->addAction(hbTrId(hsLocTextId_OptionsMenu_RemovePage),
   900         action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_RemovePage),
   807             this, SIGNAL(event_removePage()));
   901             this, SIGNAL(event_removePage()));
       
   902         action->setObjectName("action_remove_page"); 
   808     }
   903     }
   809 
   904 
   810     // Online / Offline
   905     // Online / Offline
   811     if (scene->isOnline()) {
   906     if (scene->isOnline()) {
   812         menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOffline),
   907         action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOffline),
   813             this, SIGNAL(event_toggleConnection()));
   908             this, SIGNAL(event_toggleConnection()));
       
   909         action->setObjectName("action_to_offline");
   814     } else {
   910     } else {
   815         menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOnline),
   911         action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOnline),
   816             this, SIGNAL(event_toggleConnection()));
   912             this, SIGNAL(event_toggleConnection()));
       
   913         action->setObjectName("action_to_online");
   817     }
   914     }
   818 
   915 
   819     HsGui::idleView()->setMenu(menu);
   916     HsGui::idleView()->setMenu(menu);
   820 }
   917 }
   821 
   918 
   822 /*!
   919 void HsIdleState::action_waitInput_connectGestureHandlers()
   823     Connects the waitInput state's mouse event handlers.
   920 {
   824 */
   921     HsScene *scene = HsScene::instance();
   825 void HsIdleState::action_waitInput_connectMouseEventHandlers()
   922 
   826 {
   923     connect(scene, 
   827     CONNECT_MOUSE_EVENT_HANDLER(mousePressed, waitInput_onMousePressed)
   924         SIGNAL(pageTapAndHoldFinished(QGestureEvent*)), 
   828 }
   925         SLOT(onPageTapAndHoldFinished(QGestureEvent*)),
   829 
   926         Qt::UniqueConnection);
   830 /*!
   927 
   831     Disconnects the waitInput state's mouse event handlers.
   928     connect(scene,
   832 */
   929         SIGNAL(pagePanStarted(QGestureEvent*)),
   833 void HsIdleState::action_waitInput_disconnectMouseEventHandlers()
   930         SLOT(onPagePanStarted(QGestureEvent*)),
   834 {
   931         Qt::UniqueConnection);
   835     DISCONNECT_MOUSE_EVENT_HANDLER(mousePressed, waitInput_onMousePressed)
   932 
       
   933     connect(scene, 
       
   934         SIGNAL(widgetTapStarted(HsWidgetHost*)), 
       
   935         SLOT(onWidgetTapStarted(HsWidgetHost*)),
       
   936         Qt::UniqueConnection);
       
   937     
       
   938     connect(scene, 
       
   939         SIGNAL(widgetTapAndHoldFinished(QGestureEvent*,HsWidgetHost*)), 
       
   940         SLOT(onWidgetTapAndHoldFinished(QGestureEvent*,HsWidgetHost*)),
       
   941         Qt::UniqueConnection);
       
   942 }
       
   943 
       
   944 void HsIdleState::action_waitInput_disconnectGestureHandlers()
       
   945 {
       
   946     HsScene *scene = HsScene::instance();
       
   947     scene->disconnect(this);
   836 }
   948 }
   837 
   949 
   838 /*!
   950 /*!
   839     Resets new widget layout.
   951     Resets new widget layout.
   840 */
   952 */
   841 void HsIdleState::action_waitInput_resetNewWidgets()
   953 void HsIdleState::action_waitInput_resetNewWidgets()
   842 {
   954 {
   843     HsScene::instance()->activePage()->resetNewWidgets();
   955     HsScene::instance()->activePage()->resetNewWidgets();
   844 }
       
   845 
       
   846 /*!
       
   847     Connects the widgetInteraction state's mouse event handlers.
       
   848 */
       
   849 void HsIdleState::action_widgetInteraction_connectMouseEventHandlers()
       
   850 {
       
   851     CONNECT_MOUSE_EVENT_HANDLER(mouseMoved, widgetInteraction_onMouseMoved)
       
   852     CONNECT_MOUSE_EVENT_HANDLER(mouseReleased, widgetInteraction_onMouseReleased)
       
   853 }
       
   854 
       
   855 /*!
       
   856     Connects the widgetInteraction state's gesture timers.
       
   857 */
       
   858 void HsIdleState::action_widgetInteraction_connectGestureTimers()
       
   859 {
       
   860     mTimer.setInterval(HSCONFIGURATION_GET(widgetTapAndHoldTimeout));
       
   861     connect(&mTimer, SIGNAL(timeout()),
       
   862         SLOT(widgetInteraction_onTapAndHoldTimeout()));
       
   863     mTimer.start();
       
   864 }
       
   865 
       
   866 /*!
       
   867     Disconnects the widgetInteraction state's mouse event handlers.
       
   868 */
       
   869 void HsIdleState::action_widgetInteraction_disconnectMouseEventHandlers()
       
   870 {
       
   871     DISCONNECT_MOUSE_EVENT_HANDLER(mouseMoved, widgetInteraction_onMouseMoved)
       
   872     DISCONNECT_MOUSE_EVENT_HANDLER(mouseReleased, widgetInteraction_onMouseReleased)
       
   873 }
       
   874 
       
   875 /*!
       
   876     Disconnects the widgetInteraction state's gesture timers.
       
   877 */
       
   878 void HsIdleState::action_widgetInteraction_disconnectGestureTimers()
       
   879 {
       
   880     disconnect(&mTimer, SIGNAL(timeout()),
       
   881         this, SLOT(widgetInteraction_onTapAndHoldTimeout()));
       
   882 }
       
   883 
       
   884 /*!
       
   885     Connects the sceneInteraction state's mouse event handlers.
       
   886 */
       
   887 void HsIdleState::action_sceneInteraction_connectMouseEventHandlers()
       
   888 {
       
   889     CONNECT_MOUSE_EVENT_HANDLER(mouseMoved, sceneInteraction_onMouseMoved)
       
   890     CONNECT_MOUSE_EVENT_HANDLER(mouseReleased, sceneInteraction_onMouseReleased)
       
   891 }
       
   892 
       
   893 /*!
       
   894     Connects the sceneInteraction state's gesture timers.
       
   895 */
       
   896 void HsIdleState::action_sceneInteraction_connectGestureTimers()
       
   897 {
       
   898     mTimer.setInterval(HSCONFIGURATION_GET(sceneTapAndHoldTimeout));
       
   899     connect(&mTimer, SIGNAL(timeout()),
       
   900         SLOT(sceneInteraction_onTapAndHoldTimeout()));
       
   901     mTimer.start();
       
   902 }
       
   903 
       
   904 /*!
       
   905     Disconnects the sceneInteraction state's mouse event handlers.
       
   906 */
       
   907 void HsIdleState::action_sceneInteraction_disconnectMouseEventHandlers()
       
   908 {
       
   909     DISCONNECT_MOUSE_EVENT_HANDLER(mouseMoved, sceneInteraction_onMouseMoved)
       
   910     DISCONNECT_MOUSE_EVENT_HANDLER(mouseReleased, sceneInteraction_onMouseReleased)
       
   911 }
       
   912 
       
   913 /*!
       
   914     Disconnects the sceneInteraction state's gesture timers.
       
   915 */
       
   916 void HsIdleState::action_sceneInteraction_disconnectGestureTimers()
       
   917 {
       
   918     disconnect(&mTimer, SIGNAL(timeout()),
       
   919         this, SLOT(sceneInteraction_onTapAndHoldTimeout()));
       
   920 }
   956 }
   921 
   957 
   922 /*!
   958 /*!
   923     Reparents the active widget to the control layer.
   959     Reparents the active widget to the control layer.
   924 */
   960 */
   940     Q_ASSERT(widget);
   976     Q_ASSERT(widget);
   941     widget->startDragEffect();
   977     widget->startDragEffect();
   942     mAllowZoneAnimation = true;
   978     mAllowZoneAnimation = true;
   943 }
   979 }
   944 
   980 
   945 /*!
   981 void HsIdleState::action_moveWidget_connectGestureHandlers()
   946     Connects the moveWidget state's mouse event handlers.
   982 {
   947 */
   983     HsScene *scene = HsScene::instance();
   948 void HsIdleState::action_moveWidget_connectMouseEventHandlers()
   984         
   949 {
   985     connect(scene, 
   950     CONNECT_MOUSE_EVENT_HANDLER(mouseMoved, moveWidget_onMouseMoved)
   986         SIGNAL(widgetMoveUpdated(const QPointF&,HsWidgetHost*)), 
   951     CONNECT_MOUSE_EVENT_HANDLER(mouseReleased, moveWidget_onMouseReleased)
   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;
   952 }
  1052 }
   953 
  1053 
   954 /*!
  1054 /*!
   955     Reparents the active widget to the active page.
  1055     Reparents the active widget to the active page.
   956 */
  1056 */
   957 void HsIdleState::action_moveWidget_reparentToPage()
  1057 void HsIdleState::action_moveWidget_reparentToPage()
   958 {
  1058 {
   959     mTimer.stop();
       
   960 
       
   961     if (mZoneAnimation
  1059     if (mZoneAnimation
   962         && mZoneAnimation->state() == QAbstractAnimation::Running
  1060         && mZoneAnimation->state() == QAbstractAnimation::Running
   963         && mZoneAnimation->direction() == QAbstractAnimation::Forward) {
  1061         && mZoneAnimation->direction() == QAbstractAnimation::Forward) {
   964         mZoneAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration));
  1062         mZoneAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration));
   965         mZoneAnimation->setDirection(QAbstractAnimation::Backward);
  1063         mZoneAnimation->setDirection(QAbstractAnimation::Backward);
   985             }
  1083             }
   986         }
  1084         }
   987 
  1085 
   988         QRectF widgetRect = widget->geometry();
  1086         QRectF widgetRect = widget->geometry();
   989         QRectF pageRect = page->rect();
  1087         QRectF pageRect = page->rect();
   990         qreal widgetX = qBound(qreal(0), widgetRect.x(), pageRect.width() - widgetRect.width());
  1088 
   991         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());
   992 
  1100 
   993         // 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
   994         if( widgetX != widgetRect.x() || widgetY != widgetRect.y()) {
  1102         if( widgetX != widgetRect.x() || widgetY != widgetRect.y()) {
   995             HbInstantFeedback::play(HSCONFIGURATION_GET(widgetRepositionFeedbackEffect));
  1103             HbInstantFeedback::play(HSCONFIGURATION_GET(widgetRepositionFeedbackEffect));
   996         }
  1104         }
  1014     if (widget) {
  1122     if (widget) {
  1015         widget->startDropEffect();
  1123         widget->startDropEffect();
  1016     }
  1124     }
  1017 }
  1125 }
  1018 
  1126 
  1019 /*!
  1127 void HsIdleState::action_moveWidget_disconnectGestureHandlers()
  1020     Disconnects the moveWidget state's mouse event handlers.
  1128 {
  1021 */
  1129     HsScene *scene = HsScene::instance();
  1022 void HsIdleState::action_moveWidget_disconnectMouseEventHandlers()
  1130     scene->disconnect(this);
  1023 {
  1131 }
  1024     DISCONNECT_MOUSE_EVENT_HANDLER(mouseMoved, moveWidget_onMouseMoved)
  1132 
  1025     DISCONNECT_MOUSE_EVENT_HANDLER(mouseReleased, moveWidget_onMouseReleased)
  1133 /*!
       
  1134     Resets the snap position
       
  1135     Disconnect the Active Page Changed SIGNAL
       
  1136     Disconnects the timers to show snap lines
       
  1137 */
       
  1138 void HsIdleState::action_moveWidget_deleteWidgetSnap()
       
  1139 {
       
  1140     if (HSCONFIGURATION_GET(isSnapEnabled)) {
       
  1141         resetSnapPosition();
       
  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     }
  1026 }
  1153 }
  1027 
  1154 
  1028 /*!
  1155 /*!
  1029     Prevents page change zone animation.
  1156     Prevents page change zone animation.
  1030 */
  1157 */
  1031 void HsIdleState::action_moveWidget_preventZoneAnimation()
  1158 void HsIdleState::action_moveWidget_preventZoneAnimation()
  1032 {
  1159 {
  1033     mAllowZoneAnimation = false;
  1160     mAllowZoneAnimation = false;
  1034 }
  1161 }
  1035 
  1162 
  1036 /*!
  1163 void HsIdleState::action_moveScene_connectGestureHandlers()
  1037     Connects the moveScene state's mouse event handlers.
  1164 {
  1038 */
  1165     HsScene *scene = HsScene::instance();
  1039 void HsIdleState::action_moveScene_connectMouseEventHandlers()
  1166 
  1040 {
  1167     connect(scene,
  1041     CONNECT_MOUSE_EVENT_HANDLER(mouseMoved, moveScene_onMouseMoved)
  1168         SIGNAL(pagePanUpdated(QGestureEvent*)),
  1042     CONNECT_MOUSE_EVENT_HANDLER(mouseReleased, moveScene_onMouseReleased)
  1169         SLOT(onPagePanUpdated(QGestureEvent*)),
       
  1170         Qt::UniqueConnection);
       
  1171 
       
  1172     connect(scene,
       
  1173         SIGNAL(pagePanFinished(QGestureEvent*)),
       
  1174         SLOT(onPagePanFinished(QGestureEvent*)),
       
  1175         Qt::UniqueConnection);
  1043 }
  1176 }
  1044 
  1177 
  1045 /*!
  1178 /*!
  1046     Moves to the nearest page.
  1179     Moves to the nearest page.
  1047 */
  1180 */
  1061     HsScene::instance()->setActivePageIndex(pageIndex);
  1194     HsScene::instance()->setActivePageIndex(pageIndex);
  1062 
  1195 
  1063     startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration));
  1196     startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration));
  1064 }
  1197 }
  1065 
  1198 
  1066 /*!
  1199 void HsIdleState::action_moveScene_disconnectGestureHandlers()
  1067     Disconnects the moveScene state's mouse event handlers.
  1200 {
  1068 */
  1201     HsScene *scene = HsScene::instance();
  1069 void HsIdleState::action_moveScene_disconnectMouseEventHandlers()
  1202     scene->disconnect(this);
  1070 {
  1203 }
  1071     DISCONNECT_MOUSE_EVENT_HANDLER(mouseMoved, moveScene_onMouseMoved)
       
  1072     DISCONNECT_MOUSE_EVENT_HANDLER(mouseReleased, moveScene_onMouseReleased)
       
  1073 }
       
  1074 
       
  1075 #ifdef COVERAGE_MEASUREMENT
       
  1076 #pragma CTC SKIP
       
  1077 #endif //COVERAGE_MEASUREMENT
       
  1078 /*!
       
  1079     Shows the scene menu.
       
  1080 */
       
  1081 void HsIdleState::action_sceneMenu_showMenu()
       
  1082 {
       
  1083     mSceneMenu = new HbMenu();
       
  1084     mSceneMenu->setAttribute(Qt::WA_DeleteOnClose);
       
  1085     mSceneMenu->setDismissPolicy(HbDialog::TapOutside);
       
  1086     //This is used to check if any action is not triggered ( == menu is dismissed by user or timeout).
       
  1087     connect(mSceneMenu, SIGNAL(aboutToClose()), this, SLOT(onSceneMenuAboutToClose()));
       
  1088 
       
  1089     mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent), this, SLOT(onAddContentActionTriggered()));
       
  1090 
       
  1091     HsScene *scene = HsScene::instance();
       
  1092     if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) {
       
  1093         mSceneMenu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage), this, SIGNAL(event_addPage()));
       
  1094     }
       
  1095 
       
  1096     mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper), this, SIGNAL(event_selectWallpaper()));
       
  1097     mSceneMenu->setPreferredPos(mTouchScenePos);
       
  1098     mSceneMenu->open(this, SLOT(onSceneMenuTriggered(HbAction *)));
       
  1099 }
       
  1100 #ifdef COVERAGE_MEASUREMENT
       
  1101 #pragma CTC ENDSKIP
       
  1102 #endif //COVERAGE_MEASUREMENT
       
  1103 
  1204 
  1104 /*!
  1205 /*!
  1105     Adds a new page to the scene.
  1206     Adds a new page to the scene.
  1106 */
  1207 */
  1107 void HsIdleState::action_addPage_addPage()
  1208 void HsIdleState::action_addPage_addPage()
  1133         box->setText(hbTrId(hsLocTextId_Confirmation_RemovePage));
  1234         box->setText(hbTrId(hsLocTextId_Confirmation_RemovePage));
  1134 
  1235 
  1135         QAction *buttonOk = box->actions().at(0);
  1236         QAction *buttonOk = box->actions().at(0);
  1136         //We are keen only from OK button. Cancel is not connected to any slot.
  1237         //We are keen only from OK button. Cancel is not connected to any slot.
  1137         connect(buttonOk, SIGNAL(triggered()), SLOT(onRemovePageConfirmationOk()));
  1238         connect(buttonOk, SIGNAL(triggered()), SLOT(onRemovePageConfirmationOk()));
  1138 
  1239        
  1139         HsScene::mainWindow()->setInteractive(true);
       
  1140 
       
  1141         box->open();
  1240         box->open();
  1142 #endif //HOMESCREEN_TEST
  1241 #endif // HOMESCREEN_TEST
  1143     } else {
  1242     } else {
  1144         //Empty page can be removed without confirmation
  1243         // Empty page can be removed without confirmation
  1145         removeActivePage();
  1244         removeActivePage();
  1146     }
  1245     }
  1147 }
  1246 }
  1148 
  1247 
  1149 /*!
  1248 /*!
  1151 */
  1250 */
  1152 void HsIdleState::action_toggleConnection_toggleConnection()
  1251 void HsIdleState::action_toggleConnection_toggleConnection()
  1153 {
  1252 {
  1154     HsScene *scene = HsScene::instance();
  1253     HsScene *scene = HsScene::instance();
  1155     scene->setOnline(!scene->isOnline());
  1254     scene->setOnline(!scene->isOnline());
  1156 }
       
  1157 
       
  1158 /*!
       
  1159     Handles mouse press events for the waitInput state.
       
  1160     Filters events for the item \a watched. \a event is the
       
  1161     filtered event. Sets the \a filtered true if the event
       
  1162     was filtered by this handler.
       
  1163 */
       
  1164 void HsIdleState::waitInput_onMousePressed(
       
  1165     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1166 {
       
  1167     filtered = true;
       
  1168 
       
  1169     HsScene *scene = HsScene::instance();
       
  1170     HsPage *page = scene->activePage();
       
  1171     QList<HsWidgetHost *> widgets = page->widgets();
       
  1172 
       
  1173     if (mUiWidget->controlLayer() == watched ||
       
  1174         mUiWidget->controlLayer()->isAncestorOf(watched)) {
       
  1175         filtered = false;
       
  1176         return;
       
  1177     }
       
  1178 
       
  1179     mUiWidget->captureDelayedPress(event);
       
  1180 
       
  1181     foreach (HsWidgetHost *widget, widgets) {
       
  1182         if (widget == watched || widget->isAncestorOf(watched)) {
       
  1183             scene->setActiveWidget(widget);
       
  1184             emit event_widgetInteraction();
       
  1185             return;
       
  1186         }
       
  1187     }
       
  1188 
       
  1189     mTouchScenePos = event->scenePos();
       
  1190     emit event_sceneInteraction();
       
  1191 }
       
  1192 
       
  1193 /*!
       
  1194     Handles mouse move events for the widgetInteraction state.
       
  1195     Filters events for the item \a watched. \a event is the
       
  1196     filtered event. Sets the \a filtered true if the event
       
  1197     was filtered by this handler.
       
  1198 */
       
  1199 void HsIdleState::widgetInteraction_onMouseMoved(
       
  1200     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1201 {
       
  1202     Q_UNUSED(watched)
       
  1203     Q_UNUSED(filtered)
       
  1204 
       
  1205     if (!mTimer.isActive()) {
       
  1206         return;
       
  1207     }
       
  1208 
       
  1209     filtered = true;
       
  1210 
       
  1211     QPointF point =
       
  1212         event->scenePos() - event->buttonDownScenePos(Qt::LeftButton);
       
  1213     if (HSCONFIGURATION_GET(tapAndHoldDistance) < point.manhattanLength()) {
       
  1214         // Threshold area for tap exceeded. This is pan or swipe
       
  1215         mTimer.stop();
       
  1216         if (HsScene::instance()->activeWidget()->isPannable(event)) {
       
  1217             // let widget get first press
       
  1218             mUiWidget->sendDelayedPress();
       
  1219         } else {
       
  1220             // Widget doesn't consume pan or swipe gestures
       
  1221             mUiWidget->clearDelayedPress();
       
  1222             emit event_moveScene();
       
  1223         }
       
  1224     }
       
  1225 }
       
  1226 
       
  1227 /*!
       
  1228     Handles mouse release events for the widgetInteraction state.
       
  1229     Filters events for the item \a watched. \a event is the
       
  1230     filtered event. Sets the \a filtered true if the event
       
  1231     was filtered by this handler.
       
  1232 */
       
  1233 void HsIdleState::widgetInteraction_onMouseReleased(
       
  1234     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1235 {
       
  1236     Q_UNUSED(watched)
       
  1237     Q_UNUSED(event)
       
  1238     Q_UNUSED(filtered)
       
  1239 
       
  1240     if (mTimer.isActive()) {
       
  1241         mTimer.stop();
       
  1242         mUiWidget->sendDelayedPress();
       
  1243     }
       
  1244 
       
  1245     HsPage *page = HsScene::instance()->activePage();
       
  1246     QMetaObject::invokeMethod(page, "updateZValues", Qt::QueuedConnection);
       
  1247 
       
  1248     emit event_waitInput();
       
  1249 }
       
  1250 
       
  1251 /*!
       
  1252     Handles mouse move events for the sceneInteraction state.
       
  1253     Filters events for the item \a watched. \a event is the
       
  1254     filtered event. Sets the \a filtered true if the event
       
  1255     was filtered by this handler.
       
  1256 */
       
  1257 void HsIdleState::sceneInteraction_onMouseMoved(
       
  1258     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1259 {
       
  1260     Q_UNUSED(watched)
       
  1261     Q_UNUSED(filtered)
       
  1262 
       
  1263     mTouchScenePos = event->scenePos();
       
  1264 
       
  1265     if (!mTimer.isActive()) {
       
  1266         return;
       
  1267     }
       
  1268 
       
  1269     filtered = true;
       
  1270 
       
  1271     QPointF point =
       
  1272         event->scenePos() - event->buttonDownScenePos(Qt::LeftButton);
       
  1273     if (HSCONFIGURATION_GET(tapAndHoldDistance) < point.manhattanLength()) {
       
  1274         mTimer.stop();
       
  1275         mUiWidget->clearDelayedPress();
       
  1276         emit event_moveScene();
       
  1277     }
       
  1278 }
       
  1279 
       
  1280 /*!
       
  1281     Handles mouse release events for the sceneInteraction state.
       
  1282     Filters events for the item \a watched. \a event is the
       
  1283     filtered event. Sets the \a filtered true if the event
       
  1284     was filtered by this handler.
       
  1285 */
       
  1286 void HsIdleState::sceneInteraction_onMouseReleased(
       
  1287     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1288 {
       
  1289     Q_UNUSED(watched)
       
  1290     Q_UNUSED(event)
       
  1291     Q_UNUSED(filtered)
       
  1292 
       
  1293     filtered = true;
       
  1294 
       
  1295     if (mTimer.isActive()) {
       
  1296         mTimer.stop();
       
  1297         mUiWidget->clearDelayedPress();
       
  1298     }
       
  1299 
       
  1300     emit event_waitInput();
       
  1301 }
       
  1302 
       
  1303 /*!
       
  1304     Handles mouse move events for the moveWidget state.
       
  1305     Filters events for the item \a watched. \a event is the
       
  1306     filtered event. Sets the \a filtered true if the event
       
  1307     was filtered by this handler.
       
  1308 */
       
  1309 void HsIdleState::moveWidget_onMouseMoved(
       
  1310     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1311 {
       
  1312     Q_UNUSED(watched)
       
  1313 
       
  1314     HsScene *scene = HsScene::instance();
       
  1315     HsWidgetHost *widget = scene->activeWidget();
       
  1316     QRectF widgetRect = widget->geometry();
       
  1317 
       
  1318     //Move widget to new position:
       
  1319     mTouchScenePos = event->scenePos();
       
  1320     QPointF delta(event->scenePos() - event->lastScenePos());
       
  1321     widgetRect.moveTopLeft(widgetRect.topLeft() + delta);
       
  1322 
       
  1323     //Widget can be moved over the pages left border
       
  1324     qreal lowerBoundX = -widgetRect.width();
       
  1325     HsPage *page = scene->activePage();
       
  1326     QRectF pageRect = HsGui::idleView()->rect();
       
  1327     //Widget can be moved over the pages right border
       
  1328     qreal upperBoundX = pageRect.width();
       
  1329 
       
  1330     //Notice that chrome height is 64 pixels
       
  1331     qreal lowerBoundY = qreal(64) - widgetRect.height();
       
  1332     //Widget can be moved over the pages down border
       
  1333     qreal upperBoundY = pageRect.height();
       
  1334 
       
  1335     qreal widgetX = qBound(lowerBoundX, widgetRect.x(), upperBoundX);
       
  1336     qreal widgetY = qBound(lowerBoundY, widgetRect.y(), upperBoundY);
       
  1337     /* if using ItemClipsChildrenToShape-flag in widgethost then
       
  1338        setPos does not update position here, however setGeometry does it, QT bug?
       
  1339     */
       
  1340     widget->setGeometry(widgetX, widgetY, widgetRect.width(), widgetRect.height());
       
  1341 
       
  1342     int bounceFeedbackEffectDistance = HSCONFIGURATION_GET(bounceFeedbackEffectDistance);
       
  1343     //Handle effects:
       
  1344     //User is indicated by a tactile feedback if he/she is trying to move
       
  1345     //widget over the first or the last page.
       
  1346     if( (page == scene->pages().first() && mTouchScenePos.x() < bounceFeedbackEffectDistance ) ||
       
  1347         (page == scene->pages().last() && scene->pages().count() == HSCONFIGURATION_GET(maximumPageCount)
       
  1348          && mTouchScenePos.x() > pageRect.width() - bounceFeedbackEffectDistance)) {
       
  1349              HbInstantFeedback::play(HSCONFIGURATION_GET(widgetMoveBlockedFeedbackEffect));
       
  1350             // TODO: use code below when Orbit has updated ContinuousFeedback API
       
  1351             //if (!mContinuousFeedback->isPlaying()) {
       
  1352             //    mContinuousFeedback->play();
       
  1353             //}
       
  1354         }
       
  1355         else /*if (mContinuousFeedback->isPlaying())*/ {
       
  1356             //mContinuousFeedback->stop();
       
  1357         }
       
  1358 
       
  1359     updateZoneAnimation();
       
  1360     showTrashBin();
       
  1361 
       
  1362     filtered = true;
       
  1363 }
       
  1364 
       
  1365 /*!
       
  1366     Handles mouse release events for the moveWidget state.
       
  1367     Filters events for the item \a watched. \a event is the
       
  1368     filtered event. Sets the \a filtered true if the event
       
  1369     was filtered by this handler.
       
  1370 */
       
  1371 void HsIdleState::moveWidget_onMouseReleased(
       
  1372     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1373 {
       
  1374     Q_UNUSED(watched)
       
  1375     Q_UNUSED(event)
       
  1376 
       
  1377     filtered = true;
       
  1378     emit event_waitInput();
       
  1379 }
       
  1380 
       
  1381 /*!
       
  1382     Handles mouse move events for the moveScene state.
       
  1383     Filters events for the item \a watched. \a event is the
       
  1384     filtered event. Sets the \a filtered true if the event
       
  1385     was filtered by this handler.
       
  1386 */
       
  1387 void HsIdleState::moveScene_onMouseMoved(
       
  1388     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1389 {
       
  1390     Q_UNUSED(watched)
       
  1391     Q_UNUSED(filtered)
       
  1392 
       
  1393     filtered = true;
       
  1394 
       
  1395     HsScene *scene = HsScene::instance();
       
  1396     mDeltaX = event->scenePos().x() - event->buttonDownScenePos(Qt::LeftButton).x();
       
  1397 
       
  1398     int bounceEffect = HSCONFIGURATION_GET(bounceEffect);
       
  1399 
       
  1400     qreal x = qBound(pageLayerXPos(scene->pages().count() - 1) - bounceEffect / 2 / mUiWidget->parallaxFactor(),
       
  1401                      pageLayerXPos(scene->activePageIndex()) + mDeltaX,
       
  1402                      pageLayerXPos(0) + (bounceEffect / 2 / mUiWidget->parallaxFactor()));
       
  1403 
       
  1404     mUiWidget->setSceneX(x);
       
  1405 }
       
  1406 
       
  1407 /*!
       
  1408     Handles mouse release events for the moveScene state.
       
  1409     Filters events for the item \a watched. \a event is the
       
  1410     filtered event. Sets the \a filtered true if the event
       
  1411     was filtered by this handler.
       
  1412 */
       
  1413 void HsIdleState::moveScene_onMouseReleased(
       
  1414     QGraphicsItem *watched, QGraphicsSceneMouseEvent *event, bool &filtered)
       
  1415 {
       
  1416     Q_UNUSED(watched)
       
  1417     Q_UNUSED(filtered)
       
  1418     filtered = true;
       
  1419 
       
  1420     mDeltaX = event->scenePos().x() - event->buttonDownScenePos(Qt::LeftButton).x();
       
  1421 
       
  1422     emit event_waitInput();
       
  1423 }
       
  1424 
       
  1425 /*!
       
  1426     Handles tap-and-hold events for the widgetInteraction state.
       
  1427 */
       
  1428 void HsIdleState::widgetInteraction_onTapAndHoldTimeout()
       
  1429 {
       
  1430     mUiWidget->clearDelayedPress();
       
  1431     emit event_moveWidget();
       
  1432 }
       
  1433 
       
  1434 /*!
       
  1435     Handles tap-and-hold events for the sceneInteraction state.
       
  1436 */
       
  1437 void HsIdleState::sceneInteraction_onTapAndHoldTimeout()
       
  1438 {
       
  1439     mUiWidget->clearDelayedPress();
       
  1440     emit event_sceneMenu();
       
  1441 }
  1255 }
  1442 
  1256 
  1443 #ifdef COVERAGE_MEASUREMENT
  1257 #ifdef COVERAGE_MEASUREMENT
  1444 #pragma CTC SKIP
  1258 #pragma CTC SKIP
  1445 #endif //COVERAGE_MEASUREMENT
  1259 #endif //COVERAGE_MEASUREMENT
  1466 
  1280 
  1467     if (mZoneAnimation->direction() == QAbstractAnimation::Forward) {
  1281     if (mZoneAnimation->direction() == QAbstractAnimation::Forward) {
  1468         if (isInLeftPageChangeZone() &&
  1282         if (isInLeftPageChangeZone() &&
  1469             0 < pageIndex) {
  1283             0 < pageIndex) {
  1470             --pageIndex;
  1284             --pageIndex;
  1471         }
  1285         } else if (isInRightPageChangeZone() &&
  1472         else if (isInRightPageChangeZone() &&
  1286                    pageIndex < scene->pages().count()) {
  1473             pageIndex < scene->pages().count()) {
       
  1474             ++pageIndex;
  1287             ++pageIndex;
  1475         }
  1288         }
  1476 
       
  1477         if (pageIndex == scene->pages().count()) {
  1289         if (pageIndex == scene->pages().count()) {
  1478             if (pageIndex < HSCONFIGURATION_GET(maximumPageCount)) {
  1290             if (pageIndex < HSCONFIGURATION_GET(maximumPageCount)) {
  1479                 addPageToScene(pageIndex);
  1291                 addPageToScene(pageIndex);
  1480                 mUiWidget->showPageIndicator();
  1292                 mUiWidget->showPageIndicator();
  1481                 mUiWidget->pageIndicator()->addItem(pageIndex);
  1293                 mUiWidget->pageIndicator()->addItem(pageIndex);
  1482             }
  1294             }
  1483         }
  1295         }
  1484         scene->setActivePageIndex(pageIndex);
  1296         scene->setActivePageIndex(pageIndex);
  1485         startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration));
  1297         startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration));
  1486     }
  1298     } else {
  1487     else {
       
  1488         scene->setActivePageIndex(pageIndex);
  1299         scene->setActivePageIndex(pageIndex);
  1489         mUiWidget->setActivePage(pageIndex);
  1300         mUiWidget->setActivePage(pageIndex);
  1490     }
  1301     }
       
  1302 
  1491     deleteZoneAnimation();
  1303     deleteZoneAnimation();
  1492 }
  1304 }
  1493 
  1305 
  1494 /*!
  1306 /*!
  1495     Page change animation has been finished.
  1307     Page change animation has been finished.
  1498 {
  1310 {
  1499     updateZoneAnimation();
  1311     updateZoneAnimation();
  1500 }
  1312 }
  1501 
  1313 
  1502 /*!
  1314 /*!
  1503     Handles the close of the scene menu when menu is dismissed.
       
  1504     While dismissed menu should be triggered with NULL action.
       
  1505     Actions on menu are connected stright to desired slot or signal.
       
  1506 */
       
  1507 void HsIdleState::onSceneMenuTriggered(HbAction *action)
       
  1508 {
       
  1509     //We check if menu was dismissed either by user tap in outside of the menu,
       
  1510     //menu's dismiss timer timeouts or state_sceneMenu was exited by any other reason
       
  1511     //than triggered action, e.g. applib activated while context menu is active.
       
  1512     if(!action) {
       
  1513         emit event_waitInput();
       
  1514     }
       
  1515 }
       
  1516 
       
  1517 /*!
       
  1518     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.
  1519 */
  1316 */
  1520 void HsIdleState::onRemovePageConfirmationOk()
  1317 void HsIdleState::onRemovePageConfirmationOk()
  1521 {
  1318 {
  1522     removeActivePage();
  1319     removeActivePage();
  1523 }
  1320 }
  1524 
  1321 
  1525 /*!
  1322 /*!
  1526     Handles the close of the scene menu.
  1323     Provides the page presentation to the Widget Snap algorithm
  1527 
  1324 */
  1528     This workaround is needed since HbMenu does not trigger empty action in case of
  1325 void HsIdleState::updatePagePresentationToWidgetSnap()
  1529     dismission of menu dialog. That functionality will be added in near future. Thereafter
  1326 {
  1530     onSceneMenuTriggered() can handle dismissions (HbMenu::triggered() emitted with NULL
  1327     QRectF containerRect = HsScene::instance()->activePage()->rect();
  1531     action). This workaround can be removed at that time.
  1328     containerRect.setTop(qreal(64));
  1532 */
  1329     HsWidgetHost *activeWidget = HsScene::instance()->activeWidget();
  1533 void HsIdleState::onSceneMenuAboutToClose() {
  1330     HsWidgetPositioningOnWidgetMove::instance()->setPagePresentation(containerRect, createInactiveWidgetRects(), activeWidget->geometry());
  1534     //We need to check if menu is dismissed either by user tap in outside of the menu or
  1331 }
  1535     //menu's dismiss timer timeouts. There is active action if any action tapped otherwise
  1332 
  1536     //menu was dissmised.
  1333 /*!
  1537     HbMenu *menu = static_cast<HbMenu*>(sender());
  1334     Reset Snap position, hide the snap lines
  1538     if(!menu->activeAction()) {
  1335 */
  1539         //mSceneMenu = 0;  //Menu deletes itself at the close
  1336 void HsIdleState::resetSnapPosition()
  1540         emit event_waitInput();
  1337 {
  1541     }
  1338     mSnapResult = HsWidgetPositioningOnWidgetMove::Result();
  1542 }
  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 }