Avoid the add-to-dictionary indicator from being clipped

With this CL, the display bounds is taken into consideration
when the location of add-to-dictionary indicator is determined.

BUG: 17578360
Change-Id: I31e458fa7bbc33e539578b331fe1c51ff7f8668e
main
Yohei Yukawa 2014-09-19 17:48:50 +09:00
parent 00e018370f
commit 9d2f606aa8
3 changed files with 42 additions and 28 deletions

View File

@ -49,7 +49,7 @@ public class TextDecorator {
private int mMode = MODE_MONITOR; private int mMode = MODE_MONITOR;
private String mLastComposingText = null; private String mLastComposingText = null;
private RectF mIndicatorBoundsForLastComposingText = new RectF(); private boolean mHasRtlCharsInLastComposingText = false;
private RectF mComposingTextBoundsForLastComposingText = new RectF(); private RectF mComposingTextBoundsForLastComposingText = new RectF();
private boolean mIsFullScreenMode = false; private boolean mIsFullScreenMode = false;
@ -241,20 +241,8 @@ public class TextDecorator {
right = Math.max(characterBounds.right, right); right = Math.max(characterBounds.right, right);
} }
mLastComposingText = composingTextString; mLastComposingText = composingTextString;
mHasRtlCharsInLastComposingText = useRtlLayout;
mComposingTextBoundsForLastComposingText.set(left, top, right, bottom); mComposingTextBoundsForLastComposingText.set(left, top, right, bottom);
// The height and width of the indicator is the same as the height of the composing
// text.
final float indicatorSize = bottom - top;
mIndicatorBoundsForLastComposingText.set(0.0f, 0.0f, indicatorSize, indicatorSize);
// The horizontal position of the indicator depends on the text direction.
final float indicatorTop = top;
final float indicatorLeft;
if (useRtlLayout) {
indicatorLeft = left - indicatorSize;
} else {
indicatorLeft = right;
}
mIndicatorBoundsForLastComposingText.offset(indicatorLeft, indicatorTop);
} }
final int selectionStart = info.getSelectionStart(); final int selectionStart = info.getSelectionStart();
@ -295,8 +283,8 @@ public class TextDecorator {
return; return;
} }
mUiOperator.layoutUi(matrix, mIndicatorBoundsForLastComposingText, mUiOperator.layoutUi(matrix, mComposingTextBoundsForLastComposingText,
mComposingTextBoundsForLastComposingText); mHasRtlCharsInLastComposingText);
} }
private void onClickIndicator() { private void onClickIndicator() {
@ -374,7 +362,7 @@ public class TextDecorator {
public void setOnClickListener(Runnable listener) { public void setOnClickListener(Runnable listener) {
} }
@Override @Override
public void layoutUi(Matrix matrix, RectF indicatorBounds, RectF composingTextBounds) { public void layoutUi(Matrix matrix, RectF composingTextBounds, boolean useRtlLayout) {
} }
}; };
} }

View File

@ -26,6 +26,7 @@ import android.graphics.Path;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
@ -50,6 +51,7 @@ public final class TextDecoratorUi implements TextDecoratorUiOperator {
private final PopupWindow mTouchEventWindow; private final PopupWindow mTouchEventWindow;
private final View mTouchEventWindowClickListenerView; private final View mTouchEventWindowClickListenerView;
private final float mHitAreaMarginInPixels; private final float mHitAreaMarginInPixels;
private final RectF mDisplayRect;
/** /**
* This constructor is designed to be called from {@link InputMethodService#setInputView(View)}. * This constructor is designed to be called from {@link InputMethodService#setInputView(View)}.
@ -64,6 +66,9 @@ public final class TextDecoratorUi implements TextDecoratorUiOperator {
R.integer.text_decorator_hit_area_margin_in_dp); R.integer.text_decorator_hit_area_margin_in_dp);
mHitAreaMarginInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHitAreaMarginInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
hitAreaMarginInDP, resources.getDisplayMetrics()); hitAreaMarginInDP, resources.getDisplayMetrics());
final DisplayMetrics displayMetrics = resources.getDisplayMetrics();
mDisplayRect = new RectF(0.0f, 0.0f, displayMetrics.widthPixels,
displayMetrics.heightPixels);
mLocalRootView = new RelativeLayout(context); mLocalRootView = new RelativeLayout(context);
mLocalRootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, mLocalRootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
@ -111,17 +116,40 @@ public final class TextDecoratorUi implements TextDecoratorUiOperator {
mTouchEventWindow.dismiss(); mTouchEventWindow.dismiss();
} }
private static final RectF getIndicatorBoundsInScreenCoordinates(final Matrix matrix,
final RectF composingTextBounds, final boolean showAtLeftSide) {
final float indicatorSize = composingTextBounds.height();
final RectF indicatorBounds;
if (showAtLeftSide) {
indicatorBounds = new RectF(composingTextBounds.left - indicatorSize,
composingTextBounds.top, composingTextBounds.left,
composingTextBounds.top + indicatorSize);
} else {
indicatorBounds = new RectF(composingTextBounds.right, composingTextBounds.top,
composingTextBounds.right + indicatorSize,
composingTextBounds.top + indicatorSize);
}
matrix.mapRect(indicatorBounds);
return indicatorBounds;
}
@Override @Override
public void layoutUi(final Matrix matrix, final RectF indicatorBounds, public void layoutUi(final Matrix matrix, final RectF composingTextBounds,
final RectF composingTextBounds) { final boolean useRtlLayout) {
final RectF indicatorBoundsInScreenCoordinates = new RectF(); RectF indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix,
matrix.mapRect(indicatorBoundsInScreenCoordinates, indicatorBounds); composingTextBounds, useRtlLayout /* showAtLeftSide */);
if (indicatorBoundsInScreenCoordinates.left < mDisplayRect.left ||
mDisplayRect.right < indicatorBoundsInScreenCoordinates.right) {
// The indicator is clipped by the screen. Show the indicator at the opposite side.
indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix,
composingTextBounds, !useRtlLayout /* showAtLeftSide */);
}
mAddToDictionaryIndicatorView.setBounds(indicatorBoundsInScreenCoordinates); mAddToDictionaryIndicatorView.setBounds(indicatorBoundsInScreenCoordinates);
final RectF hitAreaBounds = new RectF(composingTextBounds);
hitAreaBounds.union(indicatorBounds);
final RectF hitAreaBoundsInScreenCoordinates = new RectF(); final RectF hitAreaBoundsInScreenCoordinates = new RectF();
matrix.mapRect(hitAreaBoundsInScreenCoordinates, hitAreaBounds); matrix.mapRect(hitAreaBoundsInScreenCoordinates, composingTextBounds);
hitAreaBoundsInScreenCoordinates.union(indicatorBoundsInScreenCoordinates);
hitAreaBoundsInScreenCoordinates.inset(-mHitAreaMarginInPixels, -mHitAreaMarginInPixels); hitAreaBoundsInScreenCoordinates.inset(-mHitAreaMarginInPixels, -mHitAreaMarginInPixels);
final int[] originScreen = new int[2]; final int[] originScreen = new int[2];

View File

@ -17,7 +17,6 @@
package com.android.inputmethod.keyboard; package com.android.inputmethod.keyboard;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF; import android.graphics.RectF;
/** /**
@ -45,9 +44,8 @@ public interface TextDecoratorUiOperator {
/** /**
* Called when the layout should be updated. * Called when the layout should be updated.
* @param matrix The matrix that transforms the local coordinates into the screen coordinates. * @param matrix The matrix that transforms the local coordinates into the screen coordinates.
* @param indicatorBounds The bounding box of the indicator, in local coordinates.
* @param composingTextBounds The bounding box of the composing text, in local coordinates. * @param composingTextBounds The bounding box of the composing text, in local coordinates.
* @param useRtlLayout {@code true} if the indicator should be optimized for RTL layout.
*/ */
void layoutUi(final Matrix matrix, final RectF indicatorBounds, void layoutUi(final Matrix matrix, final RectF composingTextBounds, final boolean useRtlLayout);
final RectF composingTextBounds);
} }