Merge "[Scribe] Support setTransformationMethod in insert mode"

This commit is contained in:
Haoyu Zhang
2023-02-16 20:41:53 +00:00
committed by Android (Google) Code Review
3 changed files with 73 additions and 9 deletions

View File

@@ -80,12 +80,34 @@ public class InsertModeTransformationMethod implements TransformationMethod, Tex
*/
public InsertModeTransformationMethod(@IntRange(from = 0) int offset, boolean singleLine,
@NonNull TransformationMethod oldTransformationMethod) {
mStart = offset;
mEnd = offset;
this(offset, offset, singleLine, oldTransformationMethod);
}
private InsertModeTransformationMethod(int start, int end, boolean singleLine,
@NonNull TransformationMethod oldTransformationMethod) {
mStart = start;
mEnd = end;
mSingleLine = singleLine;
mOldTransformationMethod = oldTransformationMethod;
}
/**
* Create a new {@code InsertModeTransformation} with the given new inner
* {@code oldTransformationMethod} and the {@code singleLine} value. The returned
* {@link InsertModeTransformationMethod} will keep the highlight range.
*
* @param oldTransformationMethod the updated inner transformation method at the
* {@link android.widget.TextView}.
* @param singleLine the updated singleLine value.
* @return the new {@link InsertModeTransformationMethod} with the updated
* {@code oldTransformationMethod} and {@code singleLine} value.
*/
public InsertModeTransformationMethod update(TransformationMethod oldTransformationMethod,
boolean singleLine) {
return new InsertModeTransformationMethod(mStart, mEnd, singleLine,
oldTransformationMethod);
}
public TransformationMethod getOldTransformationMethod() {
return mOldTransformationMethod;
}

View File

@@ -8072,7 +8072,7 @@ public class Editor {
final boolean isSingleLine = mTextView.isSingleLine();
mInsertModeTransformationMethod = new InsertModeTransformationMethod(offset,
isSingleLine, oldTransformationMethod);
mTextView.setTransformationMethod(mInsertModeTransformationMethod);
mTextView.setTransformationMethodInternal(mInsertModeTransformationMethod);
Selection.setSelection((Spannable) mTextView.getText(), offset);
mIsInsertModeActive = true;
@@ -8083,11 +8083,6 @@ public class Editor {
if (!mIsInsertModeActive) return;
if (mInsertModeTransformationMethod == null
|| mInsertModeTransformationMethod != mTextView.getTransformationMethod()) {
// If mInsertionModeTransformationMethod doesn't match the one on TextView,
// something else have changed the TextView's TransformationMethod while the
// insertion mode is active. We don't need to restore the oldTransformationMethod.
// TODO(265871733): support the case where setTransformationMethod is called in
// the insert mode.
mIsInsertModeActive = false;
return;
}
@@ -8097,7 +8092,7 @@ public class Editor {
final int selectionEnd = mTextView.getSelectionEnd();
final TransformationMethod oldTransformationMethod =
mInsertModeTransformationMethod.getOldTransformationMethod();
mTextView.setTransformationMethod(oldTransformationMethod);
mTextView.setTransformationMethodInternal(oldTransformationMethod);
Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
mIsInsertModeActive = false;
}
@@ -8118,6 +8113,25 @@ public class Editor {
layout.getSelection(highlightStart, highlightEnd, consumer);
}
}
/**
* Notify the {@link InsertModeController} before the TextView's
* {@link TransformationMethod} is updated. If it's not in the insert mode,
* the given method is directly returned. Otherwise, it will wrap the given transformation
* method with an {@link InsertModeTransformationMethod} and then return.
*
* @param oldTransformationMethod the new {@link TransformationMethod} to be set on the
* TextView.
* @return the updated {@link TransformationMethod} to be set on the Textview.
*/
TransformationMethod updateTransformationMethod(
TransformationMethod oldTransformationMethod) {
if (!mIsInsertModeActive) return oldTransformationMethod;
mInsertModeTransformationMethod = mInsertModeTransformationMethod.update(
oldTransformationMethod, mTextView.isSingleLine());
return mInsertModeTransformationMethod;
}
}
boolean enterInsertMode(int offset) {
@@ -8133,6 +8147,26 @@ public class Editor {
mInsertModeController.exitInsertMode();
}
/**
* Called by the {@link TextView} when the {@link TransformationMethod} is updated.
*
* @param method the {@link TransformationMethod} to be set on the TextView.
*/
void setTransformationMethod(TransformationMethod method) {
if (mInsertModeController == null || !mInsertModeController.mIsInsertModeActive) {
mTextView.setTransformationMethodInternal(method);
return;
}
// Changing TransformationMethod will reset selection range to [0, 0), we need to
// manually restore the old selection range.
final int selectionStart = mTextView.getSelectionStart();
final int selectionEnd = mTextView.getSelectionEnd();
method = mInsertModeController.updateTransformationMethod(method);
mTextView.setTransformationMethodInternal(method);
Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
}
/**
* Initializes the nodeInfo with smart actions.
*/

View File

@@ -2769,6 +2769,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_singleLine
*/
public final void setTransformationMethod(TransformationMethod method) {
if (mEditor != null) {
mEditor.setTransformationMethod(method);
} else {
setTransformationMethodInternal(method);
}
}
void setTransformationMethodInternal(@Nullable TransformationMethod method) {
if (method == mTransformation) {
// Avoid the setText() below if the transformation is
// the same.