am b08013c3
: Added overlay support for drawing/responding to text anchors.
Merge commit 'b08013c312e3d849029a2f4c11889274c00f438d' into gingerbread-plus-aosp * commit 'b08013c312e3d849029a2f4c11889274c00f438d': Added overlay support for drawing/responding to text anchors.
This commit is contained in:
@ -5828,28 +5828,6 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
<field name="kraken_resource_pad58"
|
|
||||||
type="int"
|
|
||||||
transient="false"
|
|
||||||
volatile="false"
|
|
||||||
value="16843463"
|
|
||||||
static="true"
|
|
||||||
final="true"
|
|
||||||
deprecated="not deprecated"
|
|
||||||
visibility="public"
|
|
||||||
>
|
|
||||||
</field>
|
|
||||||
<field name="kraken_resource_pad59"
|
|
||||||
type="int"
|
|
||||||
transient="false"
|
|
||||||
volatile="false"
|
|
||||||
value="16843462"
|
|
||||||
static="true"
|
|
||||||
final="true"
|
|
||||||
deprecated="not deprecated"
|
|
||||||
visibility="public"
|
|
||||||
>
|
|
||||||
</field>
|
|
||||||
<field name="kraken_resource_pad6"
|
<field name="kraken_resource_pad6"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
@ -5861,17 +5839,6 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
<field name="kraken_resource_pad60"
|
|
||||||
type="int"
|
|
||||||
transient="false"
|
|
||||||
volatile="false"
|
|
||||||
value="16843461"
|
|
||||||
static="true"
|
|
||||||
final="true"
|
|
||||||
deprecated="not deprecated"
|
|
||||||
visibility="public"
|
|
||||||
>
|
|
||||||
</field>
|
|
||||||
<field name="kraken_resource_pad7"
|
<field name="kraken_resource_pad7"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
@ -9513,6 +9480,39 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="textSelectHandle"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="16843463"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
|
<field name="textSelectHandleLeft"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="16843461"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
|
<field name="textSelectHandleRight"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="16843462"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
<field name="textSize"
|
<field name="textSize"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
@ -225620,8 +225620,19 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="isShowing"
|
||||||
|
return="boolean"
|
||||||
|
abstract="true"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</method>
|
||||||
<method name="onTouchEvent"
|
<method name="onTouchEvent"
|
||||||
return="void"
|
return="boolean"
|
||||||
abstract="true"
|
abstract="true"
|
||||||
native="false"
|
native="false"
|
||||||
synchronized="false"
|
synchronized="false"
|
||||||
|
@ -1550,6 +1550,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
*/
|
*/
|
||||||
private static final int AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
|
private static final int AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that this view has a visible/touchable overlay.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
static final int HAS_OVERLAY = 0x10000000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always allow a user to overscroll this view, provided it is a
|
* Always allow a user to overscroll this view, provided it is a
|
||||||
* view that can scroll.
|
* view that can scroll.
|
||||||
@ -2837,6 +2843,57 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
|||||||
resetPressedState();
|
resetPressedState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable drawing overlays after a full drawing pass. This enables a view to
|
||||||
|
* draw on a topmost overlay layer after normal drawing completes and get right of first
|
||||||
|
* refusal for touch events in the window.
|
||||||
|
*
|
||||||
|
* <em>Warning:</em> Views that use this feature should take care to disable/enable overlay
|
||||||
|
* appropriately when they are attached/detached from their window. All overlays should be
|
||||||
|
* disabled when detached.
|
||||||
|
*
|
||||||
|
* @param enabled true if overlay drawing should be enabled for this view, false otherwise
|
||||||
|
*
|
||||||
|
* @see #onDrawOverlay(Canvas)
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
protected void setOverlayEnabled(boolean enabled) {
|
||||||
|
final boolean oldValue = (mPrivateFlags & HAS_OVERLAY) == HAS_OVERLAY;
|
||||||
|
mPrivateFlags = (mPrivateFlags & ~HAS_OVERLAY) | (enabled ? HAS_OVERLAY : 0);
|
||||||
|
if (enabled != oldValue) {
|
||||||
|
final ViewParent parent = getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
try {
|
||||||
|
parent.childOverlayStateChanged(this);
|
||||||
|
} catch (AbstractMethodError e) {
|
||||||
|
Log.e(VIEW_LOG_TAG, "Could not propagate hasOverlay state", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this View has an overlay enabled.
|
||||||
|
*
|
||||||
|
* @see #setOverlayEnabled(boolean)
|
||||||
|
* @see #onDrawOverlay(Canvas)
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isOverlayEnabled() {
|
||||||
|
return (mPrivateFlags & HAS_OVERLAY) == HAS_OVERLAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method to draw on an overlay layer above all other views in the window
|
||||||
|
* after the standard drawing pass is complete. This allows a view to draw outside its
|
||||||
|
* normal boundaries.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void onDrawOverlay(Canvas canvas) {
|
||||||
|
}
|
||||||
|
|
||||||
private void resetPressedState() {
|
private void resetPressedState() {
|
||||||
if ((mViewFlags & ENABLED_MASK) == DISABLED) {
|
if ((mViewFlags & ENABLED_MASK) == DISABLED) {
|
||||||
return;
|
return;
|
||||||
|
@ -227,6 +227,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
*/
|
*/
|
||||||
protected static final int FLAG_DISALLOW_INTERCEPT = 0x80000;
|
protected static final int FLAG_DISALLOW_INTERCEPT = 0x80000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set, at least one child of this ViewGroup will return true from hasOverlay.
|
||||||
|
*/
|
||||||
|
private static final int FLAG_CHILD_HAS_OVERLAY = 0x100000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates which types of drawing caches are to be kept in memory.
|
* Indicates which types of drawing caches are to be kept in memory.
|
||||||
* This field should be made private, so it is hidden from the SDK.
|
* This field should be made private, so it is hidden from the SDK.
|
||||||
@ -854,6 +859,34 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
final int scrolledYInt = (int) scrolledYFloat;
|
final int scrolledYInt = (int) scrolledYFloat;
|
||||||
final View[] children = mChildren;
|
final View[] children = mChildren;
|
||||||
final int count = mChildrenCount;
|
final int count = mChildrenCount;
|
||||||
|
|
||||||
|
// Check for children with overlays first. They don't rely on hit rects to determine
|
||||||
|
// if they can accept a new touch event.
|
||||||
|
if ((mGroupFlags & FLAG_CHILD_HAS_OVERLAY) == FLAG_CHILD_HAS_OVERLAY) {
|
||||||
|
for (int i = count - 1; i >= 0; i--) {
|
||||||
|
final View child = children[i];
|
||||||
|
// Don't let children respond to events as an overlay during an animation.
|
||||||
|
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
|
||||||
|
&& child.getAnimation() == null
|
||||||
|
&& child.isOverlayEnabled()) {
|
||||||
|
// offset the event to the view's coordinate system
|
||||||
|
final float xc = scrolledXFloat - child.mLeft;
|
||||||
|
final float yc = scrolledYFloat - child.mTop;
|
||||||
|
ev.setLocation(xc, yc);
|
||||||
|
child.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
|
||||||
|
if (child.dispatchTouchEvent(ev)) {
|
||||||
|
// Event handled, we have a target now.
|
||||||
|
mMotionTarget = child;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// The event didn't get handled, try the next view.
|
||||||
|
// Don't reset the event's location, it's not
|
||||||
|
// necessary here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check views normally.
|
||||||
for (int i = count - 1; i >= 0; i--) {
|
for (int i = count - 1; i >= 0; i--) {
|
||||||
final View child = children[i];
|
final View child = children[i];
|
||||||
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
|
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
|
||||||
@ -2312,6 +2345,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
if (clearChildFocus != null) {
|
if (clearChildFocus != null) {
|
||||||
clearChildFocus(clearChildFocus);
|
clearChildFocus(clearChildFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mGroupFlags &= ~FLAG_CHILD_HAS_OVERLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2534,7 +2569,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
final int left = mLeft;
|
final int left = mLeft;
|
||||||
final int top = mTop;
|
final int top = mTop;
|
||||||
|
|
||||||
if (dirty.intersect(0, 0, mRight - left, mBottom - top) ||
|
if ((mGroupFlags & FLAG_CHILD_HAS_OVERLAY) == FLAG_CHILD_HAS_OVERLAY ||
|
||||||
|
dirty.intersect(0, 0, mRight - left, mBottom - top) ||
|
||||||
(mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
|
(mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
|
||||||
mPrivateFlags &= ~DRAWING_CACHE_VALID;
|
mPrivateFlags &= ~DRAWING_CACHE_VALID;
|
||||||
|
|
||||||
@ -3452,6 +3488,69 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
mAnimationListener = animationListener;
|
mAnimationListener = animationListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a child's overlay state changes between enabled/disabled.
|
||||||
|
* @param child Child view whose state has changed or null
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void childOverlayStateChanged(View child) {
|
||||||
|
boolean childHasOverlay = false;
|
||||||
|
if (child != null) {
|
||||||
|
childHasOverlay = child.isOverlayEnabled();
|
||||||
|
} else {
|
||||||
|
final int childCount = getChildCount();
|
||||||
|
for (int i = 0; i < childCount; i++) {
|
||||||
|
if (childHasOverlay |= getChildAt(i).isOverlayEnabled()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean hasChildWithOverlay = childHasOverlay ||
|
||||||
|
(mGroupFlags & FLAG_CHILD_HAS_OVERLAY) == FLAG_CHILD_HAS_OVERLAY;
|
||||||
|
|
||||||
|
final boolean oldValue = isOverlayEnabled();
|
||||||
|
mGroupFlags = (mGroupFlags & ~FLAG_CHILD_HAS_OVERLAY) |
|
||||||
|
(hasChildWithOverlay ? FLAG_CHILD_HAS_OVERLAY : 0);
|
||||||
|
if (isOverlayEnabled() != oldValue) {
|
||||||
|
final ViewParent parent = getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
try {
|
||||||
|
parent.childOverlayStateChanged(this);
|
||||||
|
} catch (AbstractMethodError e) {
|
||||||
|
Log.e("ViewGroup", "Could not propagate hasOverlay state", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isOverlayEnabled() {
|
||||||
|
return super.isOverlayEnabled() ||
|
||||||
|
((mGroupFlags & FLAG_CHILD_HAS_OVERLAY) == FLAG_CHILD_HAS_OVERLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onDrawOverlay(Canvas canvas) {
|
||||||
|
if ((mGroupFlags & FLAG_CHILD_HAS_OVERLAY) == FLAG_CHILD_HAS_OVERLAY) {
|
||||||
|
final int childCount = getChildCount();
|
||||||
|
for (int i = 0; i < childCount; i++) {
|
||||||
|
final View child = getChildAt(i);
|
||||||
|
if (child.isOverlayEnabled()) {
|
||||||
|
canvas.translate(child.mLeft + child.mScrollX, child.mTop + child.mScrollY);
|
||||||
|
child.onDrawOverlay(canvas);
|
||||||
|
canvas.translate(-(child.mLeft + child.mScrollX),
|
||||||
|
-(child.mTop + child.mScrollY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LayoutParams are used by views to tell their parents how they want to be
|
* LayoutParams are used by views to tell their parents how they want to be
|
||||||
* laid out. See
|
* laid out. See
|
||||||
|
@ -208,4 +208,11 @@ public interface ViewParent {
|
|||||||
*/
|
*/
|
||||||
public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
|
public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
|
||||||
boolean immediate);
|
boolean immediate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a child view's overlay state changes between enabled/disabled.
|
||||||
|
* @param child Child view whose state changed or null.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void childOverlayStateChanged(View child);
|
||||||
}
|
}
|
||||||
|
@ -222,6 +222,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
|
|
||||||
private final int mDensity;
|
private final int mDensity;
|
||||||
|
|
||||||
|
private boolean mHasOverlay;
|
||||||
|
|
||||||
public static IWindowSession getWindowSession(Looper mainLooper) {
|
public static IWindowSession getWindowSession(Looper mainLooper) {
|
||||||
synchronized (mStaticInit) {
|
synchronized (mStaticInit) {
|
||||||
if (!mInitialized) {
|
if (!mInitialized) {
|
||||||
@ -1518,6 +1520,9 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
canvas.setScreenDensity(scalingRequired
|
canvas.setScreenDensity(scalingRequired
|
||||||
? DisplayMetrics.DENSITY_DEVICE : 0);
|
? DisplayMetrics.DENSITY_DEVICE : 0);
|
||||||
mView.draw(canvas);
|
mView.draw(canvas);
|
||||||
|
if (mHasOverlay) {
|
||||||
|
mView.onDrawOverlay(canvas);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
mAttachInfo.mIgnoreDirtyState = false;
|
mAttachInfo.mIgnoreDirtyState = false;
|
||||||
canvas.restoreToCount(saveCount);
|
canvas.restoreToCount(saveCount);
|
||||||
@ -2914,6 +2919,19 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
return scrollToRectOrFocus(rectangle, immediate);
|
return scrollToRectOrFocus(rectangle, immediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void childOverlayStateChanged(View child) {
|
||||||
|
final boolean oldState = mHasOverlay;
|
||||||
|
mHasOverlay = child.isOverlayEnabled();
|
||||||
|
// Invalidate the whole thing when we change overlay states just in case
|
||||||
|
// something left chunks of data drawn someplace it shouldn't have.
|
||||||
|
if (mHasOverlay != oldState) {
|
||||||
|
child.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TakenSurfaceHolder extends BaseSurfaceHolder {
|
class TakenSurfaceHolder extends BaseSurfaceHolder {
|
||||||
@Override
|
@Override
|
||||||
public boolean onAllowLockCanvas() {
|
public boolean onAllowLockCanvas() {
|
||||||
|
@ -285,6 +285,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
InputMethodState mInputMethodState;
|
InputMethodState mInputMethodState;
|
||||||
|
|
||||||
|
private int mTextSelectHandleLeftRes;
|
||||||
|
private int mTextSelectHandleRightRes;
|
||||||
|
private int mTextSelectHandleRes;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kick-start the font cache for the zygote process (to pay the cost of
|
* Kick-start the font cache for the zygote process (to pay the cost of
|
||||||
* initializing freetype for our default font only once).
|
* initializing freetype for our default font only once).
|
||||||
@ -705,6 +709,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
Log.w(LOG_TAG, "Failure reading input extras", e);
|
Log.w(LOG_TAG, "Failure reading input extras", e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case com.android.internal.R.styleable.TextView_textSelectHandleLeft:
|
||||||
|
mTextSelectHandleLeftRes = a.getResourceId(attr, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case com.android.internal.R.styleable.TextView_textSelectHandleRight:
|
||||||
|
mTextSelectHandleRightRes = a.getResourceId(attr, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case com.android.internal.R.styleable.TextView_textSelectHandle:
|
||||||
|
mTextSelectHandleRes = a.getResourceId(attr, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.recycle();
|
a.recycle();
|
||||||
@ -3733,6 +3749,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
showError();
|
showError();
|
||||||
mShowErrorAfterAttach = false;
|
mShowErrorAfterAttach = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -3750,6 +3768,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
if (mError != null) {
|
if (mError != null) {
|
||||||
hideError();
|
hideError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setOverlayEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -4100,7 +4120,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onDrawOverlay(Canvas canvas) {
|
||||||
if (mInsertionPointCursorController != null) {
|
if (mInsertionPointCursorController != null) {
|
||||||
mInsertionPointCursorController.draw(canvas);
|
mInsertionPointCursorController.draw(canvas);
|
||||||
}
|
}
|
||||||
@ -6684,10 +6710,31 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
final int action = event.getActionMasked();
|
final int action = event.getActionMasked();
|
||||||
if (action == MotionEvent.ACTION_DOWN) {
|
if (action == MotionEvent.ACTION_DOWN) {
|
||||||
|
// Check to see if we're testing for our anchor overlay.
|
||||||
|
boolean handled = false;
|
||||||
|
final float x = event.getX();
|
||||||
|
final float y = event.getY();
|
||||||
|
if (x < mLeft || x > mRight || y < mTop || y > mBottom) {
|
||||||
|
if (mInsertionPointCursorController != null) {
|
||||||
|
handled |= mInsertionPointCursorController.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
if (mSelectionModifierCursorController != null) {
|
||||||
|
handled |= mSelectionModifierCursorController.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Reset this state; it will be re-set if super.onTouchEvent
|
// Reset this state; it will be re-set if super.onTouchEvent
|
||||||
// causes focus to move to the view.
|
// causes focus to move to the view.
|
||||||
mTouchFocusSelected = false;
|
mTouchFocusSelected = false;
|
||||||
mScrolled = false;
|
mScrolled = false;
|
||||||
|
|
||||||
|
if (handled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean superResult = super.onTouchEvent(event);
|
final boolean superResult = super.onTouchEvent(event);
|
||||||
@ -7576,6 +7623,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateOverlay() {
|
||||||
|
boolean enableOverlay = false;
|
||||||
|
if (mSelectionModifierCursorController != null) {
|
||||||
|
enableOverlay |= mSelectionModifierCursorController.isShowing();
|
||||||
|
}
|
||||||
|
if (mInsertionPointCursorController != null) {
|
||||||
|
enableOverlay |= mInsertionPointCursorController.isShowing();
|
||||||
|
}
|
||||||
|
setOverlayEnabled(enableOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A CursorController instance can be used to control a cursor in the text.
|
* A CursorController instance can be used to control a cursor in the text.
|
||||||
*
|
*
|
||||||
@ -7598,6 +7656,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
*/
|
*/
|
||||||
public void hide();
|
public void hide();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the CursorController is currently visible
|
||||||
|
*/
|
||||||
|
public boolean isShowing();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the controller's position.
|
* Update the controller's position.
|
||||||
*/
|
*/
|
||||||
@ -7620,7 +7683,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
* a chance to become active and/or visible.
|
* a chance to become active and/or visible.
|
||||||
* @param event The touch event
|
* @param event The touch event
|
||||||
*/
|
*/
|
||||||
public void onTouchEvent(MotionEvent event);
|
public boolean onTouchEvent(MotionEvent event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a visual representation of the controller on the canvas.
|
* Draws a visual representation of the controller on the canvas.
|
||||||
@ -7654,10 +7717,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
final Rect bounds = sCursorControllerTempRect;
|
final Rect bounds = sCursorControllerTempRect;
|
||||||
bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - drawableWidth / 2.0)
|
bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - drawableWidth / 2.0)
|
||||||
+ mScrollX;
|
+ mScrollX;
|
||||||
bounds.top = (bottom ? lineBottom : lineTop) - drawableHeight / 2 + mScrollY;
|
bounds.top = (bottom ? lineBottom : lineTop) + mScrollY;
|
||||||
|
|
||||||
mTopExtension = bottom ? 0 : drawableHeight / 2;
|
mTopExtension = bottom ? 0 : drawableHeight / 2;
|
||||||
mBottomExtension = drawableHeight;
|
mBottomExtension = 0; //drawableHeight / 4;
|
||||||
|
|
||||||
// Extend touch region up when editing the last line of text (or a single line) so that
|
// Extend touch region up when editing the last line of text (or a single line) so that
|
||||||
// it is easier to grab.
|
// it is easier to grab.
|
||||||
@ -7715,7 +7778,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
InsertionPointCursorController() {
|
InsertionPointCursorController() {
|
||||||
Resources res = mContext.getResources();
|
Resources res = mContext.getResources();
|
||||||
mHandle = new Handle(res.getDrawable(com.android.internal.R.drawable.text_select_handle));
|
mHandle = new Handle(res.getDrawable(mTextSelectHandleRes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show() {
|
public void show() {
|
||||||
@ -7723,6 +7786,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
// Has to be done after updateDrawablePosition, so that previous position invalidate
|
// Has to be done after updateDrawablePosition, so that previous position invalidate
|
||||||
// in only done if necessary.
|
// in only done if necessary.
|
||||||
mIsVisible = true;
|
mIsVisible = true;
|
||||||
|
updateOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hide() {
|
public void hide() {
|
||||||
@ -7736,6 +7800,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isShowing() {
|
||||||
|
return mIsVisible;
|
||||||
|
}
|
||||||
|
|
||||||
public void draw(Canvas canvas) {
|
public void draw(Canvas canvas) {
|
||||||
if (mIsVisible) {
|
if (mIsVisible) {
|
||||||
int time = (int) (System.currentTimeMillis() - mFadeOutTimerStart);
|
int time = (int) (System.currentTimeMillis() - mFadeOutTimerStart);
|
||||||
@ -7751,6 +7819,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
} else {
|
} else {
|
||||||
mHandle.mDrawable.setAlpha(0);
|
mHandle.mDrawable.setAlpha(0);
|
||||||
mIsVisible = false;
|
mIsVisible = false;
|
||||||
|
updateOverlay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mHandle.mDrawable.draw(canvas);
|
mHandle.mDrawable.draw(canvas);
|
||||||
@ -7779,6 +7848,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
// Should never happen, safety check.
|
// Should never happen, safety check.
|
||||||
Log.w(LOG_TAG, "Update cursor controller position called with no cursor");
|
Log.w(LOG_TAG, "Update cursor controller position called with no cursor");
|
||||||
mIsVisible = false;
|
mIsVisible = false;
|
||||||
|
updateOverlay();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7788,7 +7858,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
mHandle.mDrawable.setAlpha(255);
|
mHandle.mDrawable.setAlpha(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
if (isFocused() && isTextEditable() && mIsVisible) {
|
if (isFocused() && isTextEditable() && mIsVisible) {
|
||||||
switch (event.getActionMasked()) {
|
switch (event.getActionMasked()) {
|
||||||
case MotionEvent.ACTION_DOWN : {
|
case MotionEvent.ACTION_DOWN : {
|
||||||
@ -7816,8 +7886,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
mOffsetY += viewportToContentVerticalOffset();
|
mOffsetY += viewportToContentVerticalOffset();
|
||||||
|
|
||||||
mOnDownTimerStart = event.getEventTime();
|
mOnDownTimerStart = event.getEventTime();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MotionEvent.ACTION_UP : {
|
case MotionEvent.ACTION_UP : {
|
||||||
@ -7835,6 +7906,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getOffsetX() {
|
public float getOffsetX() {
|
||||||
@ -7864,8 +7936,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
SelectionModifierCursorController() {
|
SelectionModifierCursorController() {
|
||||||
Resources res = mContext.getResources();
|
Resources res = mContext.getResources();
|
||||||
mStartHandle = new Handle(res.getDrawable(com.android.internal.R.drawable.text_select_handle));
|
mStartHandle = new Handle(res.getDrawable(mTextSelectHandleLeftRes));
|
||||||
mEndHandle = new Handle(res.getDrawable(com.android.internal.R.drawable.text_select_handle));
|
mEndHandle = new Handle(res.getDrawable(mTextSelectHandleRightRes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show() {
|
public void show() {
|
||||||
@ -7873,6 +7945,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
// Has to be done after updateDrawablePositions, so that previous position invalidate
|
// Has to be done after updateDrawablePositions, so that previous position invalidate
|
||||||
// in only done if necessary.
|
// in only done if necessary.
|
||||||
mIsVisible = true;
|
mIsVisible = true;
|
||||||
|
updateOverlay();
|
||||||
mFadeOutTimerStart = -1;
|
mFadeOutTimerStart = -1;
|
||||||
hideInsertionPointCursorController();
|
hideInsertionPointCursorController();
|
||||||
}
|
}
|
||||||
@ -7885,8 +7958,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isShowing() {
|
||||||
|
return mIsVisible;
|
||||||
|
}
|
||||||
|
|
||||||
public void cancelFadeOutAnimation() {
|
public void cancelFadeOutAnimation() {
|
||||||
mIsVisible = false;
|
mIsVisible = false;
|
||||||
|
updateOverlay();
|
||||||
mStartHandle.postInvalidate();
|
mStartHandle.postInvalidate();
|
||||||
mEndHandle.postInvalidate();
|
mEndHandle.postInvalidate();
|
||||||
}
|
}
|
||||||
@ -7905,6 +7983,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
mStartHandle.mDrawable.setAlpha(0);
|
mStartHandle.mDrawable.setAlpha(0);
|
||||||
mEndHandle.mDrawable.setAlpha(0);
|
mEndHandle.mDrawable.setAlpha(0);
|
||||||
mIsVisible = false;
|
mIsVisible = false;
|
||||||
|
updateOverlay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mStartHandle.mDrawable.draw(canvas);
|
mStartHandle.mDrawable.draw(canvas);
|
||||||
@ -7962,6 +8041,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
// Should never happen, safety check.
|
// Should never happen, safety check.
|
||||||
Log.w(LOG_TAG, "Update selection controller position called with no cursor");
|
Log.w(LOG_TAG, "Update selection controller position called with no cursor");
|
||||||
mIsVisible = false;
|
mIsVisible = false;
|
||||||
|
updateOverlay();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7974,7 +8054,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
mEndHandle.mDrawable.setAlpha(255);
|
mEndHandle.mDrawable.setAlpha(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
if (isTextEditable()) {
|
if (isTextEditable()) {
|
||||||
switch (event.getActionMasked()) {
|
switch (event.getActionMasked()) {
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
@ -8009,6 +8089,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
mOnDownTimerStart = event.getEventTime();
|
mOnDownTimerStart = event.getEventTime();
|
||||||
((ArrowKeyMovementMethod)mMovement).setCursorController(this);
|
((ArrowKeyMovementMethod)mMovement).setCursorController(this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8034,6 +8115,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
BIN
core/res/res/drawable-hdpi/text_select_handle_left.png
Normal file
BIN
core/res/res/drawable-hdpi/text_select_handle_left.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 620 B |
BIN
core/res/res/drawable-hdpi/text_select_handle_middle.png
Normal file
BIN
core/res/res/drawable-hdpi/text_select_handle_middle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 718 B |
BIN
core/res/res/drawable-hdpi/text_select_handle_right.png
Normal file
BIN
core/res/res/drawable-hdpi/text_select_handle_right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 697 B |
@ -451,6 +451,21 @@
|
|||||||
<!-- The preference layout that has the child/tabbed effect. -->
|
<!-- The preference layout that has the child/tabbed effect. -->
|
||||||
<attr name="preferenceLayoutChild" format="reference" />
|
<attr name="preferenceLayoutChild" format="reference" />
|
||||||
|
|
||||||
|
<!-- ============================ -->
|
||||||
|
<!-- Text selection handle styles -->
|
||||||
|
<!-- ============================ -->
|
||||||
|
<eat-comment />
|
||||||
|
|
||||||
|
<!-- Reference to a drawable that will be used to display a text selection
|
||||||
|
anchor on the left side of a selection region. -->
|
||||||
|
<attr name="textSelectHandleLeft" format="reference" />
|
||||||
|
<!-- Reference to a drawable that will be used to display a text selection
|
||||||
|
anchor on the right side of a selection region. -->
|
||||||
|
<attr name="textSelectHandleRight" format="reference" />
|
||||||
|
<!-- Reference to a drawable that will be used to display a text selection
|
||||||
|
anchor for positioning the cursor within text. -->
|
||||||
|
<attr name="textSelectHandle" format="reference" />
|
||||||
|
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<!-- **************************************************************** -->
|
<!-- **************************************************************** -->
|
||||||
@ -2152,6 +2167,16 @@
|
|||||||
EditorInfo.extras} field when the input
|
EditorInfo.extras} field when the input
|
||||||
method is connected. -->
|
method is connected. -->
|
||||||
<attr name="editorExtras" format="reference" />
|
<attr name="editorExtras" format="reference" />
|
||||||
|
|
||||||
|
<!-- Reference to a drawable that will be used to display a text selection
|
||||||
|
anchor on the left side of a selection region. -->
|
||||||
|
<attr name="textSelectHandleLeft" />
|
||||||
|
<!-- Reference to a drawable that will be used to display a text selection
|
||||||
|
anchor on the right side of a selection region. -->
|
||||||
|
<attr name="textSelectHandleRight" />
|
||||||
|
<!-- Reference to a drawable that will be used to display a text selection
|
||||||
|
anchor for positioning the cursor within text. -->
|
||||||
|
<attr name="textSelectHandle" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
<!-- An <code>input-extras</code> is a container for extra data to supply to
|
<!-- An <code>input-extras</code> is a container for extra data to supply to
|
||||||
an input method. Contains
|
an input method. Contains
|
||||||
|
@ -1255,6 +1255,9 @@
|
|||||||
<public type="attr" name="overscrollHeader" id="0x010102c2" />
|
<public type="attr" name="overscrollHeader" id="0x010102c2" />
|
||||||
<public type="attr" name="overscrollFooter" id="0x010102c3" />
|
<public type="attr" name="overscrollFooter" id="0x010102c3" />
|
||||||
<public type="attr" name="filterTouchesWhenObscured" id="0x010102c4" />
|
<public type="attr" name="filterTouchesWhenObscured" id="0x010102c4" />
|
||||||
|
<public type="attr" name="textSelectHandleLeft" id="0x010102c5" />
|
||||||
|
<public type="attr" name="textSelectHandleRight" id="0x010102c6" />
|
||||||
|
<public type="attr" name="textSelectHandle" id="0x010102c7" />
|
||||||
|
|
||||||
<public-padding type="attr" name="kraken_resource_pad" end="0x01010300" />
|
<public-padding type="attr" name="kraken_resource_pad" end="0x01010300" />
|
||||||
|
|
||||||
|
@ -382,6 +382,9 @@
|
|||||||
|
|
||||||
<style name="Widget.TextView">
|
<style name="Widget.TextView">
|
||||||
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
|
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
|
||||||
|
<item name="android:textSelectHandleLeft">?android:attr/textSelectHandleLeft</item>
|
||||||
|
<item name="android:textSelectHandleRight">?android:attr/textSelectHandleRight</item>
|
||||||
|
<item name="android:textSelectHandle">?android:attr/textSelectHandle</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Widget.TextView.ListSeparator">
|
<style name="Widget.TextView.ListSeparator">
|
||||||
|
@ -136,6 +136,11 @@
|
|||||||
<item name="scrollbarTrackHorizontal">@null</item>
|
<item name="scrollbarTrackHorizontal">@null</item>
|
||||||
<item name="scrollbarTrackVertical">@null</item>
|
<item name="scrollbarTrackVertical">@null</item>
|
||||||
|
|
||||||
|
<!-- Text selection handle attributes -->
|
||||||
|
<item name="textSelectHandleLeft">@android:drawable/text_select_handle_middle</item>
|
||||||
|
<item name="textSelectHandleRight">@android:drawable/text_select_handle_middle</item>
|
||||||
|
<item name="textSelectHandle">@android:drawable/text_select_handle_middle</item>
|
||||||
|
|
||||||
<!-- Widget styles -->
|
<!-- Widget styles -->
|
||||||
<item name="absListViewStyle">@android:style/Widget.AbsListView</item>
|
<item name="absListViewStyle">@android:style/Widget.AbsListView</item>
|
||||||
<item name="autoCompleteTextViewStyle">@android:style/Widget.AutoCompleteTextView</item>
|
<item name="autoCompleteTextViewStyle">@android:style/Widget.AutoCompleteTextView</item>
|
||||||
|
Reference in New Issue
Block a user