use of android.view.ScaleGestureDetector 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.ScaleGestureDetector in project android_frameworks_base by ParanoidAndroid.
the class WebViewClassic method performLongClick.
@Override
public boolean performLongClick() {
// view system. In that case, do nothing.
if (mWebView.getParent() == null)
return false;
// A multi-finger gesture can look like a long press; make sure we don't take
// long press actions if we're scaling.
final ScaleGestureDetector detector = mZoomManager.getScaleGestureDetector();
if (detector != null && detector.isInProgress()) {
return false;
}
// long click does nothing on selection
if (mSelectingText)
return false;
/* if long click brings up a context menu, the super function
* returns true and we're done. Otherwise, nothing happened when
* the user clicked. */
if (mWebViewPrivate.super_performLongClick()) {
return true;
}
/* In the case where the application hasn't already handled the long
* click action, look for a word under the click. If one is found,
* animate the text selection into view.
* FIXME: no animation code yet */
final boolean isSelecting = selectText();
if (isSelecting) {
mWebView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
} else if (focusCandidateIsEditableText()) {
mSelectCallback = new SelectActionModeCallback();
mSelectCallback.setWebView(this);
mSelectCallback.setTextSelected(false);
mWebView.startActionMode(mSelectCallback);
}
return isSelecting;
}
use of android.view.ScaleGestureDetector in project android_frameworks_base by ParanoidAndroid.
the class ExpandHelper method cancel.
/**
* Use this to abort any pending expansions in progress.
*/
public void cancel() {
finishExpanding(true);
clearView();
// reset the gesture detector
mSGD = new ScaleGestureDetector(mContext, mScaleGestureListener);
}
use of android.view.ScaleGestureDetector in project android_frameworks_base by ParanoidAndroid.
the class OverlayDisplayWindow method createWindow.
private void createWindow() {
LayoutInflater inflater = LayoutInflater.from(mContext);
mWindowContent = inflater.inflate(com.android.internal.R.layout.overlay_display_window, null);
mWindowContent.setOnTouchListener(mOnTouchListener);
mTextureView = (TextureView) mWindowContent.findViewById(com.android.internal.R.id.overlay_display_window_texture);
mTextureView.setPivotX(0);
mTextureView.setPivotY(0);
mTextureView.getLayoutParams().width = mWidth;
mTextureView.getLayoutParams().height = mHeight;
mTextureView.setOpaque(false);
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
mTitleTextView = (TextView) mWindowContent.findViewById(com.android.internal.R.id.overlay_display_window_title);
mTitleTextView.setText(mTitle);
mWindowParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY);
mWindowParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
if (DISABLE_MOVE_AND_RESIZE) {
mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
}
mWindowParams.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
mWindowParams.alpha = WINDOW_ALPHA;
mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
mWindowParams.setTitle(mTitle);
mGestureDetector = new GestureDetector(mContext, mOnGestureListener);
mScaleGestureDetector = new ScaleGestureDetector(mContext, mOnScaleGestureListener);
// Set the initial position and scale.
// The position and scale will be clamped when the display is first shown.
mWindowX = (mGravity & Gravity.LEFT) == Gravity.LEFT ? 0 : mDefaultDisplayInfo.logicalWidth;
mWindowY = (mGravity & Gravity.TOP) == Gravity.TOP ? 0 : mDefaultDisplayInfo.logicalHeight;
mWindowScale = INITIAL_SCALE;
}
use of android.view.ScaleGestureDetector in project StickerCamera by Skykai521.
the class ImageViewTouch method init.
@Override
protected void init(Context context, AttributeSet attrs, int defStyle) {
super.init(context, attrs, defStyle);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
mGestureListener = getGestureListener();
mScaleListener = getScaleListener();
mScaleDetector = new ScaleGestureDetector(getContext(), mScaleListener);
mGestureDetector = new GestureDetector(getContext(), mGestureListener, null, true);
mDoubleTapDirection = 1;
}
Aggregations