public override bool dispatchTouchEvent(android.view.MotionEvent ev)
		{
			if (mDefaultTouchRecepient == null)
			{
				return base.dispatchTouchEvent(ev);
			}
			if (base.dispatchTouchEvent(ev))
			{
				return true;
			}
			mTempRect.set(0, 0, 0, 0);
			offsetRectIntoDescendantCoords(mDefaultTouchRecepient, mTempRect);
			ev.setLocation(ev.getX() + mTempRect.left, ev.getY() + mTempRect.top);
			return mDefaultTouchRecepient.dispatchTouchEvent(ev);
		}
Exemplo n.º 2
0
		public override bool onInterceptTouchEvent(android.view.MotionEvent ev)
		{
			int action = ev.getAction();
			if ((action == android.view.MotionEvent.ACTION_MOVE) && (mIsBeingDragged))
			{
				return true;
			}
			switch (action & android.view.MotionEvent.ACTION_MASK)
			{
				case android.view.MotionEvent.ACTION_MOVE:
				{
					int activePointerId = mActivePointerId;
					if (activePointerId == INVALID_POINTER)
					{
						// If we don't have a valid id, the touch down wasn't on content.
						break;
					}
					int pointerIndex = ev.findPointerIndex(activePointerId);
					float x = ev.getX(pointerIndex);
					int xDiff = (int)System.Math.Abs(x - mLastMotionX);
					if (xDiff > mTouchSlop)
					{
						mIsBeingDragged = true;
						mLastMotionX = x;
						initVelocityTrackerIfNotExists();
						mVelocityTracker.addMovement(ev);
						if (mParent != null)
						{
							mParent.requestDisallowInterceptTouchEvent(true);
						}
					}
					break;
				}

				case android.view.MotionEvent.ACTION_DOWN:
				{
					float x = ev.getX();
					if (!inChild((int)x, (int)ev.getY()))
					{
						mIsBeingDragged = false;
						recycleVelocityTracker();
						break;
					}
					mLastMotionX = x;
					mActivePointerId = ev.getPointerId(0);
					initOrResetVelocityTracker();
					mVelocityTracker.addMovement(ev);
					mIsBeingDragged = !mScroller.isFinished();
					break;
				}

				case android.view.MotionEvent.ACTION_CANCEL:
				case android.view.MotionEvent.ACTION_UP:
				{
					mIsBeingDragged = false;
					mActivePointerId = INVALID_POINTER;
					if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0))
					{
						invalidate();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_DOWN:
				{
					int index = ev.getActionIndex();
					mLastMotionX = ev.getX(index);
					mActivePointerId = ev.getPointerId(index);
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_UP:
				{
					onSecondaryPointerUp(ev);
					mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId));
					break;
				}
			}
			return mIsBeingDragged;
		}
Exemplo n.º 3
0
		private bool isConsideredDoubleTap(android.view.MotionEvent firstDown, android.view.MotionEvent
			 firstUp, android.view.MotionEvent secondDown)
		{
			if (!mAlwaysInBiggerTapRegion)
			{
				return false;
			}
			if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT)
			{
				return false;
			}
			int deltaX = (int)firstDown.getX() - (int)secondDown.getX();
			int deltaY = (int)firstDown.getY() - (int)secondDown.getY();
			return (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare);
		}
Exemplo n.º 4
0
			public virtual bool onTouch(android.view.View v, android.view.MotionEvent @event)
			{
				int action = @event.getAction();
				int x = (int)@event.getX();
				int y = (int)@event.getY();
				if (action == android.view.MotionEvent.ACTION_DOWN && this._enclosing.mPopup != null
					 && this._enclosing.mPopup.isShowing() && (x >= 0 && x < this._enclosing.mPopup.
					getWidth() && y >= 0 && y < this._enclosing.mPopup.getHeight()))
				{
					this._enclosing.mHandler.postDelayed(this._enclosing.mResizePopupRunnable, android.widget.ListPopupWindow
						.EXPAND_LIST_TIMEOUT);
				}
				else
				{
					if (action == android.view.MotionEvent.ACTION_UP)
					{
						this._enclosing.mHandler.removeCallbacks(this._enclosing.mResizePopupRunnable);
					}
				}
				return false;
			}
Exemplo n.º 5
0
		protected internal override bool dispatchGenericPointerEvent(android.view.MotionEvent
			 @event)
		{
			// Send the event to the child under the pointer.
			int childrenCount = mChildrenCount;
			if (childrenCount != 0)
			{
				android.view.View[] children = mChildren;
				float x = @event.getX();
				float y = @event.getY();
				{
					for (int i = childrenCount - 1; i >= 0; i--)
					{
						android.view.View child = children[i];
						if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child
							, null))
						{
							continue;
						}
						if (dispatchTransformedGenericPointerEvent(@event, child))
						{
							return true;
						}
					}
				}
			}
			// No child handled the event.  Send it to this view group.
			return base.dispatchGenericPointerEvent(@event);
		}
Exemplo n.º 6
0
		public virtual bool onDown(android.view.MotionEvent e)
		{
			// Kill any existing fling/scroll
			mFlingRunnable.stop(false);
			// Get the item's view that was touched
			mDownTouchPosition = pointToPosition((int)e.getX(), (int)e.getY());
			if (mDownTouchPosition >= 0)
			{
				mDownTouchView = getChildAt(mDownTouchPosition - mFirstPosition);
				mDownTouchView.setPressed(true);
			}
			// Reset the multiple-scroll tracking state
			mIsFirstScroll = true;
			// Must return true to get matching events for this down event.
			return true;
		}
Exemplo n.º 7
0
		/// <summary>MotionEvent has no getRawY(int) method; simulate it pending future API approval.
		/// 	</summary>
		/// <remarks>MotionEvent has no getRawY(int) method; simulate it pending future API approval.
		/// 	</remarks>
		private static float getRawY(android.view.MotionEvent @event, int pointerIndex)
		{
			if (pointerIndex < 0)
			{
				return float.MinValue;
			}
			if (pointerIndex == 0)
			{
				return @event.getRawY();
			}
			float offset = @event.getRawY() - @event.getY();
			return @event.getY(pointerIndex) + offset;
		}
Exemplo n.º 8
0
		public override bool onTouchEvent(android.view.MotionEvent ev)
		{
			if (!isEnabled())
			{
				return false;
			}
			if (mVelocityTracker == null)
			{
				mVelocityTracker = android.view.VelocityTracker.obtain();
			}
			mVelocityTracker.addMovement(ev);
			int action = ev.getActionMasked();
			switch (action)
			{
				case android.view.MotionEvent.ACTION_MOVE:
				{
					float currentMoveY = ev.getY();
					if (mBeginEditOnUpEvent || mScrollState != android.widget.NumberPicker.OnScrollListenerClass.SCROLL_STATE_TOUCH_SCROLL)
					{
						int deltaDownY = (int)System.Math.Abs(currentMoveY - mLastDownEventY);
						if (deltaDownY > mTouchSlop)
						{
							mBeginEditOnUpEvent = false;
							onScrollStateChange(android.widget.NumberPicker.OnScrollListenerClass.SCROLL_STATE_TOUCH_SCROLL
								);
						}
					}
					int deltaMoveY = (int)(currentMoveY - mLastMotionEventY);
					scrollBy(0, deltaMoveY);
					invalidate();
					mLastMotionEventY = currentMoveY;
					break;
				}

				case android.view.MotionEvent.ACTION_UP:
				{
					if (mBeginEditOnUpEvent)
					{
						setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
						showInputControls(mShowInputControlsAnimimationDuration);
						mInputText.requestFocus();
						return true;
					}
					android.view.VelocityTracker velocityTracker = mVelocityTracker;
					velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
					int initialVelocity = (int)velocityTracker.getYVelocity();
					if (System.Math.Abs(initialVelocity) > mMinimumFlingVelocity)
					{
						fling(initialVelocity);
						onScrollStateChange(android.widget.NumberPicker.OnScrollListenerClass.SCROLL_STATE_FLING
							);
					}
					else
					{
						if (mAdjustScrollerOnUpEvent)
						{
							if (mFlingScroller.isFinished() && mAdjustScroller.isFinished())
							{
								postAdjustScrollerCommand(0);
							}
						}
						else
						{
							postAdjustScrollerCommand(SHOW_INPUT_CONTROLS_DELAY_MILLIS);
						}
					}
					mVelocityTracker.recycle();
					mVelocityTracker = null;
					break;
				}
			}
			return true;
		}
Exemplo n.º 9
0
		public override bool onInterceptTouchEvent(android.view.MotionEvent ev)
		{
			int action = ev.getAction();
			switch (action & android.view.MotionEvent.ACTION_MASK)
			{
				case android.view.MotionEvent.ACTION_DOWN:
				{
					if (mActivePointerId == INVALID_POINTER)
					{
						mInitialX = ev.getX();
						mInitialY = ev.getY();
						mActivePointerId = ev.getPointerId(0);
					}
					break;
				}

				case android.view.MotionEvent.ACTION_MOVE:
				{
					int pointerIndex = ev.findPointerIndex(mActivePointerId);
					if (pointerIndex == INVALID_POINTER)
					{
						// no data for our primary pointer, this shouldn't happen, log it
						android.util.Log.d(TAG, "Error: No data for our primary pointer.");
						return false;
					}
					float newY = ev.getY(pointerIndex);
					float deltaY = newY - mInitialY;
					beginGestureIfNeeded(deltaY);
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_UP:
				{
					onSecondaryPointerUp(ev);
					break;
				}

				case android.view.MotionEvent.ACTION_UP:
				case android.view.MotionEvent.ACTION_CANCEL:
				{
					mActivePointerId = INVALID_POINTER;
					mSwipeGestureType = GESTURE_NONE;
					break;
				}
			}
			return mSwipeGestureType != GESTURE_NONE;
		}
Exemplo n.º 10
0
		private void onSecondaryPointerUp(android.view.MotionEvent ev)
		{
			int pointerIndex = (ev.getAction() & android.view.MotionEvent.ACTION_POINTER_INDEX_MASK
				) >> android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
			int pointerId = ev.getPointerId(pointerIndex);
			if (pointerId == mActivePointerId)
			{
				// This was our active pointer going up. Choose a new
				// active pointer and adjust accordingly.
				// TODO: Make this decision more intelligent.
				int newPointerIndex = pointerIndex == 0 ? 1 : 0;
				mLastMotionY = ev.getY(newPointerIndex);
				mActivePointerId = ev.getPointerId(newPointerIndex);
				if (mVelocityTracker != null)
				{
					mVelocityTracker.clear();
				}
			}
		}
Exemplo n.º 11
0
		public override bool onTouchEvent(android.view.MotionEvent ev)
		{
			initVelocityTrackerIfNotExists();
			mVelocityTracker.addMovement(ev);
			int action = ev.getAction();
			switch (action & android.view.MotionEvent.ACTION_MASK)
			{
				case android.view.MotionEvent.ACTION_DOWN:
				{
					mIsBeingDragged = getChildCount() != 0;
					if (!mIsBeingDragged)
					{
						return false;
					}
					if (!mScroller.isFinished())
					{
						mScroller.abortAnimation();
						if (mFlingStrictSpan != null)
						{
							mFlingStrictSpan.finish();
							mFlingStrictSpan = null;
						}
					}
					// Remember where the motion event started
					mLastMotionY = ev.getY();
					mActivePointerId = ev.getPointerId(0);
					break;
				}

				case android.view.MotionEvent.ACTION_MOVE:
				{
					if (mIsBeingDragged)
					{
						// Scroll to follow the motion event
						int activePointerIndex = ev.findPointerIndex(mActivePointerId);
						float y = ev.getY(activePointerIndex);
						int deltaY = (int)(mLastMotionY - y);
						mLastMotionY = y;
						int oldX = mScrollX;
						int oldY = mScrollY;
						int range = getScrollRange();
						int overscrollMode = getOverScrollMode();
						bool 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)
						{
							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
								()))
							{
								invalidate();
							}
						}
					}
					break;
				}

				case android.view.MotionEvent.ACTION_UP:
				{
					if (mIsBeingDragged)
					{
						android.view.VelocityTracker velocityTracker = mVelocityTracker;
						velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
						int initialVelocity = (int)velocityTracker.getYVelocity(mActivePointerId);
						if (getChildCount() > 0)
						{
							if ((System.Math.Abs(initialVelocity) > mMinimumVelocity))
							{
								fling(-initialVelocity);
							}
							else
							{
								if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange()))
								{
									invalidate();
								}
							}
						}
						mActivePointerId = INVALID_POINTER;
						endDrag();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_CANCEL:
				{
					if (mIsBeingDragged && getChildCount() > 0)
					{
						if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange()))
						{
							invalidate();
						}
						mActivePointerId = INVALID_POINTER;
						endDrag();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_DOWN:
				{
					int index = ev.getActionIndex();
					float y = ev.getY(index);
					mLastMotionY = y;
					mActivePointerId = ev.getPointerId(index);
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_UP:
				{
					onSecondaryPointerUp(ev);
					mLastMotionY = ev.getY(ev.findPointerIndex(mActivePointerId));
					break;
				}
			}
			return true;
		}
Exemplo n.º 12
0
		public override bool onInterceptTouchEvent(android.view.MotionEvent ev)
		{
			int action = ev.getAction();
			if ((action == android.view.MotionEvent.ACTION_MOVE) && (mIsBeingDragged))
			{
				return true;
			}
			switch (action & android.view.MotionEvent.ACTION_MASK)
			{
				case android.view.MotionEvent.ACTION_MOVE:
				{
					int activePointerId = mActivePointerId;
					if (activePointerId == INVALID_POINTER)
					{
						// If we don't have a valid id, the touch down wasn't on content.
						break;
					}
					int pointerIndex = ev.findPointerIndex(activePointerId);
					float y = ev.getY(pointerIndex);
					int yDiff = (int)System.Math.Abs(y - mLastMotionY);
					if (yDiff > mTouchSlop)
					{
						mIsBeingDragged = true;
						mLastMotionY = y;
						initVelocityTrackerIfNotExists();
						mVelocityTracker.addMovement(ev);
						if (mScrollStrictSpan == null)
						{
							mScrollStrictSpan = android.os.StrictMode.enterCriticalSpan("ScrollView-scroll");
						}
					}
					break;
				}

				case android.view.MotionEvent.ACTION_DOWN:
				{
					float y = ev.getY();
					if (!inChild((int)ev.getX(), (int)y))
					{
						mIsBeingDragged = false;
						recycleVelocityTracker();
						break;
					}
					mLastMotionY = y;
					mActivePointerId = ev.getPointerId(0);
					initOrResetVelocityTracker();
					mVelocityTracker.addMovement(ev);
					mIsBeingDragged = !mScroller.isFinished();
					if (mIsBeingDragged && mScrollStrictSpan == null)
					{
						mScrollStrictSpan = android.os.StrictMode.enterCriticalSpan("ScrollView-scroll");
					}
					break;
				}

				case android.view.MotionEvent.ACTION_CANCEL:
				case android.view.MotionEvent.ACTION_UP:
				{
					mIsBeingDragged = false;
					mActivePointerId = INVALID_POINTER;
					recycleVelocityTracker();
					if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange()))
					{
						invalidate();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_UP:
				{
					onSecondaryPointerUp(ev);
					break;
				}
			}
			return mIsBeingDragged;
		}
Exemplo n.º 13
0
		internal virtual bool onTouchEvent(android.view.MotionEvent me)
		{
			if (mState == STATE_NONE)
			{
				return false;
			}
			int action = me.getAction();
			if (action == android.view.MotionEvent.ACTION_DOWN)
			{
				if (isPointInside(me.getX(), me.getY()))
				{
					if (!mList.isInScrollingContainer())
					{
						beginDrag();
						return true;
					}
					mInitialTouchY = me.getY();
					startPendingDrag();
				}
			}
			else
			{
				if (action == android.view.MotionEvent.ACTION_UP)
				{
					// don't add ACTION_CANCEL here
					if (mPendingDrag)
					{
						// Allow a tap to scroll.
						beginDrag();
						int viewHeight = mList.getHeight();
						// Jitter
						int newThumbY = (int)me.getY() - mThumbH + 10;
						if (newThumbY < 0)
						{
							newThumbY = 0;
						}
						else
						{
							if (newThumbY + mThumbH > viewHeight)
							{
								newThumbY = viewHeight - mThumbH;
							}
						}
						mThumbY = newThumbY;
						scrollTo((float)mThumbY / (viewHeight - mThumbH));
						cancelPendingDrag();
					}
					// Will hit the STATE_DRAGGING check below
					if (mState == STATE_DRAGGING)
					{
						if (mList != null)
						{
							// ViewGroup does the right thing already, but there might
							// be other classes that don't properly reset on touch-up,
							// so do this explicitly just in case.
							mList.requestDisallowInterceptTouchEvent(false);
							mList.reportScrollStateChange(android.widget.AbsListView.OnScrollListenerClass.SCROLL_STATE_IDLE
								);
						}
						setState(STATE_VISIBLE);
						android.os.Handler handler = mHandler;
						handler.removeCallbacks(mScrollFade);
						if (!mAlwaysShow)
						{
							handler.postDelayed(mScrollFade, 1000);
						}
						mList.invalidate();
						return true;
					}
				}
				else
				{
					if (action == android.view.MotionEvent.ACTION_MOVE)
					{
						if (mPendingDrag)
						{
							float y = me.getY();
							if (System.Math.Abs(y - mInitialTouchY) > mScaledTouchSlop)
							{
								setState(STATE_DRAGGING);
								if (mListAdapter == null && mList != null)
								{
									getSectionsFromIndexer();
								}
								if (mList != null)
								{
									mList.requestDisallowInterceptTouchEvent(true);
									mList.reportScrollStateChange(android.widget.AbsListView.OnScrollListenerClass.SCROLL_STATE_TOUCH_SCROLL
										);
								}
								cancelFling();
								cancelPendingDrag();
							}
						}
						// Will hit the STATE_DRAGGING check below
						if (mState == STATE_DRAGGING)
						{
							int viewHeight = mList.getHeight();
							// Jitter
							int newThumbY = (int)me.getY() - mThumbH + 10;
							if (newThumbY < 0)
							{
								newThumbY = 0;
							}
							else
							{
								if (newThumbY + mThumbH > viewHeight)
								{
									newThumbY = viewHeight - mThumbH;
								}
							}
							if (System.Math.Abs(mThumbY - newThumbY) < 2)
							{
								return true;
							}
							mThumbY = newThumbY;
							// If the previous scrollTo is still pending
							if (mScrollCompleted)
							{
								scrollTo((float)mThumbY / (viewHeight - mThumbH));
							}
							return true;
						}
					}
					else
					{
						if (action == android.view.MotionEvent.ACTION_CANCEL)
						{
							cancelPendingDrag();
						}
					}
				}
			}
			return false;
		}
Exemplo n.º 14
0
		internal virtual bool onInterceptTouchEvent(android.view.MotionEvent ev)
		{
			switch (ev.getActionMasked())
			{
				case android.view.MotionEvent.ACTION_DOWN:
				{
					if (mState > STATE_NONE && isPointInside(ev.getX(), ev.getY()))
					{
						if (!mList.isInScrollingContainer())
						{
							beginDrag();
							return true;
						}
						mInitialTouchY = ev.getY();
						startPendingDrag();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_UP:
				case android.view.MotionEvent.ACTION_CANCEL:
				{
					cancelPendingDrag();
					break;
				}
			}
			return false;
		}
Exemplo n.º 15
0
		private bool isOutOfBounds(android.content.Context context, android.view.MotionEvent
			 @event)
		{
			int x = (int)@event.getX();
			int y = (int)@event.getY();
			int slop = android.view.ViewConfiguration.get(context).getScaledWindowTouchSlop();
			android.view.View decorView = getDecorView();
			return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop)) || (y > 
				(decorView.getHeight() + slop));
		}
Exemplo n.º 16
0
		/// <returns>If the <code>event</code> is in the <code>view</code>.</returns>
		private bool isEventInViewHitRect(android.view.MotionEvent @event, android.view.View
			 view)
		{
			view.getHitRect(mTempRect);
			return mTempRect.contains((int)@event.getX(), (int)@event.getY());
		}
Exemplo n.º 17
0
		public override bool onInterceptTouchEvent(android.view.MotionEvent @event)
		{
			if (!isEnabled() || !mFlingable)
			{
				return false;
			}
			switch (@event.getActionMasked())
			{
				case android.view.MotionEvent.ACTION_DOWN:
				{
					mLastMotionEventY = mLastDownEventY = @event.getY();
					removeAllCallbacks();
					mShowInputControlsAnimator.cancel();
					mDimSelectorWheelAnimator.cancel();
					mBeginEditOnUpEvent = false;
					mAdjustScrollerOnUpEvent = true;
					if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE)
					{
						bool scrollersFinished = mFlingScroller.isFinished() && mAdjustScroller.isFinished
							();
						if (!scrollersFinished)
						{
							mFlingScroller.forceFinished(true);
							mAdjustScroller.forceFinished(true);
							onScrollStateChange(android.widget.NumberPicker.OnScrollListenerClass.SCROLL_STATE_IDLE
								);
						}
						mBeginEditOnUpEvent = scrollersFinished;
						mAdjustScrollerOnUpEvent = true;
						hideInputControls();
						return true;
					}
					if (isEventInViewHitRect(@event, mInputText) || (!mIncrementButton.isShown() && isEventInViewHitRect
						(@event, mIncrementButton)) || (!mDecrementButton.isShown() && isEventInViewHitRect
						(@event, mDecrementButton)))
					{
						mAdjustScrollerOnUpEvent = false;
						setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
						hideInputControls();
						return true;
					}
					break;
				}

				case android.view.MotionEvent.ACTION_MOVE:
				{
					float currentMoveY = @event.getY();
					int deltaDownY = (int)System.Math.Abs(currentMoveY - mLastDownEventY);
					if (deltaDownY > mTouchSlop)
					{
						mBeginEditOnUpEvent = false;
						onScrollStateChange(android.widget.NumberPicker.OnScrollListenerClass.SCROLL_STATE_TOUCH_SCROLL
							);
						setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
						hideInputControls();
						return true;
					}
					break;
				}
			}
			return false;
		}
Exemplo n.º 18
0
		public override bool onTouchEvent(android.view.MotionEvent ev)
		{
			base.onTouchEvent(ev);
			int action = ev.getAction();
			int pointerIndex = ev.findPointerIndex(mActivePointerId);
			if (pointerIndex == INVALID_POINTER)
			{
				// no data for our primary pointer, this shouldn't happen, log it
				android.util.Log.d(TAG, "Error: No data for our primary pointer.");
				return false;
			}
			float newY = ev.getY(pointerIndex);
			float newX = ev.getX(pointerIndex);
			float deltaY = newY - mInitialY;
			float deltaX = newX - mInitialX;
			if (mVelocityTracker == null)
			{
				mVelocityTracker = android.view.VelocityTracker.obtain();
			}
			mVelocityTracker.addMovement(ev);
			switch (action & android.view.MotionEvent.ACTION_MASK)
			{
				case android.view.MotionEvent.ACTION_MOVE:
				{
					beginGestureIfNeeded(deltaY);
					float rx = deltaX / (mSlideAmount * 1.0f);
					if (mSwipeGestureType == GESTURE_SLIDE_DOWN)
					{
						float r = (deltaY - mTouchSlop * 1.0f) / mSlideAmount * 1.0f;
						if (mStackMode == ITEMS_SLIDE_DOWN)
						{
							r = 1 - r;
						}
						mStackSlider.setYProgress(1 - r);
						mStackSlider.setXProgress(rx);
						return true;
					}
					else
					{
						if (mSwipeGestureType == GESTURE_SLIDE_UP)
						{
							float r = -(deltaY + mTouchSlop * 1.0f) / mSlideAmount * 1.0f;
							if (mStackMode == ITEMS_SLIDE_DOWN)
							{
								r = 1 - r;
							}
							mStackSlider.setYProgress(r);
							mStackSlider.setXProgress(rx);
							return true;
						}
					}
					break;
				}

				case android.view.MotionEvent.ACTION_UP:
				{
					handlePointerUp(ev);
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_UP:
				{
					onSecondaryPointerUp(ev);
					break;
				}

				case android.view.MotionEvent.ACTION_CANCEL:
				{
					mActivePointerId = INVALID_POINTER;
					mSwipeGestureType = GESTURE_NONE;
					break;
				}
			}
			return true;
		}
Exemplo n.º 19
0
		public virtual bool onTouchEvent(android.view.MotionEvent @event)
		{
			if (mInputEventConsistencyVerifier != null)
			{
				mInputEventConsistencyVerifier.onTouchEvent(@event, 0);
			}
			int action = @event.getActionMasked();
			if (action == android.view.MotionEvent.ACTION_DOWN)
			{
				reset();
			}
			// Start fresh
			bool handled = true;
			if (mInvalidGesture)
			{
				handled = false;
			}
			else
			{
				if (!mGestureInProgress)
				{
					switch (action)
					{
						case android.view.MotionEvent.ACTION_DOWN:
						{
							mActiveId0 = @event.getPointerId(0);
							mActive0MostRecent = true;
							break;
						}

						case android.view.MotionEvent.ACTION_UP:
						{
							reset();
							break;
						}

						case android.view.MotionEvent.ACTION_POINTER_DOWN:
						{
							// We have a new multi-finger gesture
							// as orientation can change, query the metrics in touch down
							android.util.DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
							mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
							mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;
							if (mPrevEvent != null)
							{
								mPrevEvent.recycle();
							}
							mPrevEvent = android.view.MotionEvent.obtain(@event);
							mTimeDelta = 0;
							int index1 = @event.getActionIndex();
							int index0 = @event.findPointerIndex(mActiveId0);
							mActiveId1 = @event.getPointerId(index1);
							if (index0 < 0 || index0 == index1)
							{
								// Probably someone sending us a broken event stream.
								index0 = findNewActiveIndex(@event, index0 == index1 ? -1 : mActiveId1, index0);
								mActiveId0 = @event.getPointerId(index0);
							}
							mActive0MostRecent = false;
							setContext(@event);
							// Check if we have a sloppy gesture. If so, delay
							// the beginning of the gesture until we're sure that's
							// what the user wanted. Sloppy gestures can happen if the
							// edge of the user's hand is touching the screen, for example.
							float edgeSlop = mEdgeSlop;
							float rightSlop = mRightSlopEdge;
							float bottomSlop = mBottomSlopEdge;
							float x0 = getRawX(@event, index0);
							float y0 = getRawY(@event, index0);
							float x1 = getRawX(@event, index1);
							float y1 = getRawY(@event, index1);
							bool p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlop || y0 > bottomSlop;
							bool p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlop || y1 > bottomSlop;
							if (p0sloppy && p1sloppy)
							{
								mFocusX = -1;
								mFocusY = -1;
								mSloppyGesture = true;
							}
							else
							{
								if (p0sloppy)
								{
									mFocusX = @event.getX(index1);
									mFocusY = @event.getY(index1);
									mSloppyGesture = true;
								}
								else
								{
									if (p1sloppy)
									{
										mFocusX = @event.getX(index0);
										mFocusY = @event.getY(index0);
										mSloppyGesture = true;
									}
									else
									{
										mSloppyGesture = false;
										mGestureInProgress = mListener.onScaleBegin(this);
									}
								}
							}
							break;
						}

						case android.view.MotionEvent.ACTION_MOVE:
						{
							if (mSloppyGesture)
							{
								// Initiate sloppy gestures if we've moved outside of the slop area.
								float edgeSlop = mEdgeSlop;
								float rightSlop = mRightSlopEdge;
								float bottomSlop = mBottomSlopEdge;
								int index0 = @event.findPointerIndex(mActiveId0);
								int index1 = @event.findPointerIndex(mActiveId1);
								float x0 = getRawX(@event, index0);
								float y0 = getRawY(@event, index0);
								float x1 = getRawX(@event, index1);
								float y1 = getRawY(@event, index1);
								bool p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlop || y0 > bottomSlop;
								bool p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlop || y1 > bottomSlop;
								if (p0sloppy)
								{
									// Do we have a different pointer that isn't sloppy?
									int index = findNewActiveIndex(@event, mActiveId1, index0);
									if (index >= 0)
									{
										index0 = index;
										mActiveId0 = @event.getPointerId(index);
										x0 = getRawX(@event, index);
										y0 = getRawY(@event, index);
										p0sloppy = false;
									}
								}
								if (p1sloppy)
								{
									// Do we have a different pointer that isn't sloppy?
									int index = findNewActiveIndex(@event, mActiveId0, index1);
									if (index >= 0)
									{
										index1 = index;
										mActiveId1 = @event.getPointerId(index);
										x1 = getRawX(@event, index);
										y1 = getRawY(@event, index);
										p1sloppy = false;
									}
								}
								if (p0sloppy && p1sloppy)
								{
									mFocusX = -1;
									mFocusY = -1;
								}
								else
								{
									if (p0sloppy)
									{
										mFocusX = @event.getX(index1);
										mFocusY = @event.getY(index1);
									}
									else
									{
										if (p1sloppy)
										{
											mFocusX = @event.getX(index0);
											mFocusY = @event.getY(index0);
										}
										else
										{
											mSloppyGesture = false;
											mGestureInProgress = mListener.onScaleBegin(this);
										}
									}
								}
							}
							break;
						}

						case android.view.MotionEvent.ACTION_POINTER_UP:
						{
							if (mSloppyGesture)
							{
								int pointerCount = @event.getPointerCount();
								int actionIndex = @event.getActionIndex();
								int actionId = @event.getPointerId(actionIndex);
								if (pointerCount > 2)
								{
									if (actionId == mActiveId0)
									{
										int newIndex = findNewActiveIndex(@event, mActiveId1, actionIndex);
										if (newIndex >= 0)
										{
											mActiveId0 = @event.getPointerId(newIndex);
										}
									}
									else
									{
										if (actionId == mActiveId1)
										{
											int newIndex = findNewActiveIndex(@event, mActiveId0, actionIndex);
											if (newIndex >= 0)
											{
												mActiveId1 = @event.getPointerId(newIndex);
											}
										}
									}
								}
								else
								{
									// Set focus point to the remaining finger
									int index = @event.findPointerIndex(actionId == mActiveId0 ? mActiveId1 : mActiveId0
										);
									if (index < 0)
									{
										mInvalidGesture = true;
										android.util.Log.e(TAG, "Invalid MotionEvent stream detected.", new System.Exception
											());
										if (mGestureInProgress)
										{
											mListener.onScaleEnd(this);
										}
										return false;
									}
									mActiveId0 = @event.getPointerId(index);
									mActive0MostRecent = true;
									mActiveId1 = -1;
									mFocusX = @event.getX(index);
									mFocusY = @event.getY(index);
								}
							}
							break;
						}
					}
				}
				else
				{
					switch (action)
					{
						case android.view.MotionEvent.ACTION_POINTER_DOWN:
						{
							// Transform gesture in progress - attempt to handle it
							// End the old gesture and begin a new one with the most recent two fingers.
							mListener.onScaleEnd(this);
							int oldActive0 = mActiveId0;
							int oldActive1 = mActiveId1;
							reset();
							mPrevEvent = android.view.MotionEvent.obtain(@event);
							mActiveId0 = mActive0MostRecent ? oldActive0 : oldActive1;
							mActiveId1 = @event.getPointerId(@event.getActionIndex());
							mActive0MostRecent = false;
							int index0 = @event.findPointerIndex(mActiveId0);
							if (index0 < 0 || mActiveId0 == mActiveId1)
							{
								// Probably someone sending us a broken event stream.
								android.util.Log.e(TAG, "Got " + android.view.MotionEvent.actionToString(action) 
									+ " with bad state while a gesture was in progress. " + "Did you forget to pass an event to "
									 + "ScaleGestureDetector#onTouchEvent?");
								index0 = findNewActiveIndex(@event, mActiveId0 == mActiveId1 ? -1 : mActiveId1, index0
									);
								mActiveId0 = @event.getPointerId(index0);
							}
							setContext(@event);
							mGestureInProgress = mListener.onScaleBegin(this);
							break;
						}

						case android.view.MotionEvent.ACTION_POINTER_UP:
						{
							int pointerCount = @event.getPointerCount();
							int actionIndex = @event.getActionIndex();
							int actionId = @event.getPointerId(actionIndex);
							bool gestureEnded = false;
							if (pointerCount > 2)
							{
								if (actionId == mActiveId0)
								{
									int newIndex = findNewActiveIndex(@event, mActiveId1, actionIndex);
									if (newIndex >= 0)
									{
										mListener.onScaleEnd(this);
										mActiveId0 = @event.getPointerId(newIndex);
										mActive0MostRecent = true;
										mPrevEvent = android.view.MotionEvent.obtain(@event);
										setContext(@event);
										mGestureInProgress = mListener.onScaleBegin(this);
									}
									else
									{
										gestureEnded = true;
									}
								}
								else
								{
									if (actionId == mActiveId1)
									{
										int newIndex = findNewActiveIndex(@event, mActiveId0, actionIndex);
										if (newIndex >= 0)
										{
											mListener.onScaleEnd(this);
											mActiveId1 = @event.getPointerId(newIndex);
											mActive0MostRecent = false;
											mPrevEvent = android.view.MotionEvent.obtain(@event);
											setContext(@event);
											mGestureInProgress = mListener.onScaleBegin(this);
										}
										else
										{
											gestureEnded = true;
										}
									}
								}
								mPrevEvent.recycle();
								mPrevEvent = android.view.MotionEvent.obtain(@event);
								setContext(@event);
							}
							else
							{
								gestureEnded = true;
							}
							if (gestureEnded)
							{
								// Gesture ended
								setContext(@event);
								// Set focus point to the remaining finger
								int activeId = actionId == mActiveId0 ? mActiveId1 : mActiveId0;
								int index = @event.findPointerIndex(activeId);
								mFocusX = @event.getX(index);
								mFocusY = @event.getY(index);
								mListener.onScaleEnd(this);
								reset();
								mActiveId0 = activeId;
								mActive0MostRecent = true;
							}
							break;
						}

						case android.view.MotionEvent.ACTION_CANCEL:
						{
							mListener.onScaleEnd(this);
							reset();
							break;
						}

						case android.view.MotionEvent.ACTION_UP:
						{
							reset();
							break;
						}

						case android.view.MotionEvent.ACTION_MOVE:
						{
							setContext(@event);
							// Only accept the event if our relative pressure is within
							// a certain limit - this can help filter shaky data as a
							// finger is lifted.
							if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD)
							{
								bool updatePrevious = mListener.onScale(this);
								if (updatePrevious)
								{
									mPrevEvent.recycle();
									mPrevEvent = android.view.MotionEvent.obtain(@event);
								}
							}
							break;
						}
					}
				}
			}
			if (!handled && mInputEventConsistencyVerifier != null)
			{
				mInputEventConsistencyVerifier.onUnhandledEvent(@event, 0);
			}
			return handled;
		}
Exemplo n.º 20
0
		private void onSecondaryPointerUp(android.view.MotionEvent ev)
		{
			int activePointerIndex = ev.getActionIndex();
			int pointerId = ev.getPointerId(activePointerIndex);
			if (pointerId == mActivePointerId)
			{
				int activeViewIndex = (mSwipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1;
				android.view.View v = getViewAtRelativeIndex(activeViewIndex);
				if (v == null)
				{
					return;
				}
				{
					// Our primary pointer has gone up -- let's see if we can find
					// another pointer on the view. If so, then we should replace
					// our primary pointer with this new pointer and adjust things
					// so that the view doesn't jump
					for (int index = 0; index < ev.getPointerCount(); index++)
					{
						if (index != activePointerIndex)
						{
							float x = ev.getX(index);
							float y = ev.getY(index);
							mTouchRect.set(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
							if (mTouchRect.contains(Sharpen.Util.Round(x), Sharpen.Util.Round(y)))
							{
								float oldX = ev.getX(activePointerIndex);
								float oldY = ev.getY(activePointerIndex);
								// adjust our frame of reference to avoid a jump
								mInitialY += (y - oldY);
								mInitialX += (x - oldX);
								mActivePointerId = ev.getPointerId(index);
								if (mVelocityTracker != null)
								{
									mVelocityTracker.clear();
								}
								// ok, we're good, we found a new pointer which is touching the active view
								return;
							}
						}
					}
				}
				// if we made it this far, it means we didn't find a satisfactory new pointer :(,
				// so end the gesture
				handlePointerUp(ev);
			}
		}
Exemplo n.º 21
0
		private void setContext(android.view.MotionEvent curr)
		{
			if (mCurrEvent != null)
			{
				mCurrEvent.recycle();
			}
			mCurrEvent = android.view.MotionEvent.obtain(curr);
			mCurrLen = -1;
			mPrevLen = -1;
			mScaleFactor = -1;
			android.view.MotionEvent prev = mPrevEvent;
			int prevIndex0 = prev.findPointerIndex(mActiveId0);
			int prevIndex1 = prev.findPointerIndex(mActiveId1);
			int currIndex0 = curr.findPointerIndex(mActiveId0);
			int currIndex1 = curr.findPointerIndex(mActiveId1);
			if (prevIndex0 < 0 || prevIndex1 < 0 || currIndex0 < 0 || currIndex1 < 0)
			{
				mInvalidGesture = true;
				android.util.Log.e(TAG, "Invalid MotionEvent stream detected.", new System.Exception
					());
				if (mGestureInProgress)
				{
					mListener.onScaleEnd(this);
				}
				return;
			}
			float px0 = prev.getX(prevIndex0);
			float py0 = prev.getY(prevIndex0);
			float px1 = prev.getX(prevIndex1);
			float py1 = prev.getY(prevIndex1);
			float cx0 = curr.getX(currIndex0);
			float cy0 = curr.getY(currIndex0);
			float cx1 = curr.getX(currIndex1);
			float cy1 = curr.getY(currIndex1);
			float pvx = px1 - px0;
			float pvy = py1 - py0;
			float cvx = cx1 - cx0;
			float cvy = cy1 - cy0;
			mPrevFingerDiffX = pvx;
			mPrevFingerDiffY = pvy;
			mCurrFingerDiffX = cvx;
			mCurrFingerDiffY = cvy;
			mFocusX = cx0 + cvx * 0.5f;
			mFocusY = cy0 + cvy * 0.5f;
			mTimeDelta = curr.getEventTime() - prev.getEventTime();
			mCurrPressure = curr.getPressure(currIndex0) + curr.getPressure(currIndex1);
			mPrevPressure = prev.getPressure(prevIndex0) + prev.getPressure(prevIndex1);
		}
Exemplo n.º 22
0
		private void handlePointerUp(android.view.MotionEvent ev)
		{
			int pointerIndex = ev.findPointerIndex(mActivePointerId);
			float newY = ev.getY(pointerIndex);
			int deltaY = (int)(newY - mInitialY);
			mLastInteractionTime = Sharpen.Util.CurrentTimeMillis;
			if (mVelocityTracker != null)
			{
				mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
				mYVelocity = (int)mVelocityTracker.getYVelocity(mActivePointerId);
			}
			if (mVelocityTracker != null)
			{
				mVelocityTracker.recycle();
				mVelocityTracker = null;
			}
			if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN && mStackSlider
				.mMode == android.widget.StackView.StackSlider.NORMAL_MODE)
			{
				// We reset the gesture variable, because otherwise we will ignore showPrevious() /
				// showNext();
				mSwipeGestureType = GESTURE_NONE;
				// Swipe threshold exceeded, swipe down
				if (mStackMode == ITEMS_SLIDE_UP)
				{
					showPrevious();
				}
				else
				{
					showNext();
				}
				mHighlight.bringToFront();
			}
			else
			{
				if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP && mStackSlider
					.mMode == android.widget.StackView.StackSlider.NORMAL_MODE)
				{
					// We reset the gesture variable, because otherwise we will ignore showPrevious() /
					// showNext();
					mSwipeGestureType = GESTURE_NONE;
					// Swipe threshold exceeded, swipe up
					if (mStackMode == ITEMS_SLIDE_UP)
					{
						showNext();
					}
					else
					{
						showPrevious();
					}
					mHighlight.bringToFront();
				}
				else
				{
					if (mSwipeGestureType == GESTURE_SLIDE_UP)
					{
						// Didn't swipe up far enough, snap back down
						int duration;
						float finalYProgress = (mStackMode == ITEMS_SLIDE_DOWN) ? 1 : 0;
						if (mStackMode == ITEMS_SLIDE_UP || mStackSlider.mMode != android.widget.StackView
							.StackSlider.NORMAL_MODE)
						{
							duration = Sharpen.Util.Round(mStackSlider.getDurationForNeutralPosition());
						}
						else
						{
							duration = Sharpen.Util.Round(mStackSlider.getDurationForOffscreenPosition());
						}
						android.widget.StackView.StackSlider animationSlider = new android.widget.StackView
							.StackSlider(this, mStackSlider);
						android.animation.PropertyValuesHolder snapBackY = android.animation.PropertyValuesHolder
							.ofFloat("YProgress", finalYProgress);
						android.animation.PropertyValuesHolder snapBackX = android.animation.PropertyValuesHolder
							.ofFloat("XProgress", 0.0f);
						android.animation.ObjectAnimator pa = android.animation.ObjectAnimator.ofPropertyValuesHolder
							(animationSlider, snapBackX, snapBackY);
						pa.setDuration(duration);
						pa.setInterpolator(new android.view.animation.LinearInterpolator());
						pa.start();
					}
					else
					{
						if (mSwipeGestureType == GESTURE_SLIDE_DOWN)
						{
							// Didn't swipe down far enough, snap back up
							float finalYProgress = (mStackMode == ITEMS_SLIDE_DOWN) ? 0 : 1;
							int duration;
							if (mStackMode == ITEMS_SLIDE_DOWN || mStackSlider.mMode != android.widget.StackView
								.StackSlider.NORMAL_MODE)
							{
								duration = Sharpen.Util.Round(mStackSlider.getDurationForNeutralPosition());
							}
							else
							{
								duration = Sharpen.Util.Round(mStackSlider.getDurationForOffscreenPosition());
							}
							android.widget.StackView.StackSlider animationSlider = new android.widget.StackView
								.StackSlider(this, mStackSlider);
							android.animation.PropertyValuesHolder snapBackY = android.animation.PropertyValuesHolder
								.ofFloat("YProgress", finalYProgress);
							android.animation.PropertyValuesHolder snapBackX = android.animation.PropertyValuesHolder
								.ofFloat("XProgress", 0.0f);
							android.animation.ObjectAnimator pa = android.animation.ObjectAnimator.ofPropertyValuesHolder
								(animationSlider, snapBackX, snapBackY);
							pa.setDuration(duration);
							pa.start();
						}
					}
				}
			}
			mActivePointerId = INVALID_POINTER;
			mSwipeGestureType = GESTURE_NONE;
		}
Exemplo n.º 23
0
		protected internal override bool dispatchHoverEvent(android.view.MotionEvent @event
			)
		{
			int action = @event.getAction();
			// First check whether the view group wants to intercept the hover event.
			bool interceptHover = onInterceptHoverEvent(@event);
			@event.setAction(action);
			// restore action in case it was changed
			android.view.MotionEvent eventNoHistory = @event;
			bool handled = false;
			// Send events to the hovered children and build a new list of hover targets until
			// one is found that handles the event.
			android.view.ViewGroup.HoverTarget firstOldHoverTarget = mFirstHoverTarget;
			mFirstHoverTarget = null;
			if (!interceptHover && action != android.view.MotionEvent.ACTION_HOVER_EXIT)
			{
				float x = @event.getX();
				float y = @event.getY();
				int childrenCount = mChildrenCount;
				if (childrenCount != 0)
				{
					android.view.View[] children = mChildren;
					android.view.ViewGroup.HoverTarget lastHoverTarget = null;
					{
						for (int i = childrenCount - 1; i >= 0; i--)
						{
							android.view.View child = children[i];
							if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child
								, null))
							{
								continue;
							}
							// Obtain a hover target for this child.  Dequeue it from the
							// old hover target list if the child was previously hovered.
							android.view.ViewGroup.HoverTarget hoverTarget = firstOldHoverTarget;
							bool wasHovered;
							{
								for (android.view.ViewGroup.HoverTarget predecessor = null; ; )
								{
									if (hoverTarget == null)
									{
										hoverTarget = android.view.ViewGroup.HoverTarget.obtain(child);
										wasHovered = false;
										break;
									}
									if (hoverTarget.child == child)
									{
										if (predecessor != null)
										{
											predecessor.next = hoverTarget.next;
										}
										else
										{
											firstOldHoverTarget = hoverTarget.next;
										}
										hoverTarget.next = null;
										wasHovered = true;
										break;
									}
									predecessor = hoverTarget;
									hoverTarget = hoverTarget.next;
								}
							}
							// Enqueue the hover target onto the new hover target list.
							if (lastHoverTarget != null)
							{
								lastHoverTarget.next = hoverTarget;
							}
							else
							{
								lastHoverTarget = hoverTarget;
								mFirstHoverTarget = hoverTarget;
							}
							// Dispatch the event to the child.
							if (action == android.view.MotionEvent.ACTION_HOVER_ENTER)
							{
								if (!wasHovered)
								{
									// Send the enter as is.
									handled |= dispatchTransformedGenericPointerEvent(@event, child);
								}
							}
							else
							{
								// enter
								if (action == android.view.MotionEvent.ACTION_HOVER_MOVE)
								{
									if (!wasHovered)
									{
										// Synthesize an enter from a move.
										eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory);
										eventNoHistory.setAction(android.view.MotionEvent.ACTION_HOVER_ENTER);
										handled |= dispatchTransformedGenericPointerEvent(eventNoHistory, child);
										// enter
										eventNoHistory.setAction(action);
										handled |= dispatchTransformedGenericPointerEvent(eventNoHistory, child);
									}
									else
									{
										// move
										// Send the move as is.
										handled |= dispatchTransformedGenericPointerEvent(@event, child);
									}
								}
							}
							if (handled)
							{
								break;
							}
						}
					}
				}
			}
			// Send exit events to all previously hovered children that are no longer hovered.
			while (firstOldHoverTarget != null)
			{
				android.view.View child = firstOldHoverTarget.child;
				// Exit the old hovered child.
				if (action == android.view.MotionEvent.ACTION_HOVER_EXIT)
				{
					// Send the exit as is.
					handled |= dispatchTransformedGenericPointerEvent(@event, child);
				}
				else
				{
					// exit
					// Synthesize an exit from a move or enter.
					// Ignore the result because hover focus has moved to a different view.
					if (action == android.view.MotionEvent.ACTION_HOVER_MOVE)
					{
						dispatchTransformedGenericPointerEvent(@event, child);
					}
					// move
					eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory);
					eventNoHistory.setAction(android.view.MotionEvent.ACTION_HOVER_EXIT);
					dispatchTransformedGenericPointerEvent(eventNoHistory, child);
					// exit
					eventNoHistory.setAction(action);
				}
				android.view.ViewGroup.HoverTarget nextOldHoverTarget = firstOldHoverTarget.next;
				firstOldHoverTarget.recycle();
				firstOldHoverTarget = nextOldHoverTarget;
			}
			// Send events to the view group itself if no children have handled it.
			bool newHoveredSelf = !handled;
			if (newHoveredSelf == mHoveredSelf)
			{
				if (newHoveredSelf)
				{
					// Send event to the view group as before.
					handled |= base.dispatchHoverEvent(@event);
				}
			}
			else
			{
				if (mHoveredSelf)
				{
					// Exit the view group.
					if (action == android.view.MotionEvent.ACTION_HOVER_EXIT)
					{
						// Send the exit as is.
						handled |= base.dispatchHoverEvent(@event);
					}
					else
					{
						// exit
						// Synthesize an exit from a move or enter.
						// Ignore the result because hover focus is moving to a different view.
						if (action == android.view.MotionEvent.ACTION_HOVER_MOVE)
						{
							base.dispatchHoverEvent(@event);
						}
						// move
						eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory);
						eventNoHistory.setAction(android.view.MotionEvent.ACTION_HOVER_EXIT);
						base.dispatchHoverEvent(eventNoHistory);
						// exit
						eventNoHistory.setAction(action);
					}
					mHoveredSelf = false;
				}
				if (newHoveredSelf)
				{
					// Enter the view group.
					if (action == android.view.MotionEvent.ACTION_HOVER_ENTER)
					{
						// Send the enter as is.
						handled |= base.dispatchHoverEvent(@event);
						// enter
						mHoveredSelf = true;
					}
					else
					{
						if (action == android.view.MotionEvent.ACTION_HOVER_MOVE)
						{
							// Synthesize an enter from a move.
							eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory);
							eventNoHistory.setAction(android.view.MotionEvent.ACTION_HOVER_ENTER);
							handled |= base.dispatchHoverEvent(eventNoHistory);
							// enter
							eventNoHistory.setAction(action);
							handled |= base.dispatchHoverEvent(eventNoHistory);
							// move
							mHoveredSelf = true;
						}
					}
				}
			}
			// Recycle the copy of the event that we made.
			if (eventNoHistory != @event)
			{
				eventNoHistory.recycle();
			}
			// Done.
			return handled;
		}
Exemplo n.º 24
0
		public override bool onTouchEvent(android.widget.TextView widget, android.text.Spannable
			 buffer, android.view.MotionEvent @event)
		{
			int initialScrollX = -1;
			int initialScrollY = -1;
			int action = @event.getAction();
			if (action == android.view.MotionEvent.ACTION_UP)
			{
				initialScrollX = android.text.method.Touch.getInitialScrollX(widget, buffer);
				initialScrollY = android.text.method.Touch.getInitialScrollY(widget, buffer);
			}
			bool handled = android.text.method.Touch.onTouchEvent(widget, buffer, @event);
			if (widget.isFocused() && !widget.didTouchFocusSelect())
			{
				if (action == android.view.MotionEvent.ACTION_DOWN)
				{
					if (isSelecting(buffer))
					{
						int offset = widget.getOffsetForPosition(@event.getX(), @event.getY());
						buffer.setSpan(LAST_TAP_DOWN, offset, offset, android.text.SpannedClass.SPAN_POINT_POINT
							);
						// Disallow intercepting of the touch events, so that
						// users can scroll and select at the same time.
						// without this, users would get booted out of select
						// mode once the view detected it needed to scroll.
						widget.getParent().requestDisallowInterceptTouchEvent(true);
					}
				}
				else
				{
					if (action == android.view.MotionEvent.ACTION_MOVE)
					{
						if (isSelecting(buffer) && handled)
						{
							// Before selecting, make sure we've moved out of the "slop".
							// handled will be true, if we're in select mode AND we're
							// OUT of the slop
							// Turn long press off while we're selecting. User needs to
							// re-tap on the selection to enable long press
							widget.cancelLongPress();
							// Update selection as we're moving the selection area.
							// Get the current touch position
							int offset = widget.getOffsetForPosition(@event.getX(), @event.getY());
							android.text.Selection.extendSelection(buffer, offset);
							return true;
						}
					}
					else
					{
						if (action == android.view.MotionEvent.ACTION_UP)
						{
							// If we have scrolled, then the up shouldn't move the cursor,
							// but we do need to make sure the cursor is still visible at
							// the current scroll offset to avoid the scroll jumping later
							// to show it.
							if ((initialScrollY >= 0 && initialScrollY != widget.getScrollY()) || (initialScrollX
								 >= 0 && initialScrollX != widget.getScrollX()))
							{
								widget.moveCursorToVisibleOffset();
								return true;
							}
							int offset = widget.getOffsetForPosition(@event.getX(), @event.getY());
							if (isSelecting(buffer))
							{
								buffer.removeSpan(LAST_TAP_DOWN);
								android.text.Selection.extendSelection(buffer, offset);
							}
							else
							{
								if (!widget.shouldIgnoreActionUpEvent())
								{
									android.text.Selection.setSelection(buffer, offset);
								}
							}
							android.text.method.MetaKeyKeyListener.adjustMetaAfterKeypress(buffer);
							android.text.method.MetaKeyKeyListener.resetLockedMeta(buffer);
							return true;
						}
					}
				}
			}
			return handled;
		}
Exemplo n.º 25
0
		public override bool dispatchTouchEvent(android.view.MotionEvent ev)
		{
			if (mInputEventConsistencyVerifier != null)
			{
				mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
			}
			bool handled = false;
			if (onFilterTouchEventForSecurity(ev))
			{
				int action = ev.getAction();
				int actionMasked = action & android.view.MotionEvent.ACTION_MASK;
				// Handle an initial down.
				if (actionMasked == android.view.MotionEvent.ACTION_DOWN)
				{
					// Throw away all previous state when starting a new touch gesture.
					// The framework may have dropped the up or cancel event for the previous gesture
					// due to an app switch, ANR, or some other state change.
					cancelAndClearTouchTargets(ev);
					resetTouchState();
				}
				// Check for interception.
				bool intercepted;
				if (actionMasked == android.view.MotionEvent.ACTION_DOWN || mFirstTouchTarget != 
					null)
				{
					bool disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
					if (!disallowIntercept)
					{
						intercepted = onInterceptTouchEvent(ev);
						ev.setAction(action);
					}
					else
					{
						// restore action in case it was changed
						intercepted = false;
					}
				}
				else
				{
					// There are no touch targets and this action is not an initial down
					// so this view group continues to intercept touches.
					intercepted = true;
				}
				// Check for cancelation.
				bool canceled = resetCancelNextUpFlag(this) || actionMasked == android.view.MotionEvent
					.ACTION_CANCEL;
				// Update list of touch targets for pointer down, if needed.
				bool split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
				android.view.ViewGroup.TouchTarget newTouchTarget = null;
				bool alreadyDispatchedToNewTouchTarget = false;
				if (!canceled && !intercepted)
				{
					if (actionMasked == android.view.MotionEvent.ACTION_DOWN || (split && actionMasked
						 == android.view.MotionEvent.ACTION_POINTER_DOWN) || actionMasked == android.view.MotionEvent
						.ACTION_HOVER_MOVE)
					{
						int actionIndex = ev.getActionIndex();
						// always 0 for down
						int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex) : android.view.ViewGroup
							.TouchTarget.ALL_POINTER_IDS;
						// Clean up earlier touch targets for this pointer id in case they
						// have become out of sync.
						removePointersFromTouchTargets(idBitsToAssign);
						int childrenCount = mChildrenCount;
						if (childrenCount != 0)
						{
							// Find a child that can receive the event.
							// Scan children from front to back.
							android.view.View[] children = mChildren;
							float x = ev.getX(actionIndex);
							float y = ev.getY(actionIndex);
							{
								for (int i = childrenCount - 1; i >= 0; i--)
								{
									android.view.View child = children[i];
									if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child
										, null))
									{
										continue;
									}
									newTouchTarget = getTouchTarget(child);
									if (newTouchTarget != null)
									{
										// Child is already receiving touch within its bounds.
										// Give it the new pointer in addition to the ones it is handling.
										newTouchTarget.pointerIdBits |= idBitsToAssign;
										break;
									}
									resetCancelNextUpFlag(child);
									if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign))
									{
										// Child wants to receive touch within its bounds.
										mLastTouchDownTime = ev.getDownTime();
										mLastTouchDownIndex = i;
										mLastTouchDownX = ev.getX();
										mLastTouchDownY = ev.getY();
										newTouchTarget = addTouchTarget(child, idBitsToAssign);
										alreadyDispatchedToNewTouchTarget = true;
										break;
									}
								}
							}
						}
						if (newTouchTarget == null && mFirstTouchTarget != null)
						{
							// Did not find a child to receive the event.
							// Assign the pointer to the least recently added target.
							newTouchTarget = mFirstTouchTarget;
							while (newTouchTarget.next != null)
							{
								newTouchTarget = newTouchTarget.next;
							}
							newTouchTarget.pointerIdBits |= idBitsToAssign;
						}
					}
				}
				// Dispatch to touch targets.
				if (mFirstTouchTarget == null)
				{
					// No touch targets so treat this as an ordinary view.
					handled = dispatchTransformedTouchEvent(ev, canceled, null, android.view.ViewGroup
						.TouchTarget.ALL_POINTER_IDS);
				}
				else
				{
					// Dispatch to touch targets, excluding the new touch target if we already
					// dispatched to it.  Cancel touch targets if necessary.
					android.view.ViewGroup.TouchTarget predecessor = null;
					android.view.ViewGroup.TouchTarget target = mFirstTouchTarget;
					while (target != null)
					{
						android.view.ViewGroup.TouchTarget next = target.next;
						if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget)
						{
							handled = true;
						}
						else
						{
							bool cancelChild = resetCancelNextUpFlag(target.child) || intercepted;
							if (dispatchTransformedTouchEvent(ev, cancelChild, target.child, target.pointerIdBits
								))
							{
								handled = true;
							}
							if (cancelChild)
							{
								if (predecessor == null)
								{
									mFirstTouchTarget = next;
								}
								else
								{
									predecessor.next = next;
								}
								target.recycle();
								target = next;
								continue;
							}
						}
						predecessor = target;
						target = next;
					}
				}
				// Update list of touch targets for pointer up or cancel, if needed.
				if (canceled || actionMasked == android.view.MotionEvent.ACTION_UP || actionMasked
					 == android.view.MotionEvent.ACTION_HOVER_MOVE)
				{
					resetTouchState();
				}
				else
				{
					if (split && actionMasked == android.view.MotionEvent.ACTION_POINTER_UP)
					{
						int actionIndex = ev.getActionIndex();
						int idBitsToRemove = 1 << ev.getPointerId(actionIndex);
						removePointersFromTouchTargets(idBitsToRemove);
					}
				}
			}
			if (!handled && mInputEventConsistencyVerifier != null)
			{
				mInputEventConsistencyVerifier.onUnhandledEvent(ev, 1);
			}
			return handled;
		}
Exemplo n.º 26
0
		/// <summary>
		/// Will forward touch events to the delegate view if the event is within the bounds
		/// specified in the constructor.
		/// </summary>
		/// <remarks>
		/// Will forward touch events to the delegate view if the event is within the bounds
		/// specified in the constructor.
		/// </remarks>
		/// <param name="event">The touch event to forward</param>
		/// <returns>True if the event was forwarded to the delegate, false otherwise.</returns>
		public virtual bool onTouchEvent(android.view.MotionEvent @event)
		{
			int x = (int)@event.getX();
			int y = (int)@event.getY();
			bool sendToDelegate = false;
			bool hit = true;
			bool handled = false;
			switch (@event.getAction())
			{
				case android.view.MotionEvent.ACTION_DOWN:
				{
					android.graphics.Rect bounds = mBounds;
					if (bounds.contains(x, y))
					{
						mDelegateTargeted = true;
						sendToDelegate = true;
					}
					break;
				}

				case android.view.MotionEvent.ACTION_UP:
				case android.view.MotionEvent.ACTION_MOVE:
				{
					sendToDelegate = mDelegateTargeted;
					if (sendToDelegate)
					{
						android.graphics.Rect slopBounds = mSlopBounds;
						if (!slopBounds.contains(x, y))
						{
							hit = false;
						}
					}
					break;
				}

				case android.view.MotionEvent.ACTION_CANCEL:
				{
					sendToDelegate = mDelegateTargeted;
					mDelegateTargeted = false;
					break;
				}
			}
			if (sendToDelegate)
			{
				android.view.View delegateView = mDelegateView;
				if (hit)
				{
					// Offset event coordinates to be inside the target view
					@event.setLocation(delegateView.getWidth() / 2, delegateView.getHeight() / 2);
				}
				else
				{
					// Offset event coordinates to be outside the target view (in case it does
					// something like tracking pressed state)
					int slop = mSlop;
					@event.setLocation(-(slop * 2), -(slop * 2));
				}
				handled = delegateView.dispatchTouchEvent(@event);
			}
			return handled;
		}
Exemplo n.º 27
0
			public override bool onTouchEvent(android.view.MotionEvent @event)
			{
				int x = (int)@event.getX();
				int y = (int)@event.getY();
				if ((@event.getAction() == android.view.MotionEvent.ACTION_DOWN) && ((x < 0) || (
					x >= this.getWidth()) || (y < 0) || (y >= this.getHeight())))
				{
					this._enclosing.dismiss();
					return true;
				}
				else
				{
					if (@event.getAction() == android.view.MotionEvent.ACTION_OUTSIDE)
					{
						this._enclosing.dismiss();
						return true;
					}
					else
					{
						return base.onTouchEvent(@event);
					}
				}
			}
Exemplo n.º 28
0
		/// <summary>
		/// Analyzes the given motion event and if applicable triggers the
		/// appropriate callbacks on the
		/// <see cref="OnGestureListener">OnGestureListener</see>
		/// supplied.
		/// </summary>
		/// <param name="ev">The current motion event.</param>
		/// <returns>
		/// true if the
		/// <see cref="OnGestureListener">OnGestureListener</see>
		/// consumed the event,
		/// else false.
		/// </returns>
		public virtual bool onTouchEvent(android.view.MotionEvent ev)
		{
			if (mInputEventConsistencyVerifier != null)
			{
				mInputEventConsistencyVerifier.onTouchEvent(ev, 0);
			}
			int action = ev.getAction();
			float y = ev.getY();
			float x = ev.getX();
			if (mVelocityTracker == null)
			{
				mVelocityTracker = android.view.VelocityTracker.obtain();
			}
			mVelocityTracker.addMovement(ev);
			bool handled = false;
			switch (action & android.view.MotionEvent.ACTION_MASK)
			{
				case android.view.MotionEvent.ACTION_POINTER_DOWN:
				{
					if (mIgnoreMultitouch)
					{
						// Multitouch event - abort.
						cancel();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_UP:
				{
					// Ending a multitouch gesture and going back to 1 finger
					if (mIgnoreMultitouch && ev.getPointerCount() == 2)
					{
						int index = (((action & android.view.MotionEvent.ACTION_POINTER_INDEX_MASK) >> android.view.MotionEvent
							.ACTION_POINTER_INDEX_SHIFT) == 0) ? 1 : 0;
						mLastMotionX = ev.getX(index);
						mLastMotionY = ev.getY(index);
						mVelocityTracker.recycle();
						mVelocityTracker = android.view.VelocityTracker.obtain();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_DOWN:
				{
					if (mDoubleTapListener != null)
					{
						bool hadTapMessage = mHandler.hasMessages(TAP);
						if (hadTapMessage)
						{
							mHandler.removeMessages(TAP);
						}
						if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
							 isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev))
						{
							// This is a second tap
							mIsDoubleTapping = true;
							// Give a callback with the first tap of the double-tap
							handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
							// Give a callback with down event of the double-tap
							handled |= mDoubleTapListener.onDoubleTapEvent(ev);
						}
						else
						{
							// This is a first tap
							mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
						}
					}
					mLastMotionX = x;
					mLastMotionY = y;
					if (mCurrentDownEvent != null)
					{
						mCurrentDownEvent.recycle();
					}
					mCurrentDownEvent = android.view.MotionEvent.obtain(ev);
					mAlwaysInTapRegion = true;
					mAlwaysInBiggerTapRegion = true;
					mStillDown = true;
					mInLongPress = false;
					if (mIsLongpressEnabled)
					{
						mHandler.removeMessages(LONG_PRESS);
						mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT
							 + LONGPRESS_TIMEOUT);
					}
					mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT
						);
					handled |= mListener.onDown(ev);
					break;
				}

				case android.view.MotionEvent.ACTION_MOVE:
				{
					if (mInLongPress || (mIgnoreMultitouch && ev.getPointerCount() > 1))
					{
						break;
					}
					float scrollX = mLastMotionX - x;
					float scrollY = mLastMotionY - y;
					if (mIsDoubleTapping)
					{
						// Give the move events of the double-tap
						handled |= mDoubleTapListener.onDoubleTapEvent(ev);
					}
					else
					{
						if (mAlwaysInTapRegion)
						{
							int deltaX = (int)(x - mCurrentDownEvent.getX());
							int deltaY = (int)(y - mCurrentDownEvent.getY());
							int distance = (deltaX * deltaX) + (deltaY * deltaY);
							if (distance > mTouchSlopSquare)
							{
								handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
								mLastMotionX = x;
								mLastMotionY = y;
								mAlwaysInTapRegion = false;
								mHandler.removeMessages(TAP);
								mHandler.removeMessages(SHOW_PRESS);
								mHandler.removeMessages(LONG_PRESS);
							}
							if (distance > mBiggerTouchSlopSquare)
							{
								mAlwaysInBiggerTapRegion = false;
							}
						}
						else
						{
							if ((System.Math.Abs(scrollX) >= 1) || (System.Math.Abs(scrollY) >= 1))
							{
								handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
								mLastMotionX = x;
								mLastMotionY = y;
							}
						}
					}
					break;
				}

				case android.view.MotionEvent.ACTION_UP:
				{
					mStillDown = false;
					android.view.MotionEvent currentUpEvent = android.view.MotionEvent.obtain(ev);
					if (mIsDoubleTapping)
					{
						// Finally, give the up event of the double-tap
						handled |= mDoubleTapListener.onDoubleTapEvent(ev);
					}
					else
					{
						if (mInLongPress)
						{
							mHandler.removeMessages(TAP);
							mInLongPress = false;
						}
						else
						{
							if (mAlwaysInTapRegion)
							{
								handled = mListener.onSingleTapUp(ev);
							}
							else
							{
								// A fling must travel the minimum tap distance
								android.view.VelocityTracker velocityTracker = mVelocityTracker;
								velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
								float velocityY = velocityTracker.getYVelocity();
								float velocityX = velocityTracker.getXVelocity();
								if ((System.Math.Abs(velocityY) > mMinimumFlingVelocity) || (System.Math.Abs(velocityX
									) > mMinimumFlingVelocity))
								{
									handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY);
								}
							}
						}
					}
					if (mPreviousUpEvent != null)
					{
						mPreviousUpEvent.recycle();
					}
					// Hold the event we obtained above - listeners may have changed the original.
					mPreviousUpEvent = currentUpEvent;
					mVelocityTracker.recycle();
					mVelocityTracker = null;
					mIsDoubleTapping = false;
					mHandler.removeMessages(SHOW_PRESS);
					mHandler.removeMessages(LONG_PRESS);
					break;
				}

				case android.view.MotionEvent.ACTION_CANCEL:
				{
					cancel();
					break;
				}
			}
			if (!handled && mInputEventConsistencyVerifier != null)
			{
				mInputEventConsistencyVerifier.onUnhandledEvent(ev, 0);
			}
			return handled;
		}