homescreenapp/stateplugins/hshomescreenstateplugin/src/hsidlestate.cpp
changeset 63 52b0f64eeb51
parent 62 341166945d65
child 69 87476091b3f5
equal deleted inserted replaced
62:341166945d65 63:52b0f64eeb51
    51 #include "hshomescreenstatecommon.h"
    51 #include "hshomescreenstatecommon.h"
    52 #include "hstitleresolver.h"
    52 #include "hstitleresolver.h"
    53 #include "hsmenuservice.h"
    53 #include "hsmenuservice.h"
    54 #include "hsgui.h"
    54 #include "hsgui.h"
    55 #include "hsconfiguration.h"
    55 #include "hsconfiguration.h"
       
    56 #include "hsmessageboxwrapper.h"
       
    57 #include "hspropertyanimationwrapper.h"
    56 
    58 
    57 // Helper macros for connecting state entry and exit actions.
    59 // Helper macros for connecting state entry and exit actions.
    58 #define ENTRY_ACTION(state, action) \
    60 #define ENTRY_ACTION(state, action) \
    59     connect(state, SIGNAL(entered()), SLOT(action()));
    61     connect(state, SIGNAL(entered()), SLOT(action()));
    60 #define EXIT_ACTION(state, action) \
    62 #define EXIT_ACTION(state, action) \
    90 
    92 
    91     //Text in confirmation dialog while removing page with content
    93     //Text in confirmation dialog while removing page with content
    92     const char hsLocTextId_Confirmation_RemovePage[] = "txt_homescreen_info_page_and_content_will_be_remov";
    94     const char hsLocTextId_Confirmation_RemovePage[] = "txt_homescreen_info_page_and_content_will_be_remov";
    93 
    95 
    94     //Button in confirmation dialog while removing page with content
    96     //Button in confirmation dialog while removing page with content
    95     const char hsLocTextId_ConfirmationButton_Ok[] = "txt_homescreen_button_ok";
    97     //const char hsLocTextId_ConfirmationButton_Ok[] = "txt_homescreen_button_ok";
    96 
    98 
    97     //Button in confirmation dialog while removing page with content
    99     //Button in confirmation dialog while removing page with content
    98     const char hsLocTextId_ConfirmationButton_Cancel[] = "txt_homescreen_button_cancel";
   100     //const char hsLocTextId_ConfirmationButton_Cancel[] = "txt_homescreen_button_cancel";
    99 }
   101 }
   100 
   102 
   101 /*!
   103 /*!
   102     \class HsIdleState
   104     \class HsIdleState
   103     \ingroup group_hshomescreenstateplugin
   105     \ingroup group_hshomescreenstateplugin
   112 /*!
   114 /*!
   113     Constructs a new idle state with the given \a parent.
   115     Constructs a new idle state with the given \a parent.
   114 */
   116 */
   115 HsIdleState::HsIdleState(QState *parent)
   117 HsIdleState::HsIdleState(QState *parent)
   116   : QState(parent),
   118   : QState(parent),
   117     mNavigationAction(0), mUiWidget(0),
   119     mNavigationAction(0), 
       
   120     mUiWidget(0),
   118     mTitleResolver(0),
   121     mTitleResolver(0),
   119     mZoneAnimation(0),
   122     mZoneAnimation(0),
   120     mAllowZoneAnimation(false),
   123     mAllowZoneAnimation(false),
   121     mPageChangeAnimation(0),
   124     mPageChangeAnimation(0),
   122     mContinuousFeedback(0),
   125     mContinuousFeedback(0),
   123     mTrashBinFeedbackAlreadyPlayed(false),
   126     mTrashBinFeedbackAlreadyPlayed(false),
   124     mDeltaX(0),
   127     mDeltaX(0),
   125     mSceneMenu(0),
   128     mSceneMenu(0)
   126     mSnapBorderGap(0.0)
       
   127 #ifdef Q_OS_SYMBIAN
   129 #ifdef Q_OS_SYMBIAN
   128     ,mSettingsMgr(0)
   130     ,mSettingsMgr(0)
   129 #endif
   131 #endif
       
   132     ,mMessageBoxWrapper(0)
       
   133     
   130 {
   134 {
   131     setupStates();
   135     setupStates();
   132     mTitleResolver = new HsTitleResolver(this);
   136     mTitleResolver = new HsTitleResolver(this);
   133 
   137      
   134     // TODO: Uncomment when updated API available
   138     // TODO: Uncomment when updated API available
   135     //mContinuousFeedback = new HbContinuousFeedback;
   139     //mContinuousFeedback = new HbContinuousFeedback;
   136     //mContinuousFeedback->setContinuousEffect(HbFeedback::ContinuousSmooth);
   140     //mContinuousFeedback->setContinuousEffect(HbFeedback::ContinuousSmooth);
   137     //mContinuousFeedback->setIntensity(HbFeedback::IntensityFull );
   141     //mContinuousFeedback->setIntensity(HbFeedback::IntensityFull );
   138 
   142 
   143 /*!
   147 /*!
   144     Destroys this idle state.
   148     Destroys this idle state.
   145 */
   149 */
   146 HsIdleState::~HsIdleState()
   150 HsIdleState::~HsIdleState()
   147 {
   151 {
   148     delete mZoneAnimation;
   152     if (mZoneAnimation) {
       
   153         mZoneAnimation->stop();
       
   154         delete mZoneAnimation;
       
   155     }
       
   156     if (mPageChangeAnimation) {
       
   157         mPageChangeAnimation->stop();
       
   158         delete mPageChangeAnimation;
       
   159     }
       
   160     
   149     // TODO: Uncomment when updated API available
   161     // TODO: Uncomment when updated API available
   150     //delete mContinuousFeedback;
   162     //delete mContinuousFeedback;
   151 }
   163 }
   152 
   164 
   153 /*!
   165 /*!
   229     QState *state_moveWidget = new QState(this);
   241     QState *state_moveWidget = new QState(this);
   230     QState *state_moveScene = new QState(this);
   242     QState *state_moveScene = new QState(this);
   231     HsWallpaperSelectionState *state_wallpaperSelectionState =
   243     HsWallpaperSelectionState *state_wallpaperSelectionState =
   232         new HsWallpaperSelectionState(this);
   244         new HsWallpaperSelectionState(this);
   233     QState *state_addPage = new QState(this);
   245     QState *state_addPage = new QState(this);
       
   246     QState *state_preRemovePage = new QState(this);
   234     QState *state_removePage = new QState(this);
   247     QState *state_removePage = new QState(this);
   235     QState *state_toggleConnection = new QState(this);
   248     QState *state_toggleConnection = new QState(this);
   236 
   249 
   237     // Transitions
   250     // Transitions
   238 
   251 
   239     state_waitInput->addTransition(
   252     state_waitInput->addTransition(
   240         this, SIGNAL(event_addPage()), state_addPage);
   253         this, SIGNAL(event_addPage()), state_addPage);
   241     state_waitInput->addTransition(
   254     state_waitInput->addTransition(
   242         this, SIGNAL(event_removePage()), state_removePage);
   255         this, SIGNAL(event_preRemovePage()), state_preRemovePage);
   243     state_waitInput->addTransition(
   256     state_waitInput->addTransition(
   244         this, SIGNAL(event_toggleConnection()), state_toggleConnection);
   257         this, SIGNAL(event_toggleConnection()), state_toggleConnection);
   245     state_waitInput->addTransition(
   258     state_waitInput->addTransition(
   246         this, SIGNAL(event_selectWallpaper()), state_wallpaperSelectionState);
   259         this, SIGNAL(event_selectWallpaper()), state_wallpaperSelectionState);
   247     state_waitInput->addTransition(
   260     state_waitInput->addTransition(
   257 
   270 
   258     state_wallpaperSelectionState->addTransition(
   271     state_wallpaperSelectionState->addTransition(
   259         state_wallpaperSelectionState, SIGNAL(event_waitInput()), state_waitInput);
   272         state_wallpaperSelectionState, SIGNAL(event_waitInput()), state_waitInput);
   260 
   273 
   261     state_addPage->addTransition(state_waitInput);
   274     state_addPage->addTransition(state_waitInput);
   262 
   275     
   263     state_removePage->addTransition(state_waitInput);
   276     state_preRemovePage->addTransition(
       
   277         this,SIGNAL(event_removePage()),state_removePage);
       
   278     
       
   279     state_preRemovePage->addTransition(
       
   280         this,SIGNAL(event_waitInput()),state_waitInput);
       
   281 
       
   282     state_removePage->addTransition(
       
   283         this,SIGNAL(event_waitInput()),state_waitInput);
   264 
   284 
   265     state_toggleConnection->addTransition(state_waitInput);
   285     state_toggleConnection->addTransition(state_waitInput);
   266 
   286 
   267     // Actions
   287     // Actions
   268 
   288 
   297     ENTRY_ACTION(state_moveScene, action_moveScene_connectGestureHandlers)
   317     ENTRY_ACTION(state_moveScene, action_moveScene_connectGestureHandlers)
   298     EXIT_ACTION(state_moveScene, action_moveScene_moveToNearestPage)
   318     EXIT_ACTION(state_moveScene, action_moveScene_moveToNearestPage)
   299     EXIT_ACTION(state_moveScene, action_moveScene_disconnectGestureHandlers)
   319     EXIT_ACTION(state_moveScene, action_moveScene_disconnectGestureHandlers)
   300     
   320     
   301     ENTRY_ACTION(state_addPage, action_addPage_addPage)
   321     ENTRY_ACTION(state_addPage, action_addPage_addPage)
   302 
   322     
   303     ENTRY_ACTION(state_removePage, action_removePage_removePage)
   323     ENTRY_ACTION(state_preRemovePage, action_preRemovePage_showQuery)
       
   324 
       
   325     ENTRY_ACTION(state_removePage, action_removePage_startRemovePageAnimation)
       
   326     EXIT_ACTION(state_removePage, action_removePage_removePage)
   304 
   327 
   305     ENTRY_ACTION(state_toggleConnection, action_toggleConnection_toggleConnection)
   328     ENTRY_ACTION(state_toggleConnection, action_toggleConnection_toggleConnection)
   306 }
   329 }
   307 
   330 
   308 /*!
   331 /*!
   317     Starts the page change animation based on the given \a targetPageIndex
   340     Starts the page change animation based on the given \a targetPageIndex
   318     and \a duration.
   341     and \a duration.
   319 */
   342 */
   320 void HsIdleState::startPageChangeAnimation(int targetPageIndex, int duration)
   343 void HsIdleState::startPageChangeAnimation(int targetPageIndex, int duration)
   321 {
   344 {
   322     if (!mPageChangeAnimation) {
   345     if (mPageChangeAnimation->isRunning()) {
   323         mPageChangeAnimation = new QPropertyAnimation(mUiWidget, "sceneX");        
       
   324     }
       
   325     else if (mPageChangeAnimation->state() != QAbstractAnimation::Stopped) {
       
   326         mPageChangeAnimation->stop();
   346         mPageChangeAnimation->stop();
   327     }        
   347     }        
   328     
   348     mPageChangeAnimation->disconnect(this);
   329     mPageChangeAnimation->setEndValue(pageLayerXPos(targetPageIndex));
   349     mPageChangeAnimation->setEndValue(pageLayerXPos(targetPageIndex));
   330     mPageChangeAnimation->setDuration(duration);
   350     mPageChangeAnimation->setDuration(duration);
   331     connect(mPageChangeAnimation,
   351     connect(mPageChangeAnimation,
   332             SIGNAL(finished()),
   352             SIGNAL(finished()),
   333             SLOT(pageChangeAnimationFinished()), 
   353             SLOT(pageChangeAnimationFinished()), 
   356         ++targetPageIndex;
   376         ++targetPageIndex;
   357     } else {
   377     } else {
   358         return;
   378         return;
   359     }
   379     }
   360 
   380 
   361     if (!mZoneAnimation) {
       
   362         mZoneAnimation = new QPropertyAnimation(mUiWidget, "sceneX");
       
   363     }
       
   364 
       
   365     int bounceEffect = HSCONFIGURATION_GET(bounceEffect);
   381     int bounceEffect = HSCONFIGURATION_GET(bounceEffect);
   366 
   382 
   367     if (isInLeftPageChangeZone()) {
   383     if (isInLeftPageChangeZone()) {
   368         mZoneAnimation->setEndValue(pageLayerXPos(scene->activePageIndex()) + bounceEffect);
   384         mZoneAnimation->setEndValue(pageLayerXPos(scene->activePageIndex()) + bounceEffect);
   369     } else {
   385     } else {
   372     mZoneAnimation->setDuration(duration);
   388     mZoneAnimation->setDuration(duration);
   373     mZoneAnimation->setDirection(QAbstractAnimation::Forward);
   389     mZoneAnimation->setDirection(QAbstractAnimation::Forward);
   374 
   390 
   375     connect(mZoneAnimation,
   391     connect(mZoneAnimation,
   376             SIGNAL(finished()),
   392             SIGNAL(finished()),
   377             SLOT(zoneAnimationFinished()));
   393             SLOT(zoneAnimationFinished()),
       
   394             Qt::UniqueConnection);
   378     
   395     
   379     mZoneAnimation->start();
   396     mZoneAnimation->start();
   380 }
   397 }
   381 
   398 
   382 /*!
   399 /*!
   424 /*!
   441 /*!
   425     Checks if page change zone animation needs to be started or stopped
   442     Checks if page change zone animation needs to be started or stopped
   426 */
   443 */
   427 void HsIdleState::updateZoneAnimation()
   444 void HsIdleState::updateZoneAnimation()
   428 {
   445 {
   429     if (isInPageChangeZone() && mAllowZoneAnimation) {
   446     if (!mAllowZoneAnimation) {
   430         if (!mZoneAnimation && (!mPageChangeAnimation
   447         mZoneAnimation->stop();
   431             || mPageChangeAnimation->state() == QAbstractAnimation::Stopped )) {
   448     } else if (isInPageChangeZone()) {
       
   449         // should we start it
       
   450         if (mZoneAnimation->state() == QAbstractAnimation::Stopped &&
       
   451             !mPageChangeAnimation->isRunning()) {
   432             startPageChangeZoneAnimation(HSCONFIGURATION_GET(pageChangeZoneAnimationDuration));
   452             startPageChangeZoneAnimation(HSCONFIGURATION_GET(pageChangeZoneAnimationDuration));
   433         }
   453         } 
   434     } else if (mZoneAnimation && !isInPageChangeZone()) {
   454     } else if (mZoneAnimation->state() == QAbstractAnimation::Running) {
   435         if (mZoneAnimation->state() == QAbstractAnimation::Running) {
   455         // Not in zone, but still running     
   436             if (mZoneAnimation->direction() == QAbstractAnimation::Forward) {
   456         if (mZoneAnimation->direction() == QAbstractAnimation::Forward){
   437                 mZoneAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration));
   457             // reverse
   438                 mZoneAnimation->setDirection(QAbstractAnimation::Backward);
   458             mZoneAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration));
   439             }
   459             mZoneAnimation->setDirection(QAbstractAnimation::Backward);
   440         } else {
   460         } 
   441             // Out of the page change zone. Delete animation.
   461     } 
   442             deleteZoneAnimation();
       
   443         }
       
   444     } else if (!isInPageChangeZone()) {
       
   445         if (mZoneAnimation) {
       
   446             mZoneAnimation->stop();
       
   447         }
       
   448     }
       
   449 }
   462 }
   450 
   463 
   451 /*!
   464 /*!
   452     Selects which trash bin icon is shown or not shown at all
   465     Selects which trash bin icon is shown or not shown at all
   453 */
   466 */
   468         mUiWidget->showTrashBin();
   481         mUiWidget->showTrashBin();
   469     }
   482     }
   470 }
   483 }
   471 
   484 
   472 /*!
   485 /*!
   473     Removes currently active page.
       
   474 */
       
   475 void HsIdleState::removeActivePage()
       
   476 {
       
   477     HsScene *scene = HsScene::instance();
       
   478     HsPage *page = scene->activePage();
       
   479 
       
   480     int pageIndex = scene->activePageIndex();
       
   481 
       
   482     mUiWidget->removePage(pageIndex);
       
   483     scene->removePage(page);
       
   484     
       
   485     if (page->wallpaper()) {
       
   486         page->wallpaper()->remove();        
       
   487     }
       
   488     delete page;
       
   489 
       
   490     pageIndex = pageIndex == 0 ? 0 : pageIndex - 1;
       
   491     scene->setActivePageIndex(pageIndex);
       
   492 
       
   493     startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageRemovedAnimationDuration));
       
   494 
       
   495     mUiWidget->pageIndicator()->removeItem(pageIndex);
       
   496     mUiWidget->setActivePage(pageIndex);
       
   497     mUiWidget->showPageIndicator();
       
   498 }
       
   499 
       
   500 /*!
       
   501     Deletes page change zone animation.
       
   502 */
       
   503 void HsIdleState::deleteZoneAnimation()
       
   504 {
       
   505     delete mZoneAnimation;
       
   506     mZoneAnimation = NULL;
       
   507 }
       
   508 
       
   509 /*!
       
   510     If called for the first time, setups the idle view.
   486     If called for the first time, setups the idle view.
   511     Updates the soft key action and sets the idle view
   487     Updates the soft key action and sets the idle view
   512     as the current view to the main window.
   488     as the current view to the main window.
   513 */
   489 */
   514 void HsIdleState::action_idle_setupView()
   490 void HsIdleState::action_idle_setupView()
   524         mNavigationAction->setObjectName("applib_navigation_action");
   500         mNavigationAction->setObjectName("applib_navigation_action");
   525         connect(mNavigationAction, SIGNAL(triggered()), SIGNAL(event_applicationLibrary()));
   501         connect(mNavigationAction, SIGNAL(triggered()), SIGNAL(event_applicationLibrary()));
   526         idleView->setNavigationAction(mNavigationAction);
   502         idleView->setNavigationAction(mNavigationAction);
   527 
   503 
   528         HsGui::setIdleView(idleView);
   504         HsGui::setIdleView(idleView);
   529 
   505         
   530         if (mPageChangeAnimation) {
   506         delete mPageChangeAnimation;
   531             delete mPageChangeAnimation;
   507         mPageChangeAnimation = NULL;
   532             mPageChangeAnimation = NULL;
   508         mPageChangeAnimation = new HsPropertyAnimationWrapper;
   533         }
   509         mPageChangeAnimation->setTargetObject(mUiWidget);
       
   510         mPageChangeAnimation->setPropertyName("sceneX"); 
       
   511         delete mZoneAnimation;
       
   512         mZoneAnimation = NULL;
       
   513         mZoneAnimation = new QPropertyAnimation(mUiWidget, "sceneX");
       
   514        
   534     }
   515     }
   535 
   516 
   536     HsScene::mainWindow()->setCurrentView(idleView);
   517     HsScene::mainWindow()->setCurrentView(idleView);
   537 }
   518 }
   538 
   519 
   585 void HsIdleState::action_idle_cleanupTitle()
   566 void HsIdleState::action_idle_cleanupTitle()
   586 {
   567 {
   587     mTitleResolver->disconnect(this);
   568     mTitleResolver->disconnect(this);
   588 }
   569 }
   589 
   570 
   590 #ifdef COVERAGE_MEASUREMENT
       
   591 #pragma CTC SKIP
       
   592 #endif //COVERAGE_MEASUREMENT
       
   593 /*!
   571 /*!
   594 
   572 
   595 */
   573 */
   596 void HsIdleState::onPageTapAndHoldFinished(QGestureEvent *event)
   574 void HsIdleState::onPageTapAndHoldFinished(QGestureEvent *event)
   597 {
   575 {
   615     action = mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper), this, SIGNAL(event_selectWallpaper()));
   593     action = mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper), this, SIGNAL(event_selectWallpaper()));
   616     action->setObjectName("action_change_wallpaper_ctx_menu");
   594     action->setObjectName("action_change_wallpaper_ctx_menu");
   617     mSceneMenu->setPreferredPos(mPageHotSpot);
   595     mSceneMenu->setPreferredPos(mPageHotSpot);
   618     mSceneMenu->open();
   596     mSceneMenu->open();
   619 }
   597 }
   620 #ifdef COVERAGE_MEASUREMENT
       
   621 #pragma CTC ENDSKIP
       
   622 #endif //COVERAGE_MEASUREMENT
       
   623 
   598 
   624 void HsIdleState::onPagePanStarted(QGestureEvent *event)
   599 void HsIdleState::onPagePanStarted(QGestureEvent *event)
   625 {
   600 {
   626     Q_UNUSED(event)
   601     Q_UNUSED(event)
   627     emit event_moveScene();
   602     emit event_moveScene();
   671     emit event_moveWidget();
   646     emit event_moveWidget();
   672 }
   647 }
   673  
   648  
   674 void HsIdleState::onWidgetMoveUpdated(const QPointF &scenePos, HsWidgetHost *widget)
   649 void HsIdleState::onWidgetMoveUpdated(const QPointF &scenePos, HsWidgetHost *widget)
   675 {
   650 {
   676     HsScene *scene = HsScene::instance();
       
   677     QRectF widgetRect = widget->geometry();
   651     QRectF widgetRect = widget->geometry();
   678 
   652 
   679     // Move widget to new position.
   653     // Move widget to updated position.
   680     mWidgetHotSpot = scenePos;
   654     mWidgetHotSpot = scenePos;
   681        
       
   682     widgetRect.moveTopLeft(mWidgetHotSpot - mWidgetHotSpotOffset);
   655     widgetRect.moveTopLeft(mWidgetHotSpot - mWidgetHotSpotOffset);
   683 
   656 
   684     // Widget can be moved over the pages left border.
   657     // When moving widget can go over the pages left border.
   685     qreal lowerBoundX = -widgetRect.width();
   658     qreal lowerBoundX = -widgetRect.width();
   686     HsPage *page = scene->activePage();
   659 
       
   660     // When moving widget can go over the pages right border.
   687     QRectF pageRect = HsGui::idleView()->rect();
   661     QRectF pageRect = HsGui::idleView()->rect();
   688     // Widget can be moved over the pages right border.
       
   689     qreal upperBoundX = pageRect.width();
   662     qreal upperBoundX = pageRect.width();
   690 
   663 
       
   664     // When moving widget can go under the chrome at the pages upper border.
   691     // Notice that chrome height is 64 pixels.
   665     // Notice that chrome height is 64 pixels.
   692     qreal lowerBoundY = qreal(64) - widgetRect.height();
   666     qreal lowerBoundY = qreal(64) - widgetRect.height();
   693     // Widget can be moved over the pages down border.
   667 
       
   668     // When moving widget can go over the pages down border.
   694     qreal upperBoundY = pageRect.height();
   669     qreal upperBoundY = pageRect.height();
   695 
   670 
   696     qreal widgetX = qBound(lowerBoundX, widgetRect.x(), upperBoundX);
   671     qreal widgetX = qBound(lowerBoundX, widgetRect.x(), upperBoundX);
   697     qreal widgetY = qBound(lowerBoundY, widgetRect.y(), upperBoundY);
   672     qreal widgetY = qBound(lowerBoundY, widgetRect.y(), upperBoundY);
       
   673 
   698     // If using ItemClipsChildrenToShape-flag in widgethost then
   674     // If using ItemClipsChildrenToShape-flag in widgethost then
   699     // setPos does not update position here, however setGeometry does it, QT bug?
   675     // setPos does not update position here, however setGeometry does it, QT bug?
   700     widget->setGeometry(widgetX, widgetY, widgetRect.width(), widgetRect.height());
   676     widget->setGeometry(widgetX, widgetY, widgetRect.width(), widgetRect.height());
   701     
   677     
   702     if (HSCONFIGURATION_GET(isSnapEnabled)) {
   678     if (HSCONFIGURATION_GET(isSnapEnabled)) {
   718         }
   694         }
   719 
   695 
   720         mPreviousSnapResult = mSnapResult;
   696         mPreviousSnapResult = mSnapResult;
   721     }
   697     }
   722 
   698 
   723 
       
   724     int bounceFeedbackEffectDistance = HSCONFIGURATION_GET(bounceFeedbackEffectDistance);
       
   725     // Handle effects:
   699     // Handle effects:
   726     // User is indicated by a tactile feedback if he/she is trying to move
   700     // User is indicated by a tactile feedback if he/she is trying to move
   727     // widget over the first or the last page.
   701     // widget over the first or the last page.
       
   702     HsScene *scene = HsScene::instance();
       
   703     HsPage *page = scene->activePage();
       
   704     int bounceFeedbackEffectDistance = HSCONFIGURATION_GET(bounceFeedbackEffectDistance);
   728     if( (page == scene->pages().first() && mWidgetHotSpot.x() < bounceFeedbackEffectDistance ) ||
   705     if( (page == scene->pages().first() && mWidgetHotSpot.x() < bounceFeedbackEffectDistance ) ||
   729         (page == scene->pages().last() && scene->pages().count() == HSCONFIGURATION_GET(maximumPageCount)
   706         (page == scene->pages().last() && scene->pages().count() == HSCONFIGURATION_GET(maximumPageCount)
   730          && mWidgetHotSpot.x() > pageRect.width() - bounceFeedbackEffectDistance)) {
   707          && mWidgetHotSpot.x() > pageRect.width() - bounceFeedbackEffectDistance)) {
   731              HbInstantFeedback::play(HSCONFIGURATION_GET(widgetMoveBlockedFeedbackEffect));
   708              HbInstantFeedback::play(HSCONFIGURATION_GET(widgetMoveBlockedFeedbackEffect));
   732             // TODO: use code below when Orbit has updated ContinuousFeedback API
   709             // TODO: use code below when Orbit has updated ContinuousFeedback API
   733             //if (!mContinuousFeedback->isPlaying()) {
   710             //if (!mContinuousFeedback->isPlaying()) {
   734             //    mContinuousFeedback->play();
   711             //    mContinuousFeedback->play();
   735             //}
   712             //}
   736         }
   713         } else /*if (mContinuousFeedback->isPlaying())*/ {
   737         else /*if (mContinuousFeedback->isPlaying())*/ {
       
   738             //mContinuousFeedback->stop();
   714             //mContinuousFeedback->stop();
   739         }
   715         }
   740 
   716 
   741     updateZoneAnimation();
   717     updateZoneAnimation();
   742     showTrashBin();
   718     showTrashBin();
   874     HsScene *scene = HsScene::instance();
   850     HsScene *scene = HsScene::instance();
   875 
   851 
   876     HbMenu *menu = new HbMenu();
   852     HbMenu *menu = new HbMenu();
   877     menu->setObjectName("hs_menu");
   853     menu->setObjectName("hs_menu");
   878     // Task switcher
   854     // Task switcher
   879     HbAction *action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_TaskSwitcher),
   855     menu->addAction(hbTrId(hsLocTextId_OptionsMenu_TaskSwitcher),
   880         this, SLOT(openTaskSwitcher()));
   856         this, SLOT(openTaskSwitcher()));
   881     action->setObjectName("action_open_task_switcher");
   857     
   882     // Add content
   858     // Add content
   883     action = menu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent),
   859     menu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent),
   884         this, SLOT(onAddContentFromOptionsMenuActionTriggered()));
   860         this, SLOT(onAddContentFromOptionsMenuActionTriggered()));
   885     action->setObjectName("action_add_content");
       
   886     // Add page
   861     // Add page
   887     if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) {
   862     if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) {
   888         action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage),
   863         menu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage),
   889             this, SIGNAL(event_addPage()));
   864             this, SIGNAL(event_addPage()));
   890         action->setObjectName("action_add_page");
   865     
   891 
       
   892     }
   866     }
   893 
   867 
   894     // Change wallpaper
   868     // Change wallpaper
   895     action = menu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper),
   869     menu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper),
   896         this, SIGNAL(event_selectWallpaper()));
   870         this, SIGNAL(event_selectWallpaper()));
   897     action->setObjectName("action_change_wallpaper");
   871     
   898     // Remove page
   872     // Remove page
   899     if (scene->activePage()->isRemovable()) {
   873     if (scene->activePage()->isRemovable()) {
   900         action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_RemovePage),
   874         menu->addAction(hbTrId(hsLocTextId_OptionsMenu_RemovePage),
   901             this, SIGNAL(event_removePage()));
   875             this, SIGNAL(event_preRemovePage()));
   902         action->setObjectName("action_remove_page"); 
       
   903     }
   876     }
   904 
   877 
   905     // Online / Offline
   878     // Online / Offline
   906     if (scene->isOnline()) {
   879     if (scene->isOnline()) {
   907         action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOffline),
   880         menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOffline),
   908             this, SIGNAL(event_toggleConnection()));
   881             this, SIGNAL(event_toggleConnection()));
   909         action->setObjectName("action_to_offline");
       
   910     } else {
   882     } else {
   911         action = menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOnline),
   883         menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOnline),
   912             this, SIGNAL(event_toggleConnection()));
   884             this, SIGNAL(event_toggleConnection()));
   913         action->setObjectName("action_to_online");
       
   914     }
   885     }
   915 
   886 
   916     HsGui::idleView()->setMenu(menu);
   887     HsGui::idleView()->setMenu(menu);
   917 }
   888 }
   918 
   889 
   999     Connects the timer for showing the snap lines
   970     Connects the timer for showing the snap lines
  1000 */
   971 */
  1001 void HsIdleState::action_moveWidget_setWidgetSnap()
   972 void HsIdleState::action_moveWidget_setWidgetSnap()
  1002 {
   973 {
  1003     if (HSCONFIGURATION_GET(isSnapEnabled)) {
   974     if (HSCONFIGURATION_GET(isSnapEnabled)) {
  1004         mSnapBorderGap = HSCONFIGURATION_GET(snapBorderGap);
       
  1005 
   975 
  1006         QVariantHash snapConfiguration;
   976         QVariantHash snapConfiguration;
  1007         snapConfiguration[SNAPENABLED] = QString::number(HSCONFIGURATION_GET(isSnapEnabled));
   977         snapConfiguration[SNAPENABLED] = QString::number(HSCONFIGURATION_GET(isSnapEnabled));
  1008         snapConfiguration[SNAPFORCE] = QString::number(HSCONFIGURATION_GET(snapForce));
   978         snapConfiguration[SNAPFORCE] = QString::number(HSCONFIGURATION_GET(snapForce));
  1009         snapConfiguration[SNAPGAP] = QString::number(HSCONFIGURATION_GET(snapGap));
   979         snapConfiguration[SNAPGAP] = QString::number(HSCONFIGURATION_GET(snapGap));
  1010         snapConfiguration[SNAPBORDERGAP] = mSnapBorderGap;
       
  1011         HsWidgetPositioningOnWidgetMove::instance()->setConfiguration(snapConfiguration);
   980         HsWidgetPositioningOnWidgetMove::instance()->setConfiguration(snapConfiguration);
  1012 
       
  1013 
   981 
  1014         updatePagePresentationToWidgetSnap();
   982         updatePagePresentationToWidgetSnap();
  1015 
   983 
  1016         connect(HsScene::instance(), SIGNAL(activePageChanged()),
   984         connect(HsScene::instance(), SIGNAL(activePageChanged()),
  1017             SLOT(onActivePageChanged()));
   985             SLOT(onActivePageChanged()));
  1081             } else {
  1049             } else {
  1082                 widget->removePresentation(Qt::Horizontal);
  1050                 widget->removePresentation(Qt::Horizontal);
  1083             }
  1051             }
  1084         }
  1052         }
  1085 
  1053 
       
  1054         //Set the snap position of the widget and save the position
  1086         QRectF widgetRect = widget->geometry();
  1055         QRectF widgetRect = widget->geometry();
  1087         QRectF pageRect = page->rect();
       
  1088 
       
  1089         //Set the snap position of the widget and save the position
       
  1090         if (mSnapResult.hasHorizontalSnap) {
  1056         if (mSnapResult.hasHorizontalSnap) {
  1091             widgetRect.moveLeft(mSnapResult.horizontalSnapPosition);
  1057             widgetRect.moveLeft(mSnapResult.horizontalSnapPosition);
  1092         }
  1058         }
  1093         if (mSnapResult.hasVerticalSnap) {
  1059         if (mSnapResult.hasVerticalSnap) {
  1094             widgetRect.moveTop(mSnapResult.verticalSnapPosition);
  1060             widgetRect.moveTop(mSnapResult.verticalSnapPosition);
  1095         }
  1061         }
  1096 
  1062 
  1097         //if snapBorderGap is defined, the widget is bounded in the rectangle which is smaller by snapBorderGap on all sides
  1063         QPointF adjustedWidgetPosition = page->adjustedWidgetPosition(widgetRect);
  1098         qreal widgetX = qBound(qreal(0) + mSnapBorderGap, widgetRect.x(), (pageRect.width() - mSnapBorderGap) - widgetRect.width());
  1064         widget->setPos(adjustedWidgetPosition);
  1099         qreal widgetY = qBound(qreal(64) + mSnapBorderGap, widgetRect.y(), (pageRect.height() - mSnapBorderGap) - widgetRect.height());
       
  1100 
       
  1101         // play feedback effect if user drops widget between pages and it needs to be repositioned back to original page
       
  1102         if( widgetX != widgetRect.x() || widgetY != widgetRect.y()) {
       
  1103             HbInstantFeedback::play(HSCONFIGURATION_GET(widgetRepositionFeedbackEffect));
       
  1104         }
       
  1105         widget->setPos(widgetX, widgetY);
       
  1106 
  1065 
  1107         widget->savePresentation();
  1066         widget->savePresentation();
  1108         page->updateZValues();
  1067         page->updateZValues();
  1109     }
  1068     }
  1110 
  1069 
  1214     startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(newPageAddedAnimationDuration));
  1173     startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(newPageAddedAnimationDuration));
  1215     mUiWidget->pageIndicator()->addItem(pageIndex);
  1174     mUiWidget->pageIndicator()->addItem(pageIndex);
  1216     mUiWidget->showPageIndicator();
  1175     mUiWidget->showPageIndicator();
  1217 }
  1176 }
  1218 
  1177 
  1219 /*!
  1178 void HsIdleState::action_preRemovePage_showQuery()
  1220     Removes an existing page from the scene.
       
  1221 */
       
  1222 void HsIdleState::action_removePage_removePage()
       
  1223 {
  1179 {
  1224     HsScene *scene = HsScene::instance();
  1180     HsScene *scene = HsScene::instance();
  1225     HsPage *page = scene->activePage();
  1181     HsPage *page = scene->activePage();
  1226 
  1182 
  1227     if (!page->widgets().isEmpty()) {
  1183     if (!page->widgets().isEmpty()) {
  1228 #ifndef HOMESCREEN_TEST //We don't want to test message box.
  1184         if (!mMessageBoxWrapper) {
  1229         //Confirm removal of page having content
  1185             mMessageBoxWrapper = new HsMessageBoxWrapper(this);
  1230         HbMessageBox *box = new HbMessageBox(HbMessageBox::MessageTypeQuestion);
  1186             mMessageBoxWrapper->setHeader(hbTrId(hsLocTextId_Title_RemovePage));
  1231         box->setAttribute(Qt::WA_DeleteOnClose);
  1187             mMessageBoxWrapper->setQueryText(hbTrId(hsLocTextId_Confirmation_RemovePage));
  1232         box->setHeadingWidget(new HbLabel
  1188             connect(mMessageBoxWrapper,SIGNAL(accepted()),SIGNAL(event_removePage())); 
  1233                                 (hbTrId(hsLocTextId_Title_RemovePage)));
  1189             connect(mMessageBoxWrapper,SIGNAL(rejected()),SIGNAL(event_waitInput())); 
  1234         box->setText(hbTrId(hsLocTextId_Confirmation_RemovePage));
  1190         }
  1235 
  1191         mMessageBoxWrapper->show();
  1236         QAction *buttonOk = box->actions().at(0);
       
  1237         //We are keen only from OK button. Cancel is not connected to any slot.
       
  1238         connect(buttonOk, SIGNAL(triggered()), SLOT(onRemovePageConfirmationOk()));
       
  1239        
       
  1240         box->open();
       
  1241 #endif // HOMESCREEN_TEST
       
  1242     } else {
  1192     } else {
  1243         // Empty page can be removed without confirmation
  1193         // Empty page can be removed without confirmation
  1244         removeActivePage();
  1194         emit event_removePage();
  1245     }
  1195     }
  1246 }
  1196 }
  1247 
  1197 
       
  1198 /*!
       
  1199     Start remove page animation.
       
  1200 */
       
  1201 void HsIdleState::action_removePage_startRemovePageAnimation()
       
  1202 {
       
  1203     HsScene *scene = HsScene::instance();
       
  1204    
       
  1205     int pageToRemoveIndex = scene->activePageIndex();
       
  1206     bool isLastPage(scene->activePage() == scene->pages().last());
       
  1207     
       
  1208     int nextPageIndex(pageToRemoveIndex);
       
  1209     nextPageIndex++;
       
  1210     if (isLastPage) {
       
  1211         nextPageIndex--; 
       
  1212     }
       
  1213     
       
  1214     if (mPageChangeAnimation->isRunning()) {
       
  1215         mPageChangeAnimation->stop();
       
  1216     }
       
  1217     mPageChangeAnimation->disconnect(this);
       
  1218     connect(mPageChangeAnimation,
       
  1219             SIGNAL(finished()),
       
  1220             SIGNAL(event_waitInput()), 
       
  1221             Qt::UniqueConnection);
       
  1222     mPageChangeAnimation->setEndValue(pageLayerXPos(nextPageIndex));
       
  1223     mPageChangeAnimation->setDuration(HSCONFIGURATION_GET(pageRemovedAnimationDuration));
       
  1224    
       
  1225     mPageChangeAnimation->start();
       
  1226     
       
  1227     HbInstantFeedback::play(HSCONFIGURATION_GET(pageChangeFeedbackEffect));
       
  1228     
       
  1229 }
       
  1230 
       
  1231 /*!
       
  1232     Removes an existing page from the scene.
       
  1233 */
       
  1234 void HsIdleState::action_removePage_removePage()
       
  1235 {
       
  1236     if (mPageChangeAnimation->isRunning()) {
       
  1237         mPageChangeAnimation->stop();
       
  1238     }
       
  1239     HsScene *scene = HsScene::instance();
       
  1240     HsPage *pageToRemove = scene->activePage();
       
  1241     
       
  1242     // remove from ui
       
  1243     mUiWidget->removePage(pageToRemove->pageIndex());
       
  1244     mUiWidget->showPageIndicator();
       
  1245     // update data model
       
  1246     HsScene::instance()->removePage(pageToRemove);
       
  1247     // Take new active page (previous was removed) and move scene to right position
       
  1248     qreal x = pageLayerXPos(scene->activePageIndex());
       
  1249     mUiWidget->setSceneX(x);
       
  1250     // delete it   
       
  1251     pageToRemove->deleteLater();
       
  1252    
       
  1253 }
  1248 /*!
  1254 /*!
  1249     Toggles the homescreen online/offline state.
  1255     Toggles the homescreen online/offline state.
  1250 */
  1256 */
  1251 void HsIdleState::action_toggleConnection_toggleConnection()
  1257 void HsIdleState::action_toggleConnection_toggleConnection()
  1252 {
  1258 {
  1297         startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration));
  1303         startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration));
  1298     } else {
  1304     } else {
  1299         scene->setActivePageIndex(pageIndex);
  1305         scene->setActivePageIndex(pageIndex);
  1300         mUiWidget->setActivePage(pageIndex);
  1306         mUiWidget->setActivePage(pageIndex);
  1301     }
  1307     }
  1302 
       
  1303     deleteZoneAnimation();
       
  1304 }
  1308 }
  1305 
  1309 
  1306 /*!
  1310 /*!
  1307     Page change animation has been finished.
  1311     Page change animation has been finished.
  1308  */
  1312  */
  1309 void HsIdleState::pageChangeAnimationFinished()
  1313 void HsIdleState::pageChangeAnimationFinished()
  1310 {
  1314 {
  1311     updateZoneAnimation();
  1315     updateZoneAnimation();
  1312 }
  1316 }
  1313 
  1317 
  1314 /*!
       
  1315     Handles the close of remove page confirmation dialog for page having content.
       
  1316 */
       
  1317 void HsIdleState::onRemovePageConfirmationOk()
       
  1318 {
       
  1319     removeActivePage();
       
  1320 }
       
  1321 
  1318 
  1322 /*!
  1319 /*!
  1323     Provides the page presentation to the Widget Snap algorithm
  1320     Provides the page presentation to the Widget Snap algorithm
  1324 */
  1321 */
  1325 void HsIdleState::updatePagePresentationToWidgetSnap()
  1322 void HsIdleState::updatePagePresentationToWidgetSnap()
  1326 {
  1323 {
  1327     QRectF containerRect = HsScene::instance()->activePage()->rect();
  1324     QRectF containerRect = HsScene::instance()->activePage()->contentGeometry();
  1328     containerRect.setTop(qreal(64));
       
  1329     HsWidgetHost *activeWidget = HsScene::instance()->activeWidget();
  1325     HsWidgetHost *activeWidget = HsScene::instance()->activeWidget();
  1330     HsWidgetPositioningOnWidgetMove::instance()->setPagePresentation(containerRect, createInactiveWidgetRects(), activeWidget->geometry());
  1326     HsWidgetPositioningOnWidgetMove::instance()->setPagePresentation(containerRect, createInactiveWidgetRects(), activeWidget->geometry());
  1331 }
  1327 }
  1332 
  1328 
  1333 /*!
  1329 /*!
  1417 void HsIdleState::onActivePageChanged()
  1413 void HsIdleState::onActivePageChanged()
  1418 {
  1414 {
  1419     updatePagePresentationToWidgetSnap();
  1415     updatePagePresentationToWidgetSnap();
  1420     resetSnapPosition();
  1416     resetSnapPosition();
  1421 }
  1417 }
       
  1418 
       
  1419