Exemple #1
0
        /// <summary>Maps a point to a position in the list.</summary>
        /// <remarks>Maps a point to a position in the list.</remarks>
        /// <param name="x">X in local coordinate</param>
        /// <param name="y">Y in local coordinate</param>
        /// <returns>
        /// The position of the item which contains the specified point, or
        /// <see cref="android.widget.AdapterView.INVALID_POSITION">android.widget.AdapterView.INVALID_POSITION
        ///     </see>
        /// if the point does not intersect an item.
        /// </returns>
        public virtual int pointToPosition(int x, int y)
        {
            android.graphics.Rect frame = mTouchFrame;
            if (frame == null)
            {
                mTouchFrame = new android.graphics.Rect();
                frame       = mTouchFrame;
            }
            int count = getChildCount();

            {
                for (int i = count - 1; i >= 0; i--)
                {
                    android.view.View child = getChildAt(i);
                    if (child.getVisibility() == android.view.View.VISIBLE)
                    {
                        child.getHitRect(frame);
                        if (frame.contains(x, y))
                        {
                            return(mFirstPosition + i);
                        }
                    }
                }
            }
            return(android.widget.AdapterView.INVALID_POSITION);
        }
Exemple #2
0
        /// <summary>Returns the View that should receive a touch at the given coordinates.</summary>
        /// <remarks>Returns the View that should receive a touch at the given coordinates.</remarks>
        /// <param name="rawX">The raw X.</param>
        /// <param name="rawY">The raw Y.</param>
        /// <returns>The view that should receive the touches, or null if there is not one.</returns>
        private android.view.View findViewForTouch(int rawX, int rawY)
        {
            // Reverse order so the child drawn on top gets first dibs.
            int containerCoordsX = rawX - mContainerRawLocation[0];
            int containerCoordsY = rawY - mContainerRawLocation[1];

            android.graphics.Rect frame        = mTempRect;
            android.view.View     closestChild = null;
            int closestChildDistanceSq         = int.MaxValue;

            {
                for (int i = mContainer.getChildCount() - 1; i >= 0; i--)
                {
                    android.view.View child = mContainer.getChildAt(i);
                    if (child.getVisibility() != android.view.View.VISIBLE)
                    {
                        continue;
                    }
                    child.getHitRect(frame);
                    if (frame.contains(containerCoordsX, containerCoordsY))
                    {
                        return(child);
                    }
                    int distanceX;
                    if (containerCoordsX >= frame.left && containerCoordsX <= frame.right)
                    {
                        distanceX = 0;
                    }
                    else
                    {
                        distanceX = System.Math.Min(System.Math.Abs(frame.left - containerCoordsX), System.Math.Abs
                                                        (containerCoordsX - frame.right));
                    }
                    int distanceY;
                    if (containerCoordsY >= frame.top && containerCoordsY <= frame.bottom)
                    {
                        distanceY = 0;
                    }
                    else
                    {
                        distanceY = System.Math.Min(System.Math.Abs(frame.top - containerCoordsY), System.Math.Abs
                                                        (containerCoordsY - frame.bottom));
                    }
                    int distanceSq = distanceX * distanceX + distanceY * distanceY;
                    if ((distanceSq < mTouchPaddingScaledSq) && (distanceSq < closestChildDistanceSq))
                    {
                        closestChild           = child;
                        closestChildDistanceSq = distanceSq;
                    }
                }
            }
            return(closestChild);
        }
Exemple #3
0
        /// <summary>Find the nearest touchable view to the specified view.</summary>
        /// <remarks>Find the nearest touchable view to the specified view.</remarks>
        /// <param name="root">The root of the tree in which to search</param>
        /// <param name="x">X coordinate from which to start the search</param>
        /// <param name="y">Y coordinate from which to start the search</param>
        /// <param name="direction">Direction to look</param>
        /// <param name="deltas">
        /// Offset from the <x, y> to the edge of the nearest view. Note that this array
        /// may already be populated with values.
        /// </param>
        /// <returns>The nearest touchable view, or null if none exists.</returns>
        public virtual android.view.View findNearestTouchable(android.view.ViewGroup root
                                                              , int x, int y, int direction, int[] deltas)
        {
            java.util.ArrayList <android.view.View> touchables = root.getTouchables();
            int minDistance = int.MaxValue;

            android.view.View closest = null;
            int numTouchables         = touchables.size();
            int edgeSlop = android.view.ViewConfiguration.get(root.mContext).getScaledEdgeSlop
                               ();

            android.graphics.Rect closestBounds   = new android.graphics.Rect();
            android.graphics.Rect touchableBounds = mOtherRect;
            {
                for (int i = 0; i < numTouchables; i++)
                {
                    android.view.View touchable = touchables.get(i);
                    // get visible bounds of other view in same coordinate system
                    touchable.getDrawingRect(touchableBounds);
                    root.offsetRectBetweenParentAndChild(touchable, touchableBounds, true, true);
                    if (!isTouchCandidate(x, y, touchableBounds, direction))
                    {
                        continue;
                    }
                    int distance = int.MaxValue;
                    switch (direction)
                    {
                    case android.view.View.FOCUS_LEFT:
                    {
                        distance = x - touchableBounds.right + 1;
                        break;
                    }

                    case android.view.View.FOCUS_RIGHT:
                    {
                        distance = touchableBounds.left;
                        break;
                    }

                    case android.view.View.FOCUS_UP:
                    {
                        distance = y - touchableBounds.bottom + 1;
                        break;
                    }

                    case android.view.View.FOCUS_DOWN:
                    {
                        distance = touchableBounds.top;
                        break;
                    }
                    }
                    if (distance < edgeSlop)
                    {
                        // Give preference to innermost views
                        if (closest == null || closestBounds.contains(touchableBounds) || (!touchableBounds
                                                                                           .contains(closestBounds) && distance < minDistance))
                        {
                            minDistance = distance;
                            closest     = touchable;
                            closestBounds.set(touchableBounds);
                            switch (direction)
                            {
                            case android.view.View.FOCUS_LEFT:
                            {
                                deltas[0] = -distance;
                                break;
                            }

                            case android.view.View.FOCUS_RIGHT:
                            {
                                deltas[0] = distance;
                                break;
                            }

                            case android.view.View.FOCUS_UP:
                            {
                                deltas[1] = -distance;
                                break;
                            }

                            case android.view.View.FOCUS_DOWN:
                            {
                                deltas[1] = distance;
                                break;
                            }
                            }
                        }
                    }
                }
            }
            return(closest);
        }
Exemple #4
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);
        }