summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/widget/PopupWindow.java30
-rw-r--r--core/java/android/widget/TextView.java60
2 files changed, 74 insertions, 16 deletions
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 1bc0612..6799ffd 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -88,6 +88,7 @@ public class PopupWindow {
private boolean mOutsideTouchable = false;
private boolean mClippingEnabled = true;
private boolean mSplitTouchEnabled;
+ private boolean mLayoutInScreen;
private OnTouchListener mTouchInterceptor;
@@ -607,6 +608,29 @@ public class PopupWindow {
}
/**
+ * <p>Indicates whether the popup window will be forced into using absolute screen coordinates
+ * for positioning.</p>
+ *
+ * @return true if the window will always be positioned in screen coordinates.
+ * @hide
+ */
+ public boolean isLayoutInScreenEnabled() {
+ return mLayoutInScreen;
+ }
+
+ /**
+ * <p>Allows the popup window to force the flag
+ * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior.
+ * This will cause the popup to be positioned in absolute screen coordinates.</p>
+ *
+ * @param enabled true if the popup should always be positioned in screen coordinates
+ * @hide
+ */
+ public void setLayoutInScreenEnabled(boolean enabled) {
+ mLayoutInScreen = enabled;
+ }
+
+ /**
* <p>Change the width and height measure specs that are given to the
* window manager by the popup. By default these are 0, meaning that
* the current width or height is requested as an explicit size from
@@ -910,7 +934,8 @@ public class PopupWindow {
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
- WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
+ WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
if(mIgnoreCheekPress) {
curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
}
@@ -934,6 +959,9 @@ public class PopupWindow {
if (mSplitTouchEnabled) {
curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
}
+ if (mLayoutInScreen) {
+ curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+ }
return curFlags;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f4d193f..f5e806f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3798,6 +3798,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mError != null) {
hideError();
}
+
+ hideControllers();
}
@Override
@@ -4165,6 +4167,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
canvas.restore();
+
+ if (mInsertionPointCursorController != null &&
+ mInsertionPointCursorController.isShowing()) {
+ mInsertionPointCursorController.updatePosition();
+ }
+ if (mSelectionModifierCursorController != null &&
+ mSelectionModifierCursorController.isShowing()) {
+ mSelectionModifierCursorController.updatePosition();
+ }
}
@Override
@@ -4788,6 +4799,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mInputMethodState != null) {
mInputMethodState.mExtracting = req;
}
+ hideControllers();
}
/**
@@ -6326,7 +6338,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
sendOnTextChanged(buffer, start, before, after);
onTextChanged(buffer, start, before, after);
- hideControllers();
+
+ // Hide the controller if the amount of content changed
+ if (before != after) {
+ hideControllers();
+ }
}
/**
@@ -6668,11 +6684,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mInputContentType != null) {
mInputContentType.enterDown = false;
}
+ hideControllers();
}
startStopMarquee(hasWindowFocus);
}
+ @Override
+ protected void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+ if (visibility != VISIBLE) {
+ hideControllers();
+ }
+ }
+
/**
* Use {@link BaseInputConnection#removeComposingSpans
* BaseInputConnection.removeComposingSpans()} to remove any IME composing
@@ -6742,8 +6767,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (hasSelection()) {
startSelectionActionMode();
- } else if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.show();
}
}
}
@@ -7732,6 +7755,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private int mPositionY;
private CursorController mController;
private boolean mIsDragging;
+ private int mOffsetX;
+ private int mOffsetY;
public HandleView(CursorController controller, Drawable handle) {
super(TextView.this.mContext);
@@ -7740,6 +7765,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mContainer = new PopupWindow(TextView.this.mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
mContainer.setSplitTouchEnabled(true);
+ mContainer.setClippingEnabled(false);
+ mContainer.setLayoutInScreenEnabled(true);
}
@Override
@@ -7777,19 +7804,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int compoundPaddingRight = getCompoundPaddingRight();
final TextView hostView = TextView.this;
- final int right = hostView.mRight;
- final int left = hostView.mLeft;
- final int bottom = hostView.mBottom;
- final int top = hostView.mTop;
+ final int handleWidth = mDrawable.getIntrinsicWidth();
+ final int left = 0;
+ final int right = hostView.getWidth();
+ final int top = 0;
+ final int bottom = hostView.getHeight();
- final int clipLeft = left + compoundPaddingLeft;
+ final int clipLeft = left + compoundPaddingLeft - (int) (handleWidth * 0.75f);
final int clipTop = top + extendedPaddingTop;
- final int clipRight = right - compoundPaddingRight;
+ final int clipRight = right - compoundPaddingRight + (int) (handleWidth * 0.25f);
final int clipBottom = bottom - extendedPaddingBottom;
- final int handleWidth = mDrawable.getIntrinsicWidth();
- return mPositionX >= clipLeft - handleWidth * 0.75f &&
- mPositionX <= clipRight + handleWidth * 0.25f &&
+ return mPositionX >= clipLeft && mPositionX <= clipRight &&
mPositionY >= clipTop && mPositionY <= clipBottom;
}
@@ -7828,6 +7854,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
+ mOffsetX = (int) (ev.getX() - mDrawable.getIntrinsicWidth() / 2.f + 0.5f);
+ mOffsetY = (int) (ev.getY() - mDrawable.getIntrinsicHeight() / 2.f + 0.5f);
mIsDragging = true;
break;
@@ -7836,8 +7864,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final float rawY = ev.getRawY();
final int[] coords = mTempCoords;
TextView.this.getLocationOnScreen(coords);
- final int x = (int) (rawX - coords[0] + 0.5f);
- final int y = (int) (rawY - coords[1] + 0.5f);
+ final int x = (int) (rawX - coords[0] + 0.5f) - mOffsetX;
+ final int y = (int) (rawY - coords[1] + 0.5f) -
+ (int) (mDrawable.getIntrinsicHeight() * 0.8f) - mOffsetY;
+
mController.updatePosition(this, x, y);
break;
@@ -8146,7 +8176,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int previousLine = layout.getLineForOffset(previousOffset);
final int previousLineTop = layout.getLineTop(previousLine);
final int previousLineBottom = layout.getLineBottom(previousLine);
- final int hysteresisThreshold = (previousLineBottom - previousLineTop) / 2;
+ final int hysteresisThreshold = (previousLineBottom - previousLineTop) / 6;
// If new line is just before or after previous line and y position is less than
// hysteresisThreshold away from previous line, keep cursor on previous line.