Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java

Issue 11068010: Show selection handles around selected text. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: tweaked comments Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 7c35cf9bcfab312f296560040bfdad4ebbbc9e22..eefedeb359a05198c552ca161a0b06a787368691 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -186,13 +186,20 @@ public class ContentViewCore implements MotionEventDelegate {
private SelectionHandleController mSelectionHandleController;
private InsertionHandleController mInsertionHandleController;
+ // These offsets in document space with page scale normalized to 1.0.
+ private final PointF mStartHandleNormalizedPoint = new PointF();
+ private final PointF mEndHandleNormalizedPoint = new PointF();
+ private final PointF mInsertionHandleNormalizedPoint = new PointF();
// Tracks whether a selection is currently active. When applied to selected text, indicates
// whether the last selected text is still highlighted.
private boolean mHasSelection;
private String mLastSelectedText;
private boolean mSelectionEditable;
- private ActionMode mActionMode;
+ // TODO(husky@chromium.org): Register the necessary resources in
+ // ContentViewActivity so we can create an action bar for text editing.
+ // private ActionMode mActionMode;
+ private boolean mActionBarVisible; // Remove this when mActionMode is upstreamed.
// The legacy webview DownloadListener.
private DownloadListener mDownloadListener;
@@ -903,8 +910,10 @@ public class ContentViewCore implements MotionEventDelegate {
}
void hideSelectActionBar() {
- if (mActionMode != null) {
- mActionMode.finish();
+ if (mActionBarVisible) {
+ mActionBarVisible = false;
+ mImeAdapter.unselect();
+ getContentViewClient().onContextualActionBarHidden();
}
}
@@ -1170,6 +1179,8 @@ public class ContentViewCore implements MotionEventDelegate {
if (!mPopupZoomer.isShowing()) mPopupZoomer.setLastTouch(x, y);
if (isLongPress) {
+ getInsertionHandleController().allowAutomaticShowing();
+ getSelectionHandleController().allowAutomaticShowing();
if (mNativeContentViewCore != 0) {
nativeLongPress(mNativeContentViewCore, timeMs, x, y, false);
}
@@ -1260,8 +1271,28 @@ public class ContentViewCore implements MotionEventDelegate {
private SelectionHandleController getSelectionHandleController() {
if (mSelectionHandleController == null) {
- mSelectionHandleController = new SelectionHandleController(getContainerView());
- // TODO(olilan): add specific method implementations.
+ mSelectionHandleController = new SelectionHandleController(getContainerView()) {
+ @Override
+ public void selectBetweenCoordinates(int x1, int y1, int x2, int y2) {
+ if (mNativeContentViewCore != 0 && !(x1 == x2 && y1 == y2)) {
+ nativeSelectBetweenCoordinates(mNativeContentViewCore, x1, y1, x2, y2);
+ }
+ }
+
+ @Override
+ public void showHandlesAt(int x1, int y1, int dir1, int x2, int y2, int dir2) {
+ super.showHandlesAt(x1, y1, dir1, x2, y2, dir2);
+ mStartHandleNormalizedPoint.set(
+ (x1 + mNativeScrollX) / mNativePageScaleFactor,
+ (y1 + mNativeScrollY) / mNativePageScaleFactor);
+ mEndHandleNormalizedPoint.set(
+ (x2 + mNativeScrollX) / mNativePageScaleFactor,
+ (y2 + mNativeScrollY) / mNativePageScaleFactor);
+
+ showSelectActionBar();
+ }
+
+ };
mSelectionHandleController.hideAndDisallowAutomaticShowing();
}
@@ -1271,8 +1302,35 @@ public class ContentViewCore implements MotionEventDelegate {
private InsertionHandleController getInsertionHandleController() {
if (mInsertionHandleController == null) {
- mInsertionHandleController = new InsertionHandleController(getContainerView());
- // TODO(olilan): add specific method implementations.
+ mInsertionHandleController = new InsertionHandleController(getContainerView()) {
+ private static final int AVERAGE_LINE_HEIGHT = 14;
+
+ @Override
+ public void setCursorPosition(int x, int y) {
+ if (mNativeContentViewCore != 0) {
+ nativeSelectBetweenCoordinates(mNativeContentViewCore, x, y, x, y);
+ }
+ }
+
+ @Override
+ public void paste() {
+ mImeAdapter.paste();
+ hideHandles();
+ }
+
+ @Override
+ public int getLineHeight() {
+ return (int) (mNativePageScaleFactor * AVERAGE_LINE_HEIGHT);
+ }
+
+ @Override
+ public void showHandleAt(int x, int y) {
+ super.showHandleAt(x, y);
+ mInsertionHandleNormalizedPoint.set(
+ (x + mNativeScrollX) / mNativePageScaleFactor,
+ (y + mNativeScrollY) / mNativePageScaleFactor);
+ }
+ };
mInsertionHandleController.hideAndDisallowAutomaticShowing();
}
@@ -1280,59 +1338,39 @@ public class ContentViewCore implements MotionEventDelegate {
return mInsertionHandleController;
}
- private void showSelectActionBar() {
- if (mActionMode != null) {
- mActionMode.invalidate();
- return;
+ private void updateHandleScreenPositions() {
+ if (mSelectionHandleController != null && mSelectionHandleController.isShowing()) {
+ mSelectionHandleController.setStartHandlePosition(
+ (int) (mStartHandleNormalizedPoint.x * mNativePageScaleFactor
+ - mNativeScrollX),
bulach 2012/10/05 12:50:59 nit: I know this is the same downstream, but I thi
olilan 2012/10/05 13:43:59 AIUI the Java style is to break lines before opera
Iain Merrick 2012/10/05 19:01:52 As there are repeated expressions here, I'll just
+ (int) (mStartHandleNormalizedPoint.y * mNativePageScaleFactor
+ - mNativeScrollY));
+ mSelectionHandleController.setEndHandlePosition(
+ (int) (mEndHandleNormalizedPoint.x * mNativePageScaleFactor - mNativeScrollX),
+ (int) (mEndHandleNormalizedPoint.y * mNativePageScaleFactor - mNativeScrollY));
}
- // Start a new action mode with a SelectActionModeCallback.
olilan 2012/10/05 13:43:59 Do we need to remove this (seeing as we'll have to
Iain Merrick 2012/10/08 17:18:01 Oops, I didn't address this comment of Oli's. I'll
- SelectActionModeCallback.ActionHandler actionHandler =
- new SelectActionModeCallback.ActionHandler() {
- @Override
- public boolean selectAll() {
- return mImeAdapter.selectAll();
- }
-
- @Override
- public boolean cut() {
- return mImeAdapter.cut();
- }
-
- @Override
- public boolean copy() {
- return mImeAdapter.copy();
- }
-
- @Override
- public boolean paste() {
- return mImeAdapter.paste();
- }
-
- @Override
- public boolean isSelectionEditable() {
- return mSelectionEditable;
- }
+ if (mInsertionHandleController != null && mInsertionHandleController.isShowing()) {
+ mInsertionHandleController.setHandlePosition(
+ (int) (mInsertionHandleNormalizedPoint.x * mNativePageScaleFactor
+ - mNativeScrollX),
+ (int) (mInsertionHandleNormalizedPoint.y * mNativePageScaleFactor
+ - mNativeScrollY));
+ }
+ }
- @Override
- public String getSelectedText() {
- return ContentViewCore.this.getSelectedText();
- }
+ private void hideHandles() {
+ if (mSelectionHandleController != null) {
+ mSelectionHandleController.hideAndDisallowAutomaticShowing();
+ }
+ if (mInsertionHandleController != null) {
+ mInsertionHandleController.hideAndDisallowAutomaticShowing();
+ }
+ }
- @Override
- public void onDestroyActionMode() {
- mActionMode = null;
- mImeAdapter.unselect();
- getContentViewClient().onContextualActionBarHidden();
- }
- };
- mActionMode = mContainerView.startActionMode(
- getContentViewClient().getSelectActionModeCallback(getContext(), actionHandler,
- nativeIsIncognito(mNativeContentViewCore)));
- if (mActionMode == null) {
- // There is no ActionMode, so remove the selection.
- mImeAdapter.unselect();
- } else {
+ private void showSelectActionBar() {
+ if (!mActionBarVisible) {
+ mActionBarVisible = true;
getContentViewClient().onContextualActionBarShown();
}
}
@@ -1451,6 +1489,56 @@ public class ContentViewCore implements MotionEventDelegate {
@SuppressWarnings("unused")
@CalledByNative
+ private void onSelectionChanged(String text) {
+ mLastSelectedText = text;
+ }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ private void onSelectionBoundsChanged(Rect startRect, int dir1, Rect endRect, int dir2) {
+ int x1 = startRect.left;
+ int y1 = startRect.bottom;
+ int x2 = endRect.left;
+ int y2 = endRect.bottom;
+ if (x1 != x2 || y1 != y2) {
+ if (mInsertionHandleController != null) {
+ mInsertionHandleController.hide();
+ }
+ getSelectionHandleController().onSelectionChanged(x1, y1, dir1, x2, y2, dir2);
+ mHasSelection = true;
+ } else {
+ hideSelectActionBar();
+ if (x1 != 0 && y1 != 0
+ && (mSelectionHandleController == null
bulach 2012/10/05 12:50:59 nit: as above, operators in the previous lines.
Iain Merrick 2012/10/05 19:01:52 I think in this case I agree with Oli -- this is t
+ || !mSelectionHandleController.isDragging())
+ && mSelectionEditable) {
+ // Selection is a caret, and a text field is focused.
+ if (mSelectionHandleController != null) {
+ mSelectionHandleController.hide();
+ }
+ getInsertionHandleController().onCursorPositionChanged(x1, y1);
+ InputMethodManager manager = (InputMethodManager)
+ getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (manager.isWatchingCursor(mContainerView)) {
+ manager.updateCursor(mContainerView, startRect.left, startRect.top,
+ startRect.right, startRect.bottom);
+ }
+ } else {
+ // Deselection
+ if (mSelectionHandleController != null
+ && !mSelectionHandleController.isDragging()) {
+ mSelectionHandleController.hideAndDisallowAutomaticShowing();
+ }
+ if (mInsertionHandleController != null) {
+ mInsertionHandleController.hideAndDisallowAutomaticShowing();
+ }
+ }
+ mHasSelection = false;
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
private void onEvaluateJavaScriptResult(int id, String jsonResult) {
getContentViewClient().onEvaluateJavaScriptResult(id, jsonResult);
}

Powered by Google App Engine
This is Rietveld 408576698