homescreenapp/hsdomainmodel/src/hswidgethost.cpp
changeset 69 87476091b3f5
parent 62 341166945d65
child 81 7dd137878ff8
equal deleted inserted replaced
67:474929a40a0f 69:87476091b3f5
    17 
    17 
    18 #include <QApplication>
    18 #include <QApplication>
    19 #include <QStateMachine>
    19 #include <QStateMachine>
    20 #include <QState>
    20 #include <QState>
    21 #include <QFinalState>
    21 #include <QFinalState>
    22 #include <QGraphicsLinearLayout>
       
    23 #include <QParallelAnimationGroup>
       
    24 #include <QPropertyAnimation>
       
    25 #include <QGraphicsDropShadowEffect>
       
    26 #include <QGraphicsSceneResizeEvent>
       
    27 #include <QGesture>
       
    28 #include <QGraphicsScene>
       
    29 
       
    30 #include <qservicemanager.h>
       
    31 #include <qservicefilter.h>
       
    32 #include <qserviceinterfacedescriptor.h>
       
    33 
       
    34 #include <HbInstantFeedback>
       
    35 #include <HbTouchArea>
       
    36 
    22 
    37 #include "hsdatabase.h"
    23 #include "hsdatabase.h"
    38 #include "hsdomainmodeldatastructures.h"
    24 #include "hsdomainmodeldatastructures.h"
    39 #include "hsscene.h"
    25 #include "hsscene.h"
    40 #include "hspage.h"
    26 #include "hspage.h"
    41 #include "hswidgethost.h"
    27 #include "hswidgethost.h"
    42 #include "hswidgettoucharea.h"
    28 #include "hswidgethostvisual.h"
       
    29 #include "hshostedwidgetfactory.h"
       
    30 
    43 #include "hswidgetcomponentregistry.h"
    31 #include "hswidgetcomponentregistry.h"
    44 #include "hswidgetcomponent.h"
    32 #include "hswidgetcomponent.h"
    45 #include "hsconfiguration.h"
    33 #include "hsconfiguration.h"
    46 #include "hscontentservice.h"
    34 #include "hscontentservice.h"
       
    35 #include "hsgui.h"
    47 
    36 
    48 // Helper macros for connecting state entry and exit actions.
    37 // Helper macros for connecting state entry and exit actions.
    49 #define ENTRY_ACTION(state, action) \
    38 #define ENTRY_ACTION(state, action) \
    50     connect(state, SIGNAL(entered()), SLOT(action()));
    39     connect(state, SIGNAL(entered()), SLOT(action()));
    51 #define EXIT_ACTION(state, action) \
    40 #define EXIT_ACTION(state, action) \
    52     connect(state, SIGNAL(exited()), SLOT(action()));
    41     connect(state, SIGNAL(exited()), SLOT(action()));
    53 
    42 
    54 QTM_USE_NAMESPACE
    43 
    55 
    44 
    56 
    45 
    57 /*!
    46 /*!
    58     \class HsWidgetHost
    47     \class HsWidgetHost
    59     \ingroup group_hsdomainmodel
    48     \ingroup group_hsdomainmodel
    62 
    51 
    63 /*!
    52 /*!
    64     Constructs a new widget host with given \a databaseId and
    53     Constructs a new widget host with given \a databaseId and
    65     \a parent item.
    54     \a parent item.
    66 */
    55 */
    67 HsWidgetHost::HsWidgetHost(int databaseId, QGraphicsItem *parent)
    56 HsWidgetHost::HsWidgetHost(int databaseId, QObject *parent)
    68   : HbWidget(parent),
    57   : QObject(parent),
       
    58     mVisual(new HsWidgetHostVisual),
    69     mDatabaseId(databaseId),
    59     mDatabaseId(databaseId),
    70     mStateMachine(0),
    60     mStateMachine(0),
    71     mWidget(0),
    61     mWidget(0),
    72     mPage(0),
    62     mPage(0),
    73     mComponent(0),
    63     mComponent(0),
    74     mIsFinishing(false)
    64     mIsFinishing(false)
    75 {
    65 {
    76     setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
    77     setFlag(QGraphicsItem::ItemHasNoContents);
       
    78 
       
    79     grabGesture(Qt::TapGesture);
       
    80     grabGesture(Qt::TapAndHoldGesture);
       
    81     grabGesture(Qt::PanGesture);
       
    82     grabGesture(Qt::PinchGesture);
       
    83     grabGesture(Qt::SwipeGesture);
       
    84     grabGesture(Qt::CustomGesture);
       
    85     
       
    86     setupTouchArea();
       
    87     setupEffects();
       
    88     setupStates();
    66     setupStates();
       
    67     mVisual->setVisualModel(this);
    89 }
    68 }
    90 
    69 
    91 /*!
    70 /*!
    92     Destructor.
    71     Destructor.
    93 */
    72 */
    94 HsWidgetHost::~HsWidgetHost()
    73 HsWidgetHost::~HsWidgetHost()
    95 {
    74 {
       
    75     delete mVisual;
    96 }
    76 }
    97 
    77 
    98 /*!
    78 /*!
    99     Creates a new widget host instance based on the give
    79     Creates a new widget host instance based on the give
   100     \a widgetData and \a preferences. Returns the created
    80     \a widgetData and \a preferences. Returns the created
   143     } else {
   123     } else {
   144         return false;
   124         return false;
   145     }
   125     }
   146 
   126 
   147     mPage = page;
   127     mPage = page;
       
   128     
   148     return true;
   129     return true;
   149 }
   130 }
   150  
   131  
   151 /*!
   132 /*!
   152     Returns the containing page for this widget. Returns 0 
   133     Returns the containing page for this widget. Returns 0 
   161     Loads presentation based on the current orientation.
   142     Loads presentation based on the current orientation.
   162     Returns true on success, otherwise returns false.
   143     Returns true on success, otherwise returns false.
   163 */
   144 */
   164 bool HsWidgetHost::loadPresentation()
   145 bool HsWidgetHost::loadPresentation()
   165 {
   146 {
   166     return loadPresentation(HsScene::orientation());
   147     return loadPresentation(HsGui::instance()->orientation());
   167 }
   148 }
   168 
   149 
   169 /*!
   150 /*!
   170     Loads presentation based on the given \a orientation.
   151     Loads presentation based on the given \a orientation.
   171     Returns true on success, otherwise returns false.
   152     Returns true on success, otherwise returns false.
   178     data.orientation = orientation;
   159     data.orientation = orientation;
   179     data.widgetId = mDatabaseId;
   160     data.widgetId = mDatabaseId;
   180     if (!db->widgetPresentation(data)) {
   161     if (!db->widgetPresentation(data)) {
   181         return false;
   162         return false;
   182     }
   163     }
   183     setPos(data.x, data.y);
   164     mVisual->setPos(data.x, data.y);
   184     setZValue(data.zValue);
   165     mVisual->setZValue(data.zValue);
   185     return true;
   166     return true;
   186 }
   167 }
   187 
   168 
   188 /*!
   169 /*!
   189     Saves the current presentation.
   170     Saves the current presentation.
   190     Returns true on success, otherwise returns false.
   171     Returns true on success, otherwise returns false.
   191 */
   172 */
   192 bool HsWidgetHost::savePresentation()
   173 bool HsWidgetHost::savePresentation()
   193 {
   174 {
   194     return savePresentation(HsScene::orientation());
   175     return savePresentation(HsGui::instance()->orientation());
   195 }
   176 }
   196 
   177 
   197 /*!
   178 /*!
   198     Saves the current presentation for the given \a orientation.
   179     Saves the current presentation for the given \a orientation.
   199     Returns true on success, otherwise returns false.
   180     Returns true on success, otherwise returns false.
   202 {
   183 {
   203     HsDatabase *db = HsDatabase::instance();
   184     HsDatabase *db = HsDatabase::instance();
   204         
   185         
   205     HsWidgetPresentationData data;
   186     HsWidgetPresentationData data;
   206     data.orientation = orientation;
   187     data.orientation = orientation;
   207     data.setPos(pos());
   188     data.setPos(mVisual->pos());
   208     data.zValue = zValue();
   189     data.zValue = mVisual->zValue();
   209     data.widgetId = mDatabaseId;
   190     data.widgetId = mDatabaseId;
   210     return db->setWidgetPresentation(data);
   191     return db->setWidgetPresentation(data);
   211 }
   192 }
   212 
   193 
   213 /*!
   194 /*!
   243 {
   224 {
   244     HsDatabase *db = HsDatabase::instance();
   225     HsDatabase *db = HsDatabase::instance();
   245     return db->deleteWidgetPresentation(mDatabaseId, orientation);
   226     return db->deleteWidgetPresentation(mDatabaseId, orientation);
   246 }
   227 }
   247 
   228 
   248 /*!
   229 HsWidgetHostVisual *HsWidgetHost::visual() const
   249     Reimplemented from QGraphicsItem. Returns the shape of the
   230 {
   250     this widget host. The shape is computed based on the contained
   231     return mVisual;
   251     widget.
       
   252 */
       
   253 QPainterPath HsWidgetHost::shape() const
       
   254 {
       
   255     QPainterPath path;
       
   256 
       
   257     if (mWidget) {
       
   258         QRectF currRect = rect();
       
   259         path = mWidget->shape();
       
   260 
       
   261         QRectF pathRect(path.boundingRect());
       
   262 
       
   263         if (pathRect.width() > currRect.width()
       
   264             || pathRect.height() > currRect.height()) {
       
   265             QPainterPath newPath(currRect.topLeft());
       
   266             newPath.addRect(currRect);
       
   267             path = path.intersected(newPath);
       
   268         }
       
   269     }
       
   270     return path;
       
   271 }
   232 }
   272 
   233 
   273 /*!
   234 /*!
   274     \fn HsWidgetHost::event_startAndShow()
   235     \fn HsWidgetHost::event_startAndShow()
   275     Initiates a transition to show state.
   236     Initiates a transition to show state.
   325     \fn HsWidgetHost::faulted()
   286     \fn HsWidgetHost::faulted()
   326     Notifies the home screen framework that this widget
   287     Notifies the home screen framework that this widget
   327     host has moved to faulted state.
   288     host has moved to faulted state.
   328 */
   289 */
   329 
   290 
   330 /*!
   291 
   331     \fn HsWidgetHost::resized()
       
   332     Notifies the home screen framework that this widget
       
   333     host has resized itself.
       
   334 */
       
   335 
   292 
   336 /*!
   293 /*!
   337     \fn HsWidgetHost::available()
   294     \fn HsWidgetHost::available()
   338     Notifies the home screen framework that this widget
   295     Notifies the home screen framework that this widget
   339     is now available.
   296     is now available.
   422 /*!
   379 /*!
   423     Starts the drag effect.
   380     Starts the drag effect.
   424 */
   381 */
   425 void HsWidgetHost::startDragEffect()
   382 void HsWidgetHost::startDragEffect()
   426 {
   383 {
   427     /* TODO: Uncomment after the Qt bug has been fixed.
   384    mVisual->startDragEffect();
   428     QGraphicsDropShadowEffect *effect =
       
   429         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
       
   430     */
       
   431     HbInstantFeedback::play(HbFeedback::ItemPick);
       
   432 
       
   433     setTransformOriginPoint(rect().center());
       
   434 
       
   435     QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup();
       
   436 
       
   437     QPropertyAnimation *animation = new QPropertyAnimation(this, "scale");
       
   438     animation->setDuration(HSCONFIGURATION_GET(widgetDragEffectDuration));
       
   439     animation->setEndValue(1.1);
       
   440     animationGroup->addAnimation(animation);
       
   441 
       
   442     /* TODO: Uncomment after the Qt bug has been fixed.
       
   443     animation = new QPropertyAnimation(effect, "offset");
       
   444     animation->setDuration(200);
       
   445     animation->setEndValue(QPointF(8 ,8));
       
   446     animationGroup->addAnimation(animation);
       
   447     */
       
   448 
       
   449     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
       
   450 }
   385 }
   451 
   386 
   452 /*!
   387 /*!
   453     Starts the drop effect.
   388     Starts the drop effect.
   454 */
   389 */
   455 void HsWidgetHost::startDropEffect()
   390 void HsWidgetHost::startDropEffect()
   456 {
   391 {
   457     /* TODO: Uncomment after the Qt bug has been fixed.
   392     mVisual->startDropEffect();
   458     QGraphicsDropShadowEffect *effect =
       
   459         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
       
   460     */
       
   461     HbInstantFeedback::play(HbFeedback::ItemDrop);
       
   462 
       
   463     QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup;
       
   464 
       
   465     QPropertyAnimation *animation = new QPropertyAnimation(this, "scale");
       
   466     animation->setDuration(HSCONFIGURATION_GET(widgetDropEffectDuration));
       
   467     animation->setEndValue(1);
       
   468     animationGroup->addAnimation(animation);
       
   469 
       
   470     /* TODO: Uncomment after the Qt bug has been fixed.
       
   471     animation = new QPropertyAnimation(effect, "offset");
       
   472     animation->setDuration(200);
       
   473     animation->setEndValue(QPointF(3, 3));
       
   474     animationGroup->addAnimation(animation);
       
   475     */
       
   476 
       
   477     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
       
   478 }
       
   479 
       
   480 /*!
       
   481     Reimplemented from QObject for monitoring changes in 
       
   482     contained widget's size.
       
   483 */
       
   484 bool HsWidgetHost::eventFilter(QObject *watched, QEvent *event)
       
   485 {
       
   486     if (event->type() == QEvent::GraphicsSceneResize ) {
       
   487         QGraphicsSceneResizeEvent *resizeEvent = 
       
   488             static_cast<QGraphicsSceneResizeEvent *>(event);
       
   489         setNewSize(resizeEvent->newSize());
       
   490         emit resized();
       
   491     }
       
   492     return HbWidget::eventFilter(watched, event);
       
   493 }
       
   494 
       
   495 /*!
       
   496     Reimplemented from HbWidget for pan gesture handling.
       
   497 */
       
   498 void HsWidgetHost::gestureEvent(QGestureEvent *event)
       
   499 {
       
   500     HsScene *scene = HsScene::instance();    
       
   501     QGesture *gesture = event->gesture(Qt::PanGesture);
       
   502     if (gesture) {
       
   503         switch (gesture->state()) {
       
   504             case Qt::GestureStarted:
       
   505                 grabMouse();
       
   506                 emit scene->pagePanStarted(event);
       
   507                 break;
       
   508             case Qt::GestureUpdated:
       
   509                 emit scene->pagePanUpdated(event);
       
   510                 break;
       
   511             case Qt::GestureFinished:
       
   512             case Qt::GestureCanceled:
       
   513                 ungrabMouse();
       
   514                 emit scene->pagePanFinished(event);
       
   515                 break;
       
   516             default:
       
   517                 break;
       
   518         }
       
   519     }
       
   520 }
       
   521 
       
   522 /*!
       
   523     \fn HsWidgetHost::mousePressEvent(QGraphicsSceneMouseEvent *)
       
   524     Reimplemented from QGraphicsItem for eating all mouse presses.
       
   525 */
       
   526 
       
   527 /*!
       
   528     Configures the touch are for this widget host.
       
   529 */
       
   530 void HsWidgetHost::setupTouchArea()
       
   531 {
       
   532     mTouchArea = new HsWidgetTouchArea(this);
       
   533     mTouchArea->setZValue(1);
       
   534 }
       
   535 
       
   536 /*!
       
   537     Configures the effects for this widget host.
       
   538 */
       
   539 void HsWidgetHost::setupEffects()
       
   540 {
       
   541     /* TODO: Uncomment after the Qt bug has been fixed.
       
   542     QGraphicsDropShadowEffect *effect =
       
   543         new QGraphicsDropShadowEffect(this);
       
   544     effect->setColor(QColor(0, 0, 0, 150));
       
   545     effect->setBlurRadius(5);
       
   546     effect->setOffset(3);
       
   547     setGraphicsEffect(effect);
       
   548     */
       
   549 }
   393 }
   550 
   394 
   551 /*!
   395 /*!
   552     Configures the state machine for this widget host.
   396     Configures the state machine for this widget host.
   553 */
   397 */
   679     int index = object->indexOfSignal(
   523     int index = object->indexOfSignal(
   680         QMetaObject::normalizedSignature(signature));
   524         QMetaObject::normalizedSignature(signature));
   681     return index >= 0;
   525     return index >= 0;
   682 }
   526 }
   683 
   527 
   684 /*!
       
   685     Resizes this widget host to the given \a size.
       
   686 */
       
   687 void HsWidgetHost::setNewSize(const QSizeF &size)
       
   688 {
       
   689     mTouchArea->resize(size);
       
   690     resize(size);
       
   691     setPreferredSize(size);
       
   692 }
       
   693 
   528 
   694 /*!
   529 /*!
   695     Assigns preferences for the contained widget.
   530     Assigns preferences for the contained widget.
   696     Returns true on success, otherwise returns false.
   531     Returns true on success, otherwise returns false.
   697 */
   532 */
   750     Loads the contained widget from a widget plugin and 
   585     Loads the contained widget from a widget plugin and 
   751     connects to it's meta interface.
   586     connects to it's meta interface.
   752 */
   587 */
   753 void HsWidgetHost::action_load()
   588 void HsWidgetHost::action_load()
   754 {
   589 {
   755     QServiceManager manager;
   590     mWidget = HsHostedWidgetFactory::instance()->createWidget(mComponent->uri());
   756     QServiceFilter filter("com.nokia.symbian.IHomeScreenWidget");
   591     if (!mWidget) {
   757     filter.setServiceName(mComponent->uri());
       
   758     QList<QServiceInterfaceDescriptor> interfaces = manager.findInterfaces(filter);
       
   759     if (interfaces.isEmpty()) {
       
   760         emit event_faulted();
   592         emit event_faulted();
   761         return;
   593         return;
   762     }
   594     }
   763 
   595     // must have fuctions
   764     QObject *widgetObject = manager.loadInterface(interfaces.first());
   596     if (!setMethod("onShow()", mOnShowMethod) || 
   765     mWidget = qobject_cast<QGraphicsWidget *>(widgetObject);
       
   766 
       
   767     if (!mWidget ||
       
   768         !setMethod("onShow()", mOnShowMethod) ||
       
   769         !setMethod("onHide()", mOnHideMethod)) {
   597         !setMethod("onHide()", mOnHideMethod)) {
       
   598         delete mWidget;
   770         mWidget = 0;
   599         mWidget = 0;
   771         delete widgetObject;
       
   772         emit event_faulted();
   600         emit event_faulted();
   773         return;
   601         return;
   774     }
   602     }
       
   603     
       
   604     mVisual->setWidget(mWidget);
   775 
   605 
   776     setMethod("onInitialize()", mOnInitializeMethod);
   606     setMethod("onInitialize()", mOnInitializeMethod);
   777     setMethod("onUninitialize()", mOnUninitializeMethod);
   607     setMethod("onUninitialize()", mOnUninitializeMethod);
   778     
   608     
   779     setProperty("isOnline", mIsOnlineProperty);
   609     setProperty("isOnline", mIsOnlineProperty);
   790     if (hasSignal("error()")) {
   620     if (hasSignal("error()")) {
   791         connect(mWidget, SIGNAL(error()),
   621         connect(mWidget, SIGNAL(error()),
   792             SLOT(onError()), Qt::QueuedConnection);
   622             SLOT(onError()), Qt::QueuedConnection);
   793     }
   623     }
   794 
   624 
   795     mWidget->installEventFilter(this);
       
   796 
       
   797     setMinimumSize(HSCONFIGURATION_GET(minimumWidgetSizeInPixels));
       
   798     setMaximumSize(HSCONFIGURATION_GET(maximumWidgetSizeInPixels));
       
   799     
       
   800     loadPresentation();
   625     loadPresentation();
   801 
   626    
   802     mWidget->setParentItem(this);
       
   803 
       
   804     setNewSize(mWidget->size());
       
   805 
       
   806     QString objName(mComponent->uri());
   627     QString objName(mComponent->uri());
   807     objName.append(":");
   628     objName.append(":");
   808     objName.append(QString::number(mDatabaseId));
   629     objName.append(QString::number(mDatabaseId));
   809     setObjectName(objName);
   630     mVisual->setObjectName(objName);
   810 }
   631 }
   811 
   632 
   812 /*!
   633 /*!
   813     Unloads the contained widget. 
   634     Unloads the contained widget. 
   814 */
   635 */
   815 void HsWidgetHost::action_unload()
   636 void HsWidgetHost::action_unload()
   816 {
   637 {
       
   638     mVisual->setWidget(0);
   817     delete mWidget;
   639     delete mWidget;
   818     mWidget = 0;
   640     mWidget = 0;
   819 		// This is needed because QServicePluginCleanup is 
   641 		// This is needed because QServicePluginCleanup is 
   820     // deleted asynchronously via the eventloop (deleteLater). 
   642     // deleted asynchronously via the eventloop (deleteLater). 
   821     // Here we want the plugin to unload synchronously.
   643     // Here we want the plugin to unload synchronously.