src/hbcore/gui/hbtoolbutton.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 "hbtoolbutton.h"
       
    27 #include "hbtoolbutton_p.h"
       
    28 #include "hbtooltip.h"
       
    29 #include "hbstyleoptiontoolbutton.h"
       
    30 #include "hbtoolbarextension.h"
       
    31 #include "hbtoolbarextension_p.h"
       
    32 #include "hbaction.h"
       
    33 #include "hbaction_p.h"
       
    34 #include <hbglobal.h>
       
    35 #include "hbcolorscheme.h"
       
    36 #include "hbtextitem.h"
       
    37 #include "hbiconitem.h"
       
    38 
       
    39 #include <QGraphicsSceneHelpEvent>
       
    40 #include <QGraphicsSceneMouseEvent>
       
    41 
       
    42 /*!
       
    43     @stable
       
    44     @hbcore
       
    45     \class HbToolButton
       
    46     \brief The HbToolButton class provides a quick-access button for actions.
       
    47 
       
    48     A tool button is a special button that provides quick-access to
       
    49     a specific action. Unlike a normal push button HbPushButton, a tool
       
    50     button represents an action. In other words, HbToolButton is
       
    51     synchronized with an instance of HbAction.
       
    52 
       
    53     The action may also be associated with other parts of the user interface,
       
    54     as menu items and keyboard shortcuts. Sharing actions in this way helps
       
    55     make the user interface more consistent and is often less work to implement.
       
    56 
       
    57     Tool buttons are normally created indirectly when actions are added to a
       
    58     toolbar with HbToolBar::addAction(). It is also possible to
       
    59     construct tool buttons directly in the same way as any other widget, and
       
    60     arrange them alongside other widgets in layouts.
       
    61 
       
    62     The style of a tool button is adjustable with setToolButtonStyle().
       
    63     By default a tool button shows only an icon.
       
    64 
       
    65     A tool button's background is set as HbIcon. This makes it possible to
       
    66     specify different images for the normal and pressed states.
       
    67 
       
    68     Example usage:
       
    69     \code
       
    70     HbAction *action = new HbAction(icon, name, this);
       
    71     HbToolButton *toolButton = new HbToolButton(action, this);
       
    72     layout->addItem(toolButton);
       
    73     \endcode
       
    74 
       
    75     \sa HbAction, HbPushButton
       
    76 */
       
    77 
       
    78 /*!
       
    79     \enum HbToolButton::ToolButtonStyle
       
    80 
       
    81     This enum defines available tool button styles.
       
    82 
       
    83     The tool button style describes how the button's text and icon should be displayed.
       
    84  */
       
    85 
       
    86 /*!
       
    87     \var HbToolButton::ToolButtonIcon
       
    88 
       
    89     Only display the icon.
       
    90  */
       
    91 
       
    92 /*!
       
    93     \var HbToolButton::ToolButtonText
       
    94 
       
    95     Only display the text.
       
    96  */
       
    97 
       
    98 /*!
       
    99     \var HbToolButton::ToolButtonTextAndIcon
       
   100 
       
   101     Display both text and icon.
       
   102  */
       
   103 
       
   104 /*!
       
   105     \fn void HbToolButton::triggered(HbAction *action)
       
   106 
       
   107     This signal is emitted when the \a action is triggered.
       
   108  */
       
   109 
       
   110 /*!
       
   111     \reimp
       
   112     \fn int HbToolButton::type() const
       
   113  */
       
   114 
       
   115 HbToolButtonPrivate::HbToolButtonPrivate() :
       
   116     action(0),
       
   117     textItem(0),
       
   118     iconItem(0),
       
   119     frameItem(0),
       
   120     customBackground(),
       
   121     backgroundVisible(true),
       
   122     buttonStyle(HbToolButton::ToolButtonIcon),
       
   123     toolBarPosition(HbStyleOptionToolButton::TB_None),
       
   124     orientation(Qt::Vertical),
       
   125     mDialogToolBar(false),
       
   126     mButtonSize(QSizeF())
       
   127 {    
       
   128 }
       
   129 
       
   130 HbToolButtonPrivate::~HbToolButtonPrivate()
       
   131 {
       
   132 }
       
   133 
       
   134 void HbToolButtonPrivate::createPrimitives()
       
   135 {
       
   136     Q_Q(HbToolButton);
       
   137     
       
   138     if (backgroundVisible) {
       
   139         if (!frameItem) {
       
   140             frameItem = q->style()->createPrimitive(HbStyle::P_ToolButton_frame, q);
       
   141         }
       
   142     } else if (frameItem) {
       
   143         delete frameItem;
       
   144         frameItem = 0;
       
   145     }
       
   146 
       
   147     if (action && !action->text().isEmpty()) {
       
   148         if (!textItem) {
       
   149             textItem = static_cast<HbTextItem *>(q->style()->createPrimitive(HbStyle::P_ToolButton_text, q));            
       
   150             textItem->setTextWrapping(Hb::TextWordWrap);
       
   151         }
       
   152         textItem->setVisible(buttonStyle & HbToolButton::ToolButtonText);
       
   153     } else if (textItem) {
       
   154         delete textItem;
       
   155         textItem = 0;
       
   156     }
       
   157 
       
   158     if (action && (buttonStyle & HbToolButton::ToolButtonIcon)) {
       
   159         if (!iconItem) {
       
   160             iconItem = q->style()->createPrimitive(HbStyle::P_ToolButton_icon, q);
       
   161         }
       
   162     } else if (iconItem){
       
   163         delete iconItem;
       
   164         iconItem = 0;
       
   165     }
       
   166 }
       
   167 
       
   168 void HbToolButtonPrivate::setOrientation(Qt::Orientation orientation)
       
   169 {
       
   170     if (this->orientation != orientation) {
       
   171         this->orientation = orientation;
       
   172         Q_Q(HbToolButton);        
       
   173         if (q->isVisible() && polished) {
       
   174             q->repolish();
       
   175         }
       
   176     }    
       
   177 }
       
   178 
       
   179 void HbToolButtonPrivate::setToolBarPosition(HbStyleOptionToolButton::ToolBarPosition position)
       
   180 {
       
   181     Q_Q(HbToolButton);
       
   182     if (toolBarPosition != position) {
       
   183         toolBarPosition = position;
       
   184         // required for toolbar()->action()[i]->setVisible(visible)
       
   185         // to work for all cases
       
   186         if (q->isVisible() && polished) {
       
   187             q->updatePrimitives();
       
   188         }
       
   189     }    
       
   190 }
       
   191 
       
   192 void HbToolButtonPrivate::setBackgroundVisible(bool visible)
       
   193 {
       
   194     Q_Q(HbToolButton);
       
   195     if (backgroundVisible != visible) {
       
   196         backgroundVisible = visible;
       
   197         // required to make extension orientation switch from
       
   198         // landscape to portrait work correctly with automatic more
       
   199         // extension.
       
   200         q->repolish();
       
   201     }
       
   202 }
       
   203 
       
   204 void HbToolButtonPrivate::setLayoutProperty(const char *name, bool value)
       
   205 {
       
   206     Q_Q(HbToolButton);
       
   207     q->setProperty(name, value);
       
   208     if (q->isVisible() && polished) {
       
   209         q->repolish();
       
   210     }
       
   211 }
       
   212 
       
   213 QSizeF HbToolButtonPrivate::getMinimumSize()
       
   214 {
       
   215     Q_Q(HbToolButton);
       
   216     mRepolishRequested = true;
       
   217     polishPending = false;
       
   218     q->updateGeometry();
       
   219     QSizeF size = q->minimumSize();
       
   220     //Workaround (causing extra polish)
       
   221     mSizeHintPolish = false;
       
   222     //workaround ends
       
   223     return size;
       
   224 }
       
   225 
       
   226 void HbToolButtonPrivate::_q_actionTriggered()
       
   227 {
       
   228     Q_Q(HbToolButton);
       
   229     emit q->triggered(action);
       
   230 }
       
   231 
       
   232 void HbToolButtonPrivate::_q_actionChanged()
       
   233 {
       
   234     Q_Q(HbToolButton);
       
   235     if (!action->icon().isNull()) {
       
   236         if (orientation == Qt::Horizontal) {
       
   237             buttonStyle = HbToolButton::ToolButtonIcon;
       
   238         } else if (!action->text().isEmpty()) {
       
   239             buttonStyle = HbToolButton::ToolButtonTextAndIcon;
       
   240         } else {
       
   241             buttonStyle = HbToolButton::ToolButtonIcon;
       
   242         }
       
   243     } else {
       
   244         buttonStyle = HbToolButton::ToolButtonText;
       
   245     }
       
   246     // action text/icon may have changed,            
       
   247     if (q->isVisible() && polished) {
       
   248         q->repolish();
       
   249     }
       
   250 }
       
   251 
       
   252 void HbToolButtonPrivate::showToolTip()
       
   253 {
       
   254     Q_Q(HbToolButton);
       
   255     HbToolTip::showText(q->toolTip(), q, orientation == Qt::Vertical ? Qt::AlignTop : Qt::AlignLeft);
       
   256 }
       
   257 
       
   258 /*!
       
   259     Constructs a new HbToolButton with \a parent.
       
   260 */
       
   261 HbToolButton::HbToolButton(QGraphicsItem *parent) :
       
   262     HbAbstractButton(*new HbToolButtonPrivate, parent)
       
   263 {
       
   264     Q_D(HbToolButton);
       
   265     d->q_ptr = this;
       
   266 }
       
   267 
       
   268 /*!
       
   269     Constructs a new HbToolButton with \a action and \a parent.
       
   270 
       
   271     Ownership of the \a action is not transferred to the tool button.
       
   272  */
       
   273 HbToolButton::HbToolButton(HbAction *action, QGraphicsItem *parent) :
       
   274     HbAbstractButton(*new HbToolButtonPrivate, parent)
       
   275 {
       
   276     Q_D(HbToolButton);
       
   277     d->q_ptr = this;
       
   278     setAction(action);
       
   279     setProperty("state", "normal");
       
   280 }
       
   281 
       
   282 /*!
       
   283     Destructs the tool button.
       
   284  */
       
   285 HbToolButton::~HbToolButton()
       
   286 {
       
   287 }
       
   288 
       
   289 /*!
       
   290     Returns the action of the button.
       
   291 
       
   292     \sa setAction()
       
   293  */
       
   294 HbAction *HbToolButton::action() const
       
   295 {
       
   296     Q_D(const HbToolButton);
       
   297     return d->action;
       
   298 }
       
   299 
       
   300 /*!
       
   301     Sets the \a action of the button.
       
   302 
       
   303     Ownership of the \a action is not transferred to the tool button.
       
   304 
       
   305     \sa action()
       
   306  */
       
   307 void HbToolButton::setAction(HbAction *action)
       
   308 {
       
   309     Q_D(HbToolButton);
       
   310     if (d->action == action) {
       
   311         return;
       
   312     }
       
   313 
       
   314     if (d->action) {
       
   315         disconnect(d->action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
       
   316         disconnect(d->action, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
       
   317     }
       
   318 
       
   319     HbAction *oldAction = d->action;
       
   320     d->action = action;
       
   321     if (d->action) {
       
   322         connect(action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
       
   323         connect(action, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
       
   324     }
       
   325 
       
   326     if (isVisible() && d->polished) {
       
   327         // If action was null then there is a chance that the iconitem is not yet created.
       
   328         // If the new action is null then we may need to get rid of the icon completely.
       
   329         if ((!oldAction && action) || (oldAction && !action)) {
       
   330             repolish(); // will call createPrimitives()
       
   331         }
       
   332         updatePrimitives();
       
   333     }
       
   334 }
       
   335 
       
   336 /*!
       
   337     Returns the background image of the button.
       
   338  */
       
   339 HbIcon HbToolButton::background() const
       
   340 {
       
   341     Q_D(const HbToolButton);
       
   342     return d->customBackground;
       
   343 }
       
   344 
       
   345 /*!
       
   346     Sets the \a background image of the button.
       
   347  */
       
   348 void HbToolButton::setBackground(const HbIcon &background)
       
   349 {
       
   350     Q_D(HbToolButton);
       
   351     if (d->customBackground != background) {
       
   352         d->customBackground = background;
       
   353         if (isVisible() || d->polished)
       
   354             updatePrimitives();
       
   355     }
       
   356 }
       
   357 
       
   358 /*!
       
   359     @beta
       
   360     Returns the tool button style.
       
   361 
       
   362     The default value is \b HbToolButton::ToolButtonIcon.
       
   363 
       
   364     \sa setToolButtonStyle()
       
   365  */
       
   366 HbToolButton::ToolButtonStyle HbToolButton::toolButtonStyle() const
       
   367 {
       
   368     Q_D(const HbToolButton);
       
   369     return d->buttonStyle;
       
   370 }
       
   371 
       
   372 /*!
       
   373     @beta
       
   374     Sets the tool button style.
       
   375 
       
   376     \sa toolButtonStyle()
       
   377  */
       
   378 void HbToolButton::setToolButtonStyle(HbToolButton::ToolButtonStyle style)
       
   379 {    
       
   380     Q_D(HbToolButton);
       
   381     if (d->buttonStyle != style) {
       
   382         d->buttonStyle = style;
       
   383 
       
   384         // action text/icon may have changed,
       
   385         // primitives might need to be created/cleaned up
       
   386         if (size() != QSize(0, 0)) {
       
   387             repolish();
       
   388         }
       
   389     }
       
   390 }
       
   391 
       
   392 /*!
       
   393     \reimp
       
   394  */
       
   395 QGraphicsItem *HbToolButton::primitive(HbStyle::Primitive primitive) const
       
   396 {
       
   397     Q_D(const HbToolButton);
       
   398     switch (primitive) {
       
   399         case HbStyle::P_ToolButton_frame:
       
   400             return d->frameItem;
       
   401         case HbStyle::P_ToolButton_icon:
       
   402             return d->iconItem;
       
   403         case HbStyle::P_ToolButton_text:
       
   404             return d->textItem;
       
   405         default:
       
   406             return 0;
       
   407     }
       
   408 }
       
   409 
       
   410 /*!
       
   411     \reimp
       
   412  */
       
   413 void HbToolButton::updatePrimitives()
       
   414 {
       
   415     Q_D(HbToolButton);
       
   416 
       
   417     HbStyleOptionToolButton option;
       
   418     if (d->action) {
       
   419         setCheckable(d->action->isCheckable());
       
   420         setChecked(d->action->isChecked());
       
   421         setEnabled(d->action->isEnabled());
       
   422         HbAction *hbAction = qobject_cast<HbAction *>(d->action);
       
   423         if (hbAction && (!hbAction->toolTip().isEmpty()) && (hbAction->toolTip() != toolTip())) {
       
   424             setToolTip(hbAction->toolTip());
       
   425         } else if(!hbAction && d->action->toolTip() != toolTip()) {
       
   426             setToolTip(d->action->toolTip());
       
   427         }
       
   428         setVisible(d->action->isVisible());
       
   429     }
       
   430 
       
   431     initStyleOption(&option);
       
   432     setProperty("dialogtoolbar", d->mDialogToolBar);
       
   433     if (d->frameItem) {
       
   434         style()->updatePrimitive(d->frameItem, HbStyle::P_ToolButton_frame, &option);
       
   435     }
       
   436     if (d->textItem) {
       
   437         style()->updatePrimitive(d->textItem, HbStyle::P_ToolButton_text, &option);
       
   438     }
       
   439     if (d->iconItem) {
       
   440         style()->updatePrimitive(d->iconItem, HbStyle::P_ToolButton_icon, &option);
       
   441         if (d->action && d->action->icon().flags() & HbIcon::Colorized) {
       
   442             static_cast<HbIconItem *>(d->iconItem)->setFlags(HbIcon::Colorized);
       
   443         }
       
   444     }
       
   445 }
       
   446 
       
   447 /*!
       
   448     Initializes \a option with the values from this HbToolButton. This method is useful for
       
   449     subclasses when they need a HbStyleOptionToolButton, but don't want to fill in all the
       
   450     information themselves.
       
   451  */
       
   452 void HbToolButton::initStyleOption(HbStyleOptionToolButton *option) const
       
   453 {
       
   454     Q_D(const HbToolButton);
       
   455     HbAbstractButton::initStyleOption(option);
       
   456 
       
   457     Q_ASSERT(option);
       
   458     option->customBackground = d->customBackground;
       
   459     option->backgroundVisible = d->backgroundVisible;
       
   460     option->toolBarPosition = d->toolBarPosition;
       
   461     option->orientation = d->orientation;
       
   462     option->isCheckable = d->checkable;
       
   463     option->useSecondaryGraphics = d->mDialogToolBar;
       
   464 
       
   465     if (d->action) {
       
   466         option->text = d->action->text();
       
   467         option->icon = d->action->icon();
       
   468     }
       
   469 }
       
   470 
       
   471 /*!
       
   472     \internal
       
   473  */
       
   474 HbToolButton::HbToolButton(HbToolButtonPrivate &dd, QGraphicsItem *parent) :
       
   475     HbAbstractButton(dd, parent)
       
   476 {
       
   477 }
       
   478 
       
   479 /*!
       
   480     \reimp
       
   481  */
       
   482 void HbToolButton::resizeEvent(QGraphicsSceneResizeEvent *event)
       
   483 {
       
   484     Q_D(HbToolButton);
       
   485     QGraphicsWidget::resizeEvent(event);
       
   486     if (event->newSize() !=  event->oldSize() && d->polished && isVisible()) {
       
   487         updatePrimitives();
       
   488     }
       
   489     if (action() && action()->toolBarExtension()) {
       
   490         HbToolBarExtensionPrivate::d_ptr(action()->toolBarExtension())->placeToolBarExtension();
       
   491     }
       
   492 }
       
   493 
       
   494 /*!
       
   495     \reimp
       
   496  */
       
   497 void HbToolButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
       
   498 {
       
   499     HbAbstractButton::mousePressEvent(event);
       
   500     setProperty("state", "pressed");
       
   501     updatePrimitives();
       
   502 }
       
   503 
       
   504 /*!
       
   505     \reimp
       
   506  */
       
   507 void HbToolButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
       
   508 {
       
   509     HbAbstractButton::mouseReleaseEvent(event);
       
   510     setProperty("state", "normal");
       
   511     updatePrimitives();
       
   512 }
       
   513 
       
   514 /*!
       
   515     \reimp
       
   516  */
       
   517 void HbToolButton::nextCheckState()
       
   518 {
       
   519     Q_D(HbToolButton);
       
   520     HbAbstractButton::nextCheckState();
       
   521     if (!d->action) {
       
   522         return;
       
   523     }
       
   524     if ( d->action->toolBarExtension() ) {
       
   525         HbToolBarExtensionPrivate::d_ptr(d->action->toolBarExtension())->mExtendedButton = this;
       
   526         d->action->toolBarExtension()->show();
       
   527     }
       
   528 
       
   529     d->action->trigger();
       
   530 }
       
   531 
       
   532 /*!
       
   533     \reimp
       
   534  */
       
   535 bool HbToolButton::event(QEvent *event)
       
   536 {
       
   537     if (event) {
       
   538         switch (event->type()) {
       
   539             case QEvent::GraphicsSceneMouseRelease: {
       
   540                 mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(event));
       
   541                 return true;
       
   542             }
       
   543             case QEvent::GraphicsSceneHelp: {
       
   544                     Q_D(HbToolButton);                    
       
   545                     // Check whether toolbutton is inside a toolbar.
       
   546                     if (d->toolBarPosition != HbStyleOptionToolButton::TB_None) {
       
   547                         d->showToolTip();
       
   548                         event->accept();
       
   549                         return true;
       
   550                     }
       
   551                 }
       
   552                 break;
       
   553 
       
   554         default: break;
       
   555         }
       
   556     }
       
   557 
       
   558     return HbAbstractButton::event(event);
       
   559 }
       
   560 
       
   561 void HbToolButton::polish(HbStyleParameters &params)
       
   562 {
       
   563     Q_D(HbToolButton);
       
   564     setProperty("orientation", d->orientation);
       
   565     d->createPrimitives();
       
   566     updatePrimitives();
       
   567     HbAbstractButton::polish(params);
       
   568     // workaround for caching problem
       
   569     setMinimumSize(minimumSize());
       
   570     // workaround ends
       
   571 }
       
   572 
       
   573 #include "moc_hbtoolbutton.cpp"