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 String mLastComposingText = null;
private RectF mIndicatorBoundsForLastComposingText = new RectF();
private boolean mHasRtlCharsInLastComposingText = false;
private RectF mComposingTextBoundsForLastComposingText = new RectF();
private boolean mIsFullScreenMode = false;
@ -241,20 +241,8 @@ public class TextDecorator {
right = Math.max(characterBounds.right, right);
}
mLastComposingText = composingTextString;
mHasRtlCharsInLastComposingText = useRtlLayout;
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();
@ -295,8 +283,8 @@ public class TextDecorator {
return;
}
mUiOperator.layoutUi(matrix, mIndicatorBoundsForLastComposingText,
mComposingTextBoundsForLastComposingText);
mUiOperator.layoutUi(matrix, mComposingTextBoundsForLastComposingText,
mHasRtlCharsInLastComposingText);
}
private void onClickIndicator() {
@ -374,7 +362,7 @@ public class TextDecorator {
public void setOnClickListener(Runnable listener) {
}
@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.drawable.ColorDrawable;
import android.inputmethodservice.InputMethodService;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
@ -50,6 +51,7 @@ public final class TextDecoratorUi implements TextDecoratorUiOperator {
private final PopupWindow mTouchEventWindow;
private final View mTouchEventWindowClickListenerView;
private final float mHitAreaMarginInPixels;
private final RectF mDisplayRect;
/**
* 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);
mHitAreaMarginInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
hitAreaMarginInDP, resources.getDisplayMetrics());
final DisplayMetrics displayMetrics = resources.getDisplayMetrics();
mDisplayRect = new RectF(0.0f, 0.0f, displayMetrics.widthPixels,
displayMetrics.heightPixels);
mLocalRootView = new RelativeLayout(context);
mLocalRootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
@ -111,17 +116,40 @@ public final class TextDecoratorUi implements TextDecoratorUiOperator {
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
public void layoutUi(final Matrix matrix, final RectF indicatorBounds,
final RectF composingTextBounds) {
final RectF indicatorBoundsInScreenCoordinates = new RectF();
matrix.mapRect(indicatorBoundsInScreenCoordinates, indicatorBounds);
public void layoutUi(final Matrix matrix, final RectF composingTextBounds,
final boolean useRtlLayout) {
RectF indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix,
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);
final RectF hitAreaBounds = new RectF(composingTextBounds);
hitAreaBounds.union(indicatorBounds);
final RectF hitAreaBoundsInScreenCoordinates = new RectF();
matrix.mapRect(hitAreaBoundsInScreenCoordinates, hitAreaBounds);
matrix.mapRect(hitAreaBoundsInScreenCoordinates, composingTextBounds);
hitAreaBoundsInScreenCoordinates.union(indicatorBoundsInScreenCoordinates);
hitAreaBoundsInScreenCoordinates.inset(-mHitAreaMarginInPixels, -mHitAreaMarginInPixels);
final int[] originScreen = new int[2];

View File

@ -17,7 +17,6 @@
package com.android.inputmethod.keyboard;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
/**
@ -45,9 +44,8 @@ public interface TextDecoratorUiOperator {
/**
* Called when the layout should be updated.
* @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 useRtlLayout {@code true} if the indicator should be optimized for RTL layout.
*/
void layoutUi(final Matrix matrix, final RectF indicatorBounds,
final RectF composingTextBounds);
void layoutUi(final Matrix matrix, final RectF composingTextBounds, final boolean useRtlLayout);
}