src/hbcore/gui/hbpopup.cpp
changeset 1 f7ac710697a9
parent 0 16d8024aca5e
child 2 06ff229162e9
equal deleted inserted replaced
0:16d8024aca5e 1:f7ac710697a9
    30 #include "hbdeviceprofile.h"
    30 #include "hbdeviceprofile.h"
    31 #include "hbevent.h"
    31 #include "hbevent.h"
    32 #include "hbgraphicsscene.h"
    32 #include "hbgraphicsscene.h"
    33 #include "hbgraphicsscene_p.h"
    33 #include "hbgraphicsscene_p.h"
    34 #include "hbtooltip.h"
    34 #include "hbtooltip.h"
       
    35 #include "hbglobal_p.h"
    35 #include <QTimer>
    36 #include <QTimer>
    36 #include <QGraphicsSceneMouseEvent>
    37 #include <QGraphicsSceneMouseEvent>
    37 #include <QShowEvent>
    38 #include <QShowEvent>
    38 #include <QHideEvent>
    39 #include <QHideEvent>
    39 #include <QEventLoop>
    40 #include <QEventLoop>
    40 #include <QPointer>
    41 #include <QPointer>
       
    42 #include <QDebug>
       
    43 #include <QBitmap>
    41 #include <QApplication> // krazy:exclude=qclasses
    44 #include <QApplication> // krazy:exclude=qclasses
    42 
    45 
    43 #include <hbwidgetfeedback.h>
    46 #include <hbwidgetfeedback.h>
    44 
    47 
    45 #ifdef HB_EFFECTS
    48 #ifdef HB_EFFECTS
    46 #include "hbeffectinternal_p.h"
    49 #include "hbeffectinternal_p.h"
    47 bool HbPopupPrivate::popupEffectsLoaded = false;
    50 bool HbPopupPrivate::popupEffectsLoaded = false;
    48 #endif
    51 #endif
    49 /*!
    52 /*!
    50     @stable
    53     @beta
    51     @hbcore
    54     @hbcore
    52     \class HbPopup
    55     \class HbPopup
    53     \brief HbPopup is a base class for different popup notes in Hb library.
    56     \brief HbPopup is a base class for different popup notes in Hb library.
    54 
    57 
    55     \image html hbpopup.png A popup with a header widget, a list as a content widget, and two
    58     \image html hbpopup.png A popup with a header widget, a list as a content widget, and two
   279     backgroundItem(0),
   282     backgroundItem(0),
   280     mousePressLocation(None),
   283     mousePressLocation(None),
   281     frameType(HbPopup::Strong),
   284     frameType(HbPopup::Strong),
   282     preferredPosSet(false),
   285     preferredPosSet(false),
   283     mStartEffect(false),
   286     mStartEffect(false),
       
   287     mScreenMargin(0.0),
       
   288     mPath(0),
   284     timeoutTimerInstance(0)
   289     timeoutTimerInstance(0)
   285 {
   290 {
   286 }
   291 }
   287 
   292 
   288 HbPopupPrivate::~HbPopupPrivate()
   293 HbPopupPrivate::~HbPopupPrivate()
   302     // Only for popup without parent
   307     // Only for popup without parent
   303     if (!q->parentItem()) {
   308     if (!q->parentItem()) {
   304         backgroundItem = new HbPopupBackGround(q);
   309         backgroundItem = new HbPopupBackGround(q);
   305         backgroundItem->setVisible(false);
   310         backgroundItem->setVisible(false);
   306 
   311 
   307         // Popup is invisible by default (explicit show or exec call is required)
   312         // Popup is invisible by default (explicit show or open call is required)
   308         q->setVisible(false);
   313         q->setVisible(false);
   309     }
   314     }
   310     hidingInProgress = false;   
   315     hidingInProgress = false;   
       
   316 
       
   317     q->setFlag(QGraphicsItem::ItemClipsToShape);
       
   318     q->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
   319 
       
   320 #if QT_VERSION > 0x040602
       
   321     q->grabGesture(Qt::TapGesture);
       
   322     q->grabGesture(Qt::TapAndHoldGesture);
       
   323     q->grabGesture(Qt::PanGesture);
       
   324     q->grabGesture(Qt::SwipeGesture);
       
   325     q->grabGesture(Qt::PinchGesture);
       
   326 #endif
       
   327 
   311 }
   328 }
   312 
   329 
   313 /*
   330 /*
   314 *  *********** Begin of private features ***********
   331 *  *********** Begin of private features ***********
   315 */
   332 */
   394     }
   411     }
   395 
   412 
   396     return timeoutTimerInstance;
   413     return timeoutTimerInstance;
   397 }
   414 }
   398 
   415 
   399 void HbPopupPrivate::handleKeyEvent(QKeyEvent *event)
       
   400 {
       
   401     Q_Q(HbPopup);
       
   402     event->accept();
       
   403 
       
   404     // Any key event dismisses the popup if dismissPolicy includes TapInside flag
       
   405     if (dismissPolicy & HbPopup::TapInside && !q->parentItem()) {
       
   406         q->close();
       
   407     }
       
   408 }
       
   409 
       
   410 //returns true if popup has been added to scene here.
   416 //returns true if popup has been added to scene here.
   411 bool HbPopupPrivate::addPopupToScene()
   417 bool HbPopupPrivate::addPopupToScene()
   412 {
   418 {
   413     Q_Q(HbPopup);
   419     Q_Q(HbPopup);
   414     bool popupAdded(false);
   420     bool popupAdded(false);
   415     if (!q->parentItem()) {
   421     if (!q->parentItem()) {
   416         if (!q->scene() && !HbInstance::instance()->allMainWindows().isEmpty()) {
   422         if (!q->scene() && !HbInstance::instance()->allMainWindows().isEmpty()) {            
   417             HbInstance::instance()->allMainWindows().at(0)->scene()->addItem(q);
   423             HbInstance::instance()->allMainWindows().at(0)->scene()->addItem(q);           
   418             popupAdded = true;
   424             popupAdded = true;
   419             if (backgroundItem) {
   425             if (backgroundItem) {
   420                 q->scene()->addItem(backgroundItem);
   426                 q->scene()->addItem(backgroundItem);
   421             }
   427             }
   422         } else if (q->scene() && backgroundItem && backgroundItem->scene() != q->scene()) {
   428         } else if (q->scene() && backgroundItem && backgroundItem->scene() != q->scene()) {
   521     if(backgroundItem) {
   527     if(backgroundItem) {
   522         // When the popup is modal background item must receive focus
   528         // When the popup is modal background item must receive focus
   523         // events to be able to prevent last focus item losing its
   529         // events to be able to prevent last focus item losing its
   524         // focus
   530         // focus
   525         backgroundItem->setFlag(QGraphicsItem::ItemIsFocusable, modal);
   531         backgroundItem->setFlag(QGraphicsItem::ItemIsFocusable, modal);
   526     }
   532         backgroundItem->setFlag(QGraphicsItem::ItemIsPanel, modal);
       
   533         if(modal) {
       
   534             backgroundItem->setPanelModality(QGraphicsItem::PanelModal);
       
   535         } else {
       
   536             backgroundItem->setPanelModality(QGraphicsItem::NonModal);
       
   537         }
       
   538     }
       
   539 }
       
   540 
       
   541 void HbPopupPrivate::calculateShape()
       
   542 {
       
   543     Q_Q(HbPopup);
       
   544     if (mPath)
       
   545         delete mPath;
       
   546     mPath = new QPainterPath();
       
   547 #if 1
       
   548     QPixmap image(QSize(static_cast<int>(q->backgroundItem()->boundingRect().width() + 0.5), 
       
   549 	                    static_cast<int>(q->backgroundItem()->boundingRect().height() + 0.5)));
       
   550     image.fill(Qt::transparent);
       
   551 
       
   552     QPainter imagePainter(&image);
       
   553 
       
   554     q->backgroundItem()->paint(&imagePainter, 0, 0);
       
   555 
       
   556     imagePainter.end();
       
   557 
       
   558     mPath->addRegion(image.mask());
       
   559 #else
       
   560     QRectF rect(-0.5, -0.5, q->boundingRect().width() + 0.5, q->boundingRect().height() + 0.5);
       
   561     mPath->addRoundedRect(rect, 12, 12);
       
   562 #endif
       
   563 
       
   564     mPath->translate(-0.5, -0.5);
   527 }
   565 }
   528 
   566 
   529 /*!
   567 /*!
   530 * Constructs a popup with given  \a parent graphics item.\n
   568 * Constructs a popup with given  \a parent graphics item.\n
   531 * Note: popups with \a parent set as 0 are behaving as real popups.
   569 * Note: popups with \a parent set as 0 are behaving as real popups.
   545 HbPopup::HbPopup(QGraphicsItem *parent) :
   583 HbPopup::HbPopup(QGraphicsItem *parent) :
   546     HbWidget(*new HbPopupPrivate,parent)
   584     HbWidget(*new HbPopupPrivate,parent)
   547 {
   585 {
   548     Q_D(HbPopup);
   586     Q_D(HbPopup);
   549     d->q_ptr = this;
   587     d->q_ptr = this;
   550     d->init();
   588     d->init();    
   551 }
   589 }
   552 
   590 
   553 
   591 
   554 /*!
   592 /*!
   555     \internal
   593     \internal
   557 HbPopup::HbPopup(HbPopupPrivate &dd, QGraphicsItem *parent) :
   595 HbPopup::HbPopup(HbPopupPrivate &dd, QGraphicsItem *parent) :
   558     HbWidget(dd, parent)
   596     HbWidget(dd, parent)
   559 {
   597 {
   560     Q_D(HbPopup);
   598     Q_D(HbPopup);
   561     d->q_ptr = this;
   599     d->q_ptr = this;
   562     d->init();
   600     d->init();    
   563 }
   601 }
   564 /*!
   602 /*!
   565 * Destroys the popup.
   603 * Destroys the popup.
   566 */
   604 */
   567 HbPopup::~HbPopup()
   605 HbPopup::~HbPopup()
   740 * For non modal popups, use show().  
   778 * For non modal popups, use show().  
   741 */
   779 */
   742 void HbPopup::open( QObject *receiver, const char *member )
   780 void HbPopup::open( QObject *receiver, const char *member )
   743 {
   781 {
   744     Q_D(HbPopup);
   782     Q_D(HbPopup);
   745     connect(this, SIGNAL(aboutToClose()), receiver, member);
   783     if (receiver) {
       
   784         connect(this, SIGNAL(aboutToClose()), receiver, member);
       
   785     }
   746     d->receiverToDisconnectOnClose = receiver;
   786     d->receiverToDisconnectOnClose = receiver;
   747     d->memberToDisconnectOnClose = member;
   787     d->memberToDisconnectOnClose = member;
   748 
   788 
   749 #if needed
       
   750     // Ungrab the mouse if it is currently grabbed
       
   751         // todo; currently needed menus to work ok, otherwise:
       
   752         // - quick multiple presses on menuitem causes multiple actions (menu relaunch?)
       
   753         // - closing menu with titlepane needs multiple presses (menu relaunch?)
       
   754         // Ungrab was removed when trying to fix problem when button pressed()-signal
       
   755         // was connected to menu launch. Button did not get anymore mouse release event.
       
   756         if (scene()) {
       
   757             QGraphicsItem *item = scene()->mouseGrabberItem();
       
   758             if (item) {
       
   759                 item->ungrabMouse();
       
   760             }
       
   761         }
       
   762 #endif
       
   763     show();
   789     show();
   764 }
   790 }
   765 
   791 
   766 
   792 
   767 /*!
   793 /*!
   768     \deprecated HbPopup::exec()
   794 \deprecated HbPopup::exec()
   769         is deprecated. Please use HbPopup::show() or
   795        is deprecated. Please use HbPopup::show() or
   770         void HbPopup::open( QObject *receiver, const char *member ) instead.
   796  void HbPopup::open( QObject *receiver, const char *member ) instead.
   771 *
   797 
   772 * Executes the popup synchronously.
   798  Executes the popup synchronously.
   773 * Note: when popup is executed syncronously it is always modal.
   799  Note: when popup is executed syncronously it is always modal.
   774 * This function is deprecated. use \sa open() or \sa show() instead.
   800  This function is deprecated. use \sa open() or \sa show() instead.
   775 */
   801 */
   776 void HbPopup::exec()
   802 void HbPopup::exec()
   777 {
   803 {
   778     //    Q_ASSERT(false);
   804     HB_DEPRECATED("HbPopup::exec is deprecated. Use HbPopup::show() or HbPopup::open() instead!");
   779     Q_D(HbPopup);
   805     Q_D(HbPopup);
   780 
   806 
   781     HbMainWindow* w(mainWindow());
   807     HbMainWindow* w(mainWindow());
   782     if (w) {
   808     if (w) {
   783         disconnect(w, SIGNAL(aboutToChangeOrientation(Qt::Orientation, bool)), this, SLOT(_q_orientationChange(Qt::Orientation, bool)));
   809         disconnect(w, SIGNAL(aboutToChangeOrientation(Qt::Orientation, bool)), this, SLOT(_q_orientationChange(Qt::Orientation, bool)));
   845                 d->aboutToShowSignalGuard = true;
   871                 d->aboutToShowSignalGuard = true;
   846                 emit aboutToShow();
   872                 emit aboutToShow();
   847             }
   873             }
   848             // Note: when visibility changes to "visible" base class implementation needs
   874             // Note: when visibility changes to "visible" base class implementation needs
   849             //       to be called otherwise showEvent() is not called.
   875             //       to be called otherwise showEvent() is not called.
   850             
       
   851         } else {
   876         } else {
   852             d->aboutToShowSignalGuard = false;
   877             d->aboutToShowSignalGuard = false;
   853             if (!d->hidingInProgress) {
   878             if (!d->hidingInProgress) {
   854                 emit aboutToHide();
   879                 emit aboutToHide();
   855             }
   880             }
   932 }
   957 }
   933 
   958 
   934 /*!
   959 /*!
   935     \reimp
   960     \reimp
   936  */
   961  */
   937 void HbPopup::keyPressEvent(QKeyEvent *event)
       
   938 {
       
   939     Q_D(HbPopup);
       
   940     d->handleKeyEvent(event);
       
   941 }
       
   942 
       
   943 /*!
       
   944     \reimp
       
   945  */
       
   946 //
   962 //
   947 // Shows the popup with an animation and starts the timer to dismiss the popup,
   963 // Shows the popup with an animation and starts the timer to dismiss the popup,
   948 // unless it is a permanent popup.
   964 // unless it is a permanent popup.
   949 //
   965 //
   950 void HbPopup::showEvent(QShowEvent *event)
   966 void HbPopup::showEvent(QShowEvent *event)
   965         return;
   981         return;
   966     }
   982     }
   967     if (!parentItem()) {
   983     if (!parentItem()) {
   968         //check if popup needs to be added to scene.This can result in duplciate show event,
   984         //check if popup needs to be added to scene.This can result in duplciate show event,
   969         // if popup is added to scene here.
   985         // if popup is added to scene here.
   970            if(d->addPopupToScene())
   986         if(d->addPopupToScene()) {
   971               d->duplicateShowEvent = true;
   987               d->duplicateShowEvent = true;
   972 
   988         }
   973         // Popup clears closed state
   989         // Popup clears closed state
   974         d->closed = false;
   990         d->closed = false;
   975         if (d->backgroundItem) {
   991         if (d->backgroundItem) {
   976             d->backgroundItem->setVisible(true);
   992             d->backgroundItem->setVisible(true);
   977             d->backgroundItem->setAcceptHoverEvents(isModal());
   993             d->backgroundItem->setAcceptHoverEvents(isModal());
   978             // Let the background be a panel if the popup is one
   994             if (isModal()) {
   979             // However if the popup is not modal we don't want the background
       
   980             // to be a panel. A panel provides contained focus handling
       
   981             if ((flags() & QGraphicsItem::ItemIsPanel) && isModal()) {
       
   982                 d->backgroundItem->setFlag(QGraphicsItem::ItemIsPanel);
   995                 d->backgroundItem->setFlag(QGraphicsItem::ItemIsPanel);
   983             }
   996              }
   984         }
   997         }
   985         if (qobject_cast<HbGraphicsScene *>(scene())) {
   998         if (qobject_cast<HbGraphicsScene *>(scene())) {
   986             qobject_cast<HbGraphicsScene *>(scene())->d_ptr->showPopup(this);
   999             qobject_cast<HbGraphicsScene *>(scene())->d_ptr->showPopup(this);
   987             HbWidgetFeedback::triggered(this, Hb::InstantPopupOpened);
  1000             HbWidgetFeedback::triggered(this, Hb::InstantPopupOpened);
   988         }
  1001         }
  1045 
  1058 
  1046 /*!
  1059 /*!
  1047     \reimp
  1060     \reimp
  1048  */
  1061  */
  1049 void HbPopup::resizeEvent( QGraphicsSceneResizeEvent * event )
  1062 void HbPopup::resizeEvent( QGraphicsSceneResizeEvent * event )
  1050 {
  1063 {    
  1051     HbWidget::resizeEvent(event);
  1064     HbWidget::resizeEvent(event);
  1052     updatePrimitives();
  1065     updatePrimitives();
       
  1066 #if 1
       
  1067     Q_D(HbPopup);
       
  1068     if (d->polished) {
       
  1069         d->calculateShape();
       
  1070     }
       
  1071 #endif
  1053 }
  1072 }
  1054 
  1073 
  1055 /*!
  1074 /*!
  1056     \reimp
  1075     \reimp
  1057  */
  1076  */
  1085 /*!
  1104 /*!
  1086     \reimp
  1105     \reimp
  1087  */
  1106  */
  1088 bool HbPopup::event(QEvent *event)
  1107 bool HbPopup::event(QEvent *event)
  1089 {
  1108 {
  1090     /*Q_D(HbPopup);
  1109 /*    Q_D(HbPopup);
  1091     if (event->type() == QEvent::GraphicsSceneResize) {
  1110     if (event->type() == QEvent::LayoutRequest) {
  1092         //Workaround when showing first time                   
  1111         //Workaround when showing first time                           
  1093         #ifdef HB_EFFECTS
  1112 #ifdef HB_EFFECTS
  1094         if(d->mStartEffect && boundingRect().isValid()) {
  1113         if(d->mStartEffect && boundingRect().isValid()) {
       
  1114             d->mStartEffect = false;
       
  1115             QCoreApplication::sendPostedEvents(this, QEvent::LayoutRequest);
  1095             QRectF extRect(0.0,
  1116             QRectF extRect(0.0,
  1096                            -boundingRect().height(),
  1117                            -boundingRect().height(),
  1097                            boundingRect().width(),
  1118                            boundingRect().width(),
  1098                            0);
  1119                            0);
  1099             HbEffect::start(this, d->effectType, "appear", 0, 0, QVariant(), extRect);
  1120             HbEffect::start(this, d->effectType, "appear", 0, 0, QVariant(), extRect);            
  1100             d->mStartEffect = false;
  1121             qDebug() << "effect start";
  1101         }
  1122         }
  1102             #endif//HB_EFFECTS        
  1123 #endif//HB_EFFECTS
  1103         //workaround ends
  1124         //workaround ends
       
  1125     }
       
  1126     qDebug() << "event: " << event;*/
       
  1127     /*Q_D(HbPopup);
       
  1128     if (event->type() == QEvent::LayoutDirectionChange) {
       
  1129         d->calculateShape();
  1104     }*/
  1130     }*/
  1105     return HbWidget::event(event);
  1131     return HbWidget::event(event);
  1106 }
  1132 }
  1107 
       
  1108 
  1133 
  1109 /*!
  1134 /*!
  1110   Sets preferred position\a position for popup with \a placement
  1135   Sets preferred position\a position for popup with \a placement
  1111   as origin.
  1136   as origin.
  1112 
  1137 
  1123 
  1148 
  1124  */
  1149  */
  1125 
  1150 
  1126 void HbPopup::setPreferredPos( const QPointF& preferredPos,
  1151 void HbPopup::setPreferredPos( const QPointF& preferredPos,
  1127                                HbPopup::Placement placement )
  1152                                HbPopup::Placement placement )
  1128 
       
  1129 {
  1153 {
  1130     Q_D(HbPopup);
  1154     Q_D(HbPopup);
  1131     bool layoutFlag = false;
  1155     bool layoutFlag = false;
  1132     if (d->preferredPos != preferredPos ) {
  1156     if (d->preferredPos != preferredPos ) {
  1133         d->preferredPos = preferredPos;
  1157         d->preferredPos = preferredPos;
  1138         layoutFlag = true;
  1162         layoutFlag = true;
  1139     }
  1163     }
  1140     d->preferredPosSet = true;
  1164     d->preferredPosSet = true;
  1141     //If position updated, informing layoutproxy with layoutrequest
  1165     //If position updated, informing layoutproxy with layoutrequest
  1142     if (layoutFlag) {
  1166     if (layoutFlag) {
  1143         QApplication::postEvent(this, new QEvent(QEvent::LayoutRequest));
  1167         QApplication::sendEvent(this, new QEvent(QEvent::LayoutRequest));
  1144     }
  1168     }
       
  1169 }
       
  1170 
       
  1171 QPainterPath HbPopup::shape() const
       
  1172 {    
       
  1173 #if 1
       
  1174     Q_D(const HbPopup);    
       
  1175     if (backgroundItem() && d->mPath) {
       
  1176         return *d->mPath;
       
  1177     } else {
       
  1178         return HbWidget::shape();
       
  1179     }
       
  1180 #else
       
  1181     return HbWidget::shape();
       
  1182 #endif
  1145 }
  1183 }
  1146 
  1184 
  1147 #include "moc_hbpopup.cpp"
  1185 #include "moc_hbpopup.cpp"