src/hbinput/inputwidgets/hbinputvirtualrocker.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 HbInput 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 #include <QGraphicsSceneMouseEvent>
       
    26 #include <QPixmap>
       
    27 #include <QBitmap>
       
    28 #include <QPainter>
       
    29 #include <QCoreApplication>
       
    30 #include <QDir>
       
    31 #include <QDebug>
       
    32 #include <hbicon.h>
       
    33 #include <hbinputsettingproxy.h>
       
    34 #include <hbwidgetfeedback.h>
       
    35 
       
    36 #include "hbinputvkbwidget.h"
       
    37 #include "hbinputvirtualrocker.h"
       
    38 
       
    39 /// @cond
       
    40 
       
    41 const qreal HbRockerXThreshold = 5.0;
       
    42 const qreal HbRockerYThreshold = 50.0;
       
    43 const qreal HbRockerDimOpacity = 1.0;
       
    44 const qreal HbRockerNormalOpacity = 1.0;
       
    45 const qreal HbRockerWidth = 50.0;
       
    46 const int HbIconWidth = 30;
       
    47 const int HbPointerWidth = 15;
       
    48 
       
    49 
       
    50 class HbInputVirtualRockerPrivate
       
    51 {
       
    52 public:
       
    53     explicit HbInputVirtualRockerPrivate(HbInputVirtualRocker *rocker, HbInputVkbWidget* parent = 0);
       
    54     ~HbInputVirtualRockerPrivate();
       
    55     int rockerEventRepeats(qreal distance);
       
    56     void setCenter();
       
    57 
       
    58 public:
       
    59     HbInputVirtualRocker *q_ptr;
       
    60     HbIcon* mIconNormal;
       
    61     HbInputVirtualRocker::RockerSelectionMode mShifted;
       
    62     QPointF mLastPoint;
       
    63     QPointF mCenterPosition;
       
    64     QPointF mPointerPosition;
       
    65     QPointF mMousePressPoint;
       
    66     HbInputVkbWidget* mKeyboard;
       
    67     bool mPressed;
       
    68 };
       
    69 
       
    70 HbInputVirtualRockerPrivate::HbInputVirtualRockerPrivate(HbInputVirtualRocker *rocker, HbInputVkbWidget* parent)
       
    71         : q_ptr(rocker),
       
    72           mIconNormal(0),
       
    73           mShifted(HbInputVirtualRocker::RockerSelectionModeOff),
       
    74           mLastPoint(0.0,0.0),
       
    75           mCenterPosition(0.0,0.0),
       
    76           mMousePressPoint(0.0,0.0),
       
    77           mKeyboard(parent),
       
    78           mPressed(false)
       
    79 {
       
    80     mIconNormal = new HbIcon("qtg_graf_trackpoint_normal" );
       
    81     mIconNormal->setSize( QSizeF( HbIconWidth, HbIconWidth ));
       
    82 }
       
    83 
       
    84 HbInputVirtualRockerPrivate::~HbInputVirtualRockerPrivate()
       
    85 {
       
    86     delete mIconNormal;
       
    87 }
       
    88 
       
    89 int HbInputVirtualRockerPrivate::rockerEventRepeats(qreal distance)
       
    90 {
       
    91     // cursor move multiplier for cursor moving signals, depending on the rocker move speed
       
    92     int repeats = 1;
       
    93     if (distance > 30){
       
    94         repeats = 30;
       
    95     } else if (distance > 20) {
       
    96         repeats = 10;
       
    97     } else if(distance > 10) {
       
    98         repeats = 2;
       
    99     }
       
   100     return repeats;
       
   101 }
       
   102 
       
   103 void HbInputVirtualRockerPrivate::setCenter()
       
   104 {
       
   105     if(mCenterPosition.isNull()){
       
   106         mCenterPosition.setX(q_ptr->pos().x()+HbRockerWidth/2);
       
   107         mCenterPosition.setY(q_ptr->pos().y()+HbRockerWidth/2);
       
   108     }
       
   109     mPointerPosition.setX((HbRockerWidth - HbPointerWidth)/2);
       
   110     mPointerPosition.setY((HbRockerWidth - HbPointerWidth)/2);
       
   111 }
       
   112 
       
   113 /// @endcond
       
   114 
       
   115 /*!
       
   116 @alpha
       
   117 @hbinput
       
   118 \class HbInputVirtualRocker
       
   119 \brief Virtual rocker widget for generating direction events from virtual keyboards.
       
   120 
       
   121 Virtual rocker is a virtual version of a mouse pointer decive commonly used in many laptop PC keyboards.
       
   122 It is typically embedded into virtual keyboards. It generates direction events which can be used for
       
   123 moving editor cursor, highlighting text, etc.
       
   124 
       
   125 User first presses virtual rocker widget and then slides finger to desired direction. The widget
       
   126 will emit direction events based on the direction of finger momvement, relative to the starting point.
       
   127 When the finger is lifted, rocker widget returns to normal state and stops sending events.
       
   128 
       
   129 Double clicking will start selection mode. Rocker appearance changes and direction events have shift modifier on
       
   130 but otherwise it behaves in similar manner as described above.
       
   131 
       
   132 \sa HbInputVkbWidget
       
   133 */
       
   134 /*!
       
   135 \enum HbInputVirtualRocker::RockerDirection
       
   136 
       
   137 This enum defines virtual rocker directions.
       
   138 */
       
   139 /*!
       
   140 \enum HbInputVirtualRocker::RockerSelectionMode
       
   141 
       
   142 This enum defines virtual rocker selection modes.
       
   143 */
       
   144 
       
   145 /*!
       
   146 Constructs the object.
       
   147 */
       
   148 HbInputVirtualRocker::HbInputVirtualRocker(HbInputVkbWidget* parent)
       
   149     : HbWidget(parent), d_ptr(new HbInputVirtualRockerPrivate(this, parent))
       
   150 {
       
   151     setOpacity(HbRockerDimOpacity);
       
   152 }
       
   153 
       
   154 /*!
       
   155 Constructs the object.
       
   156 */
       
   157 HbInputVirtualRocker::HbInputVirtualRocker(HbInputVirtualRockerPrivate &dd, QGraphicsWidget* parent)
       
   158     : HbWidget(parent), d_ptr(&dd)
       
   159 {
       
   160     setOpacity(HbRockerDimOpacity);
       
   161 }
       
   162 
       
   163 /*!
       
   164 Destroys the widget.
       
   165 */
       
   166 HbInputVirtualRocker::~HbInputVirtualRocker()
       
   167 {
       
   168     delete d_ptr;
       
   169 }
       
   170 
       
   171 /*!
       
   172     \reimp
       
   173     \sa QGraphicsWidget.
       
   174 */
       
   175 void HbInputVirtualRocker::mousePressEvent(QGraphicsSceneMouseEvent* event)
       
   176 {
       
   177     Q_D(HbInputVirtualRocker);
       
   178 
       
   179     QPointF position = event->pos();
       
   180     QPointF delta = position - QPointF(HbRockerWidth/2, HbRockerWidth/2);
       
   181 
       
   182     qreal squareDistance = delta.y()*delta.y() + delta.x()*delta.x();
       
   183     qreal squareRadius = HbRockerWidth*HbRockerWidth/4;
       
   184     if (squareRadius > squareDistance) {
       
   185         // the touch point is inside circle which diameter is HbRockerWidth
       
   186         d->setCenter();
       
   187         d->mLastPoint = position;
       
   188         d->mMousePressPoint = position;
       
   189         if (d->mKeyboard) {
       
   190             d->mKeyboard->setKeyboardDimmed(true);
       
   191         }
       
   192         HbWidgetFeedback::triggered(this, Hb::InstantPressed);
       
   193         setOpacity(HbRockerNormalOpacity);
       
   194         d->mPressed = true;
       
   195     } else {
       
   196         // outside of circle: give event to a push button
       
   197         event->ignore();
       
   198     }
       
   199 }
       
   200 
       
   201 /*!
       
   202     \reimp
       
   203     \sa QGraphicsWidget.
       
   204 */
       
   205 void HbInputVirtualRocker::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
       
   206 {
       
   207     Q_UNUSED(event)
       
   208     Q_D(HbInputVirtualRocker);
       
   209 
       
   210     if (d->mKeyboard) {
       
   211         d->mKeyboard->setKeyboardDimmed(false);
       
   212         setOpacity(HbRockerDimOpacity);
       
   213     }
       
   214     d->mPressed = false;
       
   215     update();
       
   216     d->setCenter();
       
   217     d->mShifted = RockerSelectionModeOff;
       
   218     HbWidgetFeedback::triggered(this, Hb::InstantReleased);
       
   219 }
       
   220 
       
   221 /*!
       
   222     \reimp
       
   223     \sa QGraphicsWidget.
       
   224 */
       
   225 void HbInputVirtualRocker::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
       
   226 {
       
   227     Q_D(HbInputVirtualRocker);
       
   228 
       
   229     if (event->buttons() != 0) {
       
   230         QPointF delta = event->pos() - d->mLastPoint;
       
   231         QPointF deltaPressLoc = event->pos() - d->mMousePressPoint;
       
   232         int repeats = 1;
       
   233 
       
   234         HbWidgetFeedback::triggered(this, Hb::InstantDraggedOver);
       
   235 
       
   236         if (delta.x() > HbRockerXThreshold) {
       
   237             repeats = d->rockerEventRepeats( delta.x() );
       
   238             for (int i = 0; i < repeats; i++) {
       
   239                 emit rockerDirection(HbRockerDirectionRight, d->mShifted);
       
   240             }
       
   241             d->mLastPoint = event->pos();
       
   242         } else if (delta.x() < -HbRockerXThreshold) {
       
   243             repeats = d->rockerEventRepeats( -delta.x() );
       
   244             for (int i = 0; i < repeats; i++) {
       
   245                 emit rockerDirection(HbRockerDirectionLeft, d->mShifted);
       
   246             }
       
   247             d->mLastPoint = event->pos();
       
   248         }
       
   249 
       
   250         if (delta.y() > HbRockerYThreshold) {
       
   251             repeats = d->rockerEventRepeats(delta.y());
       
   252             emit rockerDirection(HbRockerDirectionDown, d->mShifted);
       
   253             d->mLastPoint = event->pos();
       
   254         } else if (delta.y() < -HbRockerYThreshold) {
       
   255             emit rockerDirection(HbRockerDirectionUp, d->mShifted);
       
   256             d->mLastPoint = event->pos();
       
   257         }
       
   258 
       
   259         d->mPointerPosition = HbIconWidth * deltaPressLoc / d->mCenterPosition.x() / 2
       
   260             + QPointF((HbRockerWidth-HbPointerWidth)/2, (HbRockerWidth-HbPointerWidth)/2);
       
   261 
       
   262         update();
       
   263 
       
   264     }
       
   265 }
       
   266 
       
   267 /*!
       
   268     \reimp
       
   269     \sa QGraphicsWidget.
       
   270 */
       
   271 void HbInputVirtualRocker::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
       
   272 {
       
   273     Q_UNUSED(event)
       
   274     Q_D(HbInputVirtualRocker);
       
   275 
       
   276     if (d->mShifted == RockerSelectionModeOff) {
       
   277         d->mShifted = RockerSelectionModeOn;
       
   278     } else {
       
   279         d->mShifted = RockerSelectionModeOff;
       
   280     }
       
   281 
       
   282     // dim the keypad.
       
   283     if (d->mKeyboard) {
       
   284         d->mKeyboard->setKeyboardDimmed(true);
       
   285     }
       
   286     setOpacity(HbRockerNormalOpacity);
       
   287 }
       
   288 
       
   289 /*!
       
   290     \reimp
       
   291     \sa QGraphicsWidget.
       
   292 */
       
   293 void HbInputVirtualRocker::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
       
   294 {
       
   295     Q_UNUSED(option)
       
   296     Q_UNUSED(widget)
       
   297     Q_D(HbInputVirtualRocker);
       
   298 
       
   299     painter->setRenderHint(QPainter::Antialiasing, true);
       
   300 
       
   301     if (d->mIconNormal &&
       
   302         !d->mIconNormal->isNull()) {
       
   303         // We have icon, lets draw it.
       
   304 
       
   305         d->mIconNormal->paint(painter, rect(), Qt::IgnoreAspectRatio);
       
   306         if (d->mPressed) {
       
   307             painter->setBrush(Qt::blue);
       
   308             painter->setPen(Qt::blue);
       
   309             painter->drawEllipse(static_cast<int>(d->mPointerPosition.x()),
       
   310                                  static_cast<int>(d->mPointerPosition.y()),
       
   311                                  HbPointerWidth, HbPointerWidth);
       
   312         }
       
   313 
       
   314     } else {
       
   315         // Otherwise just draw a white ellipse as a fallback.
       
   316         painter->setBrush(Qt::white);
       
   317         painter->setPen(Qt::white);
       
   318         painter->drawEllipse(boundingRect());
       
   319     }
       
   320 }
       
   321 
       
   322 /*!
       
   323 Returns true if virtual rocker is in selection state, ie. it sends event with shift modifier
       
   324 on.
       
   325 */
       
   326 HbInputVirtualRocker::RockerSelectionMode HbInputVirtualRocker::selectionMode() const
       
   327 {
       
   328     Q_D(const HbInputVirtualRocker);
       
   329     return d->mShifted;
       
   330 }
       
   331 
       
   332 // End of file