homescreenapp/stateplugins/hshomescreenstateplugin/src/hsidlewidget.cpp
changeset 62 341166945d65
parent 55 03646e8da489
child 63 52b0f64eeb51
--- a/homescreenapp/stateplugins/hshomescreenstateplugin/src/hsidlewidget.cpp	Thu Jun 24 13:11:40 2010 +0100
+++ b/homescreenapp/stateplugins/hshomescreenstateplugin/src/hsidlewidget.cpp	Fri Jun 25 19:19:22 2010 +0300
@@ -32,6 +32,8 @@
 #include "hspageindicator.h"
 #include "hsdocumentloader.h"
 #include "hsconfiguration.h"
+#include "hsapp_defs.h"
+#include "hssnapline.h"
 
 namespace
 {
@@ -46,8 +48,8 @@
     \ingroup group_hshomescreenstateplugin
     \brief View part of the home screen idle state.
 
-    Maintains the idle view ui layers and takes care of 
-    receiving user input and communicating it to the idle 
+    Maintains the idle view ui layers and takes care of
+    receiving user input and communicating it to the idle
     state for further processing.
 */
 
@@ -56,12 +58,13 @@
 */
 HsIdleWidget::HsIdleWidget(QGraphicsItem *parent)
   : HbWidget(parent),
-    mControlLayer(0), mPageLayer(0), mSceneLayer(0),
-    mDelayedPressEvent(0),
-    mTrashBin(0), mPageIndicator(0)
+    mControlLayer(0), mPageLayer(0), mPageWallpaperLayer(0),
+    mSceneLayer(0),
+    mTrashBin(0), mPageIndicator(0),
+    mHorizontalSnapLine(0), mVerticalSnapLine(0)
 {
     setFlag(ItemHasNoContents);
-    
+
     loadControlLayer();
 
     QGraphicsLinearLayout *linearLayout = 0;
@@ -71,7 +74,14 @@
     linearLayout->setSpacing(0);
     mPageLayer = new HbWidget(this);
     mPageLayer->setLayout(linearLayout);
-    mPageLayer->setZValue(1);
+    mPageLayer->setZValue(2);
+    
+    linearLayout = new QGraphicsLinearLayout(Qt::Horizontal);
+    linearLayout->setContentsMargins(0, 0, 0, 0);
+    linearLayout->setSpacing(0);
+    mPageWallpaperLayer = new HbWidget(this);
+    mPageWallpaperLayer->setLayout(linearLayout);
+    mPageWallpaperLayer->setZValue(1);
     
     linearLayout = new QGraphicsLinearLayout(Qt::Horizontal);
     linearLayout->setContentsMargins(0, 0, 0, 0);
@@ -86,78 +96,79 @@
 */
 HsIdleWidget::~HsIdleWidget()
 {
-    clearDelayedPress();
-
     QList<HsPage *> pages = HsScene::instance()->pages();
     foreach (HsPage *page, pages) {
         page->setParentItem(0);
         if (page->scene()) {
             page->scene()->removeItem(page);
         }
+        HsWallpaper *pageWallpaper = page->wallpaper();
+        if (pageWallpaper) {
+            pageWallpaper->setParentItem(0);
+            if (pageWallpaper->scene()) {
+                pageWallpaper->scene()->removeItem(pageWallpaper);
+            }
+        }
     }
 
-    HsWallpaper *wallpaper = HsScene::instance()->wallpaper();
-    wallpaper->setParentItem(0);
-    if (wallpaper->scene()) {
-        wallpaper->scene()->removeItem(wallpaper);
+    HsWallpaper *sceneWallpaper = HsScene::instance()->wallpaper();
+    if (sceneWallpaper) {
+        sceneWallpaper->setParentItem(0);
+        if (sceneWallpaper->scene()) {
+            sceneWallpaper->scene()->removeItem(sceneWallpaper);
+        }
+    }
+}
+
+qreal HsIdleWidget::sceneX() const
+{
+    return mPageLayer->x();
+}
+
+void HsIdleWidget::setSceneX(qreal x)
+{
+    if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::SceneWallpaper) {
+        mPageLayer->setX(x);
+        mSceneLayer->setX((parallaxFactor() * x) - HSCONFIGURATION_GET(bounceEffect) / 2);
+    } else {
+        mPageLayer->setX(x);
+        mPageWallpaperLayer->setX(x);
     }
 }
 
 /*!
     Layouts the ui layers according to the given \a rect.
+    If given \a rect has different size than a fullscreen view, rect
+    is lifted up by statuspane height. Normally HsIdleWidget position is 0,0 
+    relative to it's parent container (HbView). This functionality tackles
+    problem caused by HbStackedLayout which sets top most rect for all items 
+    (views) in a stack (not considering fullscreen mode).
 */
 void HsIdleWidget::setGeometry(const QRectF &rect)
 {
+    
     int n = HsScene::instance()->pages().count();
-	QRectF layoutRect(HsScene::instance()->mainWindow()->layoutRect());
+    QRectF layoutRect(HsScene::instance()->mainWindow()->layoutRect());
     if (layoutRect == rect || (layoutRect.height() == rect.width() && layoutRect.width() == rect.height())) {
         mControlLayer->resize(rect.size());
-		mPageLayer->resize(n * rect.width(), rect.height());
-		mSceneLayer->resize(2 * rect.width() + HsConfiguration::bounceEffect(), rect.height());
-		HbWidget::setGeometry(rect);
-	} else {
-		QRectF sceneRect = mapToScene(rect).boundingRect();
-		sceneRect.setTop(-sceneRect.top());
-		HbWidget::setGeometry(sceneRect);
-	}
-}
-
-/*!
-    Stores the given mouse press \a event.
-*/
-void HsIdleWidget::captureDelayedPress(QGraphicsSceneMouseEvent *event)
-{
-    if (event) {
-        mDelayedPressEvent = new QMouseEvent(QEvent::MouseButtonPress,
-            event->scenePos().toPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
-        mDelayedPressEvent->setAccepted(false);
+        mPageLayer->resize(n * rect.width(), rect.height());
+        if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
+            mPageWallpaperLayer->resize(n * rect.width(), rect.height());
+        }
+        mSceneLayer->resize(2 * rect.width() + HSCONFIGURATION_GET(bounceEffect), rect.height());
+        HbWidget::setGeometry(rect);
+    } else {
+        QRectF sceneRect = mapToScene(rect).boundingRect();
+        // HbView is a container item for widget, thus 0,0 is relative to view's position.
+        // Lift rect by offset. Fullscreen view is in 0,0 position in scene coordinates otherwise
+        // it's e.g 0,68 (statuspane being at 0,0 and view at 0,68)
+        sceneRect.setTop(-sceneRect.top());
+        HbWidget::setGeometry(sceneRect);
     }
 }
 
 /*!
-    Sends the stored mouse press event.
-*/
-void HsIdleWidget::sendDelayedPress()
-{
-    if (mDelayedPressEvent) {
-        QApplication::sendEvent(HsScene::mainWindow()->viewport(), mDelayedPressEvent);
-        clearDelayedPress();     
-    }
-}
-
-/*!
-    Deletes the stored mouse press event.
-*/
-void HsIdleWidget::clearDelayedPress()
-{    
-    if (mDelayedPressEvent) {
-        delete mDelayedPressEvent;
-        mDelayedPressEvent = 0;
-    }
-}
-
-/*!
-    Sets the active page \a index to the page 
+    Sets the active page \a index to the page
     indicator.
 */
 void HsIdleWidget::setActivePage(int index)
@@ -171,11 +182,19 @@
 */
 void HsIdleWidget::insertPage(int index, HsPage *page)
 {
-    QGraphicsLinearLayout *layout = 
+    QGraphicsLinearLayout *layout =
         static_cast<QGraphicsLinearLayout *>(mPageLayer->layout());
     layout->insertItem(index, page);
     mPageLayer->resize(
         layout->count() * size().width(), size().height());
+
+    if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
+        QGraphicsLinearLayout *layout =
+            static_cast<QGraphicsLinearLayout *>(mPageWallpaperLayer->layout());
+        layout->insertItem(index, page->wallpaper());
+        mPageWallpaperLayer->resize(
+            layout->count() * size().width(), size().height());
+    }
 }
 
 /*!
@@ -184,11 +203,19 @@
 */
 void HsIdleWidget::removePage(int index)
 {
-    QGraphicsLinearLayout *layout = 
+    QGraphicsLinearLayout *layout =
         static_cast<QGraphicsLinearLayout *>(mPageLayer->layout());
     layout->removeAt(index);
     mPageLayer->resize(
         layout->count() * size().width(), size().height());
+
+    if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
+        QGraphicsLinearLayout *layout =
+            static_cast<QGraphicsLinearLayout *>(mPageWallpaperLayer->layout());
+        layout->removeAt(index);
+        mPageWallpaperLayer->resize(
+            layout->count() * size().width(), size().height());
+    }
 }
 
 /*!
@@ -222,33 +249,6 @@
 */
 
 /*!
-    \fn HsIdleWidget::mousePressed(QGraphicsItem *, QGraphicsSceneMouseEvent *, bool &)
-
-    The idle state connects to this signal for handling mouse
-    press events. It filters events for the item \a watched. 
-    \a event is the filtered event. Sets the \a filtered true 
-    if the event was filtered by this handler.
-*/
-
-/*!
-    \fn HsIdleWidget::mouseMoved(QGraphicsItem *, QGraphicsSceneMouseEvent *, bool &)
-
-    The idle state connects to this signal for handling mouse
-    move events. It filters events for the item \a watched. 
-    \a event is the filtered event. Sets the \a filtered true 
-    if the event was filtered by this handler.
-*/
-
-/*!
-    \fn HsIdleWidget::mouseReleased(QGraphicsItem *, QGraphicsSceneMouseEvent *, bool &)
-
-    The idle state connects to this signal for handling mouse
-    release events. It filters events for the item \a watched. 
-    \a event is the filtered event. Sets the \a filtered true 
-    if the event was filtered by this handler.
-*/
-
-/*!
     Sets the trashbin visible and hides the page indicator.
 */
 void HsIdleWidget::showTrashBin()
@@ -256,7 +256,7 @@
     mPageIndicator->hide();
     mTrashBin->show();
 }
- 
+
 /*!
     Sets the page indicator visible and hides the trashbin.
 */
@@ -264,68 +264,50 @@
 {
     mTrashBin->hide();
     mTrashBin->deactivate();
-    mPageIndicator->setSpacing(HsConfiguration::pageIndicatorSpacing()); // for usability optimization widget, can be removed later on
+    mPageIndicator->setSpacing(HSCONFIGURATION_GET(pageIndicatorSpacing)); // for usability optimization widget, can be removed later on
     mPageIndicator->setVisible(1 < mPageIndicator->itemCount());
 }
 
 /*!
-    Filters the main window's graphics scene (\a object) \a event.
+    Shows the Vertical snapping lines showing the guidance
 */
-bool HsIdleWidget::eventFilter(QObject *object, QEvent *event)
+void HsIdleWidget::showVerticalSnapLine(const QLineF &snapLine)
 {
-    Q_UNUSED(object)
-
-    if (HbVkbHost::activeVkbHost()) {
-        setFiltersChildEvents(false);
-        return false;
-    }
-
-    bool filtered = false;
+    QVariantHash snapConfiguration;
+    snapConfiguration[SNAPLINEFADEINDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeInDuration));
+    snapConfiguration[SNAPLINEFADEOUTDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeOutDuration));
 
-    switch (event->type()) {
-    case QEvent::GraphicsSceneMousePress:
-        if (mDelayedPressEvent &&
-            scene()->mouseGrabberItem()) {
-            scene()->mouseGrabberItem()->ungrabMouse();
-        }
-        setFiltersChildEvents(!mDelayedPressEvent);
-        break;
-    case QEvent::GraphicsSceneMouseMove:
-        emit mouseMoved(0, static_cast<QGraphicsSceneMouseEvent *>(event), filtered);
-        break;
-    case QEvent::GraphicsSceneMouseRelease:
-        setItemsFocusable();
-        emit mouseReleased(0, static_cast<QGraphicsSceneMouseEvent *>(event), filtered);
-        if (filtered && scene()->mouseGrabberItem()) {
-            scene()->mouseGrabberItem()->ungrabMouse();
-        }        
-        break;
-    default:
-        break;
-    }
-
-    return filtered;
+    mVerticalSnapLine->setConfiguration(snapConfiguration);
+    mVerticalSnapLine->showLine(snapLine);
 }
 
 /*!
-    Filters events for the item \a watched. \a event is the filtered event.
+    Shows the Horizontal snapping lines showing the guidance
 */
-bool HsIdleWidget::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+void HsIdleWidget::showHorizontalSnapLine(const QLineF &snapLine)
 {
-    bool filtered = false;
+    QVariantHash snapConfiguration;
+    snapConfiguration[SNAPLINEFADEINDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeInDuration));
+    snapConfiguration[SNAPLINEFADEOUTDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeOutDuration));
+
+    mHorizontalSnapLine->setConfiguration(snapConfiguration);
+    mHorizontalSnapLine->showLine(snapLine);
+}
 
-    switch (event->type()) {
-    case QEvent::GraphicsSceneMousePress:
-        emit mousePressed(watched, static_cast<QGraphicsSceneMouseEvent *>(event), filtered);
-        if (filtered) {
-            setItemsUnfocusable(static_cast<QGraphicsSceneMouseEvent *>(event));
-        }
-        break;    
-    default:
-        break;
-    }
+/*!
+    Hides the Vertical snapping line showing the guidance
+*/
+void HsIdleWidget::hideVerticalSnapLine()
+{
+    mVerticalSnapLine->hideLine();
+}
 
-    return filtered;
+/*!
+    Hides the Horizontal snapping line showing the guidance
+*/
+void HsIdleWidget::hideHorizontalSnapLine()
+{
+    mHorizontalSnapLine->hideLine();
 }
 
 /*!
@@ -336,16 +318,25 @@
     HsScene *scene = HsScene::instance();
     Q_ASSERT(scene);
 
-    QGraphicsLinearLayout *layout = 
+    QGraphicsLinearLayout *pageLayout = 
         static_cast<QGraphicsLinearLayout *>(mPageLayer->layout());
+
     QList<HsPage *> pages = scene->pages();
+
     foreach (HsPage *page, pages) {
-        layout->addItem(page);
+        pageLayout->addItem(page);
+        if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
+            QGraphicsLinearLayout *pageWallpaperLayout = 
+                static_cast<QGraphicsLinearLayout *>(mPageWallpaperLayer->layout());
+            pageWallpaperLayout->addItem(page->wallpaper());
+        }
     }
-
-    layout = static_cast<QGraphicsLinearLayout *>(mSceneLayer->layout());
-    HsWallpaper *wallpaper = HsScene::instance()->wallpaper();
-    layout->addItem(wallpaper);
+   if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::SceneWallpaper) {
+        QGraphicsLinearLayout *sceneLayout = 
+            static_cast<QGraphicsLinearLayout *>(mSceneLayer->layout());
+    	HsWallpaper *wallpaper = HsScene::instance()->wallpaper();
+        sceneLayout->addItem(wallpaper);
+    }
            
     mPageIndicator->initialize(pages.count(), scene->activePageIndex());    
     showPageIndicator();
@@ -376,12 +367,12 @@
             loader.load(fallbackPath, &loaded);
         }
     } else {
-        loader.load(fallbackPath, &loaded);       
+        loader.load(fallbackPath, &loaded);
     }
 
     if (loaded) {
         mControlLayer = qobject_cast<HbWidget *>(loader.findWidget(gControlLayerName));
-        mControlLayer->setZValue(2);
+        mControlLayer->setZValue(3);
         mControlLayer->setParentItem(this);
 
         mTrashBin = qobject_cast<HsTrashBinWidget *>(loader.findWidget(gTrashBinName));
@@ -389,61 +380,26 @@
 
         mPageIndicator = qobject_cast<HsPageIndicator *>(loader.findWidget(gPageIndicatorName));
         mPageIndicator->setZValue(1e6);
+
+
+        mHorizontalSnapLine = new HsSnapLine(mControlLayer);
+        mHorizontalSnapLine->setZValue(10);
+
+        mVerticalSnapLine = new HsSnapLine(mControlLayer);
+        mVerticalSnapLine->setZValue(10);
     } else {
         // TODO: Handle error.
     }
 }
 
-/*!
-    Sets the items under the given mouse \a event scene position 
-    unfocusable and stores the items.
-*/
-void HsIdleWidget::setItemsUnfocusable(QGraphicsSceneMouseEvent *event)
-{
-    mFocusableItems.clear();
-
-    if (!scene()) {
-        return;
-    }
-
-    QList<QGraphicsItem *> items = scene()->items(event->scenePos());
-    if (items.isEmpty()) {
-        return;
-    }
-
-    int i = 0;
-    for (; i < items.count(); ++i) {
-        if (mPageLayer->isAncestorOf(items[i])) {
-            ++i;
-            break;
-        }
-    }
- 
-    HsPage *page = HsScene::instance()->activePage();
-    QList<HsWidgetHost *> widgets = page->widgets();
-    
-    for (; i < items.count(); ++i) {
-        QGraphicsItem *item = items.at(i);
-        if (page->isAncestorOf(item)) {
-            foreach (HsWidgetHost *widget, widgets) {
-                if ((item == widget || widget->isAncestorOf(item))&& item->isEnabled() && (item->flags() & QGraphicsItem::ItemIsFocusable)) {
-                    if (!item->isWidget() || static_cast<QGraphicsWidget *>(item)->focusPolicy() & Qt::ClickFocus) {
-                        item->setFlag(QGraphicsItem::ItemIsFocusable, false);
-                        mFocusableItems.append(item);
-                    }
-                }
-            }
-        }
+qreal HsIdleWidget::parallaxFactor() const
+{   
+    qreal clw = mControlLayer->size().width();
+    qreal slw = mSceneLayer->size().width() - HSCONFIGURATION_GET(bounceEffect);
+    int n = HsScene::instance()->pages().count();
+    if (n < 2) {
+        return 1;
+    } else {
+        return (slw - clw) / ((n - 1) * clw);
     }
 }
- 
-/*!
-    Sets the stored items focusable.
-*/
-void HsIdleWidget::setItemsFocusable()
-{
-    foreach (QGraphicsItem *item, mFocusableItems) {
-        item->setFlag(QGraphicsItem::ItemIsFocusable);
-    }
-    mFocusableItems.clear();
-}