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