use of android.view.ViewParent in project android_frameworks_base by ParanoidAndroid.
the class WebViewClassic method handleTouchEventCommon.
/*
* Common code for single touch and multi-touch.
* (x, y) denotes current focus point, which is the touch point for single touch
* and the middle point for multi-touch.
*/
private void handleTouchEventCommon(MotionEvent event, int action, int x, int y) {
ScaleGestureDetector detector = mZoomManager.getScaleGestureDetector();
long eventTime = event.getEventTime();
// Due to the touch screen edge effect, a touch closer to the edge
// always snapped to the edge. As getViewWidth() can be different from
// getWidth() due to the scrollbar, adjusting the point to match
// getViewWidth(). Same applied to the height.
x = Math.min(x, getViewWidth() - 1);
y = Math.min(y, getViewHeightWithTitle() - 1);
int deltaX = mLastTouchX - x;
int deltaY = mLastTouchY - y;
int contentX = viewToContentX(x + getScrollX());
int contentY = viewToContentY(y + getScrollY());
switch(action) {
case MotionEvent.ACTION_DOWN:
{
mConfirmMove = false;
// Channel Scrolling
mFirstTouchX = x;
mFirstTouchY = y;
mDistanceX = mDistanceY = 0;
if (!mEditTextScroller.isFinished()) {
mEditTextScroller.abortAnimation();
}
if (!mScroller.isFinished()) {
// stop the current scroll animation, but if this is
// the start of a fling, allow it to add to the current
// fling's velocity
mScroller.abortAnimation();
mTouchMode = TOUCH_DRAG_START_MODE;
mConfirmMove = true;
nativeSetIsScrolling(false);
} else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
removeTouchHighlight();
if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) {
mTouchMode = TOUCH_DOUBLE_TAP_MODE;
} else {
mTouchMode = TOUCH_INIT_MODE;
}
} else {
// the normal case
mTouchMode = TOUCH_INIT_MODE;
if (mLogEvent && eventTime - mLastTouchUpTime < 1000) {
EventLog.writeEvent(EventLogTags.BROWSER_DOUBLE_TAP_DURATION, (eventTime - mLastTouchUpTime), eventTime);
}
mSelectionStarted = false;
if (mSelectingText) {
ensureSelectionHandles();
int shiftedY = y - getTitleHeight() + getScrollY();
int shiftedX = x + getScrollX();
if (mSelectHandleBaseBounds.contains(shiftedX, shiftedY)) {
mSelectionStarted = true;
mSelectDraggingCursor = mSelectCursorBase;
mSelectDraggingTextQuad = mSelectCursorBaseTextQuad;
if (mIsCaretSelection) {
mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
hidePasteButton();
}
} else if (mSelectHandleExtentBounds.contains(shiftedX, shiftedY)) {
mSelectionStarted = true;
mSelectDraggingCursor = mSelectCursorExtent;
mSelectDraggingTextQuad = mSelectCursorExtentTextQuad;
} else if (mIsCaretSelection) {
selectionDone();
}
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "select=" + contentX + "," + contentY);
}
}
}
// Trigger the link
if (!mSelectingText && (mTouchMode == TOUCH_INIT_MODE || mTouchMode == TOUCH_DOUBLE_TAP_MODE)) {
mPrivateHandler.sendEmptyMessageDelayed(SWITCH_TO_SHORTPRESS, TAP_TIMEOUT);
mPrivateHandler.sendEmptyMessageDelayed(SWITCH_TO_LONGPRESS, LONG_PRESS_TIMEOUT);
}
startTouch(x, y, eventTime);
if (mIsEditingText) {
mTouchInEditText = mEditTextContentBounds.contains(contentX, contentY);
}
break;
}
case MotionEvent.ACTION_MOVE:
{
if (!mConfirmMove && (deltaX * deltaX + deltaY * deltaY) >= mTouchSlopSquare) {
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
mConfirmMove = true;
if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
mTouchMode = TOUCH_INIT_MODE;
}
removeTouchHighlight();
}
if (mSelectingText && mSelectionStarted) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "extend=" + contentX + "," + contentY);
}
ViewParent parent = mWebView.getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
if (deltaX != 0 || deltaY != 0) {
int handleX = contentX + viewToContentDimension(mSelectOffset.x);
int handleY = contentY + viewToContentDimension(mSelectOffset.y);
mSelectDraggingCursor.set(handleX, handleY);
boolean inCursorText = mSelectDraggingTextQuad.containsPoint(handleX, handleY);
boolean inEditBounds = mEditTextContentBounds.contains(handleX, handleY);
if (mIsEditingText && !inEditBounds) {
beginScrollEdit();
} else {
endScrollEdit();
}
boolean snapped = false;
if (inCursorText || (mIsEditingText && !inEditBounds)) {
snapDraggingCursor();
snapped = true;
}
updateWebkitSelection(snapped);
if (!inCursorText && mIsEditingText && inEditBounds) {
// Visually snap even if we have moved the handle.
snapDraggingCursor();
}
mLastTouchX = x;
mLastTouchY = y;
invalidate();
}
break;
}
if (mTouchMode == TOUCH_DONE_MODE) {
// default is yes
break;
}
if (mVelocityTracker == null) {
Log.e(LOGTAG, "Got null mVelocityTracker when " + " mTouchMode = " + mTouchMode);
} else {
mVelocityTracker.addMovement(event);
}
if (mTouchMode != TOUCH_DRAG_MODE && mTouchMode != TOUCH_DRAG_LAYER_MODE && mTouchMode != TOUCH_DRAG_TEXT_MODE) {
if (!mConfirmMove) {
break;
}
if ((detector == null || !detector.isInProgress()) && SNAP_NONE == mSnapScrollMode) {
int ax = Math.abs(x - mFirstTouchX);
int ay = Math.abs(y - mFirstTouchY);
if (ax < SNAP_BOUND && ay < SNAP_BOUND) {
break;
} else if (ax < SNAP_BOUND) {
mSnapScrollMode = SNAP_Y;
} else if (ay < SNAP_BOUND) {
mSnapScrollMode = SNAP_X;
}
}
mTouchMode = TOUCH_DRAG_MODE;
mLastTouchX = x;
mLastTouchY = y;
deltaX = 0;
deltaY = 0;
startScrollingLayer(x, y);
startDrag();
}
// do pan
boolean keepScrollBarsVisible = false;
if (deltaX == 0 && deltaY == 0) {
keepScrollBarsVisible = true;
} else {
if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) {
mDistanceX += Math.abs(deltaX);
mDistanceY += Math.abs(deltaY);
if (mSnapScrollMode == SNAP_X) {
if (mDistanceY > sChannelDistance) {
mSnapScrollMode = SNAP_NONE;
} else if (mDistanceX > sChannelDistance) {
mDistanceX = mDistanceY = 0;
}
} else {
if (mDistanceX > sChannelDistance) {
mSnapScrollMode = SNAP_NONE;
} else if (mDistanceY > sChannelDistance) {
mDistanceX = mDistanceY = 0;
}
}
}
if (mSnapScrollMode != SNAP_NONE) {
if ((mSnapScrollMode & SNAP_X) == SNAP_X) {
deltaY = 0;
} else {
deltaX = 0;
}
}
if (deltaX * deltaX + deltaY * deltaY > mTouchSlopSquare) {
mHeldMotionless = MOTIONLESS_FALSE;
} else {
mHeldMotionless = MOTIONLESS_TRUE;
keepScrollBarsVisible = true;
}
mLastTouchTime = eventTime;
boolean allDrag = doDrag(deltaX, deltaY);
if (allDrag) {
mLastTouchX = x;
mLastTouchY = y;
} else {
int contentDeltaX = (int) Math.floor(deltaX * mZoomManager.getInvScale());
int roundedDeltaX = contentToViewDimension(contentDeltaX);
int contentDeltaY = (int) Math.floor(deltaY * mZoomManager.getInvScale());
int roundedDeltaY = contentToViewDimension(contentDeltaY);
mLastTouchX -= roundedDeltaX;
mLastTouchY -= roundedDeltaY;
}
}
break;
}
case MotionEvent.ACTION_UP:
{
mFirstTouchX = mFirstTouchY = -1;
if (mIsEditingText && mSelectionStarted) {
endScrollEdit();
mPrivateHandler.sendEmptyMessageDelayed(SCROLL_HANDLE_INTO_VIEW, TEXT_SCROLL_FIRST_SCROLL_MS);
if (!mConfirmMove && mIsCaretSelection) {
showPasteWindow();
stopTouch();
break;
}
}
mLastTouchUpTime = eventTime;
if (mSentAutoScrollMessage) {
mAutoScrollX = mAutoScrollY = 0;
}
switch(mTouchMode) {
case // double tap
TOUCH_DOUBLE_TAP_MODE:
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
mTouchMode = TOUCH_DONE_MODE;
break;
// tap
case TOUCH_INIT_MODE:
case TOUCH_SHORTPRESS_START_MODE:
case TOUCH_SHORTPRESS_MODE:
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
if (!mConfirmMove) {
if (mSelectingText) {
// tapping on selection or controls does nothing
if (!mSelectionStarted) {
selectionDone();
}
break;
}
// scalable
if (mTouchMode == TOUCH_INIT_MODE && (canZoomIn() || canZoomOut())) {
mPrivateHandler.sendEmptyMessageDelayed(RELEASE_SINGLE_TAP, ViewConfiguration.getDoubleTapTimeout());
}
break;
}
case TOUCH_DRAG_MODE:
case TOUCH_DRAG_LAYER_MODE:
case TOUCH_DRAG_TEXT_MODE:
mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
// up, we don't want to do a fling
if (eventTime - mLastTouchTime <= MIN_FLING_TIME) {
if (mVelocityTracker == null) {
Log.e(LOGTAG, "Got null mVelocityTracker");
} else {
mVelocityTracker.addMovement(event);
}
// set to MOTIONLESS_IGNORE so that it won't keep
// removing and sending message in
// drawCoreAndCursorRing()
mHeldMotionless = MOTIONLESS_IGNORE;
doFling();
break;
} else {
if (mScroller.springBack(getScrollX(), getScrollY(), 0, computeMaxScrollX(), 0, computeMaxScrollY())) {
invalidate();
}
}
// redraw in high-quality, as we're done dragging
mHeldMotionless = MOTIONLESS_TRUE;
invalidate();
// fall through
case TOUCH_DRAG_START_MODE:
// TOUCH_DRAG_START_MODE should not happen for the real
// device as we almost certain will get a MOVE. But this
// is possible on emulator.
mLastVelocity = 0;
WebViewCore.resumePriority();
if (!mSelectingText) {
WebViewCore.resumeUpdatePicture(mWebViewCore);
}
break;
}
stopTouch();
break;
}
case MotionEvent.ACTION_CANCEL:
{
if (mTouchMode == TOUCH_DRAG_MODE) {
mScroller.springBack(getScrollX(), getScrollY(), 0, computeMaxScrollX(), 0, computeMaxScrollY());
invalidate();
}
cancelTouch();
break;
}
}
}
use of android.view.ViewParent in project android_frameworks_base by ParanoidAndroid.
the class Editor method isPositionVisible.
private boolean isPositionVisible(int positionX, int positionY) {
synchronized (TEMP_POSITION) {
final float[] position = TEMP_POSITION;
position[0] = positionX;
position[1] = positionY;
View view = mTextView;
while (view != null) {
if (view != mTextView) {
// Local scroll is already taken into account in positionX/Y
position[0] -= view.getScrollX();
position[1] -= view.getScrollY();
}
if (position[0] < 0 || position[1] < 0 || position[0] > view.getWidth() || position[1] > view.getHeight()) {
return false;
}
if (!view.getMatrix().isIdentity()) {
view.getMatrix().mapPoints(position);
}
position[0] += view.getLeft();
position[1] += view.getTop();
final ViewParent parent = view.getParent();
if (parent instanceof View) {
view = (View) parent;
} else {
// We've reached the ViewRoot, stop iterating
view = null;
}
}
}
// We've been able to walk up the view hierarchy and the position was never clipped
return true;
}
use of android.view.ViewParent in project android_frameworks_base by ParanoidAndroid.
the class ScrollView method onTouchEvent.
@Override
public boolean onTouchEvent(MotionEvent ev) {
initVelocityTrackerIfNotExists();
mVelocityTracker.addMovement(ev);
final int action = ev.getAction();
switch(action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
{
if (getChildCount() == 0) {
return false;
}
if ((mIsBeingDragged = !mScroller.isFinished())) {
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
}
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
if (mFlingStrictSpan != null) {
mFlingStrictSpan.finish();
mFlingStrictSpan = null;
}
}
// Remember where the motion event started
mLastMotionY = (int) ev.getY();
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE:
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
if (activePointerIndex == -1) {
Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
break;
}
final int y = (int) ev.getY(activePointerIndex);
int deltaY = mLastMotionY - y;
if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
mIsBeingDragged = true;
if (deltaY > 0) {
deltaY -= mTouchSlop;
} else {
deltaY += mTouchSlop;
}
}
if (mIsBeingDragged) {
// Scroll to follow the motion event
mLastMotionY = y;
final int oldX = mScrollX;
final int oldY = mScrollY;
final int range = getScrollRange();
final int overscrollMode = getOverScrollMode();
final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
if (overScrollBy(0, deltaY, 0, mScrollY, 0, range, 0, mOverscrollDistance, true)) {
// Break our velocity if we hit a scroll barrier.
mVelocityTracker.clear();
}
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (canOverscroll) {
final int pulledToY = oldY + deltaY;
if (pulledToY < 0) {
mEdgeGlowTop.onPull((float) deltaY / getHeight());
if (!mEdgeGlowBottom.isFinished()) {
mEdgeGlowBottom.onRelease();
}
} else if (pulledToY > range) {
mEdgeGlowBottom.onPull((float) deltaY / getHeight());
if (!mEdgeGlowTop.isFinished()) {
mEdgeGlowTop.onRelease();
}
}
if (mEdgeGlowTop != null && (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())) {
postInvalidateOnAnimation();
}
}
}
break;
case MotionEvent.ACTION_UP:
if (mIsBeingDragged) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
if (getChildCount() > 0) {
if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
fling(-initialVelocity);
} else {
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
postInvalidateOnAnimation();
}
}
}
mActivePointerId = INVALID_POINTER;
endDrag();
}
break;
case MotionEvent.ACTION_CANCEL:
if (mIsBeingDragged && getChildCount() > 0) {
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
postInvalidateOnAnimation();
}
mActivePointerId = INVALID_POINTER;
endDrag();
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
{
final int index = ev.getActionIndex();
mLastMotionY = (int) ev.getY(index);
mActivePointerId = ev.getPointerId(index);
break;
}
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));
break;
}
return true;
}
use of android.view.ViewParent in project android_frameworks_base by ParanoidAndroid.
the class PhoneWindow method openPanel.
private void openPanel(PanelFeatureState st, KeyEvent event) {
// Already open, return
if (st.isOpen || isDestroyed()) {
return;
}
// (The app should be using an action bar for menu items.)
if (st.featureId == FEATURE_OPTIONS_PANEL) {
Context context = getContext();
Configuration config = context.getResources().getConfiguration();
boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.HONEYCOMB;
if (isXLarge && isHoneycombApp) {
return;
}
}
Callback cb = getCallback();
if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) {
// Callback doesn't want the menu to open, reset any state
closePanel(st, true);
return;
}
final WindowManager wm = getWindowManager();
if (wm == null) {
return;
}
// Prepare panel (should have been done before, but just in case)
if (!preparePanel(st, event)) {
return;
}
int width = WRAP_CONTENT;
if (st.decorView == null || st.refreshDecorView) {
if (st.decorView == null) {
// Initialize the panel decor, this will populate st.decorView
if (!initializePanelDecor(st) || (st.decorView == null))
return;
} else if (st.refreshDecorView && (st.decorView.getChildCount() > 0)) {
// Decor needs refreshing, so remove its views
st.decorView.removeAllViews();
}
// This will populate st.shownPanelView
if (!initializePanelContent(st) || !st.hasPanelItems()) {
return;
}
ViewGroup.LayoutParams lp = st.shownPanelView.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
}
int backgroundResId;
if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
// If the contents is fill parent for the width, set the
// corresponding background
backgroundResId = st.fullBackground;
width = MATCH_PARENT;
} else {
// Otherwise, set the normal panel background
backgroundResId = st.background;
}
st.decorView.setWindowBackground(getContext().getResources().getDrawable(backgroundResId));
ViewParent shownPanelParent = st.shownPanelView.getParent();
if (shownPanelParent != null && shownPanelParent instanceof ViewGroup) {
((ViewGroup) shownPanelParent).removeView(st.shownPanelView);
}
st.decorView.addView(st.shownPanelView, lp);
/*
* Give focus to the view, if it or one of its children does not
* already have it.
*/
if (!st.shownPanelView.hasFocus()) {
st.shownPanelView.requestFocus();
}
} else if (!st.isInListMode()) {
width = MATCH_PARENT;
} else if (st.createdPanelView != null) {
// If we already had a panel view, carry width=MATCH_PARENT through
// as we did above when it was created.
ViewGroup.LayoutParams lp = st.createdPanelView.getLayoutParams();
if (lp != null && lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
width = MATCH_PARENT;
}
}
st.isOpen = true;
st.isHandled = false;
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, WRAP_CONTENT, st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, st.decorView.mDefaultOpacity);
if (st.isCompact) {
lp.gravity = getOptionsPanelGravity();
sRotationWatcher.addWindow(this);
} else {
lp.gravity = st.gravity;
}
lp.windowAnimations = st.windowAnimations;
wm.addView(st.decorView, lp);
// Log.v(TAG, "Adding main menu to window manager.");
}
use of android.view.ViewParent in project android_frameworks_base by ParanoidAndroid.
the class PagedView method focusableViewAvailable.
/**
* If one of our descendant views decides that it could be focused now, only
* pass that along if it's on the current page.
*
* This happens when live folders requery, and if they're off page, they
* end up calling requestFocus, which pulls it on page.
*/
@Override
public void focusableViewAvailable(View focused) {
View current = getPageAt(mCurrentPage);
View v = focused;
while (true) {
if (v == current) {
super.focusableViewAvailable(focused);
return;
}
if (v == this) {
return;
}
ViewParent parent = v.getParent();
if (parent instanceof View) {
v = (View) v.getParent();
} else {
return;
}
}
}
Aggregations