Loading core/java/android/widget/TextView.java +95 −31 Original line number Diff line number Diff line Loading @@ -3869,7 +3869,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // - ExtractEditText does not call onFocus when it is displayed. Fixing this issue would // allow to test for hasSelection in onFocusChanged, which would trigger a // startTextSelectionMode here. TODO if (selectionController != null && hasSelection()) { if (this instanceof ExtractEditText && selectionController != null && hasSelection()) { startSelectionActionMode(); } Loading Loading @@ -5042,6 +5042,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void beginBatchEdit() { mInBatchEditControllers = true; final InputMethodState ims = mInputMethodState; if (ims != null) { int nesting = ++ims.mBatchEditNesting; Loading @@ -5064,6 +5065,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void endBatchEdit() { mInBatchEditControllers = false; final InputMethodState ims = mInputMethodState; if (ims != null) { int nesting = --ims.mBatchEditNesting; Loading Loading @@ -6991,26 +6993,21 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Restore previous selection Selection.setSelection((Spannable)mText, prevStart, prevEnd); if (mSelectionModifierCursorController != null && !mSelectionModifierCursorController.isShowing()) { if (hasSelectionController() && !getSelectionController().isShowing()) { // If the anchors aren't showing, revive them. mSelectionModifierCursorController.show(); } else { // Tapping inside the selection displays the cut/copy/paste context menu // as long as the anchors are already showing. showContextMenu(); getSelectionController().show(); } return; } else { // Tapping outside stops selection mode, if any stopSelectionActionMode(); if (mInsertionPointCursorController != null) { mInsertionPointCursorController.show(); if (hasInsertionController()) { getInsertionController().show(); } } } else if (hasSelection() && mSelectionModifierCursorController != null) { mSelectionModifierCursorController.show(); } else if (hasSelection() && hasSelectionController()) { getSelectionController().show(); } } Loading Loading @@ -7043,11 +7040,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getActionMasked(); if (mInsertionPointCursorController != null) { mInsertionPointCursorController.onTouchEvent(event); if (hasInsertionController()) { getInsertionController().onTouchEvent(event); } if (mSelectionModifierCursorController != null) { mSelectionModifierCursorController.onTouchEvent(event); if (hasSelectionController()) { getSelectionController().onTouchEvent(event); } if (action == MotionEvent.ACTION_DOWN) { Loading Loading @@ -7129,21 +7127,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener || windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW; } if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null && !mTextIsSelectable) { if (mInsertionPointCursorController == null) { mInsertionPointCursorController = new InsertionPointCursorController(); } } else { hideInsertionPointCursorController(); // TODO Add an extra android:cursorController flag to disable the controller? mInsertionControllerEnabled = windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null && !mTextIsSelectable; mSelectionControllerEnabled = windowSupportsHandles && textCanBeSelected() && mLayout != null; if (!mInsertionControllerEnabled) { mInsertionPointCursorController = null; } if (windowSupportsHandles && textCanBeSelected() && mLayout != null) { if (mSelectionModifierCursorController == null) { mSelectionModifierCursorController = new SelectionModifierCursorController(); } } else { if (!mSelectionControllerEnabled) { // Stop selection mode if the controller becomes unavailable. if (mSelectionModifierCursorController != null) { stopSelectionActionMode(); Loading Loading @@ -8348,6 +8342,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return true; } if (isInBatchEditMode()) { return false; } final int extendedPaddingTop = getExtendedPaddingTop(); final int extendedPaddingBottom = getExtendedPaddingBottom(); final int compoundPaddingLeft = getCompoundPaddingLeft(); Loading Loading @@ -8626,6 +8624,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void show() { if (isInBatchEditMode()) { return; } mIsShowing = true; updatePosition(); mStartHandle.show(); Loading Loading @@ -8689,6 +8691,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void updatePosition() { if (!isShowing()) { return; } final int selectionStart = getSelectionStart(); final int selectionEnd = getSelectionEnd(); Loading Loading @@ -8913,8 +8919,62 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } /** * @return True if this view supports insertion handles. */ boolean hasInsertionController() { return mInsertionControllerEnabled; } /** * @return True if this view supports selection handles. */ boolean hasSelectionController() { return mSelectionControllerEnabled; } CursorController getInsertionController() { if (!mInsertionControllerEnabled) { return null; } if (mInsertionPointCursorController == null) { mInsertionPointCursorController = new InsertionPointCursorController(); final ViewTreeObserver observer = getViewTreeObserver(); if (observer != null) { observer.addOnTouchModeChangeListener(mInsertionPointCursorController); } } return mInsertionPointCursorController; } CursorController getSelectionController() { if (!mSelectionControllerEnabled) { return null; } if (mSelectionModifierCursorController == null) { mSelectionModifierCursorController = new SelectionModifierCursorController(); final ViewTreeObserver observer = getViewTreeObserver(); if (observer != null) { observer.addOnTouchModeChangeListener(mSelectionModifierCursorController); } } return mSelectionModifierCursorController; } boolean isInBatchEditMode() { final InputMethodState ims = mInputMethodState; if (ims != null) { return ims.mBatchEditNesting > 0; } return mInBatchEditControllers; } @ViewDebug.ExportedProperty(category = "text") private CharSequence mText; private CharSequence mTransformed; private BufferType mBufferType = BufferType.NORMAL; Loading Loading @@ -8942,10 +9002,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private Blink mBlink; private boolean mCursorVisible = true; // Cursor Controllers. Null when disabled. // Cursor Controllers. private CursorController mInsertionPointCursorController; private CursorController mSelectionModifierCursorController; private ActionMode mSelectionActionMode; private boolean mInsertionControllerEnabled; private boolean mSelectionControllerEnabled; private boolean mInBatchEditControllers; // These are needed to desambiguate a long click. If the long click comes from ones of these, we // select from the current cursor position. Otherwise, select from long pressed position. private boolean mDPadCenterIsDown = false; Loading Loading
core/java/android/widget/TextView.java +95 −31 Original line number Diff line number Diff line Loading @@ -3869,7 +3869,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // - ExtractEditText does not call onFocus when it is displayed. Fixing this issue would // allow to test for hasSelection in onFocusChanged, which would trigger a // startTextSelectionMode here. TODO if (selectionController != null && hasSelection()) { if (this instanceof ExtractEditText && selectionController != null && hasSelection()) { startSelectionActionMode(); } Loading Loading @@ -5042,6 +5042,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void beginBatchEdit() { mInBatchEditControllers = true; final InputMethodState ims = mInputMethodState; if (ims != null) { int nesting = ++ims.mBatchEditNesting; Loading @@ -5064,6 +5065,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void endBatchEdit() { mInBatchEditControllers = false; final InputMethodState ims = mInputMethodState; if (ims != null) { int nesting = --ims.mBatchEditNesting; Loading Loading @@ -6991,26 +6993,21 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Restore previous selection Selection.setSelection((Spannable)mText, prevStart, prevEnd); if (mSelectionModifierCursorController != null && !mSelectionModifierCursorController.isShowing()) { if (hasSelectionController() && !getSelectionController().isShowing()) { // If the anchors aren't showing, revive them. mSelectionModifierCursorController.show(); } else { // Tapping inside the selection displays the cut/copy/paste context menu // as long as the anchors are already showing. showContextMenu(); getSelectionController().show(); } return; } else { // Tapping outside stops selection mode, if any stopSelectionActionMode(); if (mInsertionPointCursorController != null) { mInsertionPointCursorController.show(); if (hasInsertionController()) { getInsertionController().show(); } } } else if (hasSelection() && mSelectionModifierCursorController != null) { mSelectionModifierCursorController.show(); } else if (hasSelection() && hasSelectionController()) { getSelectionController().show(); } } Loading Loading @@ -7043,11 +7040,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getActionMasked(); if (mInsertionPointCursorController != null) { mInsertionPointCursorController.onTouchEvent(event); if (hasInsertionController()) { getInsertionController().onTouchEvent(event); } if (mSelectionModifierCursorController != null) { mSelectionModifierCursorController.onTouchEvent(event); if (hasSelectionController()) { getSelectionController().onTouchEvent(event); } if (action == MotionEvent.ACTION_DOWN) { Loading Loading @@ -7129,21 +7127,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener || windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW; } if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null && !mTextIsSelectable) { if (mInsertionPointCursorController == null) { mInsertionPointCursorController = new InsertionPointCursorController(); } } else { hideInsertionPointCursorController(); // TODO Add an extra android:cursorController flag to disable the controller? mInsertionControllerEnabled = windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null && !mTextIsSelectable; mSelectionControllerEnabled = windowSupportsHandles && textCanBeSelected() && mLayout != null; if (!mInsertionControllerEnabled) { mInsertionPointCursorController = null; } if (windowSupportsHandles && textCanBeSelected() && mLayout != null) { if (mSelectionModifierCursorController == null) { mSelectionModifierCursorController = new SelectionModifierCursorController(); } } else { if (!mSelectionControllerEnabled) { // Stop selection mode if the controller becomes unavailable. if (mSelectionModifierCursorController != null) { stopSelectionActionMode(); Loading Loading @@ -8348,6 +8342,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return true; } if (isInBatchEditMode()) { return false; } final int extendedPaddingTop = getExtendedPaddingTop(); final int extendedPaddingBottom = getExtendedPaddingBottom(); final int compoundPaddingLeft = getCompoundPaddingLeft(); Loading Loading @@ -8626,6 +8624,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void show() { if (isInBatchEditMode()) { return; } mIsShowing = true; updatePosition(); mStartHandle.show(); Loading Loading @@ -8689,6 +8691,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } public void updatePosition() { if (!isShowing()) { return; } final int selectionStart = getSelectionStart(); final int selectionEnd = getSelectionEnd(); Loading Loading @@ -8913,8 +8919,62 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } /** * @return True if this view supports insertion handles. */ boolean hasInsertionController() { return mInsertionControllerEnabled; } /** * @return True if this view supports selection handles. */ boolean hasSelectionController() { return mSelectionControllerEnabled; } CursorController getInsertionController() { if (!mInsertionControllerEnabled) { return null; } if (mInsertionPointCursorController == null) { mInsertionPointCursorController = new InsertionPointCursorController(); final ViewTreeObserver observer = getViewTreeObserver(); if (observer != null) { observer.addOnTouchModeChangeListener(mInsertionPointCursorController); } } return mInsertionPointCursorController; } CursorController getSelectionController() { if (!mSelectionControllerEnabled) { return null; } if (mSelectionModifierCursorController == null) { mSelectionModifierCursorController = new SelectionModifierCursorController(); final ViewTreeObserver observer = getViewTreeObserver(); if (observer != null) { observer.addOnTouchModeChangeListener(mSelectionModifierCursorController); } } return mSelectionModifierCursorController; } boolean isInBatchEditMode() { final InputMethodState ims = mInputMethodState; if (ims != null) { return ims.mBatchEditNesting > 0; } return mInBatchEditControllers; } @ViewDebug.ExportedProperty(category = "text") private CharSequence mText; private CharSequence mTransformed; private BufferType mBufferType = BufferType.NORMAL; Loading Loading @@ -8942,10 +9002,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private Blink mBlink; private boolean mCursorVisible = true; // Cursor Controllers. Null when disabled. // Cursor Controllers. private CursorController mInsertionPointCursorController; private CursorController mSelectionModifierCursorController; private ActionMode mSelectionActionMode; private boolean mInsertionControllerEnabled; private boolean mSelectionControllerEnabled; private boolean mInBatchEditControllers; // These are needed to desambiguate a long click. If the long click comes from ones of these, we // select from the current cursor position. Otherwise, select from long pressed position. private boolean mDPadCenterIsDown = false; Loading