Example usage for java.lang Math signum

List of usage examples for java.lang Math signum

Introduction

In this page you can find the example usage for java.lang Math signum.

Prototype

public static float signum(float f) 

Source Link

Document

Returns the signum function of the argument; zero if the argument is zero, 1.0f if the argument is greater than zero, -1.0f if the argument is less than zero.

Usage

From source file:net.pms.util.Rational.java

/**
 * Compares this {@link Rational} by value with any class implementing
 * {@link Number}.//  w  w  w  .  ja v a2  s .c  o  m
 * <p>
 * This method is provided in preference to individual methods for each of
 * the six boolean comparison operators ({@literal <}, ==, {@literal >},
 * {@literal >=}, !=, {@literal <=}). The suggested idiom for performing
 * these comparisons is: {@code (x.compareTo(y)} &lt;<i>op</i>&gt;
 * {@code 0)}, where &lt;<i>op</i>&gt; is one of the six comparison
 * operators.
 * <p>
 * <b>Note:</b> {@code NaN} can't be compared by value and is considered
 * greater than anything but itself as defined for {@link Double}.
 *
 * @param number the {@link Number} to which this {@link Rational}'s value
 *            is to be compared.
 * @return A negative integer, zero, or a positive integer as this
 *         {@link Rational} is numerically less than, equal to, or greater
 *         than {@code number}.
 */
public int compareTo(@Nonnull Number number) {
    // Establish special cases
    boolean numberIsNaN;
    boolean numberIsInfinite;
    int numberSignum;
    if (number instanceof Rational) {
        numberIsNaN = Rational.isNaN((Rational) number);
        numberIsInfinite = Rational.isInfinite((Rational) number);
        numberSignum = ((Rational) number).numerator.signum();
    } else if (number instanceof Float) {
        numberIsNaN = Float.isNaN(number.floatValue());
        numberIsInfinite = Float.isInfinite(number.floatValue());
        numberSignum = (int) Math.signum(number.floatValue());
    } else if (number instanceof Double) {
        numberIsNaN = Double.isNaN(number.doubleValue());
        numberIsInfinite = Double.isInfinite(number.doubleValue());
        numberSignum = (int) Math.signum(number.doubleValue());
    } else {
        numberIsNaN = false;
        numberIsInfinite = false;
        long l = number.longValue();
        numberSignum = l == 0 ? 0 : l > 0 ? 1 : -1;
    }

    // NaN comparison is done according to the rules for Double.
    if (isNaN()) {
        return numberIsNaN ? 0 : 1;
    }
    if (numberIsNaN) {
        return -1;
    }

    if (isInfinite()) {
        if (numberIsInfinite) {
            return signum() - numberSignum;
        }
        return this.signum();
    }
    if (numberIsInfinite) {
        return -numberSignum;
    }

    // List known integer types for faster and more accurate comparison
    if (number instanceof BigInteger) {
        if (isInteger()) {
            return bigIntegerValue().compareTo((BigInteger) number);
        }
        return bigDecimalValue(2, RoundingMode.HALF_EVEN).compareTo(new BigDecimal((BigInteger) number));
    }
    if (number instanceof AtomicInteger || number instanceof AtomicLong || number instanceof Byte
            || number instanceof Integer || number instanceof Long || number instanceof Short) {
        if (isInteger()) {
            return bigIntegerValue().compareTo(BigInteger.valueOf(number.longValue()));
        }
        return bigDecimalValue(2, RoundingMode.HALF_EVEN).compareTo(new BigDecimal(number.longValue()));
    }
    if (number instanceof BigDecimal) {
        Rational other = valueOf((BigDecimal) number);
        return compareTo(other);
    }
    return bigDecimalValue().compareTo(new BigDecimal(number.doubleValue()));
}

From source file:cc.flydev.launcher.Page.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (DISABLE_TOUCH_INTERACTION) {
        return false;
    }//from  w  w  w  .  j  a v a2s .c om

    super.onTouchEvent(ev);

    // Skip touch handling if there are no pages to swipe
    if (getChildCount() <= 0)
        return super.onTouchEvent(ev);

    acquireVelocityTrackerAndAddMovement(ev);

    final int action = ev.getAction();

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        /*
         * If being flinged and user touches, stop the fling. isFinished
         * will be false if being flinged.
         */
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
        }

        // Remember where the motion event started
        mDownMotionX = mLastMotionX = ev.getX();
        mDownMotionY = mLastMotionY = ev.getY();
        mDownScrollX = getScrollX();
        float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
        mParentDownMotionX = p[0];
        mParentDownMotionY = p[1];
        mLastMotionXRemainder = 0;
        mTotalMotionX = 0;
        mActivePointerId = ev.getPointerId(0);

        if (mTouchState == TOUCH_STATE_SCROLLING) {
            pageBeginMoving();
        }
        break;

    case MotionEvent.ACTION_MOVE:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            // Scroll to follow the motion event
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);

            if (pointerIndex == -1)
                return true;

            final float x = ev.getX(pointerIndex);
            final float deltaX = mLastMotionX + mLastMotionXRemainder - x;

            mTotalMotionX += Math.abs(deltaX);

            // Only scroll and update mLastMotionX if we have moved some discrete amount.  We
            // keep the remainder because we are actually testing if we've moved from the last
            // scrolled position (which is discrete).
            if (Math.abs(deltaX) >= 1.0f) {
                mTouchX += deltaX;
                mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                if (!mDeferScrollUpdate) {
                    scrollBy((int) deltaX, 0);
                    if (DEBUG)
                        Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
                } else {
                    invalidate();
                }
                mLastMotionX = x;
                mLastMotionXRemainder = deltaX - (int) deltaX;
            } else {
                awakenScrollBars();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();

            // Find the closest page to the touch point
            final int dragViewIndex = indexOfChild(mDragView);

            // Change the drag view if we are hovering over the drop target
            boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
                    (int) mParentDownMotionY);
            setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);

            if (DEBUG)
                Log.d(TAG, "mLastMotionX: " + mLastMotionX);
            if (DEBUG)
                Log.d(TAG, "mLastMotionY: " + mLastMotionY);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);

            final int pageUnderPointIndex = getNearestHoverOverPageIndex();
            if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView)
                    && !isHoveringOverDelete) {
                mTempVisiblePagesRange[0] = 0;
                mTempVisiblePagesRange[1] = getPageCount() - 1;
                getOverviewModePages(mTempVisiblePagesRange);
                if (mTempVisiblePagesRange[0] <= pageUnderPointIndex
                        && pageUnderPointIndex <= mTempVisiblePagesRange[1]
                        && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
                    mSidePageHoverIndex = pageUnderPointIndex;
                    mSidePageHoverRunnable = new Runnable() {
                        @Override
                        public void run() {
                            // Setup the scroll to the correct page before we swap the views
                            snapToPage(pageUnderPointIndex);

                            // For each of the pages between the paged view and the drag view,
                            // animate them from the previous position to the new position in
                            // the layout (as a result of the drag view moving in the layout)
                            int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
                            int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1
                                    : pageUnderPointIndex;
                            int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1
                                    : pageUnderPointIndex;
                            for (int i = lowerIndex; i <= upperIndex; ++i) {
                                View v = getChildAt(i);
                                // dragViewIndex < pageUnderPointIndex, so after we remove the
                                // drag view all subsequent views to pageUnderPointIndex will
                                // shift down.
                                int oldX = getViewportOffsetX() + getChildOffset(i);
                                int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);

                                // Animate the view translation from its old position to its new
                                // position
                                AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY);
                                if (anim != null) {
                                    anim.cancel();
                                }

                                v.setTranslationX(oldX - newX);
                                anim = new AnimatorSet();
                                anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
                                anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f));
                                anim.start();
                                v.setTag(anim);
                            }

                            removeView(mDragView);
                            onRemoveView(mDragView, false);
                            addView(mDragView, pageUnderPointIndex);
                            onAddView(mDragView, pageUnderPointIndex);
                            mSidePageHoverIndex = -1;
                            mPageIndicator.setActiveMarker(getNextPage());
                        }
                    };
                    postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
                }
            } else {
                removeCallbacks(mSidePageHoverRunnable);
                mSidePageHoverIndex = -1;
            }
        } else {
            determineScrollingStart(ev);
        }
        break;

    case MotionEvent.ACTION_UP:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            final int activePointerId = mActivePointerId;
            final int pointerIndex = ev.findPointerIndex(activePointerId);
            final float x = ev.getX(pointerIndex);
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
            final int deltaX = (int) (x - mDownMotionX);
            final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth();
            boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD;

            mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);

            boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING
                    && Math.abs(velocityX) > mFlingThresholdVelocity;

            if (!mFreeScroll) {
                // In the case that the page is moved far to one direction and then is flung
                // in the opposite direction, we use a threshold to determine whether we should
                // just return to the starting page, or if we should skip one further.
                boolean returnToOriginalPage = false;
                if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD
                        && Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
                    returnToOriginalPage = true;
                }

                int finalPage;
                // We give flings precedence over large moves, which is why we short-circuit our
                // test for a large move if a fling has been registered. That is, a large
                // move to the left and fling to the right will register as a fling to the right.
                final boolean isRtl = isLayoutRtl();
                boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
                boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
                if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft))
                        && mCurrentPage > 0) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft))
                        && mCurrentPage < getChildCount() - 1) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else {
                    snapToDestination();
                }
            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
                // at this point we have not moved beyond the touch slop
                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
                // we can just page
                int nextPage = Math.max(0, mCurrentPage - 1);
                if (nextPage != mCurrentPage) {
                    snapToPage(nextPage);
                } else {
                    snapToDestination();
                }
            } else {
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }

                float scaleX = getScaleX();
                int vX = (int) (-velocityX * scaleX);
                int initialScrollX = (int) (getScrollX() * scaleX);

                mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0,
                        0);
                invalidate();
            }
        } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
            // at this point we have not moved beyond the touch slop
            // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
            // we can just page
            int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
            if (nextPage != mCurrentPage) {
                snapToPage(nextPage);
            } else {
                snapToDestination();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();
            boolean handledFling = false;
            if (!DISABLE_FLING_TO_DELETE) {
                // Check the velocity and see if we are flinging-to-delete
                PointF flingToDeleteVector = isFlingingToDelete();
                if (flingToDeleteVector != null) {
                    onFlingToDelete(flingToDeleteVector);
                    handledFling = true;
                }
            }
            if (!handledFling
                    && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) {
                onDropToDelete();
            }
        } else {
            if (!mCancelTap) {
                onUnhandledTap(ev);
            }
        }

        // Remove the callback to wait for the side page hover timeout
        removeCallbacks(mSidePageHoverRunnable);
        // End any intermediate reordering states
        resetTouchState();
        break;

    case MotionEvent.ACTION_CANCEL:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            snapToDestination();
        }
        resetTouchState();
        break;

    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        releaseVelocityTracker();
        break;
    }

    return true;
}

From source file:com.n2hsu.launcher.Page.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (DISABLE_TOUCH_INTERACTION) {
        return false;
    }//from   www . j a v  a2s. co  m

    super.onTouchEvent(ev);

    // Skip touch handling if there are no pages to swipe
    if (getChildCount() <= 0)
        return super.onTouchEvent(ev);

    acquireVelocityTrackerAndAddMovement(ev);

    final int action = ev.getAction();

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        /*
         * If being flinged and user touches, stop the fling. isFinished
         * will be false if being flinged.
         */
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
        }

        // Remember where the motion event started
        mDownMotionX = mLastMotionX = ev.getX();
        mDownMotionY = mLastMotionY = ev.getY();
        mDownScrollX = getScrollX();
        float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
        mParentDownMotionX = p[0];
        mParentDownMotionY = p[1];
        mLastMotionXRemainder = 0;
        mTotalMotionX = 0;
        mActivePointerId = ev.getPointerId(0);

        if (mTouchState == TOUCH_STATE_SCROLLING) {
            pageBeginMoving();
        }
        break;

    case MotionEvent.ACTION_MOVE:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            // Scroll to follow the motion event
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);

            if (pointerIndex == -1)
                return true;

            final float x = ev.getX(pointerIndex);
            final float deltaX = mLastMotionX + mLastMotionXRemainder - x;

            mTotalMotionX += Math.abs(deltaX);

            // Only scroll and update mLastMotionX if we have moved some
            // discrete amount. We
            // keep the remainder because we are actually testing if we've
            // moved from the last
            // scrolled position (which is discrete).
            if (Math.abs(deltaX) >= 1.0f) {
                mTouchX += deltaX;
                mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                if (!mDeferScrollUpdate) {
                    scrollBy((int) deltaX, 0);
                    if (DEBUG)
                        Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
                } else {
                    invalidate();
                }
                mLastMotionX = x;
                mLastMotionXRemainder = deltaX - (int) deltaX;
            } else {
                awakenScrollBars();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this
            // new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();

            // Find the closest page to the touch point
            final int dragViewIndex = indexOfChild(mDragView);

            // Change the drag view if we are hovering over the drop target
            boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
                    (int) mParentDownMotionY);
            setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);

            if (DEBUG)
                Log.d(TAG, "mLastMotionX: " + mLastMotionX);
            if (DEBUG)
                Log.d(TAG, "mLastMotionY: " + mLastMotionY);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);

            final int pageUnderPointIndex = getNearestHoverOverPageIndex();
            if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView)
                    && !isHoveringOverDelete) {
                mTempVisiblePagesRange[0] = 0;
                mTempVisiblePagesRange[1] = getPageCount() - 1;
                getOverviewModePages(mTempVisiblePagesRange);
                if (mTempVisiblePagesRange[0] <= pageUnderPointIndex
                        && pageUnderPointIndex <= mTempVisiblePagesRange[1]
                        && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
                    mSidePageHoverIndex = pageUnderPointIndex;
                    mSidePageHoverRunnable = new Runnable() {
                        @Override
                        public void run() {
                            // Setup the scroll to the correct page before
                            // we swap the views
                            snapToPage(pageUnderPointIndex);

                            // For each of the pages between the paged view
                            // and the drag view,
                            // animate them from the previous position to
                            // the new position in
                            // the layout (as a result of the drag view
                            // moving in the layout)
                            int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
                            int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1
                                    : pageUnderPointIndex;
                            int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1
                                    : pageUnderPointIndex;
                            for (int i = lowerIndex; i <= upperIndex; ++i) {
                                View v = getChildAt(i);
                                // dragViewIndex < pageUnderPointIndex, so
                                // after we remove the
                                // drag view all subsequent views to
                                // pageUnderPointIndex will
                                // shift down.
                                int oldX = getViewportOffsetX() + getChildOffset(i);
                                int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);

                                // Animate the view translation from its old
                                // position to its new
                                // position
                                AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY);
                                if (anim != null) {
                                    anim.cancel();
                                }

                                v.setTranslationX(oldX - newX);
                                anim = new AnimatorSet();
                                anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
                                anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f));
                                anim.start();
                                v.setTag(anim);
                            }

                            removeView(mDragView);
                            onRemoveView(mDragView, false);
                            addView(mDragView, pageUnderPointIndex);
                            onAddView(mDragView, pageUnderPointIndex);
                            mSidePageHoverIndex = -1;
                            mPageIndicator.setActiveMarker(getNextPage());
                        }
                    };
                    postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
                }
            } else {
                removeCallbacks(mSidePageHoverRunnable);
                mSidePageHoverIndex = -1;
            }
        } else {
            determineScrollingStart(ev);
        }
        break;

    case MotionEvent.ACTION_UP:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            final int activePointerId = mActivePointerId;
            final int pointerIndex = ev.findPointerIndex(activePointerId);
            final float x = ev.getX(pointerIndex);
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
            final int deltaX = (int) (x - mDownMotionX);
            final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth();
            boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD;

            mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);

            boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING
                    && Math.abs(velocityX) > mFlingThresholdVelocity;

            if (!mFreeScroll) {
                // In the case that the page is moved far to one direction
                // and then is flung
                // in the opposite direction, we use a threshold to
                // determine whether we should
                // just return to the starting page, or if we should skip
                // one further.
                boolean returnToOriginalPage = false;
                if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD
                        && Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
                    returnToOriginalPage = true;
                }

                int finalPage;
                // We give flings precedence over large moves, which is why
                // we short-circuit our
                // test for a large move if a fling has been registered.
                // That is, a large
                // move to the left and fling to the right will register as
                // a fling to the right.
                final boolean isRtl = isLayoutRtl();
                boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
                boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
                if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft))
                        && mCurrentPage > 0) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft))
                        && mCurrentPage < getChildCount() - 1) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else {
                    snapToDestination();
                }
            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
                // at this point we have not moved beyond the touch slop
                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING),
                // so
                // we can just page
                int nextPage = Math.max(0, mCurrentPage - 1);
                if (nextPage != mCurrentPage) {
                    snapToPage(nextPage);
                } else {
                    snapToDestination();
                }
            } else {
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }

                float scaleX = getScaleX();
                int vX = (int) (-velocityX * scaleX);
                int initialScrollX = (int) (getScrollX() * scaleX);

                mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0,
                        0);
                invalidate();
            }
        } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
            // at this point we have not moved beyond the touch slop
            // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
            // we can just page
            int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
            if (nextPage != mCurrentPage) {
                snapToPage(nextPage);
            } else {
                snapToDestination();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this
            // new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();
            boolean handledFling = false;
            if (!DISABLE_FLING_TO_DELETE) {
                // Check the velocity and see if we are flinging-to-delete
                PointF flingToDeleteVector = isFlingingToDelete();
                if (flingToDeleteVector != null) {
                    onFlingToDelete(flingToDeleteVector);
                    handledFling = true;
                }
            }
            if (!handledFling
                    && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) {
                onDropToDelete();
            }
        } else {
            if (!mCancelTap) {
                onUnhandledTap(ev);
            }
        }

        // Remove the callback to wait for the side page hover timeout
        removeCallbacks(mSidePageHoverRunnable);
        // End any intermediate reordering states
        resetTouchState();
        break;

    case MotionEvent.ACTION_CANCEL:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            snapToDestination();
        }
        resetTouchState();
        break;

    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        releaseVelocityTracker();
        break;
    }

    return true;
}

From source file:com.android.leanlauncher.CellLayout.java

private void computeDirectionVector(float deltaX, float deltaY, int[] result) {
    double angle = Math.atan(deltaY / deltaX);

    result[0] = 0;/*from ww  w  .ja va 2s .  c o m*/
    result[1] = 0;
    if (Math.abs(Math.cos(angle)) > 0.5f) {
        result[0] = (int) Math.signum(deltaX);
    }
    if (Math.abs(Math.sin(angle)) > 0.5f) {
        result[1] = (int) Math.signum(deltaY);
    }
}

From source file:com.android.launcher3.CellLayout.java

private void computeDirectionVector(float deltaX, float deltaY, int[] result) {
    double angle = Math.atan(((float) deltaY) / deltaX);

    result[0] = 0;/*from   w  w w .  j  av a 2 s .  co  m*/
    result[1] = 0;
    if (Math.abs(Math.cos(angle)) > 0.5f) {
        result[0] = (int) Math.signum(deltaX);
    }
    if (Math.abs(Math.sin(angle)) > 0.5f) {
        result[1] = (int) Math.signum(deltaY);
    }
}

From source file:com.breakout.main.GameState.java

/**
 * Tests for a collision with the rectangles in mPossibleCollisions as the ball travels from
 * (curX,curY).//  w  w  w  . java  2  s . c om
 * <p>
 * We can't return multiple values from a method call in Java.  We don't want to allocate
 * storage for the return value on each frame (this being part of the main game loop).  We
 * can define a class that holds all of the return values and allocate a single instance
 * of it when GameState is constructed, or just drop the values into dedicated return-value
 * fields.  The latter is incrementally easier, so we return the object we hit, and store
 * additional details in these fields:
 * <ul>
 * <li>mHitDistanceLeft - the amount of distance remaining to travel after impact
 * <li>mHitFace - what face orientation we hit
 * <li>mHitXAdj, mHitYAdj - position adjustment so objects won't intersect
 * </ul>
 *
 * @param rects Array of rects to test against.
 * @param numRects Number of rects in array.
 * @param curX Current X position.
 * @param curY Current Y position.
 * @param dirX X component of normalized direction vector.
 * @param dirY Y component of normalized direction vector.
 * @param distance Distance to travel.
 * @param radius Radius of the ball.
 * @return The object we struck, or null if none.
 */
private BaseRect findFirstCollision(BaseRect[] rects, final int numRects, final float curX, final float curY,
        final float dirX, final float dirY, final float distance, final float radius) {
    /*
     * The "coarse" function has indicated that a collision is possible.  We need to get
     * an exact determination of what we're hitting.
     *
     * We can either use some math to compute the time of intersection of each rect with
     * the moving ball (a "sweeping" collision test, perhaps even straying into
     * "continuous collision detection"), or we can just step the ball forward until
     * it collides with something or reaches the end point.  The latter isn't as precise,
     * but is much simpler, so we'll do that.
     *
     * We can use a test similar to the Separating Axis Theorem, but with a circle vs.
     * rectangle collision it's possible for the axis-aligned projections to overlap but
     * not have a collision (e.g. the circle is near one corner).  We need to perform an
     * additional test to check the distance from the closest vertex to the center of the
     * circle.  The fancy way to figure out which corner is closest is with Voronoi regions,
     * but we don't really need that: since we're colliding with axis-aligned rects, we can
     * just collapse the whole thing into a single quadrant.
     *
     * Nice illustration here:
     *  http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection
     *
     * Once we determine that a collision has occurred, we need to determine where we hit
     * so that we can decide how to bounce.  For our bricks we're either hitting a vertical
     * or horizontal surface; these will cause us to invert the X component or Y component
     * of our direction vector.  It also makes sense visually to reverse direction when
     * you run into a corner.
     *
     * It's possible to get "tunneling" effects, which may look weird but are actually
     * legitimate.  Two common scenarios:
     *
     *  (1) Suppose the ball is moving upward and slightly to the left.  If it
     *      squeezes between the gap in the bricks and hits a right edge, it will
     *      do a vertical-surface bounce (i.e. start moving back to the right), and
     *      almost immediately hit the vertical surface of the brick to the right.
     *      With the right angle, this can repeat in a nearby column and climb up through
     *      several layers.  (Unless the ball is small relative to the gap between bricks,
     *      this is hard to do in practice.)
     *  (2) A "sharp corner" bounce can keep the ball moving upward.  For
     *      example, a ball moving up and right hits the bottom of a brick,
     *      and heads down and to the right.  It hits the top-left corner of
     *      a brick, and reverses direction (up and left).  It hits the bottom
     *      of another brick, and while moving down and left it hits the
     *      top-right corner of a fourth brick.  If the angle is right, this
     *      pattern will continue, knocking out a vertical tunnel.  Because it's
     *      hitting on corners, this is easy to do even if the horizontal gap
     *      between bricks is fairly narrow.
     *
     * The smaller the inter-brick gap is, the less likely the tunneling
     * effects are to occur.  With a small enough gap (and a reasonable MAX_STEP)
     * it's impossible to hit an "inside" corner or surface.
     *
     * It's possible to collide with two shapes at once.  We ignore this situation.
     * Whichever object we happen to examine first gets credit.
     */

    // Maximum distance, in arena coordinates, we advance the ball on each iteration of
    // the loop.  If this is too small, we'll do a lot of unnecessary iterations.  If it's
    // too large (e.g. more than the ball's radius), the ball can end up inside an object,
    // or pass through one entirely.
    final float MAX_STEP = 2.0f;

    // Minimum distance.  After a collision the objects are just barely in contact, so at
    // each step we need to move a little or we'll double-collide.  The minimum exists to
    // ensure that we don't get hosed by floating point round-off error.
    final float MIN_STEP = 0.001f;

    float radiusSq = radius * radius;
    int faceHit = HIT_FACE_NONE;
    int faceToAdjust = HIT_FACE_NONE;
    float traveled = 0.0f;

    while (traveled < distance) {
        // Travel a bit.
        if (distance - traveled > MAX_STEP) {
            traveled += MAX_STEP;
        } else if (distance - traveled < MIN_STEP) {
            //Log.d(TAG, "WOW: skipping tiny step distance " + (distance - traveled));
            break;
        } else {
            traveled = distance;
        }
        float circleXWorld = curX + dirX * traveled;
        float circleYWorld = curY + dirY * traveled;

        for (int i = 0; i < numRects; i++) {
            BaseRect rect = rects[i];
            float rectXWorld = rect.getXPosition();
            float rectYWorld = rect.getYPosition();
            float rectXScaleHalf = rect.getXScale() / 2.0f;
            float rectYScaleHalf = rect.getYScale() / 2.0f;

            // Translate the circle so that it's in the first quadrant, with the center of the
            // rectangle at (0,0).
            float circleX = Math.abs(circleXWorld - rectXWorld);
            float circleY = Math.abs(circleYWorld - rectYWorld);

            if (circleX > rectXScaleHalf + radius || circleY > rectYScaleHalf + radius) {
                // Circle is too far from rect edge(s) to overlap.  No collision.
                continue;
            }

            /*
             * Check to see if the center of the circle is inside the rect on one axis.  The
             * previous test eliminated anything that was too far on either axis, so
             * if this passes then we must have a collision.
             *
             * We're not moving the ball fast enough (limited by MAX_STEP) to get the center
             * of the ball completely inside the rect (i.e. we shouldn't see a case where the
             * center is inside the rect on *both* axes), so if we're inside in the X axis we
             * can conclude that we just collided due to vertical motion, and have hit a
             * horizontal surface.
             *
             * If the center isn't inside on either axis, we've hit the corner case, and
             * need to do a distance test.
             */
            if (circleX <= rectXScaleHalf) {
                faceToAdjust = faceHit = HIT_FACE_HORIZONTAL;
            } else if (circleY <= rectYScaleHalf) {
                faceToAdjust = faceHit = HIT_FACE_VERTICAL;
            } else {
                // Check the distance from rect corner to center of circle.
                float xdist = circleX - rectXScaleHalf;
                float ydist = circleY - rectYScaleHalf;
                if (xdist * xdist + ydist * ydist > radiusSq) {
                    // Not close enough.
                    //Log.d(TAG, "COL: corner miss");
                    continue;
                }

                /*
                 * The center point of the ball is outside both edges of the rectangle,
                 * but the corner is inside the radius of the circle, so this is a corner
                 * hit.  We need to decide how to bounce off.
                 *
                 * One approach is to see which edge is closest.  We know we're within a
                 * ball-radius of both edges.  If you imagine a ball moving straight upward,
                 * hitting just to the left of the bottom-left corner of a brick, you'll
                 * note that the impact occurs when the X distance (from brick edge to
                 * center of ball) is very small, and the Y distance is close to the ball
                 * radius.  So if X < Y, it's a horizontal-surface hit.
                 *
                 * However, there's a nasty edge case: imagine the ball is traveling up and
                 * to the right.  It skims past the top-left corner of a brick.  If the ball
                 * is positioned just barely outside the collision radius to the left of the
                 * brick in the current frame, our next step could take us to the other side
                 * of the ball -- at which point we "collide" with the horizontal *top*
                 * surface of the brick.  The brick is destroyed and the ball "bounces" down
                 * and to the right (because we reverse Y direction on a horizontal hit).
                 * Decreasing MAX_STEP makes this less likely, but we can't make it impossible.
                 *
                 * Another approach is to compare the direction the ball was moving with
                 * which corner we hit.  Consider the bottom-left corner of a brick.  There
                 * are three ways to hit it: straight in (ball moving up and right), skimming
                 * from the left (ball moving down and right), and skimming from below
                 * (ball moving up and left).  By comparing just the sign of the components
                 * of the ball's direction vector with the sign of a vector drawn from the
                 * corner to the center of the rect, we can decide what sort of impact
                 * we've had.
                 *
                 * If the signs match, it's a "sharp" corner impact, and we want to bounce
                 * straight back.  If only X matches, we're approaching from the side, and
                 * it's a vertical side impact.  If only Y matches, we're approaching from
                 * the bottom, and it's a horizontal impact.  The collision behavior no
                 * longer depends on which side we're actually touching, concealing the
                 * fact that the ball has effectively passed through the corner of the brick
                 * and we're catching the collision a bit late.
                 *
                 * If bouncing straight back off of a corner is undesirable, we can just
                 * use the computation done in the faceToAdjust assignment for "sharp
                 * "corner" impacts instead.
                 */
                float dirXSign = Math.signum(dirX);
                float dirYSign = Math.signum(dirY);
                float cornerXSign = Math.signum(rectXWorld - circleXWorld);
                float cornerYSign = Math.signum(rectYWorld - circleYWorld);

                if (dirXSign == cornerXSign && dirYSign == cornerYSign) {
                    faceHit = HIT_FACE_SHARPCORNER;
                } else if (dirXSign == cornerXSign) {
                    faceHit = HIT_FACE_VERTICAL;
                } else if (dirYSign == cornerYSign) {
                    faceHit = HIT_FACE_HORIZONTAL;
                } else {
                    // This would mean we hit the far corner of the brick, i.e. the ball
                    // passed completely through it.
                    faceHit = HIT_FACE_SHARPCORNER;
                }

                // Adjust whichever requires the least movement to guarantee we're no
                // longer colliding.
                if (xdist < ydist) {
                    faceToAdjust = HIT_FACE_HORIZONTAL;
                } else {
                    faceToAdjust = HIT_FACE_VERTICAL;
                }
            }

            /*
             * Collision!
             *
             * Because we're moving in discrete steps rather than continuously, we will
             * usually end up slightly embedded in the object.  If, after reversing direction,
             * we subsequently step forward very slightly (assuming a non-destructable
             * object like a wall), we will detect a second collision with the same object,
             * and reverse direction back *into* the wall.  Visually, the ball will "stick"
             * to the wall and vibrate.
             *
             * We need to back the ball out slightly.  Ideally we'd back it along the path
             * the ball was traveling by just the right amount, but unless MAX_STEP is
             * really large the difference between that and a minimum-distance axis-aligned
             * shift is negligible -- and this is easier to compute.
             *
             * There's some risk that our adjustment will leave the ball trapped in a
             * different object.  Since the ball is the only object that's moving, and the
             * direction of adjustment shouldn't be too far from the angle of incidence, we
             * shouldn't have this problem in practice.
             *
             * Note this leaves the ball just *barely* in contact with the object it hit,
             * which means it's technically still colliding.  This won't cause us to
             * collide again and reverse course back into the object because we will move
             * the ball a nonzero distance away from the object before we check for another
             * collision.  The use of MIN_STEP ensures that we won't fall victim to floating
             * point round-off error.  (If we didn't want to guarantee movement, we could
             * shift the ball a tiny bit farther so that it simply wasn't in contact.)
             */
            float hitXAdj, hitYAdj;
            if (faceToAdjust == HIT_FACE_HORIZONTAL) {
                hitXAdj = 0.0f;
                hitYAdj = rectYScaleHalf + radius - circleY;
                if (circleYWorld < rectYWorld) {
                    // ball is below rect, must be moving up, so adjust it down
                    hitYAdj = -hitYAdj;
                }
            } else if (faceToAdjust == HIT_FACE_VERTICAL) {
                hitXAdj = rectXScaleHalf + radius - circleX;
                hitYAdj = 0.0f;
                if (circleXWorld < rectXWorld) {
                    // ball is left of rect, must be moving to right, so adjust it left
                    hitXAdj = -hitXAdj;
                }
            } else {
                hitXAdj = hitYAdj = 0.0f;
            }

            mHitFace = faceHit;
            mHitDistanceTraveled = traveled;
            mHitXAdj = hitXAdj;
            mHitYAdj = hitYAdj;
            return rect;
        }
    }

    //Log.d(TAG, "COL: no collision");
    return null;
}

From source file:com.wb.launcher3.Page.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (DISABLE_TOUCH_INTERACTION) {
        return false;
    }/*from  w ww  .  j a va  2  s.c om*/

    super.onTouchEvent(ev);

    // Skip touch handling if there are no pages to swipe
    if (getChildCount() <= 0)
        return super.onTouchEvent(ev);

    acquireVelocityTrackerAndAddMovement(ev);

    final int action = ev.getAction();

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        /*
         * If being flinged and user touches, stop the fling. isFinished
         * will be false if being flinged.
         */
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
        }

        // Remember where the motion event started
        mDownMotionX = mLastMotionX = ev.getX();
        mDownMotionY = mLastMotionY = ev.getY();
        mDownScrollX = getScrollX();
        float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
        mParentDownMotionX = p[0];
        mParentDownMotionY = p[1];
        mLastMotionXRemainder = 0;
        mTotalMotionX = 0;
        mActivePointerId = ev.getPointerId(0);

        if (mTouchState == TOUCH_STATE_SCROLLING) {
            pageBeginMoving();
        }
        break;

    case MotionEvent.ACTION_MOVE:
        //*/zhangwuba add 2014-5-8
        if (getLauncherDeleteAppSate()) {
            return true;
        }
        //*/
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            // Scroll to follow the motion event
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);

            if (pointerIndex == -1)
                return true;

            final float x = ev.getX(pointerIndex);
            final float deltaX = mLastMotionX + mLastMotionXRemainder - x;

            mTotalMotionX += Math.abs(deltaX);

            // Only scroll and update mLastMotionX if we have moved some discrete amount.  We
            // keep the remainder because we are actually testing if we've moved from the last
            // scrolled position (which is discrete).
            if (Math.abs(deltaX) >= 1.0f) {
                mTouchX += deltaX;
                mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                if (!mDeferScrollUpdate) {
                    scrollBy((int) deltaX, 0);
                    if (DEBUG)
                        Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
                } else {
                    invalidate();
                }
                mLastMotionX = x;
                mLastMotionXRemainder = deltaX - (int) deltaX;
            } else {
                awakenScrollBars();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();

            // Find the closest page to the touch point
            final int dragViewIndex = indexOfChild(mDragView);

            // Change the drag view if we are hovering over the drop target
            boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
                    (int) mParentDownMotionY);
            setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);

            if (DEBUG)
                Log.d(TAG, "mLastMotionX: " + mLastMotionX);
            if (DEBUG)
                Log.d(TAG, "mLastMotionY: " + mLastMotionY);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
            if (DEBUG)
                Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);

            final int pageUnderPointIndex = getNearestHoverOverPageIndex();
            if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView)
                    && !isHoveringOverDelete) {
                mTempVisiblePagesRange[0] = 0;
                mTempVisiblePagesRange[1] = getPageCount() - 1;
                getOverviewModePages(mTempVisiblePagesRange);
                if (mTempVisiblePagesRange[0] <= pageUnderPointIndex
                        && pageUnderPointIndex <= mTempVisiblePagesRange[1]
                        && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
                    mSidePageHoverIndex = pageUnderPointIndex;
                    mSidePageHoverRunnable = new Runnable() {
                        @Override
                        public void run() {
                            // Setup the scroll to the correct page before we swap the views
                            snapToPage(pageUnderPointIndex);

                            // For each of the pages between the paged view and the drag view,
                            // animate them from the previous position to the new position in
                            // the layout (as a result of the drag view moving in the layout)
                            int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
                            int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1
                                    : pageUnderPointIndex;
                            int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1
                                    : pageUnderPointIndex;
                            for (int i = lowerIndex; i <= upperIndex; ++i) {
                                View v = getChildAt(i);
                                // dragViewIndex < pageUnderPointIndex, so after we remove the
                                // drag view all subsequent views to pageUnderPointIndex will
                                // shift down.
                                int oldX = getViewportOffsetX() + getChildOffset(i);
                                int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);

                                // Animate the view translation from its old position to its new
                                // position
                                AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY);
                                if (anim != null) {
                                    anim.cancel();
                                }

                                v.setTranslationX(oldX - newX);
                                anim = new AnimatorSet();
                                anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
                                anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f));
                                anim.start();
                                v.setTag(anim);
                            }

                            removeView(mDragView);
                            onRemoveView(mDragView, false);
                            addView(mDragView, pageUnderPointIndex);
                            onAddView(mDragView, pageUnderPointIndex);
                            mSidePageHoverIndex = -1;
                            mPageIndicator.setActiveMarker(getNextPage());
                        }
                    };
                    postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
                }
            } else {
                removeCallbacks(mSidePageHoverRunnable);
                mSidePageHoverIndex = -1;
            }
        } else {
            determineScrollingStart(ev);
        }
        break;

    case MotionEvent.ACTION_UP:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            final int activePointerId = mActivePointerId;
            final int pointerIndex = ev.findPointerIndex(activePointerId);
            final float x = ev.getX(pointerIndex);
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
            final int deltaX = (int) (x - mDownMotionX);
            final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth();
            boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD;

            mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);

            boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING
                    && Math.abs(velocityX) > mFlingThresholdVelocity;

            if (!mFreeScroll) {
                // In the case that the page is moved far to one direction and then is flung
                // in the opposite direction, we use a threshold to determine whether we should
                // just return to the starting page, or if we should skip one further.
                boolean returnToOriginalPage = false;
                if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD
                        && Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
                    returnToOriginalPage = true;
                }

                //*/Added by tyd Greg 2014-03-20,for transition effect
                if (TydtechConfig.CYCLE_ROLL_PAGES_ENABLED) {
                    m_moveNextDeltaX = deltaX;
                    m_isSignificantMoveNext = (!returnToOriginalPage && (isSignificantMove || isFling));
                }
                //*/

                int finalPage;
                // We give flings precedence over large moves, which is why we short-circuit our
                // test for a large move if a fling has been registered. That is, a large
                // move to the left and fling to the right will register as a fling to the right.
                final boolean isRtl = isLayoutRtl();
                boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
                boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
                if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft))
                        && mCurrentPage > 0) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft))
                        && mCurrentPage < getChildCount() - 1) {
                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
                    snapToPageWithVelocity(finalPage, velocityX);
                } else {
                    snapToDestination();
                }
            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
                // at this point we have not moved beyond the touch slop
                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
                // we can just page
                int nextPage = Math.max(0, mCurrentPage - 1);
                if (nextPage != mCurrentPage) {
                    snapToPage(nextPage);
                } else {
                    snapToDestination();
                }
            } else {
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }

                float scaleX = getScaleX();
                int vX = (int) (-velocityX * scaleX);
                int initialScrollX = (int) (getScrollX() * scaleX);

                mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0,
                        0);
                invalidate();
            }
        } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
            // at this point we have not moved beyond the touch slop
            // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
            // we can just page
            int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
            if (nextPage != mCurrentPage) {
                snapToPage(nextPage);
            } else {
                snapToDestination();
            }
        } else if (mTouchState == TOUCH_STATE_REORDERING) {
            // Update the last motion position
            mLastMotionX = ev.getX();
            mLastMotionY = ev.getY();

            // Update the parent down so that our zoom animations take this new movement into
            // account
            float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
            mParentDownMotionX = pt[0];
            mParentDownMotionY = pt[1];
            updateDragViewTranslationDuringDrag();
            boolean handledFling = false;
            if (!DISABLE_FLING_TO_DELETE) {
                // Check the velocity and see if we are flinging-to-delete
                PointF flingToDeleteVector = isFlingingToDelete();
                if (flingToDeleteVector != null) {
                    onFlingToDelete(flingToDeleteVector);
                    handledFling = true;
                }
            }
            if (!handledFling
                    && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) {
                onDropToDelete();
            }
        }
        //*/Added by tyd Greg 2014-03-21,for support the touch swipe gesture
        else if (mTouchState == TOUCH_SWIPE_DOWN_GESTURE) {
            if (mOnTouchSwipeGestureListener != null) {
                mOnTouchSwipeGestureListener.fireSwipeDownAction();
            }
        } else if (mTouchState == TOUCH_SWIPE_UP_GESTURE) {
            if (mOnTouchSwipeGestureListener != null) {
                mOnTouchSwipeGestureListener.fireSwipeUpAction();
            }
        }
        //*/

        else {
            if (!mCancelTap) {
                onUnhandledTap(ev);
            }
        }

        // Remove the callback to wait for the side page hover timeout
        removeCallbacks(mSidePageHoverRunnable);
        // End any intermediate reordering states
        resetTouchState();
        break;

    case MotionEvent.ACTION_CANCEL:
        if (mTouchState == TOUCH_STATE_SCROLLING) {
            snapToDestination();
        }
        resetTouchState();
        break;

    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        releaseVelocityTracker();
        break;
    }

    return true;
}

From source file:jmri.enginedriver.throttle.java

int speedChange(int whichThrottle, int change) {
    SeekBar throttle_slider = getThrottleSlider(whichThrottle);
    double displayUnitScale = getDisplayUnitScale(whichThrottle);
    int lastSpeed = throttle_slider.getProgress();
    int lastScaleSpeed = (int) Math.round(lastSpeed * displayUnitScale);
    int scaleSpeed = lastScaleSpeed + change;
    int speed = (int) Math.round(scaleSpeed / displayUnitScale);
    if (lastScaleSpeed == scaleSpeed) {
        speed += Math.signum(change);
    }//w ww. jav a 2 s .  c om
    if (speed < 0) //insure speed is inside bounds
        speed = 0;
    if (speed > MAX_SPEED_VAL_WIT)
        speed = MAX_SPEED_VAL_WIT;
    throttle_slider.setProgress(speed);
    return speed;
}

From source file:com.serenegiant.autoparrot.BaseAutoPilotFragment.java

private int cameraExposureToProgress(final float exposure) {
    return (int) (Math.signum(exposure) * (Math.sqrt(Math.abs(exposure * 1500000)))) + 1500;
}

From source file:com.serenegiant.autoparrot.BaseAutoPilotFragment.java

private float progressToCameraExposure(final int progress) {
    final int p = progress - 1500;
    return Math.signum(p) * (p * p / 1500000.0f);
}