src/hbcore/gui/hbtoolbar.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbtoolbar.h"
       
    27 #include "hbtoolbar_p.h"
       
    28 #include "hbaction.h"
       
    29 #include "hbtoolbutton.h"
       
    30 #include "hbtoolbutton_p.h"
       
    31 #include "hbapplication.h"
       
    32 #include "hbnamespace_p.h"
       
    33 #include "hbtoolbarextension.h"
       
    34 #include "hbtoolbarextension_p.h"
       
    35 #include "hbwidget_p.h"
       
    36 #include "hbinstance.h"
       
    37 #include "hbactionmanager_p.h"
       
    38 #include "hbmainwindow_p.h"
       
    39 #include "hbcolorscheme.h"
       
    40 
       
    41 #include <hbwidgetfeedback.h>
       
    42 
       
    43 #include <QGraphicsLinearLayout>
       
    44 #include <QGraphicsSceneResizeEvent>
       
    45 #include <QWidget> // for QWIDGETSIZE_MAX
       
    46 #include <QActionEvent>
       
    47 #include <QDebug>
       
    48 #include <QGesture>
       
    49 
       
    50 #ifdef HB_EFFECTS
       
    51 #include "hbeffectinternal_p.h"
       
    52 #define HB_TOOLBAR_ITEM_TYPE "HB_TOOLBAR"
       
    53 #endif
       
    54 
       
    55 /*!
       
    56     @stable
       
    57     @hbcore
       
    58     \class HbToolBar
       
    59     \brief HbToolBar is a toolbar decorator.
       
    60 
       
    61     The HbToolBar class represents an HbView toolbar. It provides the interface for adding actions
       
    62     to the toolbar.
       
    63     Toolbar actions are added using one of the addAction() methods.
       
    64     Calling addAction() adds an HbToolButton to the toolbar and triggers the action when the button
       
    65     is pressed. The image and text specified with the action are applied to the toolbar button.
       
    66 
       
    67     HbToolBar also provides methods for adding pop-up toolbar extensions, represented by
       
    68     HbToolBarExtension objects.
       
    69 
       
    70     Example usage:
       
    71     \dontinclude ultimatecodesnippet/ultimatecodesnippet.cpp
       
    72     \skip Start of snippet 1
       
    73     \until End of snippet 1
       
    74 
       
    75 */
       
    76 
       
    77 /*!
       
    78     \reimp
       
    79     \fn int HbToolBar::type() const
       
    80  */
       
    81 
       
    82 // ======== MEMBER FUNCTIONS ========
       
    83 
       
    84 /*!
       
    85     Constructs a tool bar with \a parent.
       
    86 */
       
    87 
       
    88 HbToolBar::HbToolBar( QGraphicsItem *parent )
       
    89     : HbWidget(*new HbToolBarPrivate, parent)
       
    90 {
       
    91     Q_D(HbToolBar);
       
    92     d->q_ptr = this;
       
    93     d->init();
       
    94 }
       
    95 
       
    96 /*!
       
    97     Protected constructor.
       
    98 */
       
    99 HbToolBar::HbToolBar( HbToolBarPrivate &dd, QGraphicsItem *parent )
       
   100     : HbWidget(dd, parent)
       
   101 {
       
   102     Q_D(HbToolBar);
       
   103     d->q_ptr = this;
       
   104     d->init();
       
   105 }
       
   106 
       
   107 /*!
       
   108     Destructor
       
   109  */
       
   110 HbToolBar::~HbToolBar()
       
   111 {    
       
   112     if (!scene() || !scene()->property("destructed").isValid()) {
       
   113         foreach (QAction *action, actions()) {// krazy:exclude=qclasses
       
   114             HbAction* hbAction = qobject_cast<HbAction *>(action);
       
   115             if (hbAction){
       
   116                 if (hbAction->toolBarExtension()){
       
   117                     hbAction->toolBarExtension()->deleteLater();
       
   118                 }
       
   119                 hbAction->setToolBarExtension(0);
       
   120             }
       
   121         }
       
   122     }
       
   123 }
       
   124 
       
   125 /*!
       
   126     \overload
       
   127 
       
   128     Creates a new action with the given \a text. This action is added to
       
   129     the end of the toolbar.
       
   130 */
       
   131 HbAction *HbToolBar::addAction( const QString &text )
       
   132 {
       
   133     HbAction *action = new HbAction(text, this);
       
   134     addAction(action);
       
   135     return action;
       
   136 }
       
   137 
       
   138 /*!
       
   139     \overload
       
   140 
       
   141     Creates a new action with the given \a icon and \a text. This
       
   142     action is added to the end of the toolbar.
       
   143 */
       
   144 HbAction *HbToolBar::addAction( const HbIcon &icon, const QString &text )
       
   145 {
       
   146     HbAction *action = new HbAction(icon, text, this);
       
   147     addAction(action);
       
   148     return action;
       
   149 }
       
   150 
       
   151 /*!
       
   152     \overload
       
   153 
       
   154     Creates a new action with the given \a text. This action is added to
       
   155     the end of the toolbar. The action's \link HbAction::triggered()
       
   156     triggered()\endlink signal is connected to \a member in \a
       
   157     receiver.
       
   158 */
       
   159 HbAction *HbToolBar::addAction( const QString &text, const QObject *receiver, const char *member )
       
   160 {
       
   161     HbAction *action = new HbAction(text, this);
       
   162     QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
       
   163     addAction(action);
       
   164     return action;
       
   165 }
       
   166 
       
   167 /*!
       
   168     \overload
       
   169 
       
   170     Creates a new action with the icon \a icon and text \a text. This
       
   171     action is added to the end of the toolbar. The action's \link
       
   172     HbAction::triggered() triggered()\endlink signal is connected to \a
       
   173     member in \a receiver.
       
   174 */
       
   175 HbAction *HbToolBar::addAction( const HbIcon &icon, const QString &text, const QObject *receiver, const char *member )
       
   176 {
       
   177     HbAction *action = new HbAction(icon, text, this);
       
   178     QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
       
   179     addAction(action);
       
   180     return action;
       
   181 }
       
   182 
       
   183 /*!
       
   184     This convenience function adds the \a extension as an extension popup
       
   185     to the toolbar. Returns the HbAction triggering the \a extension.
       
   186 */
       
   187 HbAction *HbToolBar::addExtension( HbToolBarExtension *extension )
       
   188 {
       
   189     return insertExtension(0, extension);
       
   190 }
       
   191 
       
   192 /*!
       
   193     This convenience function inserts the \a extension as an extension popup
       
   194     before the action \a before.
       
   195 
       
   196     It appends the action if \a before is 0 or \a before is not a valid
       
   197     action for this widget.
       
   198 
       
   199     Returns the HbAction triggering the \a extension.
       
   200 */
       
   201 HbAction *HbToolBar::insertExtension( HbAction *before, HbToolBarExtension *extension )
       
   202 {    
       
   203     Q_D(HbToolBar);
       
   204 
       
   205     d->initToolBarExtension(extension);
       
   206 
       
   207     insertAction(before, extension->extensionAction());
       
   208     return extension->extensionAction();
       
   209 }
       
   210 
       
   211 /*! @beta
       
   212     \brief  Returns the orientation of the tool bar.
       
   213 
       
   214     \sa setOrientation
       
   215  */
       
   216 Qt::Orientation HbToolBar::orientation() const
       
   217 {
       
   218     Q_D(const HbToolBar);
       
   219     return d->mOrientation;
       
   220 }
       
   221 
       
   222 /*! @beta
       
   223     Sets the \a orientation of the tool bar.
       
   224 
       
   225     \sa orientation
       
   226  */
       
   227 void HbToolBar::setOrientation( Qt::Orientation orientation )
       
   228 {
       
   229     Q_D(HbToolBar);
       
   230 
       
   231     d->setOrientation ( orientation );
       
   232     d->minimumToolButtonSize = QSizeF();
       
   233 }
       
   234 
       
   235 /*!
       
   236     \deprecated HbToolBar::unsetOrientation()is deprecated.
       
   237  */
       
   238 void HbToolBar::unsetOrientation()
       
   239 {
       
   240     //Q_D(HbToolBar);
       
   241 
       
   242 }
       
   243 
       
   244 /*!
       
   245     Emits areaChanged() whenever the tool bar's visibility or position changes.
       
   246 */
       
   247 QVariant HbToolBar::itemChange( GraphicsItemChange change, const QVariant &value )
       
   248 {
       
   249     Q_D(HbToolBar);
       
   250     QVariant result = HbWidget::itemChange(change, value);
       
   251 
       
   252     switch (change) {
       
   253     case ItemVisibleChange:
       
   254         if (d->mOrientationEffectsRunning)
       
   255             return result;
       
   256         if (value.toBool()) {
       
   257             if (d->mDoLayout && d->mDoLayoutPending) {
       
   258                 d->doLayout();
       
   259             }
       
   260             if (d->emitVisibilityChangeSignal && value.toBool()) {
       
   261                 QMetaObject::invokeMethod(&d->core, "visibilityChanged", Qt::QueuedConnection);
       
   262                 d->emitVisibilityChangeSignal = false;
       
   263             }
       
   264             if (!d->mDialogToolBar) {
       
   265                 d->doLazyInit();
       
   266                 d->delayedStartEffects = d->mDoLayoutPending && !d->mSuppressNextAppearEffect;
       
   267                 if (!d->delayedStartEffects && d->hasEffects && !d->mSuppressNextAppearEffect) {
       
   268                     d->startAppearEffect();
       
   269                 }
       
   270                 d->mSuppressNextAppearEffect = false;
       
   271                 d->delayedHide = d->hasEffects;
       
   272             }
       
   273         } else {
       
   274             if (d->mVisibleToolButtons.count()){
       
   275                 d->emitVisibilityChangeSignal = true;
       
   276                 QMetaObject::invokeMethod(&d->core, "visibilityChanged", Qt::QueuedConnection);
       
   277              }
       
   278             if(d->moreExtension && d->moreExtension->isVisible()){
       
   279                d->moreExtension->setVisible(false);
       
   280             }
       
   281             if (d->delayedHide && d->hasEffects) { // about to hide and we wanna delay hiding
       
   282                 if (!d->hidingInProgress) { // Prevent reentrance
       
   283                     d->hidingInProgress = true;
       
   284                     d->startDisappearEffect();
       
   285                 }
       
   286             }
       
   287             if (d->delayedHide) {
       
   288                 return true;
       
   289             } else {
       
   290                 d->delayedHide = d->hasEffects;
       
   291                 d->hidingInProgress = false;
       
   292 #ifdef HB_EFFECTS
       
   293                         HbEffect::cancel(this, QString(), true);
       
   294 #endif
       
   295             }
       
   296         }
       
   297     break;
       
   298         default:
       
   299             break;
       
   300     }
       
   301     return result;
       
   302 }
       
   303 
       
   304 /*!
       
   305     Reimplemented from QGraphicsWidget::changeEvent().
       
   306  */
       
   307 void HbToolBar::changeEvent( QEvent *event )
       
   308 {
       
   309     Q_D(HbToolBar);
       
   310     if (event->type() == QEvent::LayoutDirectionChange) {
       
   311         d->updateToolBarExtensions();
       
   312         d->updateButtonsLayoutDirection();
       
   313     }
       
   314 
       
   315     QGraphicsWidget::changeEvent(event);
       
   316 }
       
   317 
       
   318 /*!
       
   319     Reimplemented from QGraphicsWidget::resizeEvent().
       
   320  */
       
   321 void HbToolBar::resizeEvent(QGraphicsSceneResizeEvent *event)
       
   322 {
       
   323     Q_D(HbToolBar);
       
   324     HbWidget::resizeEvent(event);
       
   325     if (isVisible() && d->mDoLayout) {
       
   326         d->updateToolBarForSizeChange();
       
   327     }
       
   328 }
       
   329 
       
   330 /*!
       
   331     \reimp
       
   332  */
       
   333 void HbToolBar::hideEvent(QHideEvent *event)
       
   334 {
       
   335     Q_D(HbToolBar);
       
   336     if (d->mPressedDownButton && d->mPressedDownButton->isDown()) {
       
   337         d->mPressedDownButton->setDown(false);
       
   338         d->mPressedDownButton = 0;
       
   339         d->mPreviouslyPressedDownButton = d->mPressedDownButton;
       
   340     }
       
   341     HbWidget::hideEvent(event);
       
   342 }
       
   343 
       
   344 /*!
       
   345     \reimp
       
   346  */
       
   347 bool HbToolBar::event(QEvent *event)
       
   348 {
       
   349     Q_D(HbToolBar);   
       
   350     switch( event->type() ) {        
       
   351     case QEvent::ActionAdded:
       
   352         d->actionAdded(static_cast<QActionEvent*>(event));
       
   353         return true;
       
   354     case QEvent::ActionRemoved:
       
   355         d->actionRemoved(static_cast<QActionEvent*>(event));
       
   356         return true;
       
   357     case QEvent::ActionChanged:
       
   358         // happens at least when action->setVisible(bool visible) is called
       
   359         if (d->polished && isVisible()) {
       
   360             d->resetVisibleButtonsList();
       
   361             d->doLayout();
       
   362         } else {
       
   363             d->mDoLayoutPending = true;
       
   364         }
       
   365         return true;
       
   366         default:
       
   367             return HbWidget::event(event);
       
   368     }    
       
   369 }
       
   370 
       
   371 /*!
       
   372     \reimp
       
   373  */
       
   374 void HbToolBar::gestureEvent(QGestureEvent *event)
       
   375 {
       
   376     Q_D(HbToolBar);    
       
   377     if (QPanGesture *panGesture = qobject_cast<QPanGesture*>(event->gesture(Qt::PanGesture))) {
       
   378         QPointF scenePoint = event->mapToGraphicsScene(panGesture->hotSpot());
       
   379         if (panGesture->state() == Qt::GestureStarted) {
       
   380             foreach (HbToolButton *button, d->mVisibleToolButtons) {
       
   381                 if (button->isDown()) {
       
   382                     d->mPressedDownButton = button;
       
   383                     break;
       
   384                 }
       
   385             }
       
   386             if (d->moreExtensionButton && d->moreExtensionButton->isDown()) {
       
   387                 d->mPressedDownButton = d->moreExtensionButton;
       
   388             }
       
   389         } else if (panGesture->state() == Qt::GestureUpdated) {
       
   390             if (mapRectToScene(boundingRect()).contains(scenePoint)) {
       
   391                 // moving inside the tool bar
       
   392                 if (!d->mPressedDownButton ||
       
   393                     !mapRectToScene(d->mPressedDownButton->geometry()).contains(scenePoint)) {
       
   394                     if (d->mPressedDownButton) {
       
   395                         // lift it up and try to find some other button
       
   396                         d->mPressedDownButton->setDown(false);
       
   397                         d->mPreviouslyPressedDownButton = d->mPressedDownButton;
       
   398                         d->mPressedDownButton = 0;
       
   399                     }
       
   400 
       
   401                     // Find the pressed button
       
   402                     foreach (HbToolButton *button, d->mVisibleToolButtons) {
       
   403                         if (button->action()->isEnabled() &&
       
   404                             mapRectToScene(button->geometry()).contains(scenePoint)) {
       
   405                             d->mPressedDownButton = button;
       
   406                             HbWidgetFeedback::triggered(button, Hb::InstantDraggedOver);
       
   407                             button->setDown(true);
       
   408                             break;
       
   409                         }
       
   410                     }
       
   411                     if (d->moreExtensionButton && d->moreExtensionButton->isVisible() &&
       
   412                         mapRectToScene(d->moreExtensionButton->geometry()).contains(scenePoint)) {
       
   413                         d->mPressedDownButton = d->moreExtensionButton;
       
   414                         HbWidgetFeedback::triggered(d->moreExtensionButton, Hb::InstantDraggedOver);
       
   415                         d->moreExtensionButton->setDown(true);
       
   416                     }
       
   417                 }
       
   418             } else {
       
   419                 // moving outside the tool bar
       
   420 
       
   421                 // if a button is pressed down, lift it.
       
   422                 if (d->mPressedDownButton) {
       
   423                     d->mPressedDownButton->setDown(false);
       
   424                     d->mPressedDownButton = 0;
       
   425                     d->mPreviouslyPressedDownButton = d->mPressedDownButton;
       
   426                 }
       
   427             }
       
   428         } else if (panGesture->state() == Qt::GestureFinished) {
       
   429             if (d->mPressedDownButton && !d->mPreviouslyPressedDownButton) {
       
   430                 // Generate tap gesture to the button
       
   431                 QGesture *gesture = new QTapGesture();
       
   432                 gesture->setHotSpot(panGesture->hotSpot());
       
   433                 QList<QGesture *> list;
       
   434                 list.append(gesture);
       
   435                 QGestureEvent *event = new QGestureEvent(list);
       
   436                 QCoreApplication::sendEvent(d->mPressedDownButton, event);                
       
   437                 d->mPressedDownButton = 0;
       
   438             } else if (d->mPressedDownButton) {
       
   439                 d->mPressedDownButton->setDown(false);
       
   440                 HbWidgetFeedback::triggered( d->mPressedDownButton, Hb::InstantClicked );
       
   441             }
       
   442             d->mPreviouslyPressedDownButton = 0;
       
   443         }
       
   444         event->accept(panGesture);
       
   445     } else {
       
   446         event->ignore();
       
   447     }
       
   448 }
       
   449 
       
   450 #include "moc_hbtoolbar.cpp"