src/hbwidgets/editors/hbselectioncontrol_p.cpp
changeset 21 4633027730f5
parent 7 923ff622b8b9
--- a/src/hbwidgets/editors/hbselectioncontrol_p.cpp	Tue Jul 06 14:36:53 2010 +0300
+++ b/src/hbwidgets/editors/hbselectioncontrol_p.cpp	Wed Aug 18 10:05:37 2010 +0300
@@ -74,6 +74,11 @@
     Q_DECLARE_PUBLIC(HbSelectionControl)
 
 public:
+    enum HandleType {
+        DummyHandle,
+        SelectionStartHandle,
+        SelectionEndHandle
+    };
     HbSelectionControlPrivate();
     void init();
     void createPrimitives();
@@ -81,11 +86,10 @@
                       Qt::AlignmentFlag handleAlignment,
                       QGraphicsItem *handle,
                       QGraphicsItem *handleTouchArea,
-                      HbStyle::Primitive handlePrimitive);
+                      HbStylePrivate::Primitive handlePrimitive);
     QGraphicsItem * reparent(QGraphicsItem *item);
     void reparent(QGraphicsItem *item, QGraphicsItem *newParent);
     void reparentHandles(QGraphicsItem *newParent);
-    void tapGestureFinished (const QPointF& point);
     void panGestureStarted (HbPanGesture *gesture);
     void panGestureUpdated (HbPanGesture *gesture);
     void panGestureFinished (HbPanGesture *gesture);
@@ -97,15 +101,17 @@
 
     HbAbstractEdit *mEdit;
     QGraphicsItem *mTopLevelAncestor;
+    QPointF mTouchOffset;
 
     QGraphicsItem *mSelectionStartHandle;
     QGraphicsItem *mSelectionEndHandle;
     HbTouchArea* mSelectionStartTouchArea;
     HbTouchArea* mSelectionEndTouchArea;
 
-    HbSelectionControl::HandleType mPressed;
+    HandleType mPressed;
     bool mPanInProgress;
     QBasicTimer mWordSnapTimer;
+    qreal mLastCursorHeight;
 };
 
 
@@ -116,8 +122,9 @@
     mSelectionEndHandle(0),
     mSelectionStartTouchArea(0),
     mSelectionEndTouchArea(0),
-    mPressed(HbSelectionControl::HandleType(0)),
-    mPanInProgress(false)
+    mPressed(HandleType(0)),
+    mPanInProgress(false),
+    mLastCursorHeight(0.0)
 {    
 }
 
@@ -132,10 +139,8 @@
     itemFlags |=  QGraphicsItem::ItemSendsGeometryChanges;
 #endif
     itemFlags &= ~QGraphicsItem::ItemIsFocusable;
-    itemFlags |=  QGraphicsItem::ItemIsPanel;
     q->setFlags(itemFlags);
     q->setFocusPolicy(Qt::NoFocus);
-    q->setActive(false);
 
     // Control will handle all events going to different handlers.
     q->setHandlesChildEvents(true);
@@ -145,24 +150,18 @@
 {
     Q_Q(HbSelectionControl);
     if (!mSelectionStartHandle) {
-        mSelectionStartHandle = q->style()->createPrimitive(HbStyle::P_SelectionControl_selectionstart, q);
-        mSelectionStartHandle->setFlag(QGraphicsItem::ItemIsPanel);
+        mSelectionStartHandle = HbStylePrivate::createPrimitive(HbStylePrivate::P_SelectionControl_selectionstart, q);
         mSelectionStartHandle->setFlag(QGraphicsItem::ItemIsFocusable,false);
-        mSelectionStartHandle->setActive(false);
     }
 
     if (!mSelectionEndHandle) {
-        mSelectionEndHandle = q->style()->createPrimitive(HbStyle::P_SelectionControl_selectionend, q);
-        mSelectionEndHandle->setFlag(QGraphicsItem::ItemIsPanel);
+        mSelectionEndHandle = HbStylePrivate::createPrimitive(HbStylePrivate::P_SelectionControl_selectionend, q);
         mSelectionEndHandle->setFlag(QGraphicsItem::ItemIsFocusable,false);
-        mSelectionEndHandle->setActive(false);
     }
 
     if (!mSelectionStartTouchArea) {
         mSelectionStartTouchArea = new HbTouchArea(q);
-        mSelectionStartTouchArea->setFlag(QGraphicsItem::ItemIsPanel);
         mSelectionStartTouchArea->setFlag(QGraphicsItem::ItemIsFocusable,false);
-        mSelectionStartTouchArea->setActive(false);
         HbStyle::setItemName(mSelectionStartTouchArea, "handle-toucharea");
         mSelectionStartTouchArea->grabGesture(Qt::TapGesture);
         mSelectionStartTouchArea->grabGesture(Qt::PanGesture);
@@ -170,9 +169,7 @@
 
     if (!mSelectionEndTouchArea) {
         mSelectionEndTouchArea = new HbTouchArea(q);
-        mSelectionEndTouchArea->setFlag(QGraphicsItem::ItemIsPanel);
         mSelectionEndTouchArea->setFlag(QGraphicsItem::ItemIsFocusable,false);
-        mSelectionEndTouchArea->setActive(false);
         HbStyle::setItemName(mSelectionEndTouchArea, "handle-toucharea");
         mSelectionEndTouchArea->grabGesture(Qt::TapGesture);
         mSelectionEndTouchArea->grabGesture(Qt::PanGesture);
@@ -188,16 +185,17 @@
                   Qt::AlignmentFlag handleAlignment,
                   QGraphicsItem *handle,
                   QGraphicsItem *handleTouchArea,
-                  HbStyle::Primitive handlePrimitive)
+                  HbStylePrivate::Primitive handlePrimitive)
 {    
     Q_Q(HbSelectionControl);
 
     HbStyleOption option;
 
     q->initStyleOption(&option);
-    mEdit->style()->updatePrimitive(handle, handlePrimitive, &option);
+    HbStylePrivate::updatePrimitive(handle, handlePrimitive, &option);
 
     QRectF rect = mEdit->rectForPosition(newHandlePos,Qt::AlignTop?QTextLine::Leading:QTextLine::Trailing);
+    mLastCursorHeight = rect.height();
 
     // Convert rect to handle's parent coordinate system
     rect = handle->parentItem()->mapRectFromItem(mEdit,rect);
@@ -215,10 +213,13 @@
 
     handle->setPos(boundingRect.topLeft());
 
-    // Center handle touch area around center pos of handle
+    // Position handle touch area around center-top of handle
     QPointF centerPos = boundingRect.center();
+    rect = boundingRect;
     boundingRect = handleTouchArea->boundingRect();
     boundingRect.moveCenter(centerPos);
+    boundingRect.moveTop(rect.top());
+
     handleTouchArea->setPos(boundingRect.topLeft());
 
     if (!mPanInProgress) {
@@ -256,20 +257,11 @@
 
 void HbSelectionControlPrivate::reparent(QGraphicsItem *item, QGraphicsItem *newParent)
 {
-    Q_Q(HbSelectionControl);
-
     if (item && newParent && newParent != item->parentItem()) {
 
         // Reparent handle items to newParent
         QPointF pos = newParent->mapFromItem(item->parentItem(),item->pos());
 
-        // If the item is parented to other then q we have to
-        // turn off the QGraphicsItem::ItemIsPanel flag because
-        // otherwise the new parent loses its activeness.
-        bool enablePanel = (newParent == q);
-
-        item->setFlag(QGraphicsItem::ItemIsPanel,enablePanel);
-
         // TODO: This is a workaround for a Qt bug when reparenting from a clipping parent to a
         //       non-clipping parent
         item->setParentItem(0);
@@ -287,37 +279,30 @@
     reparent(mSelectionEndTouchArea, newParent);
 }
 
-
-void HbSelectionControlPrivate::tapGestureFinished(const QPointF &pos)
-{
-    if (mEdit->contextMenuFlags().testFlag(Hb::ShowTextContextMenuOnSelectionClicked)) {
-        mEdit->showContextMenu(pos);
-    }
-}
-
 void HbSelectionControlPrivate::panGestureStarted(HbPanGesture *gesture)
 {
     Q_Q(HbSelectionControl);
 
     QPointF point = q->mapFromScene(gesture->sceneStartPos());
-    mPressed = HbSelectionControl::DummyHandle;
+    mPressed = DummyHandle;
 
     // Find out which handle is being moved
     if (mSelectionStartTouchArea->contains(q->mapToItem(mSelectionStartTouchArea, point))) {
-        mPressed = HbSelectionControl::SelectionStartHandle;
+        mPressed = SelectionStartHandle;
+        mTouchOffset = mSelectionStartHandle->pos() - point;
     }
     if (mSelectionEndTouchArea->contains(q->mapToItem(mSelectionEndTouchArea, point))) {
         bool useArea = true;
-        if(mPressed != HbSelectionControl::DummyHandle) {
+        if(mPressed != DummyHandle) {
 
             // The press point was inside in both of the touch areas
             // choose the touch area whose center is closer to the press point
-            QRectF rect = mSelectionStartTouchArea->boundingRect();
-            rect.moveTopLeft(mSelectionStartTouchArea->pos());
+            QRectF rect = mSelectionStartHandle->boundingRect();
+            rect.moveTopLeft(mSelectionStartHandle->pos());
             QLineF  lineEventPosSelStartCenter(point,rect.center());
 
-            rect = mSelectionEndTouchArea->boundingRect();
-            rect.moveTopLeft(mSelectionEndTouchArea->pos());
+            rect = mSelectionEndHandle->boundingRect();
+            rect.moveTopLeft(mSelectionEndHandle->pos());
             QLineF  lineEventPosSelEndCenter(point,rect.center());
 
             if (lineEventPosSelStartCenter.length() < lineEventPosSelEndCenter.length()) {
@@ -325,11 +310,12 @@
             }
         }
         if (useArea) {
-            mPressed = HbSelectionControl::SelectionEndHandle;
+            mPressed = SelectionEndHandle;
+            mTouchOffset = mSelectionEndHandle->pos() - point;
         }
     }
 
-    if (mPressed == HbSelectionControl::DummyHandle) {
+    if (mPressed == DummyHandle) {
         // Hit is outside touch areas, ignore
         return;
     }
@@ -340,7 +326,7 @@
     int selStartPos = qMin(mEdit->textCursor().anchor(),mEdit->textCursor().position());
     int selEndPos = qMax(mEdit->textCursor().anchor(),mEdit->textCursor().position());
 
-    if (mPressed == HbSelectionControl::SelectionStartHandle) {
+    if (mPressed == SelectionStartHandle) {
         cursor.setPosition(selEndPos);
         cursor.setPosition(selStartPos, QTextCursor::KeepAnchor);
     } else {
@@ -373,7 +359,7 @@
         mEdit->setTextCursor(cursor);
     }
 
-    mPressed = HbSelectionControl::DummyHandle;
+    mPressed = DummyHandle;
     q->updatePrimitives();
 }
 
@@ -396,15 +382,15 @@
 
     QRectF handleRect = mSelectionStartHandle->boundingRect();
 
-    handleRect.moveCenter(editPos);
+    handleRect.moveTopLeft(editPos + mTouchOffset);
 
     // Set hitTestPos based on which handle was grabbed
     QPointF hitTestPos = handleRect.center();
 
-    if (mPressed == HbSelectionControl::SelectionStartHandle) {
-        hitTestPos.setY(handleRect.bottom()+1);
+    if (mPressed == SelectionStartHandle) {
+        hitTestPos.setY(handleRect.bottom()+mLastCursorHeight/2);
     } else {
-        hitTestPos.setY(handleRect.top()-1);
+        hitTestPos.setY(handleRect.top()-mLastCursorHeight/2);
     }
 
     // Override hitTestPos if origEditPos was outside the canvas
@@ -610,26 +596,14 @@
 
 void HbSelectionControl::gestureEvent(QGestureEvent* event) {
     Q_D(HbSelectionControl);
+
     if(HbTapGesture *tap = qobject_cast<HbTapGesture*>(event->gesture(Qt::TapGesture))) {
-        QPointF pos = event->mapToGraphicsScene(tap->position());
-        switch(tap->state()) {
-        case Qt::GestureStarted:
-            if (d->mEdit) {
-                HbWidgetFeedback::triggered(this, Hb::InstantPressed);
-            }
-            break;
-        case Qt::GestureUpdated:
-            break;
-      case Qt::GestureFinished:
-            if (d->mEdit) {
-                d->tapGestureFinished(pos);
-                HbWidgetFeedback::triggered(this, Hb::InstantReleased);
-            }
-            break;
-      case Qt::GestureCanceled:
-            break;
-      default:
-            break;
+        if (d->mEdit && tap->tapStyleHint() != HbTapGesture::TapAndHold) {
+            d->mEdit->gestureEvent(event);
+            // Cancel HbAbstractEdit gesture overriding settings
+            tap->setProperty(HbPrivate::ThresholdRect.latin1(), QVariant());
+            scene()->setProperty(HbPrivate::OverridingGesture.latin1(),QVariant());
+            HbWidgetFeedback::triggered(this, Hb::InstantPressed);
         }
     }
 
@@ -682,8 +656,8 @@
             int selStartPos = qMin(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position());
             int selEndPos = qMax(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position());
 
-            d->updateHandle(selStartPos,Qt::AlignTop,d->mSelectionStartHandle,d->mSelectionStartTouchArea,HbStyle::P_SelectionControl_selectionstart);
-            d->updateHandle(selEndPos,Qt::AlignBottom,d->mSelectionEndHandle,d->mSelectionEndTouchArea,HbStyle::P_SelectionControl_selectionend);
+            d->updateHandle(selStartPos,Qt::AlignTop,d->mSelectionStartHandle,d->mSelectionStartTouchArea,HbStylePrivate::P_SelectionControl_selectionstart);
+            d->updateHandle(selEndPos,Qt::AlignBottom,d->mSelectionEndHandle,d->mSelectionEndTouchArea,HbStylePrivate::P_SelectionControl_selectionend);
         }
         else {
             hide();