src/hbwidgets/sliders/hbslidercontrol.cpp
changeset 28 b7da29130b0e
parent 23 e6ad4ef83b23
child 30 80e4d18b72f5
--- a/src/hbwidgets/sliders/hbslidercontrol.cpp	Thu Sep 02 20:44:51 2010 +0300
+++ b/src/hbwidgets/sliders/hbslidercontrol.cpp	Fri Sep 17 08:32:10 2010 +0300
@@ -36,11 +36,15 @@
 #include <hbtooltip.h>
 #include <hbwidgetfeedback.h>
 #include <hbgraphicsscene.h>
+#include <hbtoucharea.h>
+#include <hbslider.h>
 #include <QGraphicsItem>
 #include <QGraphicsSceneMouseEvent>
 #ifdef HB_GESTURE_FW
 #include "hbtapgesture.h"
 #include "hbpangesture.h"
+#include "hbtapandholdgesture.h"
+
 #endif 
 
 #ifdef HB_EFFECTS
@@ -63,7 +67,7 @@
     groove( 0 ), //slider groove
     progressGroove( 0 ),//progress mask top of groove
     displayCurrValueToolTip( true ), // holds whether to show current value tooltip or not
-    toolTipAlignment( Qt::AlignTop|Qt::AlignRight ), // tooltip alignment
+    toolTipAlignment( Qt::AlignTop ), // tooltip alignment
     groovePressed( false ), // hold whether groove is pressed or not
     setDefault( false ), // holds whther default value for track press is set
     previousValue( 0 ),  // default value for track press
@@ -71,7 +75,9 @@
     handleMoving( false ),
     grooveTouchArea ( 0 ),
     enableProgressTrack ( true ),
-    userDefinedTooltipAlign ( false )
+    userDefinedTooltipAlign ( false ),
+    tooltipArea(0),
+    tooltipBorderHeight( 0 )
 {
 
     majorLabel.clear();
@@ -99,14 +105,14 @@
    
     // creating handle
     handle = createHandle();
-    if(handle) {
+    if (handle) {
         HbStyle::setItemName( handle, "handle" );
     }
 #if defined( QT_KEYPAD_NAVIGATION ) && !defined( Q_OS_SYMBIAN )    
     q->setFocusPolicy( Qt::FocusPolicy( ( qApp->style( ) )->styleHint( QStyle::SH_Button_FocusPolicy ) ) );
 #endif
     groove = createGroove();
-    if(groove) {
+    if (groove) {
         HbStyle::setItemName( groove, "groove" );
     }
 #ifdef HB_GESTURE_FW
@@ -116,20 +122,49 @@
     //filled item top of groove
     if ( enableProgressTrack ) {
         progressGroove = createProgressGroove();
-        if(progressGroove) {
+        if (progressGroove) {
             HbStyle::setItemName( progressGroove, "progressgroove");
         }    
     }
+    tooltipArea = new HbTouchArea(q);
     q->connect( hbInstance->theme( ), SIGNAL( changed( ) ), q, SLOT( updateTheme( ) ) );
-    q->connect( q , SIGNAL( actionTriggered( int ) ), q , SLOT( showToolTip( ) ) );
+ //   q->connect( q , SIGNAL( actionTriggered( int ) ), q , SLOT( showToolTip( ) ) );
     q->connect( q , SIGNAL( sliderReleased( ) ), q , SLOT( hideToolTip( ) ) );
 #if defined( QT_KEYPAD_NAVIGATION ) && !defined( Q_OS_SYMBIAN )
     q->setFlags( QGraphicsItem::ItemIsFocusable );
 #endif
 }
 
+int HbSliderControlPrivate::calculateSliderPosition(QPointF relativePos) 
+{
+    Q_Q (HbSliderControl);
+    qreal span = 0;
+    qreal handlePos = 0;
+    QRectF bounds = q->boundingRect( );
+    QRectF handleBounds = handle->boundingRect( );
+    bounds.adjust( 0, 0, -handleBounds.width( ), -handleBounds.height( ) );
+    // calculate handle position and span
+    switch ( q->orientation( ) ) {
+        case Qt::Horizontal:
+            handlePos = relativePos.x( ) - handleBounds.width( ) / 2;
+            span = bounds.width( );
+            break;
+        case Qt::Vertical:
+            handlePos = relativePos.y( ) - handleBounds.height( ) / 2;
+            span = bounds.height( );
+            break;
+        default:
+            break;
+    }
+    HbStyleOptionSlider opt;
+    q->initStyleOption( &opt );
+    int pressValue = QStyle::sliderValueFromPosition( opt.minimum, opt.maximum,
+        static_cast<int>( handlePos ),static_cast<int>( span ),opt.upsideDown );
+    return pressValue;
 
 
+}
+
 /*!
   \internal
   This is used to create the handle, it is virtual and can be overridden to create different handle.
@@ -597,9 +632,18 @@
 void HbSliderControl::showToolTip( )
 {
     Q_D( HbSliderControl );
-    if ( isSliderDown( ) && d->displayCurrValueToolTip ) {
-        HbToolTip::showText( toolTip( ) , d->handle->primitive((HbStyle::Primitive)HbStylePrivate::P_SliderElement_touchhandle) , d->toolTipAlignment );
-    }
+    if ( d->displayCurrValueToolTip ) {
+        QRectF handleRect=d->handle->boundingRect();
+        QRectF tooltipRect = handleRect;
+        tooltipRect.setHeight ( d->tooltipBorderHeight);
+        tooltipRect.moveBottom( d->handle->pos().ry());
+        tooltipRect.moveLeft (d->handle->pos().rx());
+        d->tooltipArea->setGeometry(tooltipRect);
+        //d->tooltipArea->update();*/
+        HbToolTip::showText( toolTip( ) , d->tooltipArea, d->toolTipAlignment );
+       }
+
+
 }
 
 /*!
@@ -638,7 +682,7 @@
         return;
     }
     event->accept( );
-    if( d->onHandle( event->scenePos( ) ) ) {
+    if ( d->onHandle( event->scenePos( ) ) ) {
         HbWidgetFeedback::triggered( this, Hb::InstantPressed, Hb::ModifierSliderHandle );
         setSliderDown( true );
         d->handle->updatePrimitives( );
@@ -647,8 +691,8 @@
     else {
     // effect
 #ifdef HB_EFFECTS
-    if( d->grooveTouchArea->sceneBoundingRect( ).contains( event->scenePos( ) ) ) {
-        if( orientation( ) == Qt::Horizontal ) {   
+    if ( d->grooveTouchArea->sceneBoundingRect( ).contains( event->scenePos( ) ) ) {
+        if ( orientation( ) == Qt::Horizontal ) {   
         // effect for horizontal track press
             HbEffectInternal::add( HB_SLIDERCONTROL_TYPE,"slider_h_trackpress", "h_trackpress" );
             HbEffect::start( d->groove, HB_SLIDERCONTROL_TYPE, "h_trackrpress" );
@@ -781,16 +825,45 @@
 void HbSliderControl::gestureEvent(QGestureEvent *event)
 {
     Q_D(HbSliderControl);
-    if(HbTapGesture *tap = qobject_cast<HbTapGesture *>(event->gesture(Qt::TapGesture))) {
-            if( d->onHandle( event->mapToGraphicsScene(tap->position( ) ) ) ){
+    if ( HbTapAndHoldGesture *tapandHold = qobject_cast<HbTapAndHoldGesture *> ( event->gesture( Qt::TapAndHoldGesture ) ) ) {
+        if (tapandHold->state() == Qt::GestureStarted) {
+            QPointF relativePos = mapFromScene( event->mapToGraphicsScene(tapandHold->position( ) ) );
+            int pressValue = d->calculateSliderPosition( relativePos );
+            setToolTip(QString::number( pressValue ) );
+            QRectF handleRect=d->handle->boundingRect();
+            QRectF tooltipRect =  handleRect;
+            QRectF touchPointRect=handleRect;
+            if (orientation() == Qt::Horizontal) {
+                touchPointRect.moveCenter(QPointF( boundingRect().width()/2,boundingRect( ).height()/2 ) );
+                touchPointRect.moveLeft(relativePos.rx() - touchPointRect.width( )/2);
+
+            } else {
+                touchPointRect.moveCenter(QPointF( boundingRect().width()/2,boundingRect( ).height()/2 ) );
+                touchPointRect.moveTop( relativePos.ry() - touchPointRect.height()/2 );
+            }
+            tooltipRect.setHeight ( d->tooltipBorderHeight);
+            tooltipRect.moveBottom( touchPointRect.top() );
+            tooltipRect.moveLeft (touchPointRect.left( ) );
+            d->tooltipArea->setGeometry(tooltipRect);
+            d->tooltipArea->setGeometry(tooltipRect);
+            d->tooltipArea->update();
+            if ( d->displayCurrValueToolTip ) {
+                HbToolTip::showText( toolTip( ) , d->tooltipArea, d->toolTipAlignment );
+            }
+
+            return;
+        }
+    }
+    if ( HbTapGesture *tap = qobject_cast<HbTapGesture *> (event->gesture( Qt::TapGesture ) )) {
+        if ( d->onHandle( event->mapToGraphicsScene(tap->position( ) ) ) ) {
                 event->ignore();
                 return;
-            }
-        switch(tap->state()) {
+        }
+        switch( tap->state( ) ) {
         case Qt::GestureStarted: {
             QRectF eventRect = d->grooveTouchArea->sceneBoundingRect( );
             if ( !d->trackHandlingEnable  || maximum( ) == minimum( ) || 
-                !eventRect.contains( event->mapToGraphicsScene(tap->position( ) ) ) ){
+                !eventRect.contains( event->mapToGraphicsScene(tap->position( ) ) ) ) {
                 event->ignore( );
                 return;
             }
@@ -803,12 +876,11 @@
             event->accept( );
         // effect
 #ifdef HB_EFFECTS
-            if( orientation( ) == Qt::Horizontal ) {   
+            if ( orientation( ) == Qt::Horizontal ) {   
             // effect for horizontal track press
                 HbEffectInternal::add( HB_SLIDERCONTROL_TYPE,"slider_h_trackpress", "h_trackpress" );
                 HbEffect::start( d->groove, HB_SLIDERCONTROL_TYPE, "h_trackrpress" );
-            }
-            else {
+            } else {
                 HbEffectInternal::add( HB_SLIDERCONTROL_TYPE,"slider_v_trackpress", "v_trackpress" );
                 HbEffect::start( d->groove, HB_SLIDERCONTROL_TYPE, "v_trackpress" );
             }  
@@ -826,32 +898,8 @@
                 event->ignore( );
                 return;
             }
-            qreal handlePos = 0;
-            qreal span = 0;
-            QRectF bounds = boundingRect( );
-            QRectF handleBounds = d->handle->boundingRect( );
-            bounds.adjust( 0, 0, -handleBounds.width( ), -handleBounds.height( ) );
             QPointF relativePos = mapFromScene( event->mapToGraphicsScene(tap->position( ) ) );
-            // calculate handle position and span
-            switch ( orientation( ) ) {
-                case Qt::Horizontal:
-                    handlePos = relativePos.x( ) - handleBounds.width( ) / 2;
-                    span = bounds.width( );
-                    break;
-                case Qt::Vertical:
-                    handlePos = relativePos.y( ) - handleBounds.height( ) / 2;
-                    span = bounds.height( );
-                    break;
-                default:
-                    break;
-            }
-            HbStyleOptionSlider opt;
-            initStyleOption( &opt );
-
-            int pressValue = QStyle::sliderValueFromPosition( opt.minimum, opt.maximum,
-                static_cast<int>( handlePos ),static_cast<int>( span ),opt.upsideDown );
-
-
+            int pressValue = d->calculateSliderPosition (relativePos);
             // if default is set then don't increment or decrement slider value
             // just set default value to slider
             setSliderPosition( pressValue );
@@ -860,7 +908,7 @@
             HbWidgetFeedback::triggered( this, Hb::InstantReleased );
             if ( d->groovePressed ) {
 #ifdef HB_EFFECTS    
-                if( orientation( ) == Qt::Horizontal ) {   
+                if ( orientation( ) == Qt::Horizontal ) {   
                     HbEffectInternal::add( HB_SLIDERCONTROL_TYPE,"slider_h_trackrelease", "h_trackrelease" );
                     HbEffect::start( d->groove, HB_SLIDERCONTROL_TYPE, "h_trackrelease" );
                 }  else {
@@ -880,7 +928,7 @@
         case Qt::GestureCanceled: {
             if ( d->groovePressed ) {
 #ifdef HB_EFFECTS    
-                if( orientation( ) == Qt::Horizontal ) {   
+                if ( orientation( ) == Qt::Horizontal ) {   
                     HbEffectInternal::add( HB_SLIDERCONTROL_TYPE,"slider_h_trackrelease", "h_trackrelease" );
                     HbEffect::start( d->groove, HB_SLIDERCONTROL_TYPE, "h_trackrelease" );
                 }  else {
@@ -901,51 +949,64 @@
             break;
         }
     }
-    if (HbPanGesture *panGesture = qobject_cast<HbPanGesture*>(event->gesture(Qt::PanGesture))) {
-        switch(panGesture->state( )) {
+    if ( HbPanGesture *panGesture = qobject_cast<HbPanGesture*> (event->gesture(Qt::PanGesture) ) ) {
+        switch(panGesture->state( ) ) {
             case Qt::GestureStarted: 
             case Qt::GestureUpdated:{
                 QPointF startPoint = event->mapToGraphicsScene(panGesture->offset()+panGesture->startPos( ) );
                 //if the position is on thumb , then start moving the thumb
-                if( ( d->onHandle( startPoint) && d->grooveTouchArea->sceneBoundingRect( ).contains( startPoint))||isSliderDown( ) ) {
-                    qreal handlePos = 0;
-                    qreal span = 0;
-                    QRectF bounds = boundingRect( );
-                    QRectF handleBounds = d->handle->boundingRect( );
-                    bounds.adjust( 0, 0, -handleBounds.width( ), -handleBounds.height( ) );
-                    QPointF relativePos = mapFromScene( event->mapToGraphicsScene(panGesture->startPos( ) + panGesture->offset()) );
-                    // calculate handle position and span
-                    switch ( orientation( ) ) {
-                        case Qt::Horizontal:
-                            handlePos = relativePos.x( ) - handleBounds.width( ) / 2;
-                            span = bounds.width( );
-                            break;
-                        case Qt::Vertical:
-                            handlePos = relativePos.y( ) - handleBounds.height( ) / 2;
-                            span = bounds.height( );
-                            break;
-                        default:
-                            break;
-                    }
-                    HbStyleOptionSlider opt;
-                    initStyleOption( &opt );
-
-                    int pressValue = QStyle::sliderValueFromPosition( opt.minimum, opt.maximum,
-                        static_cast<int>( handlePos ),static_cast<int>( span ),opt.upsideDown ); 
+                if ( ( d->onHandle( startPoint) && d->grooveTouchArea->sceneBoundingRect( ).contains( startPoint) )||isSliderDown( ) ) {
+                    QPointF relativePos = mapFromScene( event->mapToGraphicsScene(panGesture->startPos( ) + panGesture->offset() ) );
+                    int pressValue = d->calculateSliderPosition (relativePos);
                     setRepeatAction( SliderNoAction,static_cast<int>( pressValue ) );
                     setSliderDown( true );
                     setSliderPosition( pressValue );
+                    setToolTip( QString::number( pressValue ) );
                     showToolTip( );
                     d->groovePressed = false;
                     updatePrimitives();
                     d->handleMoving = true ;
                     break;
-                } else if(d->grooveTouchArea->sceneBoundingRect().contains(startPoint) ){
+                } else if (d->grooveTouchArea->sceneBoundingRect().contains(startPoint) ) {
+                    QPointF relativePos = mapFromScene( event->mapToGraphicsScene(panGesture->startPos( ) + panGesture->offset() ) );
+                    int pressValue = d->calculateSliderPosition (relativePos);
+                    setToolTip( QString::number( pressValue ) );
+                    QRectF handleRect=d->handle->boundingRect();
+                    QRectF tooltipRect =  handleRect;
+                    QRectF touchPointRect=handleRect;
+                    if (orientation() == Qt::Horizontal) {
+                        touchPointRect.moveCenter(QPointF( boundingRect().width()/2,boundingRect( ).height()/2 ) );
+                        touchPointRect.moveLeft(relativePos.rx() - touchPointRect.width( )/2);
+                    } else {
+                        touchPointRect.moveCenter(QPointF( boundingRect().width()/2,boundingRect( ).height()/2 ) );
+                        touchPointRect.moveTop( relativePos.ry() - touchPointRect.height()/2 );
+                    }
+                    tooltipRect.setHeight ( d->tooltipBorderHeight);
+                    tooltipRect.moveBottom( touchPointRect.top() );
+                    tooltipRect.moveLeft (touchPointRect.left( ) );
+                    d->tooltipArea->setGeometry(tooltipRect);
+                    d->tooltipArea->setGeometry(tooltipRect);
+                    d->tooltipArea->update();
+                    if ( d->displayCurrValueToolTip ) {
+                        HbToolTip::showText( toolTip( ) , d->tooltipArea, d->toolTipAlignment );
+                    }
+                    d->groovePressed = true;
                     HbStyleOptionSlider opt;
-                    d->groovePressed = true;
                     initStyleOption( &opt );
                     HbStylePrivate::updatePrimitive( d->groove, HbStylePrivate::P_Slider_groove, &opt );  
                     event->ignore();
+                    QPointF diffOffset = panGesture->offset() - panGesture->lastOffset();
+                    if (orientation() == Qt::Horizontal) {
+                        if (qAbs(diffOffset.x() ) < qAbs(diffOffset.y())) {
+                            HbAbstractSliderControl::gestureEvent(event);
+
+                        }
+                    } else {
+                        if (qAbs(diffOffset.y() ) < qAbs(diffOffset.x())) {
+                            HbAbstractSliderControl::gestureEvent(event);
+                        }
+                    }
+
                     break;
                 } else {
                     setSliderDown( false );
@@ -961,15 +1022,21 @@
             break;
             case Qt::GestureFinished:
             case Qt::GestureCanceled: {
+                QPointF startPoint = event->mapToGraphicsScene(panGesture->offset()+panGesture->startPos( ) );
                 setSliderDown( false );
                 d->groovePressed = false;
                 updatePrimitives( );
                 d->handle->updatePrimitives();
                 d->handleMoving = false;
-                int pressValue = sliderPosition();
-                setRepeatAction( SliderNoAction,static_cast<int>( pressValue ) );
+                if (d->grooveTouchArea->sceneBoundingRect().contains(startPoint) ) {
+                    QPointF relativePos = mapFromScene( event->mapToGraphicsScene(panGesture->startPos( ) + panGesture->offset() ) );
+                    int pressValue = d->calculateSliderPosition (relativePos);
+                    setRepeatAction( SliderNoAction,static_cast<int>( pressValue ) );
+                    setSliderPosition( pressValue );
+                    setToolTip( QString::number( pressValue ) );
+                    showToolTip( );
+                }
                 event->ignore();
-                HbWidgetFeedback::triggered(this, Hb::InstantReleased);
                 HbAbstractSliderControl::gestureEvent(event);
             }
             break;
@@ -1024,8 +1091,6 @@
 {
     Q_D( HbSliderControl );
     QGraphicsWidget::resizeEvent( event );
-    // for Bug Fix::Ticks are not getting updated after 
-    // element is added to slider
     updatePrimitives( );
     repolish();
     d->adjustHandle( );  
@@ -1037,11 +1102,14 @@
 void HbSliderControl::polish( HbStyleParameters& params )
 {
     Q_D( HbSliderControl );
+    params.addParameter("tooltip-border-height");
     HbStyleOptionSlider option;
     initStyleOption( &option );
     HbAbstractSliderControl::polish( params );
     d->adjustHandle( );
     updatePrimitives( );
+    d->tooltipBorderHeight = params.value("tooltip-border-height").toReal();
+
 }
 
 /*!
@@ -1162,17 +1230,6 @@
     HbAbstractSliderControl::sliderChange( change );
     d->adjustHandle( );
     if ( change == SliderOrientationChange ) {
-        //Layout is not mirrored in vertical orientation with absolute ticks
-        if(d->orientation ==Qt::Horizontal) { 
-            if (!d->userDefinedTooltipAlign) {
-                d->toolTipAlignment = ( Qt::AlignTop|Qt::AlignHCenter );
-            }
-        } else {
-            if (!d->userDefinedTooltipAlign) {
-                // Bug in tooltip, cannot align it with top right
-                d->toolTipAlignment = ( Qt::AlignTop|Qt::AlignHCenter );
-            }
-        }
         repolish( );
     }
 }
@@ -1333,7 +1390,9 @@
 #ifdef HB_GESTURE_FW
             ungrabGesture(Qt::TapGesture);
             ungrabGesture(Qt::PanGesture);
+            ungrabGesture(Qt::TapAndHoldGesture);
             touchArea->grabGesture(Qt::TapGesture);
+            touchArea->grabGesture(Qt::TapAndHoldGesture);
             touchArea->grabGesture(Qt::PanGesture);
 #endif 
         }