src/hbwidgets/sliders/hbprogresssliderhandle_p.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 "hbprogresssliderhandle_p.h"
       
    27 #include <hbtooltip.h>
       
    28 #include <QGraphicsSceneMouseEvent>
       
    29 
       
    30 #define HBPROGRESSSLIDERHANDLE_TRACES
       
    31 #ifdef HBPROGRESSSLIDERHANDLE_TRACES
       
    32 #include <QtDebug>
       
    33 #endif
       
    34 
       
    35 #include <hbwidgetfeedback.h>
       
    36 
       
    37 #ifdef HB_EFFECTS
       
    38 #include "hbeffect.h"
       
    39 #include "hbeffectinternal_p.h"
       
    40 #define HB_PRGRESSSLIDERHANDLE_ITEM_TYPE "HB_PROGRESSSLIDERHANDLE"
       
    41 #endif
       
    42 
       
    43 #define   HandleMargin 0
       
    44 
       
    45 /*!
       
    46     \reimp
       
    47     \fn int HbProgressSliderHandle::type() const
       
    48  */
       
    49 
       
    50 HbProgressSliderHandle::HbProgressSliderHandle(HbHandleParent *parent) 
       
    51     :HbWidget(parent->parentGraphicsItem()),
       
    52     q(parent),
       
    53     mThumbIcon(),
       
    54     mPlayThumb(true),
       
    55     mThumbEnabled(false)
       
    56 {
       
    57     mFlags = 0;
       
    58     mFlags |= TextVisible;
       
    59     mHandleSize = QSizeF(0,0);
       
    60 
       
    61     mSliderState = HbProgressSlider::SliderStatePlayNormal;
       
    62     HbStyle *style = static_cast<HbStyle*>(q->style());
       
    63 
       
    64     mHandleItem = style->createPrimitive(HbStyle::P_ProgressSlider_handle,this);
       
    65     HbStyle::setItemName(mHandleItem , "handle");
       
    66 
       
    67     mHandleIconItem = style->createPrimitive(HbStyle::P_ProgressSlider_handleicon,this);
       
    68     HbStyle::setItemName(mHandleIconItem , "icon");
       
    69 
       
    70     mTouchItem = style->createPrimitive(HbStyle::P_ProgressSliderHandle_toucharea, this); 
       
    71     HbStyle::setItemName(mTouchItem , "toucharea");
       
    72     setProperty("state","normal");
       
    73 
       
    74 #ifdef HB_EFFECTS
       
    75     HbEffectInternal::add(HB_PRGRESSSLIDERHANDLE_ITEM_TYPE,"progressslider_handlepress", "progressslider_handlepress");
       
    76     HbEffectInternal::add(HB_PRGRESSSLIDERHANDLE_ITEM_TYPE,"progressslider_handlerelease", "progressslider_handlerelease");
       
    77     HbEffectInternal::add(HB_PRGRESSSLIDERHANDLE_ITEM_TYPE,"progressslider_handleoutofbound", "progressslider_handleoutofbound");
       
    78 #endif
       
    79 }
       
    80 
       
    81 HbProgressSliderHandle::~HbProgressSliderHandle() 
       
    82 {
       
    83 }
       
    84 
       
    85 void HbProgressSliderHandle::setThumbIcon(const HbIcon& icon)
       
    86 {
       
    87     if(icon.isNull()) {
       
    88         return;
       
    89     }
       
    90     HbStyle *style = qobject_cast<HbStyle*>(q->style());
       
    91     mThumbIcon= icon;
       
    92     HbStyleOptionProgressBar option;
       
    93     option.handleRect = boundingRect();
       
    94     option.thumbIcon = mThumbIcon;
       
    95     style->updatePrimitive(mHandleIconItem,HbStyle::P_ProgressSlider_handleicon,&option);
       
    96     mThumbEnabled = true;
       
    97 }
       
    98 
       
    99 HbIcon HbProgressSliderHandle::thumbIcon() const
       
   100 {
       
   101     return mThumbIcon;    
       
   102 }
       
   103 
       
   104 void HbProgressSliderHandle::mousePressEvent(QGraphicsSceneMouseEvent *event) 
       
   105 {
       
   106     HbWidget::mousePressEvent(event);
       
   107 
       
   108 #ifdef HB_EFFECTS
       
   109     HbEffect::start(this, HB_PRGRESSSLIDERHANDLE_ITEM_TYPE, "progressslider_handlepress");
       
   110 #endif
       
   111     mFlags |= HbProgressSliderHandle::MousePressed;
       
   112 
       
   113     mMousePressPos = event->scenePos();
       
   114     mItemPosAtPress = pos();
       
   115     if(q->textVisible()) {
       
   116         HbToolTip::showText(q->toolTipText(),this, QRectF(mItemPosAtPress,QSize(0,0)),q->textAlignment());
       
   117     }
       
   118 
       
   119     HbWidgetFeedback::triggered(q->parentGraphicsWidget(), Hb::InstantPressed, Hb::ModifierSliderHandle);
       
   120 
       
   121     event->accept();
       
   122     q->emitSliderPressed();    
       
   123 }
       
   124 
       
   125 void HbProgressSliderHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) 
       
   126 {
       
   127     HbWidget::mouseReleaseEvent(event);
       
   128     if (isHandleMoving()) {
       
   129       HbWidgetFeedback::continuousStopped(q->parentGraphicsWidget(), Hb::ContinuousDragged);
       
   130     }
       
   131     HbWidgetFeedback::triggered(q->parentGraphicsWidget(), Hb::InstantReleased, Hb::ModifierSliderHandle);
       
   132 
       
   133 #ifdef HB_EFFECTS
       
   134     HbEffect::start(this, HB_PRGRESSSLIDERHANDLE_ITEM_TYPE, "progressslider_handlerelease");
       
   135 #endif
       
   136     mFlags &= ~HbProgressSliderHandle::MousePressed;
       
   137     mFlags &=~HandleMoving;
       
   138     event->accept();
       
   139     q->emitSliderReleased();
       
   140 }
       
   141 
       
   142 void HbProgressSliderHandle::handleTrackRelease(QGraphicsSceneMouseEvent * event)
       
   143 {
       
   144     Q_UNUSED(event);
       
   145     setHandlePosForValue(q->progressValue());   
       
   146 }
       
   147 
       
   148 void HbProgressSliderHandle::handleTrackPress(QGraphicsSceneMouseEvent * event)
       
   149 {
       
   150     QPointF newPos = q->parentGraphicsItem()->mapFromScene(event->scenePos());
       
   151     if((newPos.x() >=  q->boundingRect().x()) && (newPos.x() <=  q->boundingRect().width())) {   
       
   152         if(q->orientation() == Qt::Horizontal){
       
   153             mItemCurPos = QPointF(newPos.x() - boundingRect().width()/2, pos().y());
       
   154         }
       
   155         else{
       
   156             mItemCurPos = QPointF(pos().x(), newPos.y()-boundingRect().height()/2);
       
   157         }
       
   158 
       
   159         mItemCurPos = normalizedPos(mItemCurPos,false);
       
   160         setPos(mItemCurPos);
       
   161         processItemChange(mItemCurPos);
       
   162     }
       
   163 }
       
   164 
       
   165 void HbProgressSliderHandle::mouseMoveEvent ( QGraphicsSceneMouseEvent * event ) 
       
   166 {
       
   167     HbWidget::mouseMoveEvent(event);
       
   168     mFlags |=HandleMoving;
       
   169     QPointF scenePos = event->scenePos();
       
   170     if(q->orientation() == Qt::Horizontal){
       
   171              mItemCurPos = QPointF((event->scenePos().x() - mMousePressPos.x()) + mItemPosAtPress.x(), pos().y());
       
   172              HbWidgetFeedback::continuousTriggered(qobject_cast<HbWidget*>(q->parentGraphicsWidget()), Hb::ContinuousDragged);
       
   173              if(mItemCurPos.x()+boundingRect().width() < q->boundingRect().width()
       
   174                  && mItemCurPos.x()>HandleMargin){
       
   175                 setPos(mItemCurPos);
       
   176              }
       
   177              else{
       
   178                 processItemChange(mItemCurPos);
       
   179              }
       
   180         }
       
   181 
       
   182      if (!mTouchItem->boundingRect().contains(parentItem()->mapFromScene(scenePos))) {
       
   183         #ifdef HB_EFFECTS
       
   184             HbEffect::start(this, HB_PRGRESSSLIDERHANDLE_ITEM_TYPE, "progressslider_handleoutofbound");
       
   185         #endif
       
   186     }
       
   187 
       
   188     if(q->textVisible()) {
       
   189         HbToolTip::showText(q->toolTipText(),this, QRectF(mItemCurPos,QSize(0,0)),q->textAlignment());
       
   190     }
       
   191     event->accept();
       
   192 
       
   193     q->emitSliderMoved(pointToValue(mItemCurPos));
       
   194 }
       
   195 
       
   196 int HbProgressSliderHandle::pointToValue(QPointF point) const
       
   197 {
       
   198     QRectF rect = q->boundingRect();
       
   199     qreal effectiveWidth;
       
   200     point = normalizedPos(point,q->invertedAppearance());
       
   201     qreal givenPixel;
       
   202     if(q->orientation() == Qt::Horizontal){
       
   203         effectiveWidth = rect.width() - boundingRect().width();
       
   204         givenPixel = point.x();
       
   205     }
       
   206     else{
       
   207         effectiveWidth = rect.height() - boundingRect().height();
       
   208         givenPixel = effectiveWidth-point.y();
       
   209     }
       
   210 
       
   211     qreal tickPerPixel = (qreal)(q->maximum()-q->minimum())/effectiveWidth;
       
   212     qreal tickForGivenPixel = givenPixel * tickPerPixel;
       
   213     tickForGivenPixel = qRound(tickForGivenPixel);
       
   214 
       
   215     int value;
       
   216     if(!q->invertedAppearance()) {
       
   217         value = q->minimum() + (int)tickForGivenPixel;
       
   218     } else {
       
   219         value = q->maximum() - (int)tickForGivenPixel;
       
   220     }
       
   221 
       
   222     if(value>q->maximum()) {
       
   223         return q->maximum();
       
   224     }
       
   225     else if(value<q->minimum()) {
       
   226         return q->minimum();
       
   227     }
       
   228     return value;
       
   229 }
       
   230 
       
   231 // converts value to handle coordinates
       
   232 QPointF HbProgressSliderHandle::valueToHandlePos(int value) const
       
   233 {
       
   234     QRectF r1 = q->boundingRect();
       
   235     QRectF r2 = boundingRect();
       
   236 
       
   237     qreal width;
       
   238     if(q->orientation()== Qt::Horizontal){
       
   239         width = r1.width() - r2.width();
       
   240         
       
   241     }
       
   242     else{
       
   243         width = r1.height() - r2.height();
       
   244        
       
   245     }
       
   246     if(q->maximum() != q->minimum()){
       
   247         qreal pixelpertick = width/(qreal)(q->maximum()-q->minimum());
       
   248         qreal noOfTicks = qreal(value - q->minimum());
       
   249         qreal xpos =  noOfTicks * pixelpertick;
       
   250         if(q->orientation() == Qt::Horizontal){
       
   251             return QPointF(xpos, r1.top());
       
   252         }
       
   253         else{
       
   254             return QPointF(r1.left(),width-xpos);
       
   255         }
       
   256     }
       
   257     else{
       
   258         return QPointF(0,0);
       
   259     }
       
   260 }
       
   261 
       
   262 QPointF HbProgressSliderHandle::normalizedPos(const QPointF&  pos,bool inverted) const 
       
   263 {
       
   264     Q_UNUSED(inverted);
       
   265     QPointF newPos = pos;
       
   266     if(q->orientation() == Qt::Horizontal){
       
   267         if (newPos.x() < HandleMargin) {
       
   268             newPos.setX( HandleMargin );
       
   269         }
       
   270 
       
   271         if (newPos.x() > q->boundingRect().width() - boundingRect().width() - HandleMargin) {
       
   272             newPos.setX(q->boundingRect().width() - boundingRect().width() - HandleMargin);
       
   273         }
       
   274     }
       
   275     else{
       
   276         if (newPos.y() < HandleMargin) {
       
   277             newPos.setY( HandleMargin );
       
   278         }
       
   279 
       
   280         if (newPos.y() > q->boundingRect().height() - boundingRect().height() - HandleMargin) {
       
   281             newPos.setY(q->boundingRect().height() - boundingRect().height() - HandleMargin);
       
   282         }
       
   283     }
       
   284     return newPos;
       
   285 }
       
   286 
       
   287 bool HbProgressSliderHandle::isHandlePressed() const
       
   288 {
       
   289     return mFlags.testFlag(HbProgressSliderHandle::MousePressed);
       
   290 }
       
   291 
       
   292 
       
   293 bool HbProgressSliderHandle::isHandleMoving() const
       
   294 {
       
   295     return mFlags.testFlag(HbProgressSliderHandle::HandleMoving);
       
   296 }
       
   297 
       
   298 QVariant HbProgressSliderHandle::processItemChange(const QVariant &value)
       
   299 {
       
   300         // value is the new position
       
   301         QPointF pt = value.toPointF();
       
   302         int newValue = pointToValue(pt);
       
   303         if(q->orientation() == Qt::Horizontal){
       
   304             pt.setY(q->boundingRect().top());
       
   305         }
       
   306         else{
       
   307             pt.setX(q->boundingRect().left());
       
   308         }
       
   309         q->emitSliderMoved(newValue);
       
   310         QPointF newPos = pt;
       
   311         return normalizedPos(newPos,false);
       
   312 }
       
   313 
       
   314 void HbProgressSliderHandle::setHandlePosForValue(int progressValue)
       
   315 {
       
   316     if(!mFlags.testFlag(HbProgressSliderHandle::MousePressed)){
       
   317 
       
   318         QPointF newPos = valueToHandlePos(progressValue);
       
   319         QPointF pos = normalizedPos(newPos,q->invertedAppearance());
       
   320         if(q->invertedAppearance()) {
       
   321             if(q->orientation() == Qt::Horizontal){
       
   322                 qreal xVal = q->boundingRect().width() - pos.x() - boundingRect().width();
       
   323                 pos.setX(xVal);
       
   324             }
       
   325             else{
       
   326                 qreal yVal = q->boundingRect().height() - pos.y() - boundingRect().height();
       
   327                 pos.setY(yVal);
       
   328             }
       
   329            
       
   330         }
       
   331 
       
   332         qreal yPos = qreal (q->boundingRect().height()-boundingRect().height()) /2 ;
       
   333         setPos(pos.x(),yPos);
       
   334     }   
       
   335    
       
   336 }
       
   337 
       
   338 
       
   339 void  HbProgressSliderHandle::updatePrimitives()
       
   340 {    
       
   341     HbStyleOptionProgressBar option;
       
   342     option.thumbIcon = mThumbIcon;
       
   343     option.sliderState = (HbStyleOptionProgressBar::SliderState) mSliderState;
       
   344     
       
   345     if (mHandleItem) {
       
   346         style()->updatePrimitive(mHandleItem, HbStyle::P_ProgressSlider_handle, &option);
       
   347     }
       
   348 
       
   349     if (mHandleIconItem) {
       
   350         style()->updatePrimitive(mHandleIconItem, HbStyle::P_ProgressSlider_handleicon, &option);
       
   351     }
       
   352 
       
   353 }
       
   354