Implement that a text selection handle can be moved over another text selection handle.
authorYuni Jeong <yhnet.jung@samsung.com>
Thu, 16 May 2013 13:20:24 +0000 (22:20 +0900)
committerGerrit Code Review <gerrit@gerrit.vlan144.tizendev.org>
Wed, 10 Jul 2013 03:06:32 +0000 (03:06 +0000)
[Title] Implement that a text selection handle can be moved over another text selection handle.
[Issue#] P130401-3601
[Problem] A text selection handle can not be moved another text selection handle.
[Cause] Not implemented.
[Solution] Implement that a text selection handle can be moved over another text selection handle.

Change-Id: I257c66a29e08059d6393c8fb3ecebe459ace46f6

Source/WebKit2/UIProcess/API/efl/tizen/TextSelection.cpp [changed mode: 0755->0644]
Source/WebKit2/UIProcess/API/efl/tizen/TextSelection.h
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp

old mode 100755 (executable)
new mode 100644 (file)
index 088e76d..470da01
@@ -47,6 +47,7 @@ TextSelection::TextSelection(EwkViewImpl* viewImpl)
 #if ENABLE(TIZEN_WEBKIT2_FOR_MOVING_TEXT_SELECTION_HANDLE_FROM_OSP)
       , m_selectedHandle(0)
 #endif
+      , m_handleMovingDirection(HandleMovingDirectionNormal)
 {
     ASSERT(viewWidget);
 
@@ -172,10 +173,18 @@ void TextSelection::updateHandlers()
     WebCore::IntPoint leftEvasPoint = toEvasTransform.mapPoint(leftRect.minXMaxYCorner());
     WebCore::IntPoint rightEvasPoint = toEvasTransform.mapPoint(rightRect.maxXMaxYCorner());
 
+    TextSelectionHandle* shownLeftHandle = m_leftHandle;
+    TextSelectionHandle* shownRightHandle = m_rightHandle;
+
+    if (m_handleMovingDirection == HandleMovingDirectionReverse) {
+        shownLeftHandle = m_rightHandle;
+        shownRightHandle = m_leftHandle;
+    }
+
     EditorState editorState = m_viewImpl->page()->editorState();
     if (editorState.isContentEditable) {
-        m_leftHandle->hide();
-        m_rightHandle->hide();
+        shownLeftHandle->hide();
+        shownRightHandle->hide();
 
         WebCore::IntRect editorRect = editorState.editorRect;
         WebCore::IntPoint editorLeftEvasPoint = toEvasTransform.mapPoint(editorRect.location());
@@ -185,21 +194,21 @@ void TextSelection::updateHandlers()
         evas_object_geometry_get(m_viewImpl->view(), &webViewX, &webViewY, &webViewWidth, &webViewHeight);
         if ((editorLeftEvasPoint.x() <= leftEvasPoint.x() && editorLeftEvasPoint.y() <= leftEvasPoint.y())
             && (webViewX <= leftEvasPoint.x() && webViewY <= leftEvasPoint.y())) {
-            m_leftHandle->move(leftEvasPoint, m_viewImpl->transformToScene().mapRect(leftRect));
-            m_leftHandle->show();
+            shownLeftHandle->move(leftEvasPoint, m_viewImpl->transformToScene().mapRect(leftRect));
+            shownLeftHandle->show();
         }
 
         if ((editorRightEvasPoint.x() >= rightEvasPoint.x() && editorRightEvasPoint.y() >= rightEvasPoint.y())
             && ((webViewX + webViewWidth) >= rightEvasPoint.x() && (webViewY <= rightEvasPoint.y() && (webViewY + webViewHeight) >= rightEvasPoint.y()))) {
-            m_rightHandle->move(rightEvasPoint, m_viewImpl->transformToScene().mapRect(rightRect));
-            m_rightHandle->show();
+            shownRightHandle->move(rightEvasPoint, m_viewImpl->transformToScene().mapRect(rightRect));
+            shownRightHandle->show();
         }
     } else {
-        m_leftHandle->move(leftEvasPoint, m_viewImpl->transformToScene().mapRect(leftRect));
-        m_leftHandle->show();
+        shownLeftHandle->move(leftEvasPoint, m_viewImpl->transformToScene().mapRect(leftRect));
+        shownLeftHandle->show();
 
-        m_rightHandle->move(rightEvasPoint, m_viewImpl->transformToScene().mapRect(rightRect));
-        m_rightHandle->show();
+        shownRightHandle->move(rightEvasPoint, m_viewImpl->transformToScene().mapRect(rightRect));
+        shownRightHandle->show();
     }
 }
 
@@ -350,13 +359,17 @@ void TextSelection::hideContextMenu()
 
 void TextSelection::setLeftSelectionToEvasPoint(const IntPoint& evasPoint)
 {
-    m_viewImpl->page()->setLeftSelection(m_viewImpl->transformFromScene().mapPoint(evasPoint));
+    int result = m_viewImpl->page()->setLeftSelection(m_viewImpl->transformFromScene().mapPoint(evasPoint), m_handleMovingDirection);
+    if (result)
+        m_handleMovingDirection = result;
     updateHandlers();
 }
 
 void TextSelection::setRightSelectionToEvasPoint(const IntPoint& evasPoint)
 {
-    m_viewImpl->page()->setRightSelection(m_viewImpl->transformFromScene().mapPoint(evasPoint));
+    int result = m_viewImpl->page()->setRightSelection(m_viewImpl->transformFromScene().mapPoint(evasPoint), m_handleMovingDirection);
+    if (result)
+        m_handleMovingDirection = result;
     updateHandlers();
 }
 
@@ -402,7 +415,10 @@ void TextSelection::handleMouseMove(TextSelectionHandle* handle, const IntPoint&
 
 void TextSelection::handleMouseUp(TextSelectionHandle* /* handle */, const IntPoint& /* position */)
 {
+    m_handleMovingDirection = HandleMovingDirectionNormal;
+
     hideMagnifier();
+    updateHandlers();
     showContextMenu();
 }
 
index 2337a7c..dcfbb1f 100644 (file)
@@ -54,6 +54,12 @@ public:
     }
     ~TextSelection();
 
+    enum HandleMovingDirection {
+        HandleMovingDirectionNone = 0,
+        HandleMovingDirectionNormal,
+        HandleMovingDirectionReverse,
+    };
+
     void update();
     bool isTextSelectionDowned() { return m_isTextSelectionDowned; }
     void setIsTextSelectionDowned(bool isTextSelectionDowned) { m_isTextSelectionDowned = isTextSelectionDowned; }
@@ -130,6 +136,7 @@ private:
 #if ENABLE(TIZEN_WEBKIT2_FOR_MOVING_TEXT_SELECTION_HANDLE_FROM_OSP)
     TextSelectionHandle* m_selectedHandle;
 #endif
+    int m_handleMovingDirection;
 };
 
 } // namespace WebKit
index d6c8e4c..24ef015 100755 (executable)
@@ -1003,8 +1003,8 @@ public:
 
 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
     bool selectClosestWord(const WebCore::IntPoint&);
-    bool setLeftSelection(const WebCore::IntPoint&);
-    bool setRightSelection(const WebCore::IntPoint&);
+    int setLeftSelection(const WebCore::IntPoint&, const int direction);
+    int setRightSelection(const WebCore::IntPoint&, const int direction);
     bool getSelectionHandlers(WebCore::IntRect& leftRect, WebCore::IntRect& rightRect);
     String getSelectionText();
     bool selectionRangeClear();
index 32bd9f1..d3d538a 100755 (executable)
@@ -885,23 +885,23 @@ bool WebPageProxy::selectClosestWord(const IntPoint& point)
     return result;
 }
 
-bool WebPageProxy::setLeftSelection(const IntPoint& point)
+int WebPageProxy::setLeftSelection(const IntPoint& point, const int direction)
 {
     if (!isValid())
-        return false;
+        return 0;
 
-    bool result = false;
-    process()->sendSync(Messages::WebPage::SetLeftSelection(point), Messages::WebPage::SetLeftSelection::Reply(result), m_pageID);
+    int result = 0;
+    process()->sendSync(Messages::WebPage::SetLeftSelection(point, direction), Messages::WebPage::SetLeftSelection::Reply(result), m_pageID);
     return result;
 }
 
-bool WebPageProxy::setRightSelection(const IntPoint& point)
+int WebPageProxy::setRightSelection(const IntPoint& point, const int direction)
 {
     if (!isValid())
-        return false;
+        return 0;
 
-    bool result;
-    process()->sendSync(Messages::WebPage::SetRightSelection(point), Messages::WebPage::SetRightSelection::Reply(result), m_pageID);
+    int result = 0;
+    process()->sendSync(Messages::WebPage::SetRightSelection(point, direction), Messages::WebPage::SetRightSelection::Reply(result), m_pageID);
     return result;
 }
 
index 621ac80..8c69ad3 100755 (executable)
@@ -336,9 +336,14 @@ public:
     // FIXME: We could genericize these into a DrawingArea client interface. Would that be beneficial?
     void drawRect(WebCore::GraphicsContext&, const WebCore::IntRect&);
 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+    enum HandleMovingDirection {
+        HandleMovingDirectionNone = 0,
+        HandleMovingDirectionNormal,
+        HandleMovingDirectionReverse,
+    };
     void selectClosestWord(const WebCore::IntPoint&, bool& result);
-    void setLeftSelection(const WebCore::IntPoint&, bool& result);
-    void setRightSelection(const WebCore::IntPoint&, bool& result);
+    void setLeftSelection(const WebCore::IntPoint&, const int direction, int& result);
+    void setRightSelection(const WebCore::IntPoint&, const int direction, int& result);
     void getSelectionHandlers(WebCore::IntRect& leftRect, WebCore::IntRect& rightRect);
     void getSelectionText(String& result);
     void selectionRangeClear(bool& result);
index d815d43..86db050 100755 (executable)
@@ -379,8 +379,8 @@ messages -> WebPage {
 
 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
     SelectClosestWord(WebCore::IntPoint point) -> (bool result)
-    SetLeftSelection(WebCore::IntPoint point) -> (bool result)
-    SetRightSelection(WebCore::IntPoint point) -> (bool result)
+    SetLeftSelection(WebCore::IntPoint point, int direction) -> (int result)
+    SetRightSelection(WebCore::IntPoint point, int direction) -> (int result)
     GetSelectionHandlers() -> (WebCore::IntRect leftRect, WebCore::IntRect rightRect)
     GetSelectionText() -> (String result)
     SelectionRangeClear() -> (bool result)
index 015d5ea..ffeb668 100755 (executable)
@@ -1332,9 +1332,9 @@ void WebPage::selectClosestWord(const IntPoint& point, bool& result)
     result = true;
 }
 
-void WebPage::setLeftSelection(const IntPoint& point, bool& result)
+void WebPage::setLeftSelection(const IntPoint& point, const int direction, int& result)
 {
-    result = false;
+    result = HandleMovingDirectionNone;
 
     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
     FrameSelection* frameSelection = focusedFrame->selection();
@@ -1352,8 +1352,6 @@ void WebPage::setLeftSelection(const IntPoint& point, bool& result)
     IntPoint pos = frameView->windowToContents(point);
     IntRect leftRect, rightRect;
     getSelectionHandlers(leftRect, rightRect);
-    if ((rightRect.y() + rightRect.height()) < pos.y())
-        pos.setY(rightRect.y() + (rightRect.height()/2));
 
     if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
         const int boundariesWidth = 2;
@@ -1367,6 +1365,7 @@ void WebPage::setLeftSelection(const IntPoint& point, bool& result)
     }
 
     OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
+    Position base = frameSelection->base();
     Position extent = frameSelection->extent();
 
     Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
@@ -1374,8 +1373,7 @@ void WebPage::setLeftSelection(const IntPoint& point, bool& result)
     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
     // Check if the new position is before the extent's position
     if (newSelectionStartNode
-        && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()
-        && comparePositions(position->deepEquivalent(), extent) < 0) {
+        && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()) {
         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
         // We do it, because without this, the other modification of the selection
         // would destroy the 'start' and/or 'end' positions and set them to
@@ -1386,20 +1384,35 @@ void WebPage::setLeftSelection(const IntPoint& point, bool& result)
         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
         focusedFrame->view()->setProhibitsScrolling(true);
 
-        frameSelection->setBase(*position);
+        if (direction == HandleMovingDirectionNormal) {
+            if (comparePositions(position->deepEquivalent(), extent) < 0) {
+                frameSelection->setBase(*position);
+                result = HandleMovingDirectionNormal;
+            } else if (comparePositions(position->deepEquivalent(), extent) > 0) {
+                frameSelection->setExtent(*position);
+                frameSelection->setBase(extent);
+                result = HandleMovingDirectionReverse;
+            }
+        } else if (direction == HandleMovingDirectionReverse) {
+            if (comparePositions(position->deepEquivalent(), base) > 0) {
+                frameSelection->setExtent(*position);
+                result = HandleMovingDirectionReverse;
+            } else if (comparePositions(position->deepEquivalent(), base) < 0) {
+                frameSelection->setBase(*position);
+                frameSelection->setExtent(base);
+                result = HandleMovingDirectionNormal;
+            }
+        }
 
         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
         // This forces webkit to show selection
         // m_coreFrame->invalidateSelection();
-
-        result = true;
     }
 }
 
-
-void WebPage::setRightSelection(const IntPoint& point, bool& result)
+void WebPage::setRightSelection(const IntPoint& point, const int direction, int& result)
 {
-    result = false;
+    result = HandleMovingDirectionNone;
 
     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
     FrameSelection* frameSelection = focusedFrame->selection();
@@ -1429,14 +1442,14 @@ void WebPage::setRightSelection(const IntPoint& point, bool& result)
 
     OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
     Position base = frameSelection->base();
+    Position extent = frameSelection->extent();
 
     Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
 
     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
     // Check if the new position is after the base's position
     if (newSelectionEndNode
-        && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()
-        && comparePositions(position->deepEquivalent(), base) > 0) {
+        && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()) {
         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
         // We do it, because without this, the other modifications of the selection
         // would destroy the 'start' and/or 'end' positions and set them to
@@ -1448,11 +1461,27 @@ void WebPage::setRightSelection(const IntPoint& point, bool& result)
         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
         focusedFrame->view()->setProhibitsScrolling(true);
 
-        frameSelection->setExtent(*position);
+        if (direction == HandleMovingDirectionNormal) {
+            if (comparePositions(position->deepEquivalent(), base) > 0) {
+                frameSelection->setExtent(*position);
+                result = HandleMovingDirectionNormal;
+            } else if (comparePositions(position->deepEquivalent(), base) < 0) {
+                frameSelection->setBase(*position);
+                frameSelection->setExtent(base);
+                result = HandleMovingDirectionReverse;
+            }
+        } else if (direction == HandleMovingDirectionReverse) {
+            if (comparePositions(position->deepEquivalent(), extent) < 0) {
+                frameSelection->setBase(*position);
+                result = HandleMovingDirectionReverse;
+            } else if (comparePositions(position->deepEquivalent(), extent) > 0) {
+                frameSelection->setExtent(*position);
+                frameSelection->setBase(extent);
+                result = HandleMovingDirectionNormal;
+            }
+        }
 
         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
-
-        result = true;
     }
 }