src/hbwidgets/sliders/hbsliderhandle.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 "hbsliderhandle_p.h"
       
    27 #include "hbslidercontrol_p.h"
       
    28 #include "hbslidercontrol_p_p.h"
       
    29 #include <hbwidgetfeedback.h>
       
    30 #include <hbstyle.h>
       
    31 #include <hbstyleoptionslider.h>
       
    32 #include <QGraphicsSceneMouseEvent>
       
    33 #include <QGraphicsScene>
       
    34 
       
    35 #ifdef HB_EFFECTS
       
    36 #include "hbeffect.h"
       
    37 #include "hbeffectinternal_p.h"
       
    38 #define HB_SLIDERHANDLE_TYPE "HB_SLIDERHANDLE"
       
    39 #endif
       
    40 
       
    41 /*!
       
    42     This is internal class for HbSlider
       
    43     this created slider handle
       
    44     It also has event handling for handle press/move and release
       
    45 
       
    46 */
       
    47 
       
    48 
       
    49 /*!
       
    50     Constructs a slider handle for \a slider.
       
    51 */
       
    52 HbSliderHandle::HbSliderHandle(HbSliderControl *slider)
       
    53     : HbWidget(slider),
       
    54     sliderControl(slider), 
       
    55     gItem(0) ,
       
    56     handleDragPos(0),
       
    57     touchItem(0),
       
    58     mHandleItem(0)
       
    59 {
       
    60     // create handle icon item
       
    61     gItem = slider->style()->createPrimitive(HbStyle::P_Slider_thumb, this); 
       
    62     HbStyle::setItemName(gItem , "icon");
       
    63 
       
    64     // create touch area for handle
       
    65     touchItem = slider->style()->createPrimitive(HbStyle::P_SliderElement_touchhandle, this); 
       
    66     HbStyle::setItemName(touchItem , "toucharea");
       
    67 
       
    68     setZValue(slider->zValue() + 1);
       
    69     
       
    70 
       
    71 #ifdef HB_EFFECTS
       
    72     // horizontal thumb press
       
    73    // HbEffectInternal::add(HB_SLIDERHANDLE_TYPE,"sliderhandle_h_press", "h_thumbpress");
       
    74     //horizonal thumb release
       
    75     //HbEffectInternal::add(HB_SLIDERHANDLE_TYPE,"sliderhandle_h_releasel", "h_thumbrelease");
       
    76     // vertical thumb press
       
    77     //HbEffectInternal::add(HB_SLIDERHANDLE_TYPE,"sliderhandle_v_press", "v_thumbpress");
       
    78     //vertical thumb release
       
    79     //HbEffectInternal::add(HB_SLIDERHANDLE_TYPE,"sliderhandle_v_release", "v_thumbrelease");
       
    80     // horizontal out of bound
       
    81     //HbEffectInternal::add(HB_SLIDERHANDLE_TYPE,"sliderhandle_h_outofbound", "h_outofbound");
       
    82     //vertical out of bound
       
    83     //HbEffectInternal::add(HB_SLIDERHANDLE_TYPE,"sliderhandle_v_outofbound", "v_outofbound");
       
    84 #endif
       
    85 }
       
    86 
       
    87 /*!
       
    88     Destroys the slider handle.
       
    89 */
       
    90 HbSliderHandle::~HbSliderHandle()
       
    91 {
       
    92 	if(mHandleItem) {
       
    93 		mHandleItem->removeSceneEventFilter(this);
       
    94 	}
       
    95 }
       
    96 
       
    97 
       
    98 /*!
       
    99   reimp
       
   100 
       
   101 */
       
   102 /*void HbSliderHandle::polish( HbStyleParameters& params )
       
   103 {
       
   104     updatePrimitives();
       
   105     HbWidget::polish(params);
       
   106 }*/
       
   107 
       
   108 /*!
       
   109   This Api set handle position and update handle icon to press ot normal
       
   110 */
       
   111 void HbSliderHandle::forceSetPos(const QPointF &pos)
       
   112 {
       
   113     setPos(pos);
       
   114     HbStyleOptionSlider opt;
       
   115     sliderControl->initStyleOption(&opt);
       
   116     if( scene()){
       
   117         if (true == sliderControl->isSliderDown()){
       
   118             opt.state |= QStyle::State_Sunken;
       
   119             sliderControl->style()->updatePrimitive(
       
   120                 sliderControl->primitive(HbStyle::P_Slider_groove), HbStyle::P_Slider_groove, &opt);
       
   121           } else {
       
   122             opt.state &= ~QStyle::State_Sunken;
       
   123         } 
       
   124     } else {
       
   125         opt.state &= ~QStyle::State_Sunken;
       
   126     }
       
   127 
       
   128     opt.boundingRect=boundingRect();
       
   129     sliderControl->style()->updatePrimitive(gItem, HbStyle::P_Slider_thumb, &opt); 
       
   130 }
       
   131 
       
   132 void HbSliderHandle::setHandleItem(QGraphicsItem *item)
       
   133 {
       
   134 	if(!item) {
       
   135 		return;
       
   136 	}
       
   137 	if(mHandleItem) {
       
   138 		delete mHandleItem;
       
   139         mHandleItem =0;
       
   140 	}
       
   141 
       
   142     setHandlesChildEvents(false);
       
   143 
       
   144     mHandleItem = item;  
       
   145 	mHandleItem->setParentItem(this);
       
   146 	sliderControl->style()->setItemName(mHandleItem,"widget");
       
   147     //((QGraphicsWidget*)mHandleItem)->setGeometry(gItem->geometry());//TODO:geometry from css
       
   148 
       
   149     if(scene()) {
       
   150         mHandleItem->removeSceneEventFilter(this);
       
   151         mHandleItem->installSceneEventFilter(this);
       
   152     }
       
   153 	mHandleItem->setFlag(QGraphicsItem::ItemIsMovable,true);//required as the press has to be accepted to filter move events.
       
   154 
       
   155 }
       
   156 
       
   157 QGraphicsItem *HbSliderHandle::handleItem() const
       
   158 {
       
   159     return mHandleItem;
       
   160 }
       
   161 
       
   162 void HbSliderHandle::showEvent(QShowEvent *event)
       
   163 {
       
   164     Q_UNUSED(event);
       
   165     if(scene()) {
       
   166         if(gItem) {
       
   167             //gItem->removeSceneEventFilter(this);
       
   168             //gItem->installSceneEventFilter(this);
       
   169         }
       
   170         if(mHandleItem && scene()) {
       
   171             mHandleItem->removeSceneEventFilter(this);
       
   172             mHandleItem->installSceneEventFilter(this);
       
   173         }
       
   174            
       
   175     }
       
   176 }
       
   177 bool HbSliderHandle::sceneEventFilter(QGraphicsItem *obj,QEvent *event)
       
   178 {
       
   179     //TODO: touch area doesnt work with the current filtering mechanism. find better solution
       
   180 	if( obj == mHandleItem) {
       
   181 		if(event->type() == QEvent::GraphicsSceneMouseMove){
       
   182 			mouseMoveEvent ( (QGraphicsSceneMouseEvent *) event ) ;
       
   183 			return true;
       
   184 		}
       
   185 		else if (event->type() == QEvent::GraphicsSceneMousePress){
       
   186 			mousePressEvent((QGraphicsSceneMouseEvent *) event);
       
   187 		}
       
   188 		else if (event->type() == QEvent::GraphicsSceneMouseRelease){
       
   189 			mouseReleaseEvent((QGraphicsSceneMouseEvent *) event);
       
   190 		}
       
   191 	} 
       
   192 	return false;
       
   193 }
       
   194  
       
   195 /*!
       
   196   reimp
       
   197 
       
   198 */
       
   199 void HbSliderHandle::mousePressEvent(QGraphicsSceneMouseEvent *event)
       
   200 {
       
   201     qreal span = 0;
       
   202     HbWidget::mousePressEvent(event);
       
   203     QRectF sliderBounds=sliderControl->boundingRect();
       
   204     QRectF handleBounds=boundingRect();
       
   205     sliderControl->setSliderDown(true);
       
   206     HbWidgetFeedback::triggered(sliderControl, Hb::InstantPressed, Hb::ModifierSliderHandle);
       
   207     if (scene()){
       
   208         HbStyleOptionSlider opt;
       
   209         sliderControl->initStyleOption(&opt);
       
   210         if (sliderControl->orientation() == Qt::Horizontal) {
       
   211 #ifdef HB_EFFECTS
       
   212             HbEffect::start(gItem, HB_SLIDERHANDLE_TYPE, "h_thumbpress");
       
   213 #endif
       
   214             sliderBounds.adjust(0, 0, -handleBounds.width(), 0);
       
   215             span = sliderBounds.width();
       
   216             handleInitialPos = static_cast<int>(mapToParent(event->pos()).rx());
       
   217         } else {
       
   218 #ifdef HB_EFFECTS
       
   219             HbEffect::start(gItem, HB_SLIDERHANDLE_TYPE, "v_thumbpress");
       
   220 #endif
       
   221             sliderBounds.adjust(0, 0, 0, -handleBounds.height());
       
   222             span = sliderBounds.height();
       
   223             handleInitialPos = static_cast<int>(mapToParent(event->pos()).ry());
       
   224         }
       
   225         handleDragPos= QStyle::sliderPositionFromValue(opt.minimum, opt.maximum,
       
   226             sliderControl->sliderPosition(), static_cast<int>(span),opt.upsideDown);
       
   227         updatePrimitives();
       
   228     }
       
   229     event->accept();
       
   230 }
       
   231 
       
   232 /*!
       
   233   reimp
       
   234 
       
   235 */
       
   236 void HbSliderHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
       
   237 {
       
   238     HbWidget::mouseReleaseEvent(event);
       
   239 #ifdef HB_EFFECTS
       
   240     if( sliderControl->orientation() == Qt::Horizontal ) {
       
   241         HbEffect::start(gItem, HB_SLIDERHANDLE_TYPE, "h_thumbrelease");
       
   242     }
       
   243     else {
       
   244         HbEffect::start(gItem, HB_SLIDERHANDLE_TYPE, "v_thumbrelease");
       
   245     }        
       
   246 #endif
       
   247     HbWidgetFeedback::triggered(sliderControl, Hb::InstantReleased, Hb::ModifierSliderHandle);
       
   248     sliderControl->setSliderDown(false);
       
   249     QRectF controlRect = sliderControl->sceneBoundingRect();
       
   250     if(!controlRect.contains(event->scenePos().x() , event->scenePos().y()) ){
       
   251         sliderControl->releasedOutside(true);
       
   252     }
       
   253     if(sliderControl->singleStep() != 0) {
       
   254         HbWidgetFeedback::continuousStopped(sliderControl, Hb::ContinuousDragged);
       
   255     }
       
   256     event->accept();
       
   257     if( sliderControl->snappingMode()!= HbSliderControl::NoSnapping ){
       
   258         sliderControl->updateSliderPosToTick();
       
   259     }
       
   260     updatePrimitives();
       
   261 }
       
   262 
       
   263 /*!
       
   264   reimp
       
   265 
       
   266 */
       
   267 void HbSliderHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
       
   268 {
       
   269     qreal span = 0;
       
   270     HbWidget::mouseMoveEvent(event);
       
   271     QRectF sliderBounds=sliderControl->boundingRect();
       
   272     QRectF handleBounds=boundingRect();
       
   273     HbStyleOptionSlider opt;
       
   274     sliderControl->initStyleOption(&opt);
       
   275     int sliderPos;
       
   276     if ( sliderControl->orientation() == Qt::Horizontal ) {
       
   277 #ifdef HB_EFFECTS
       
   278         if( sliderBounds.topLeft().x() > mapToParent(event->pos()).x() ||
       
   279             sliderBounds.bottomRight().x() < mapToParent(event->pos()).x()) {
       
   280             HbEffect::start(gItem, HB_SLIDERHANDLE_TYPE, "h_outofbound");
       
   281         }
       
   282 #endif
       
   283         sliderBounds.adjust(0, 0, -handleBounds.width(), 0);
       
   284         span = sliderBounds.width();
       
   285         sliderPos = static_cast<int>(
       
   286             handleDragPos+(mapToParent(event->pos()).rx()-handleInitialPos));
       
   287     } else {
       
   288 #ifdef HB_EFFECTS
       
   289         if( sliderBounds.topLeft().y() > mapToParent(event->pos()).y() ||
       
   290             sliderBounds.bottomRight().y() < mapToParent(event->pos()).y()) {
       
   291             HbEffect::start(gItem, HB_SLIDERHANDLE_TYPE, "v_outofbound");
       
   292         }
       
   293 #endif
       
   294         sliderBounds.adjust(0, 0, 0, -handleBounds.height());
       
   295         span = sliderBounds.height();
       
   296         sliderPos = static_cast<int>(
       
   297             handleDragPos+(mapToParent(event->pos()).ry()-handleInitialPos));
       
   298     }
       
   299     int pressValue= QStyle::sliderValueFromPosition(opt.minimum, opt.maximum,
       
   300         sliderPos, static_cast<int>(span),opt.upsideDown);
       
   301     sliderControl->setSliderPosition(pressValue);
       
   302     sliderControl->showToolTip();
       
   303 }
       
   304 
       
   305 /*!
       
   306   reimp
       
   307 
       
   308 */
       
   309 void HbSliderHandle::updatePrimitives()
       
   310 {
       
   311     HbStyleOptionSlider opt;
       
   312     sliderControl->initStyleOption(&opt);
       
   313     if( scene()){
       
   314         if (true == sliderControl->isSliderDown()){
       
   315             opt.state |= QStyle::State_Sunken;
       
   316             sliderControl->style()->updatePrimitive(
       
   317                 sliderControl->primitive(HbStyle::P_Slider_groove), HbStyle::P_Slider_groove, &opt);
       
   318         } else {
       
   319             opt.state &= ~QStyle::State_Sunken;
       
   320         } 
       
   321     } else {
       
   322         opt.state &= ~QStyle::State_Sunken;
       
   323     }
       
   324 
       
   325     opt.boundingRect=boundingRect();
       
   326     sliderControl->style()->updatePrimitive(gItem, HbStyle::P_Slider_thumb, &opt); 
       
   327     sliderControl->style()->updatePrimitive(touchItem , HbStyle::P_SliderElement_touchhandle ,&opt);
       
   328     sliderControl->update(boundingRect());
       
   329 }
       
   330 
       
   331 /*!
       
   332   reimp
       
   333 
       
   334 */
       
   335 QGraphicsItem * HbSliderHandle::primitive(HbStyle::Primitive primitive) const
       
   336  {
       
   337        switch (primitive) {
       
   338         case HbStyle::P_Slider_thumb:
       
   339             return gItem;
       
   340         case HbStyle::P_SliderElement_touchhandle:
       
   341             return touchItem;
       
   342         default:
       
   343             return NULL;
       
   344     }
       
   345  }