homescreenapp/stateplugins/hshomescreenstateplugin/src/hsidlewidget.cpp
changeset 69 87476091b3f5
parent 67 474929a40a0f
child 71 1db7cc813a4e
equal deleted inserted replaced
67:474929a40a0f 69:87476091b3f5
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <QApplication>
       
    19 #include <QGraphicsSceneMouseEvent>
       
    20 #include <QGraphicsLinearLayout>
       
    21 #include <QDir>
       
    22 
       
    23 #include <HbMainWindow>
       
    24 #include <HbVkbHost>
       
    25 
       
    26 #include "hsidlewidget.h"
       
    27 #include "hsscene.h"
       
    28 #include "hspage.h"
       
    29 #include "hswidgethost.h"
       
    30 #include "hswallpaper.h"
       
    31 #include "hstrashbinwidget.h"
       
    32 #include "hspageindicator.h"
       
    33 #include "hsdocumentloader.h"
       
    34 #include "hsconfiguration.h"
       
    35 #include "hsapp_defs.h"
       
    36 #include "hssnapline.h"
       
    37 
       
    38 namespace
       
    39 {
       
    40     const char gControlLayerDocmlName[] = "controllayer.docml";
       
    41     const char gControlLayerName[]      = "controlLayer";
       
    42     const char gTrashBinName[]          = "trashBin";
       
    43     const char gPageIndicatorName[]     = "pageIndicator";
       
    44 }
       
    45 
       
    46 /*!
       
    47     \class HsIdleWidget
       
    48     \ingroup group_hshomescreenstateplugin
       
    49     \brief View part of the home screen idle state.
       
    50 
       
    51     Maintains the idle view ui layers and takes care of
       
    52     receiving user input and communicating it to the idle
       
    53     state for further processing.
       
    54 */
       
    55 
       
    56 /*!
       
    57     Constructs a new idle widget with the given \a parent.
       
    58 */
       
    59 HsIdleWidget::HsIdleWidget(QGraphicsItem *parent)
       
    60   : HbWidget(parent),
       
    61     mControlLayer(0), mPageLayer(0), mPageWallpaperLayer(0),
       
    62     mSceneLayer(0),
       
    63     mTrashBin(0), mPageIndicator(0),
       
    64     mHorizontalSnapLine(0), mVerticalSnapLine(0)
       
    65 {
       
    66     setFlag(ItemHasNoContents);
       
    67 
       
    68     loadControlLayer();
       
    69 
       
    70     QGraphicsLinearLayout *linearLayout = 0;
       
    71 
       
    72     linearLayout = new QGraphicsLinearLayout(Qt::Horizontal);
       
    73     linearLayout->setContentsMargins(0, 0, 0, 0);
       
    74     linearLayout->setSpacing(0);
       
    75     mPageLayer = new HbWidget(this);
       
    76     mPageLayer->setLayout(linearLayout);
       
    77     mPageLayer->setZValue(2);
       
    78     
       
    79     linearLayout = new QGraphicsLinearLayout(Qt::Horizontal);
       
    80     linearLayout->setContentsMargins(0, 0, 0, 0);
       
    81     linearLayout->setSpacing(0);
       
    82     mPageWallpaperLayer = new HbWidget(this);
       
    83     mPageWallpaperLayer->setLayout(linearLayout);
       
    84     mPageWallpaperLayer->setZValue(1);
       
    85     
       
    86     linearLayout = new QGraphicsLinearLayout(Qt::Horizontal);
       
    87     linearLayout->setContentsMargins(0, 0, 0, 0);
       
    88     linearLayout->setSpacing(0);
       
    89     mSceneLayer = new HbWidget(this);
       
    90     mSceneLayer->setLayout(linearLayout);
       
    91     mSceneLayer->setZValue(0);
       
    92 }
       
    93 
       
    94 /*!
       
    95     Destroys this idle widget.
       
    96 */
       
    97 HsIdleWidget::~HsIdleWidget()
       
    98 {
       
    99     QList<HsPage *> pages = HsScene::instance()->pages();
       
   100     foreach (HsPage *page, pages) {
       
   101         page->setParentItem(0);
       
   102         if (page->scene()) {
       
   103             page->scene()->removeItem(page);
       
   104         }
       
   105         HsWallpaper *pageWallpaper = page->wallpaper();
       
   106         if (pageWallpaper) {
       
   107             pageWallpaper->setParentItem(0);
       
   108             if (pageWallpaper->scene()) {
       
   109                 pageWallpaper->scene()->removeItem(pageWallpaper);
       
   110             }
       
   111         }
       
   112     }
       
   113 
       
   114     HsWallpaper *sceneWallpaper = HsScene::instance()->wallpaper();
       
   115     if (sceneWallpaper) {
       
   116         sceneWallpaper->setParentItem(0);
       
   117         if (sceneWallpaper->scene()) {
       
   118             sceneWallpaper->scene()->removeItem(sceneWallpaper);
       
   119         }
       
   120     }
       
   121 }
       
   122 
       
   123 qreal HsIdleWidget::sceneX() const
       
   124 {
       
   125     return mPageLayer->x();
       
   126 }
       
   127 
       
   128 void HsIdleWidget::setSceneX(qreal x)
       
   129 {
       
   130     if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::SceneWallpaper) {
       
   131         mPageLayer->setX(x);
       
   132         mSceneLayer->setX((parallaxFactor() * x) - HSCONFIGURATION_GET(bounceEffect) / 2);
       
   133     } else {
       
   134         mPageLayer->setX(x);
       
   135         mPageWallpaperLayer->setX(x);
       
   136     }
       
   137 }
       
   138 
       
   139 /*!
       
   140     Layouts the ui layers according to the given \a rect.
       
   141     If given \a rect has different size than a fullscreen view, rect
       
   142     is lifted up by statuspane height. Normally HsIdleWidget position is 0,0 
       
   143     relative to it's parent container (HbView). This functionality tackles
       
   144     problem caused by HbStackedLayout which sets top most rect for all items 
       
   145     (views) in a stack (not considering fullscreen mode).
       
   146 */
       
   147 void HsIdleWidget::setGeometry(const QRectF &rect)
       
   148 {
       
   149     
       
   150     int n = HsScene::instance()->pages().count();
       
   151     QRectF layoutRect(HsScene::instance()->mainWindow()->layoutRect());
       
   152     if (layoutRect == rect || (layoutRect.height() == rect.width() && layoutRect.width() == rect.height())) {
       
   153         mControlLayer->resize(rect.size());
       
   154         mPageLayer->resize(n * rect.width(), rect.height());
       
   155         if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
       
   156             mPageWallpaperLayer->resize(n * rect.width(), rect.height());
       
   157         }
       
   158         mSceneLayer->resize(2 * rect.width() + HSCONFIGURATION_GET(bounceEffect), rect.height());
       
   159         HbWidget::setGeometry(rect);
       
   160     } else {
       
   161         QRectF sceneRect = mapToScene(rect).boundingRect();
       
   162         // HbView is a container item for widget, thus 0,0 is relative to view's position.
       
   163         // Lift rect by offset. Fullscreen view is in 0,0 position in scene coordinates otherwise
       
   164         // it's e.g 0,68 (statuspane being at 0,0 and view at 0,68)
       
   165         sceneRect.setTop(-sceneRect.top());
       
   166         HbWidget::setGeometry(sceneRect);
       
   167     }
       
   168 }
       
   169 
       
   170 /*!
       
   171     Sets the active page \a index to the page
       
   172     indicator.
       
   173 */
       
   174 void HsIdleWidget::setActivePage(int index)
       
   175 {
       
   176     mPageIndicator->setActiveItemIndex(index);
       
   177 }
       
   178 
       
   179 /*!
       
   180     Inserts the given \a page at index position
       
   181     \a index in the page layer.
       
   182 */
       
   183 void HsIdleWidget::insertPage(int index, HsPage *page)
       
   184 {
       
   185     QGraphicsLinearLayout *layout =
       
   186         static_cast<QGraphicsLinearLayout *>(mPageLayer->layout());
       
   187     layout->insertItem(index, page);
       
   188     mPageLayer->resize(
       
   189         layout->count() * size().width(), size().height());
       
   190 
       
   191     if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
       
   192         QGraphicsLinearLayout *layout =
       
   193             static_cast<QGraphicsLinearLayout *>(mPageWallpaperLayer->layout());
       
   194         layout->insertItem(index, page->wallpaper());
       
   195         mPageWallpaperLayer->resize(
       
   196             layout->count() * size().width(), size().height());
       
   197     }
       
   198 }
       
   199 
       
   200 /*!
       
   201     Removes the page at index position
       
   202     \a index in the page layer.
       
   203 */
       
   204 void HsIdleWidget::removePage(int index)
       
   205 {
       
   206     QGraphicsLinearLayout *layout =
       
   207         static_cast<QGraphicsLinearLayout *>(mPageLayer->layout());
       
   208     layout->removeAt(index);
       
   209     mPageLayer->resize(
       
   210         layout->count() * size().width(), size().height());
       
   211 
       
   212     if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
       
   213         QGraphicsLinearLayout *layout =
       
   214             static_cast<QGraphicsLinearLayout *>(mPageWallpaperLayer->layout());
       
   215         layout->removeAt(index);
       
   216         mPageWallpaperLayer->resize(
       
   217             layout->count() * size().width(), size().height());
       
   218     }
       
   219     mPageIndicator->removeItem(index);
       
   220 }
       
   221 
       
   222 /*!
       
   223     \fn HsIdleWidget::controlLayer() const
       
   224 
       
   225     Returns the control layer.
       
   226 */
       
   227 
       
   228 /*!
       
   229     \fn HsIdleWidget::pageLayer() const
       
   230 
       
   231     Returns the page layer.
       
   232 */
       
   233 
       
   234 /*!
       
   235     \fn HsIdleWidget::sceneLayer() const
       
   236 
       
   237     Returns the scene layer.
       
   238 */
       
   239 
       
   240 /*!
       
   241     \fn HsIdleWidget::trashBin() const
       
   242 
       
   243     Returns the trashbin widget.
       
   244 */
       
   245 
       
   246 /*!
       
   247     \fn HsIdleWidget::pageIndicator() const
       
   248 
       
   249     Returns the page indicator widget.
       
   250 */
       
   251 
       
   252 /*!
       
   253     Sets the trashbin visible and hides the page indicator.
       
   254 */
       
   255 void HsIdleWidget::showTrashBin()
       
   256 {
       
   257     mPageIndicator->hide();
       
   258     mTrashBin->show();
       
   259 }
       
   260 
       
   261 /*!
       
   262     Sets the page indicator visible and hides the trashbin.
       
   263 */
       
   264 void HsIdleWidget::showPageIndicator()
       
   265 {
       
   266     mTrashBin->hide();
       
   267     mTrashBin->deactivate();
       
   268     mPageIndicator->setSpacing(HSCONFIGURATION_GET(pageIndicatorSpacing)); // for usability optimization widget, can be removed later on
       
   269     mPageIndicator->setVisible(1 < mPageIndicator->itemCount());
       
   270 }
       
   271 
       
   272 /*!
       
   273     Shows the Vertical snapping lines showing the guidance
       
   274 */
       
   275 void HsIdleWidget::showVerticalSnapLine(const QLineF &snapLine)
       
   276 {
       
   277     QVariantHash snapConfiguration;
       
   278     snapConfiguration[SNAPLINEFADEINDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeInDuration));
       
   279     snapConfiguration[SNAPLINEFADEOUTDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeOutDuration));
       
   280 
       
   281     mVerticalSnapLine->setConfiguration(snapConfiguration);
       
   282     mVerticalSnapLine->showLine(snapLine);
       
   283 }
       
   284 
       
   285 /*!
       
   286     Shows the Horizontal snapping lines showing the guidance
       
   287 */
       
   288 void HsIdleWidget::showHorizontalSnapLine(const QLineF &snapLine)
       
   289 {
       
   290     QVariantHash snapConfiguration;
       
   291     snapConfiguration[SNAPLINEFADEINDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeInDuration));
       
   292     snapConfiguration[SNAPLINEFADEOUTDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeOutDuration));
       
   293 
       
   294     mHorizontalSnapLine->setConfiguration(snapConfiguration);
       
   295     mHorizontalSnapLine->showLine(snapLine);
       
   296 }
       
   297 
       
   298 /*!
       
   299     Hides the Vertical snapping line showing the guidance
       
   300 */
       
   301 void HsIdleWidget::hideVerticalSnapLine()
       
   302 {
       
   303     mVerticalSnapLine->hideLine();
       
   304 }
       
   305 
       
   306 /*!
       
   307     Hides the Horizontal snapping line showing the guidance
       
   308 */
       
   309 void HsIdleWidget::hideHorizontalSnapLine()
       
   310 {
       
   311     mHorizontalSnapLine->hideLine();
       
   312 }
       
   313 
       
   314 /*!
       
   315     Reimplements QGraphicsWidget::polishEvent().
       
   316 */
       
   317 void HsIdleWidget::polishEvent()
       
   318 {
       
   319     HsScene *scene = HsScene::instance();
       
   320     Q_ASSERT(scene);
       
   321 
       
   322     QGraphicsLinearLayout *pageLayout = 
       
   323         static_cast<QGraphicsLinearLayout *>(mPageLayer->layout());
       
   324 
       
   325     QList<HsPage *> pages = scene->pages();
       
   326 
       
   327     foreach (HsPage *page, pages) {
       
   328         pageLayout->addItem(page);
       
   329         if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
       
   330             QGraphicsLinearLayout *pageWallpaperLayout = 
       
   331                 static_cast<QGraphicsLinearLayout *>(mPageWallpaperLayer->layout());
       
   332             pageWallpaperLayout->addItem(page->wallpaper());
       
   333         }
       
   334     }
       
   335    if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::SceneWallpaper) {
       
   336         QGraphicsLinearLayout *sceneLayout = 
       
   337             static_cast<QGraphicsLinearLayout *>(mSceneLayer->layout());
       
   338     	HsWallpaper *wallpaper = HsScene::instance()->wallpaper();
       
   339         sceneLayout->addItem(wallpaper);
       
   340     }
       
   341            
       
   342     mPageIndicator->initialize(pages.count(), scene->activePageIndex());    
       
   343     showPageIndicator();
       
   344 
       
   345     HsScene::mainWindow()->scene()->installEventFilter(this);
       
   346 }
       
   347 
       
   348 /*!
       
   349     Loads the control layer declared in a docml file.
       
   350 */
       
   351 void HsIdleWidget::loadControlLayer()
       
   352 {
       
   353     HsDocumentLoader loader;
       
   354     bool loaded = false;
       
   355 
       
   356 #ifndef Q_OS_SYMBIAN
       
   357     QString path = QDir::currentPath();
       
   358 #else
       
   359     QString path = "c:";
       
   360 #endif
       
   361 
       
   362     QString file = path + "/hsresources/" + gControlLayerDocmlName;
       
   363     QString fallbackPath = QString(":/") + gControlLayerDocmlName;
       
   364 
       
   365     if (QFile::exists(file)) {
       
   366         loader.load(file, &loaded);
       
   367         if (!loaded) {
       
   368             loader.load(fallbackPath, &loaded);
       
   369         }
       
   370     } else {
       
   371         loader.load(fallbackPath, &loaded);
       
   372     }
       
   373 
       
   374     if (loaded) {
       
   375         mControlLayer = qobject_cast<HbWidget *>(loader.findWidget(gControlLayerName));
       
   376         mControlLayer->setZValue(3);
       
   377         mControlLayer->setParentItem(this);
       
   378 
       
   379         mTrashBin = qobject_cast<HsTrashBinWidget *>(loader.findWidget(gTrashBinName));
       
   380         mTrashBin->setZValue(1e6);
       
   381 
       
   382         mPageIndicator = qobject_cast<HsPageIndicator *>(loader.findWidget(gPageIndicatorName));
       
   383         mPageIndicator->setZValue(1e6);
       
   384 
       
   385 
       
   386         mHorizontalSnapLine = new HsSnapLine(mControlLayer);
       
   387         mHorizontalSnapLine->setZValue(10);
       
   388 
       
   389         mVerticalSnapLine = new HsSnapLine(mControlLayer);
       
   390         mVerticalSnapLine->setZValue(10);
       
   391     } else {
       
   392         // TODO: Handle error.
       
   393     }
       
   394 }
       
   395 
       
   396 qreal HsIdleWidget::parallaxFactor() const
       
   397 {   
       
   398     qreal clw = mControlLayer->size().width();
       
   399     qreal slw = mSceneLayer->size().width() - HSCONFIGURATION_GET(bounceEffect);
       
   400     int n = HsScene::instance()->pages().count();
       
   401     if (n < 2) {
       
   402         return 1;
       
   403     } else {
       
   404         return (slw - clw) / ((n - 1) * clw);
       
   405     }
       
   406 }