--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/homescreenapp/hsdomainmodel/src/hsidlewidget.cpp Fri Jul 23 13:47:57 2010 +0300
@@ -0,0 +1,409 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QApplication>
+#include <QGraphicsSceneMouseEvent>
+#include <QGraphicsLinearLayout>
+#include <QDir>
+
+#include <HbMainWindow>
+#include <HbVkbHost>
+
+#include "hsidlewidget.h"
+#include "hsscene.h"
+#include "hspage.h"
+#include "hspagevisual.h"
+#include "hswidgethost.h"
+#include "hswallpaper.h"
+#include "hstrashbinwidget.h"
+#include "hspageindicator.h"
+#include "hsdocumentloader.h"
+#include "hsconfiguration.h"
+#include "hsapp_defs.h"
+#include "hssnapline.h"
+#include "hsgui.h"
+
+
+namespace
+{
+ const char gControlLayerDocmlName[] = "controllayer.docml";
+ const char gControlLayerName[] = "controlLayer";
+ const char gTrashBinName[] = "trashBin";
+ const char gPageIndicatorName[] = "pageIndicator";
+}
+
+/*!
+ \class HsIdleWidget
+ \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
+ state for further processing.
+*/
+
+/*!
+ Constructs a new idle widget with the given \a parent.
+*/
+HsIdleWidget::HsIdleWidget(QGraphicsItem *parent)
+ : HbWidget(parent),
+ mControlLayer(0), mPageLayer(0), mPageWallpaperLayer(0),
+ mSceneLayer(0),
+ mTrashBin(0), mPageIndicator(0),
+ mHorizontalSnapLine(0), mVerticalSnapLine(0)
+{
+ setFlag(ItemHasNoContents);
+
+ loadControlLayer();
+
+ QGraphicsLinearLayout *linearLayout = 0;
+
+ linearLayout = new QGraphicsLinearLayout(Qt::Horizontal);
+ linearLayout->setContentsMargins(0, 0, 0, 0);
+ linearLayout->setSpacing(0);
+ mPageLayer = new HbWidget(this);
+ mPageLayer->setLayout(linearLayout);
+ 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);
+ linearLayout->setSpacing(0);
+ mSceneLayer = new HbWidget(this);
+ mSceneLayer->setLayout(linearLayout);
+ mSceneLayer->setZValue(0);
+}
+
+/*!
+ Destroys this idle widget.
+*/
+HsIdleWidget::~HsIdleWidget()
+{
+ QList<HsPage *> pages = HsScene::instance()->pages();
+ foreach (HsPage *page, pages) {
+ page->visual()->setParentItem(0);
+ if (page->visual()->scene()) {
+ page->visual()->scene()->removeItem(page->visual());
+ }
+ HsWallpaper *pageWallpaper = page->wallpaper();
+ if (pageWallpaper) {
+ pageWallpaper->setParentItem(0);
+ if (pageWallpaper->scene()) {
+ pageWallpaper->scene()->removeItem(pageWallpaper);
+ }
+ }
+ }
+
+ 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(HsGui::instance()->layoutRect());
+ if (layoutRect == rect || (layoutRect.height() == rect.width() && layoutRect.width() == rect.height())) {
+ mControlLayer->resize(rect.size());
+ 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);
+ }
+}
+
+/*!
+ Sets the active page \a index to the page
+ indicator.
+*/
+void HsIdleWidget::setActivePage(int index)
+{
+ mPageIndicator->setActiveItemIndex(index);
+}
+
+/*!
+ Inserts the given \a page at index position
+ \a index in the page layer.
+*/
+void HsIdleWidget::insertPage(int index, HsPage *page)
+{
+ QGraphicsLinearLayout *layout =
+ static_cast<QGraphicsLinearLayout *>(mPageLayer->layout());
+ layout->insertItem(index, page->visual());
+ 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());
+ }
+}
+
+/*!
+ Removes the page at index position
+ \a index in the page layer.
+*/
+void HsIdleWidget::removePage(int index)
+{
+ 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());
+ }
+ mPageIndicator->removeItem(index);
+}
+
+/*!
+ \fn HsIdleWidget::controlLayer() const
+
+ Returns the control layer.
+*/
+
+/*!
+ \fn HsIdleWidget::pageLayer() const
+
+ Returns the page layer.
+*/
+
+/*!
+ \fn HsIdleWidget::sceneLayer() const
+
+ Returns the scene layer.
+*/
+
+/*!
+ \fn HsIdleWidget::trashBin() const
+
+ Returns the trashbin widget.
+*/
+
+/*!
+ \fn HsIdleWidget::pageIndicator() const
+
+ Returns the page indicator widget.
+*/
+
+/*!
+ Sets the trashbin visible and hides the page indicator.
+*/
+void HsIdleWidget::showTrashBin()
+{
+ mPageIndicator->hide();
+ mTrashBin->show();
+}
+
+/*!
+ Sets the page indicator visible and hides the trashbin.
+*/
+void HsIdleWidget::showPageIndicator()
+{
+ mTrashBin->hide();
+ mTrashBin->deactivate();
+ mPageIndicator->setSpacing(HSCONFIGURATION_GET(pageIndicatorSpacing)); // for usability optimization widget, can be removed later on
+ mPageIndicator->setVisible(1 < mPageIndicator->itemCount());
+}
+
+/*!
+ Shows the Vertical snapping lines showing the guidance
+*/
+void HsIdleWidget::showVerticalSnapLine(const QLineF &snapLine)
+{
+ QVariantHash snapConfiguration;
+ snapConfiguration[SNAPLINEFADEINDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeInDuration));
+ snapConfiguration[SNAPLINEFADEOUTDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeOutDuration));
+
+ mVerticalSnapLine->setConfiguration(snapConfiguration);
+ mVerticalSnapLine->showLine(snapLine);
+}
+
+/*!
+ Shows the Horizontal snapping lines showing the guidance
+*/
+void HsIdleWidget::showHorizontalSnapLine(const QLineF &snapLine)
+{
+ QVariantHash snapConfiguration;
+ snapConfiguration[SNAPLINEFADEINDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeInDuration));
+ snapConfiguration[SNAPLINEFADEOUTDURATION] = QString::number(HSCONFIGURATION_GET(snapLineFadeOutDuration));
+
+ mHorizontalSnapLine->setConfiguration(snapConfiguration);
+ mHorizontalSnapLine->showLine(snapLine);
+}
+
+/*!
+ Hides the Vertical snapping line showing the guidance
+*/
+void HsIdleWidget::hideVerticalSnapLine()
+{
+ mVerticalSnapLine->hideLine();
+}
+
+/*!
+ Hides the Horizontal snapping line showing the guidance
+*/
+void HsIdleWidget::hideHorizontalSnapLine()
+{
+ mHorizontalSnapLine->hideLine();
+}
+
+/*!
+ Reimplements QGraphicsWidget::polishEvent().
+*/
+void HsIdleWidget::polishEvent()
+{
+ HsScene *scene = HsScene::instance();
+ Q_ASSERT(scene);
+
+ QGraphicsLinearLayout *pageLayout =
+ static_cast<QGraphicsLinearLayout *>(mPageLayer->layout());
+
+ QList<HsPage *> pages = scene->pages();
+
+ foreach (HsPage *page, pages) {
+ pageLayout->addItem(page->visual());
+ if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) {
+ QGraphicsLinearLayout *pageWallpaperLayout =
+ static_cast<QGraphicsLinearLayout *>(mPageWallpaperLayer->layout());
+ pageWallpaperLayout->addItem(page->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();
+
+ // HsGui::instance()->scene()->installEventFilter(this);
+}
+
+/*!
+ Loads the control layer declared in a docml file.
+*/
+void HsIdleWidget::loadControlLayer()
+{
+ HsDocumentLoader loader;
+ bool loaded = false;
+
+#ifndef Q_OS_SYMBIAN
+ QString path = QDir::currentPath();
+#else
+ QString path = "c:";
+#endif
+
+ QString file = path + "/hsresources/" + gControlLayerDocmlName;
+ QString fallbackPath = QString(":/") + gControlLayerDocmlName;
+
+ if (QFile::exists(file)) {
+ loader.load(file, &loaded);
+ if (!loaded) {
+ loader.load(fallbackPath, &loaded);
+ }
+ } else {
+ loader.load(fallbackPath, &loaded);
+ }
+
+ if (loaded) {
+ mControlLayer = qobject_cast<HbWidget *>(loader.findWidget(gControlLayerName));
+ mControlLayer->setZValue(3);
+ mControlLayer->setParentItem(this);
+
+ mTrashBin = qobject_cast<HsTrashBinWidget *>(loader.findWidget(gTrashBinName));
+ mTrashBin->setZValue(1e6);
+
+ 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.
+ }
+}
+
+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);
+ }
+}