src/hbwidgets/itemviews/hbindexfeedback.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 HbWidgets 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 "hbindexfeedback.h"
       
    27 #include "hbindexfeedback_p.h"
       
    28 
       
    29 #include "hbabstractitemview.h"
       
    30 
       
    31 #include <hbscrollbar.h>
       
    32 #include <hbstyleoptionindexfeedback.h>
       
    33 #include <hbstyleparameters.h>
       
    34 #include <hbstyle.h>
       
    35 #include <hbdeviceprofile.h>
       
    36 
       
    37 #include <QEvent>
       
    38 #include <QObject>
       
    39 #include <QGraphicsScene>
       
    40 
       
    41 /*!
       
    42     @alpha
       
    43     @hbwidgets
       
    44     \class HbIndexFeedback
       
    45     \brief HbIndexFeedback provides index feedback functionality when attached to an HbAbstractItemView.
       
    46 
       
    47     Index feedback functionality is provided when the vertical or horizontal scrollbars
       
    48     are interactive.
       
    49 
       
    50     To add index feedback functionality to an HbAbstractItemView, create the HbIndexFeedback and 
       
    51     use HbIndexFeedback::setItemView().
       
    52 
       
    53     Index feedback provides a non-interactive popup containing an index when the user taps
       
    54     or scrolls, the interactive scrollbar.  The data for the index feedback comes from
       
    55     Hb::IndexFeedbackRole in the item view's data model.  The index feedback will
       
    56     be displayed if that data can be interpreted as a string by QVariant.
       
    57 
       
    58     The sizing and number of characters to display are controlled by the IndexFeedbackPolicy.
       
    59 
       
    60     \sa HbAbstractItemView, HbIndexFeedback::IndexFeedbackPolicy.
       
    61 */
       
    62 
       
    63 /*!
       
    64     \enum HbIndexFeedback::IndexFeedbackPolicy
       
    65 
       
    66     \brief Controls the number of characters to display, font and sizing of the index feedback.
       
    67 
       
    68     The default is IndexFeedbackSingleCharacter.  Other options are
       
    69     IndexFeedbackThreeCharacter, 
       
    70     IndexFeedbackString, and IndexFeedbackNone.
       
    71 */
       
    72 
       
    73 /*!
       
    74     \var HbIndexFeedback::IndexFeedbackNone
       
    75 
       
    76     There is no index feedback provided.
       
    77 */
       
    78 
       
    79 /*!
       
    80     \var HbIndexFeedback::IndexFeedbackSingleCharacter
       
    81 
       
    82     Index feedback will be the first letter of the contents of Hb::IndexFeedbackRole
       
    83     cast as a string.  It will be displayed using a larger font centered over the list.
       
    84     
       
    85     Recomended use is for alphabetically sorted lists.
       
    86 */
       
    87 
       
    88 /*!
       
    89     \var HbIndexFeedback::IndexFeedbackThreeCharacter
       
    90 
       
    91     Index feedback will be the first three letters of the contents of 
       
    92     Hb::IndexFeedbackRole cast as a string.  It will be displayed using a larger font
       
    93     centered over the list.  
       
    94     
       
    95     Recomended us is for month abreviations.
       
    96 */
       
    97 
       
    98 /*!
       
    99     \var HbIndexFeedback::IndexFeedbackString
       
   100 
       
   101     Index feedback will be the contents of Hb::IndexFeedbackRole cast as a string.
       
   102     It will be displayed using primary font and centered over the list.
       
   103 */
       
   104 
       
   105 /*!
       
   106     Here are the main properties of the class:
       
   107 
       
   108     \li HbIndexFeedback::IndexFeedbackPolicy       : Controls the number of characters to display, font and sizing of the index feedback.
       
   109     \li HbIndexFeedback::ItemView                  : The item view which the index feedback is provided for.
       
   110 */
       
   111 
       
   112 /* rather than magic numbers, let's define some constants. */
       
   113 namespace {
       
   114 /*
       
   115     string name from the index feedback .css for the single character height parameter.
       
   116 */
       
   117 static const QString ONE_CHAR_HEIGHT = QLatin1String("one-char-height");
       
   118 
       
   119 /*
       
   120     string name from the index feedback .css for the three character height parameter.
       
   121 */
       
   122 static const QString THREE_CHAR_HEIGHT = QLatin1String("three-char-height");
       
   123 
       
   124 /*
       
   125     string name from the index feedback .css for the three character width parameter.
       
   126 */
       
   127 static const QString THREE_CHAR_WIDTH = QLatin1String("three-char-width");
       
   128 
       
   129 /*
       
   130     string name from the index feedback .css for the string mode offest parameter.
       
   131 */
       
   132 static const QString STRING_OFFSET = QLatin1String("string-offset");
       
   133 }
       
   134 
       
   135 /*!
       
   136     Constructs a new HbIndexFeedback with a parent.
       
   137 */
       
   138 HbIndexFeedback::HbIndexFeedback(QGraphicsItem *parent)
       
   139     : HbWidget( *new HbIndexFeedbackPrivate, parent, 0)
       
   140     
       
   141 {
       
   142     Q_D( HbIndexFeedback );
       
   143     d->q_ptr = this;
       
   144 
       
   145     d->init();
       
   146 }
       
   147 
       
   148 /*!
       
   149     Destructs the index feedback.
       
   150 */
       
   151 HbIndexFeedback::~HbIndexFeedback()
       
   152 {
       
   153 
       
   154 }
       
   155 
       
   156 /*!
       
   157     \brief sets the index feedback policy.
       
   158 
       
   159     \param policy - The HbIndexFeedback::IndexFeedbackPolicy to use.
       
   160 
       
   161     \sa HbIndexFeedback::IndexFeedbackPolicy
       
   162 */
       
   163 void HbIndexFeedback::setIndexFeedbackPolicy(IndexFeedbackPolicy policy)
       
   164 {
       
   165     Q_D( HbIndexFeedback );
       
   166 
       
   167     if (policy != d->mIndexFeedbackPolicy) {
       
   168         d->_q_hideIndexFeedbackNow();
       
   169         d->mIndexFeedbackPolicy = policy;
       
   170         d->calculatePopupRects();
       
   171         d->updatePrimitives();
       
   172     }
       
   173 }
       
   174 
       
   175 /*!
       
   176     \brief Returns the index feedback policy.
       
   177 
       
   178     \return The HbIndexFeedback::IndexFeedbackPolicy that's currently in use.
       
   179 */
       
   180 HbIndexFeedback::IndexFeedbackPolicy HbIndexFeedback::indexFeedbackPolicy() const
       
   181 {
       
   182     Q_D( const HbIndexFeedback );
       
   183 
       
   184     return d->mIndexFeedbackPolicy;
       
   185 }
       
   186 
       
   187 /*!
       
   188     \brief sets the item view for the index feedback.
       
   189 
       
   190     Disconnects from the existing item view, then connects to the specified one.
       
   191 
       
   192     If set to NULL the index feedback is simply disconnected.
       
   193 
       
   194     \param itemView The HbAbstractItemView* to provide index feedback for.
       
   195 */
       
   196 void HbIndexFeedback::setItemView(HbAbstractItemView *itemView)
       
   197 {
       
   198     Q_D( HbIndexFeedback );
       
   199 
       
   200     if (itemView == d->mItemView) {
       
   201         return;
       
   202     }
       
   203 
       
   204     d->disconnectItemView();
       
   205 
       
   206     d->mItemView = itemView;
       
   207 
       
   208     if (!d->mItemView) {
       
   209         return;
       
   210     }
       
   211 
       
   212     d->connectScrollBarToIndexFeedback(d->mItemView->horizontalScrollBar());
       
   213     d->connectScrollBarToIndexFeedback(d->mItemView->verticalScrollBar());
       
   214 
       
   215     connect(d->mItemView, SIGNAL(destroyed(QObject*)),
       
   216         this, SLOT(_q_itemViewDestroyed()));
       
   217 
       
   218     if (d->mItemView->scene()) {
       
   219         d->mItemView->scene()->addItem(this);
       
   220         d->mItemView->installSceneEventFilter(this);
       
   221     }
       
   222 
       
   223     d->calculatePopupRects();
       
   224     updatePrimitives();
       
   225 }
       
   226 
       
   227 /*!
       
   228     Returns the HbAbstractItemView which the index feedback currently monitors.
       
   229 
       
   230     \return HbAbstractItemView*.
       
   231 */
       
   232 HbAbstractItemView* HbIndexFeedback::itemView() const
       
   233 {
       
   234     Q_D( const HbIndexFeedback );
       
   235 
       
   236     return d->mItemView;
       
   237 }
       
   238 
       
   239 /*!
       
   240     Returns the primitives used in HbIndexFeedback.
       
   241 
       
   242     \param primitive The primitive type requested.
       
   243 
       
   244     \return A pointer for the primitive requested.
       
   245 */
       
   246 QGraphicsItem* HbIndexFeedback::primitive(HbStyle::Primitive primitive) const
       
   247 {
       
   248     Q_D( const HbIndexFeedback );
       
   249 
       
   250     QGraphicsItem* retVal = HbWidget::primitive(primitive);
       
   251 
       
   252     switch (primitive) {
       
   253         case HbStyle::P_IndexFeedback_popup_text:
       
   254             retVal = d->mTextItem;
       
   255             break;
       
   256             
       
   257         case HbStyle::P_IndexFeedback_popup_background:
       
   258             retVal = d->mPopupItem;
       
   259             break;
       
   260 
       
   261         default:
       
   262             qt_noop();
       
   263             break;
       
   264     }
       
   265 
       
   266     return retVal;
       
   267 }
       
   268 
       
   269 
       
   270 /*
       
   271     A scene event filter.  It's purpose is to call calculatePopupRects on
       
   272     a resize event for the item view.
       
   273 */
       
   274 bool HbIndexFeedback::sceneEventFilter(QGraphicsItem *watched, QEvent *ev)
       
   275 {
       
   276     Q_D( HbIndexFeedback );
       
   277 
       
   278     if (ev->type() == QEvent::GraphicsSceneResize) {
       
   279         d->calculatePopupRects();
       
   280     }
       
   281     
       
   282     return QGraphicsItem::sceneEventFilter(watched, ev);
       
   283 }
       
   284 
       
   285 /*
       
   286     Rather than adding signals to HbScrollBar specifically to implement 
       
   287     index feedback, an event filter is used.
       
   288 
       
   289     Specifically, if a scrollbar which is interactive is pressed or released
       
   290     this function will call the appropriate function in HbIndexFeedbackPrivate.
       
   291 */
       
   292 bool HbIndexFeedback::eventFilter(QObject *obj, QEvent *ev)
       
   293 {
       
   294     Q_D( HbIndexFeedback );
       
   295     HbScrollBar* scrollBar = qobject_cast<HbScrollBar*>(obj);
       
   296 
       
   297     if (d->mIndexFeedbackPolicy != HbIndexFeedback::IndexFeedbackNone
       
   298         && scrollBar) {
       
   299         switch (ev->type()) {
       
   300             case QEvent::GraphicsSceneMousePress:
       
   301             case QEvent::MouseButtonPress:
       
   302                 if (scrollBar->isInteractive()) {
       
   303                     d->scrollBarPressed();
       
   304                 }
       
   305                 break;
       
   306 
       
   307             case QEvent::GraphicsSceneMouseRelease:
       
   308             case QEvent::MouseButtonRelease:
       
   309                 if (scrollBar->isInteractive()) {
       
   310                     d->scrollBarReleased();
       
   311                 }
       
   312                 break;
       
   313         
       
   314             case QEvent::GraphicsSceneResize:
       
   315             case QEvent::Resize:
       
   316                     d->_q_hideIndexFeedbackNow();
       
   317                     d->calculatePopupRects();
       
   318                     d->updatePrimitives();
       
   319                 break;
       
   320 
       
   321             default:
       
   322                 // do nothing, ignore other events.
       
   323                 break;
       
   324         }
       
   325     }
       
   326 
       
   327     return QObject::eventFilter(obj, ev);
       
   328 }
       
   329 
       
   330 /*
       
   331     For use with HbStyle.
       
   332 
       
   333     Provide the correct data to use in the 'model.'
       
   334 */
       
   335 void HbIndexFeedback::initStyleOption(HbStyleOptionIndexFeedback *option) const
       
   336 {
       
   337     Q_D( const HbIndexFeedback );
       
   338 
       
   339     HbWidget::initStyleOption(option);
       
   340 
       
   341     if (!d->mItemView) {
       
   342         return;
       
   343     }
       
   344 
       
   345     HbFontSpec fontSpec;
       
   346     qreal margin = 0;
       
   347 
       
   348     style()->parameter(QLatin1String("hb-param-margin-gene-popup"), margin);
       
   349 
       
   350     switch (d->mIndexFeedbackPolicy) {
       
   351         case IndexFeedbackSingleCharacter:
       
   352             {
       
   353                 fontSpec = HbFontSpec(HbFontSpec::Primary);
       
   354                 fontSpec.setTextPaneHeight(d->textHeight());
       
   355             }
       
   356             break;
       
   357             
       
   358         case IndexFeedbackThreeCharacter:
       
   359             {
       
   360                 fontSpec = HbFontSpec(HbFontSpec::Primary);
       
   361                 fontSpec.setTextPaneHeight(d->textHeight());
       
   362             }
       
   363             break;
       
   364 
       
   365         case IndexFeedbackString:
       
   366             {
       
   367                 fontSpec = HbFontSpec(HbFontSpec::Primary);
       
   368                 qreal textPaneHeight = 0;
       
   369                 style()->parameter(QLatin1String("hb-param-text-height-primary"), textPaneHeight);
       
   370                 fontSpec.setTextPaneHeight( textPaneHeight );
       
   371             }
       
   372             break;
       
   373 
       
   374         case IndexFeedbackNone:
       
   375             // leave the HbStyleOption uninitialized
       
   376             return;
       
   377     }
       
   378 
       
   379     option->text = d->mPopupContent;
       
   380     option->fontSpec = fontSpec;
       
   381     option->textRect = d->mPopupTextRect;
       
   382     option->popupRect = d->mPopupBackgroundRect;
       
   383 }
       
   384 
       
   385 void HbIndexFeedback::polish(HbStyleParameters& params)
       
   386 {
       
   387     Q_D( HbIndexFeedback );
       
   388 
       
   389     params.addParameter( ONE_CHAR_HEIGHT );
       
   390     params.addParameter( THREE_CHAR_HEIGHT );
       
   391     params.addParameter( THREE_CHAR_WIDTH );
       
   392     params.addParameter( STRING_OFFSET );
       
   393 
       
   394     HbWidget::polish( params );
       
   395 
       
   396     d->mOneCharHeight = params.value( ONE_CHAR_HEIGHT ).toDouble();
       
   397     d->mThreeCharHeight = params.value( THREE_CHAR_HEIGHT ).toDouble();
       
   398     d->mThreeCharWidth = params.value( THREE_CHAR_WIDTH ).toDouble();
       
   399     d->mStringOffset = params.value( STRING_OFFSET ).toDouble();
       
   400 
       
   401     d->calculatePopupRects();
       
   402 }
       
   403 
       
   404 #include "moc_hbindexfeedback.cpp"