Java Code Examples for org.chromium.chrome.browser.compositor.layouts.phone.stack.StackAnimation.OverviewAnimationType#NONE

The following examples show how to use org.chromium.chrome.browser.compositor.layouts.phone.stack.StackAnimation.OverviewAnimationType#NONE . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Stack.java    From AndroidChromium with Apache License 2.0 5 votes vote down vote up
/**
 * Get called on down touch event.
 *
 * @param time The current time of the app in ms.
 */
public void onDown(long time) {
    mDragLock = DragLock.NONE;
    if (mOverviewAnimationType == OverviewAnimationType.NONE) {
        stopScrollingMovement(time);
    }
    // Resets the scrolling state.
    mScrollingTab = null;
    commitDiscard(time, false);
}
 
Example 2
Source File: Stack.java    From 365browser with Apache License 2.0 5 votes vote down vote up
/**
 * Called on touch click event.
 *
 * @param time The current time of the app in ms.
 * @param x    The x coordinate in pixel inside the stack view.
 * @param y    The y coordinate in pixel inside the stack view.
 */
public void click(long time, float x, float y) {
    if (mOverviewAnimationType != OverviewAnimationType.NONE
            && mOverviewAnimationType != OverviewAnimationType.DISCARD
            && mOverviewAnimationType != OverviewAnimationType.UNDISCARD
            && mOverviewAnimationType != OverviewAnimationType.DISCARD_ALL) {
        return;
    }
    int clicked = getTabIndexAtPositon(x, y, LayoutTab.getTouchSlop());
    if (clicked >= 0) {
        // Check if the click was within the boundaries of the close button defined by its
        // visible coordinates.
        boolean isRtl =
                !((mCurrentMode == Orientation.PORTRAIT) ^ LocalizationUtils.isLayoutRtl());
        if (mStackTabs[clicked].getLayoutTab().checkCloseHitTest(x, y, isRtl)) {
            // Tell the model to close the tab because the close button was pressed.  The model
            // will then trigger a notification which will start the actual close process here
            // if necessary.
            StackTab tab = mStackTabs[clicked];
            final float halfCloseBtnWidth = LayoutTab.CLOSE_BUTTON_WIDTH_DP / 2.f;
            final float halfCloseBtnHeight = mBorderTopPadding / 2.f;
            final float contentWidth = tab.getLayoutTab().getOriginalContentWidth();

            tab.setDiscardOriginY(halfCloseBtnHeight);
            tab.setDiscardOriginX(isRtl ? halfCloseBtnWidth : contentWidth - halfCloseBtnWidth);
            tab.setDiscardFromClick(true);
            mLayout.uiRequestingCloseTab(time, tab.getId());
            RecordUserAction.record("MobileStackViewCloseTab");
            RecordUserAction.record("MobileTabClosed");
        } else {
            // Let the model know that a new {@link LayoutTab} was selected. The model will
            // notify us if we need to do anything visual. setIndex() will possibly switch the
            // models and broadcast the event.
            mLayout.uiSelectingTab(time, mStackTabs[clicked].getId());
        }
    }
}
 
Example 3
Source File: Stack.java    From 365browser with Apache License 2.0 5 votes vote down vote up
/**
 * Get called on long press touch event.
 *
 * @param time The current time of the app in ms.
 * @param x The x coordinate in pixel inside the stack view.
 * @param y The y coordinate in pixel inside the stack view.
 */
public void onLongPress(long time, float x, float y) {
    if (mOverviewAnimationType == OverviewAnimationType.NONE) {
        mLongPressSelected = getTabIndexAtPositon(x, y);
        if (mLongPressSelected >= 0) {
            startAnimation(time, OverviewAnimationType.VIEW_MORE, mLongPressSelected, false);
            mEvenOutProgress = 0.0f;
        }
    }
}
 
Example 4
Source File: Stack.java    From 365browser with Apache License 2.0 5 votes vote down vote up
/**
 * Get called on down touch event.
 *
 * @param time The current time of the app in ms.
 */
public void onDown(long time) {
    mDragLock = DragLock.NONE;
    if (mOverviewAnimationType == OverviewAnimationType.NONE) {
        stopScrollingMovement(time);
    }
    // Resets the scrolling state.
    mScrollingTab = null;
    commitDiscard(time, false);
}
 
Example 5
Source File: Stack.java    From AndroidChromium with Apache License 2.0 5 votes vote down vote up
private boolean allowOverscroll() {
    // All the animations that want to leave the tilt value to be set by the overscroll must
    // be added here.
    return (mOverviewAnimationType == OverviewAnimationType.NONE
                   || mOverviewAnimationType == OverviewAnimationType.VIEW_MORE
                   || mOverviewAnimationType == OverviewAnimationType.ENTER_STACK)
            && mPinch0TabIndex < 0;
}
 
Example 6
Source File: Stack.java    From AndroidChromium with Apache License 2.0 5 votes vote down vote up
/**
 * Called on touch click event.
 *
 * @param time The current time of the app in ms.
 * @param x    The x coordinate in pixel inside the stack view.
 * @param y    The y coordinate in pixel inside the stack view.
 */
public void click(long time, float x, float y) {
    if (mOverviewAnimationType != OverviewAnimationType.NONE
            && mOverviewAnimationType != OverviewAnimationType.DISCARD
            && mOverviewAnimationType != OverviewAnimationType.UNDISCARD
            && mOverviewAnimationType != OverviewAnimationType.DISCARD_ALL) {
        return;
    }
    int clicked = getTabIndexAtPositon(x, y, LayoutTab.getTouchSlop());
    if (clicked >= 0) {
        // Check if the click was within the boundaries of the close button defined by its
        // visible coordinates.
        boolean isRtl =
                !((mCurrentMode == Orientation.PORTRAIT) ^ LocalizationUtils.isLayoutRtl());
        if (mStackTabs[clicked].getLayoutTab().checkCloseHitTest(x, y, isRtl)) {
            // Tell the model to close the tab because the close button was pressed.  The model
            // will then trigger a notification which will start the actual close process here
            // if necessary.
            StackTab tab = mStackTabs[clicked];
            final float halfCloseBtnWidth = LayoutTab.CLOSE_BUTTON_WIDTH_DP / 2.f;
            final float halfCloseBtnHeight = mBorderTopPadding / 2.f;
            final float contentWidth = tab.getLayoutTab().getOriginalContentWidth();

            tab.setDiscardOriginY(halfCloseBtnHeight);
            tab.setDiscardOriginX(isRtl ? halfCloseBtnWidth : contentWidth - halfCloseBtnWidth);
            tab.setDiscardFromClick(true);
            mLayout.uiRequestingCloseTab(time, tab.getId());
            RecordUserAction.record("MobileStackViewCloseTab");
            RecordUserAction.record("MobileTabClosed");
        } else {
            // Let the model know that a new {@link LayoutTab} was selected. The model will
            // notify us if we need to do anything visual. setIndex() will possibly switch the
            // models and broadcast the event.
            mLayout.uiSelectingTab(time, mStackTabs[clicked].getId());
        }
    }
}
 
Example 7
Source File: Stack.java    From AndroidChromium with Apache License 2.0 5 votes vote down vote up
/**
 * Get called on long press touch event.
 *
 * @param time The current time of the app in ms.
 * @param x The x coordinate in pixel inside the stack view.
 * @param y The y coordinate in pixel inside the stack view.
 */
public void onLongPress(long time, float x, float y) {
    if (mOverviewAnimationType == OverviewAnimationType.NONE) {
        mLongPressSelected = getTabIndexAtPositon(x, y);
        if (mLongPressSelected >= 0) {
            startAnimation(time, OverviewAnimationType.VIEW_MORE, mLongPressSelected, false);
            mEvenOutProgress = 0.0f;
        }
    }
}
 
Example 8
Source File: Stack.java    From 365browser with Apache License 2.0 5 votes vote down vote up
private boolean allowOverscroll() {
    // All the animations that want to leave the tilt value to be set by the overscroll must
    // be added here.
    return (mOverviewAnimationType == OverviewAnimationType.NONE
                   || mOverviewAnimationType == OverviewAnimationType.VIEW_MORE
                   || mOverviewAnimationType == OverviewAnimationType.ENTER_STACK)
            && mPinch0TabIndex < 0;
}
 
Example 9
Source File: Stack.java    From delion with Apache License 2.0 5 votes vote down vote up
private boolean allowOverscroll() {
    // All the animations that want to leave the tilt value to be set by the overscroll must
    // be added here.
    return (mOverviewAnimationType == OverviewAnimationType.NONE
                   || mOverviewAnimationType == OverviewAnimationType.VIEW_MORE
                   || mOverviewAnimationType == OverviewAnimationType.ENTER_STACK)
            && mPinch0TabIndex < 0;
}
 
Example 10
Source File: Stack.java    From delion with Apache License 2.0 5 votes vote down vote up
/**
 * Called on touch click event.
 *
 * @param time The current time of the app in ms.
 * @param x    The x coordinate in pixel inside the stack view.
 * @param y    The y coordinate in pixel inside the stack view.
 */
public void click(long time, float x, float y) {
    if (mOverviewAnimationType != OverviewAnimationType.NONE
            && mOverviewAnimationType != OverviewAnimationType.DISCARD
            && mOverviewAnimationType != OverviewAnimationType.UNDISCARD
            && mOverviewAnimationType != OverviewAnimationType.DISCARD_ALL) {
        return;
    }
    int clicked = getTabIndexAtPositon(x, y, LayoutTab.getTouchSlop());
    if (clicked >= 0) {
        // Check if the click was within the boundaries of the close button defined by its
        // visible coordinates.
        boolean isRtl =
                !((mCurrentMode == Orientation.PORTRAIT) ^ LocalizationUtils.isLayoutRtl());
        if (mStackTabs[clicked].getLayoutTab().checkCloseHitTest(x, y, isRtl)) {
            // Tell the model to close the tab because the close button was pressed.  The model
            // will then trigger a notification which will start the actual close process here
            // if necessary.
            StackTab tab = mStackTabs[clicked];
            final float halfCloseBtnWidth = LayoutTab.CLOSE_BUTTON_WIDTH_DP / 2.f;
            final float halfCloseBtnHeight = mBorderTopPadding / 2.f;
            final float contentWidth = tab.getLayoutTab().getOriginalContentWidth();

            tab.setDiscardOriginY(halfCloseBtnHeight);
            tab.setDiscardOriginX(isRtl ? halfCloseBtnWidth : contentWidth - halfCloseBtnWidth);
            tab.setDiscardFromClick(true);
            mLayout.uiRequestingCloseTab(time, tab.getId());
            RecordUserAction.record("MobileStackViewCloseTab");
            RecordUserAction.record("MobileTabClosed");
        } else {
            // Let the model know that a new {@link LayoutTab} was selected. The model will
            // notify us if we need to do anything visual. setIndex() will possibly switch the
            // models and broadcast the event.
            mLayout.uiSelectingTab(time, mStackTabs[clicked].getId());
        }
    }
}
 
Example 11
Source File: Stack.java    From delion with Apache License 2.0 5 votes vote down vote up
/**
 * Get called on long press touch event.
 *
 * @param time The current time of the app in ms.
 * @param x The x coordinate in pixel inside the stack view.
 * @param y The y coordinate in pixel inside the stack view.
 */
public void onLongPress(long time, float x, float y) {
    if (mOverviewAnimationType == OverviewAnimationType.NONE) {
        mLongPressSelected = getTabIndexAtPositon(x, y);
        if (mLongPressSelected >= 0) {
            startAnimation(time, OverviewAnimationType.VIEW_MORE, mLongPressSelected, false);
            mEvenOutProgress = 0.0f;
        }
    }
}
 
Example 12
Source File: Stack.java    From delion with Apache License 2.0 5 votes vote down vote up
/**
 * Get called on down touch event.
 *
 * @param time The current time of the app in ms.
 */
public void onDown(long time) {
    mDragLock = DragLock.NONE;
    if (mOverviewAnimationType == OverviewAnimationType.NONE) {
        stopScrollingMovement(time);
    }
    // Resets the scrolling state.
    mScrollingTab = null;
    commitDiscard(time, false);
}
 
Example 13
Source File: Stack.java    From AndroidChromium with Apache License 2.0 4 votes vote down vote up
/**
 * Discards and updates the position based on the input event values.
 *
 * @param x       The x coordinate of the end of the drag event.
 * @param y       The y coordinate of the end of the drag event.
 * @param amountX The number of pixels dragged in the x direction since the last event.
 * @param amountY The number of pixels dragged in the y direction since the last event.
 */
private void discard(float x, float y, float amountX, float amountY) {
    if (mStackTabs == null
            || (mOverviewAnimationType != OverviewAnimationType.NONE
                       && mOverviewAnimationType != OverviewAnimationType.DISCARD
                       && mOverviewAnimationType != OverviewAnimationType.DISCARD_ALL
                       && mOverviewAnimationType != OverviewAnimationType.UNDISCARD)) {
        return;
    }

    if (mDiscardingTab == null) {
        if (!mInSwipe) {
            mDiscardingTab = getTabAtPositon(x, y);
        } else {
            if (mTabModel.index() < 0) return;
            mDiscardingTab = mStackTabs[mTabModel.index()];
        }

        if (mDiscardingTab != null) {
            cancelDiscardScrollingAnimation();

            // Make sure we are well within the tab in the discard direction.
            RectF target = mDiscardingTab.getLayoutTab().getClickTargetBounds();
            float distanceToEdge;
            float edgeToEdge;
            if (mCurrentMode == Orientation.PORTRAIT) {
                mDiscardDirection = 1.0f;
                distanceToEdge = Math.max(target.left - x, x - target.right);
                edgeToEdge = target.width();
            } else {
                mDiscardDirection = 2.0f - 4.0f * (x / mLayout.getWidth());
                mDiscardDirection = MathUtils.clamp(mDiscardDirection, -1.0f, 1.0f);
                distanceToEdge = Math.max(target.top - y, y - target.bottom);
                edgeToEdge = target.height();
            }

            float scaledDiscardX = x - mDiscardingTab.getLayoutTab().getX();
            float scaledDiscardY = y - mDiscardingTab.getLayoutTab().getY();
            mDiscardingTab.setDiscardOriginX(scaledDiscardX / mDiscardingTab.getScale());
            mDiscardingTab.setDiscardOriginY(scaledDiscardY / mDiscardingTab.getScale());
            mDiscardingTab.setDiscardFromClick(false);

            if (Math.abs(distanceToEdge) < DISCARD_SAFE_SELECTION_PCTG * edgeToEdge) {
                mDiscardingTab = null;
            }
        }
    }
    if (mDiscardingTab != null) {
        float deltaAmount = mCurrentMode == Orientation.PORTRAIT ? amountX : amountY;
        mDiscardingTab.addToDiscardAmount(deltaAmount);
    }
}
 
Example 14
Source File: Stack.java    From AndroidChromium with Apache License 2.0 4 votes vote down vote up
/**
 * Performs the necessary actions to finish the current animation.
 *
 * @param time The current time of the app in ms.
 */
private void finishAnimation(long time) {
    if (mTabAnimations != null) mTabAnimations.updateAndFinish();
    if (mViewAnimations != null) mViewAnimations.end();
    if (mTabAnimations != null || mViewAnimations != null) mLayout.onStackAnimationFinished();

    switch (mOverviewAnimationType) {
        case ENTER_STACK:
            mLayout.uiDoneEnteringStack();
            break;
        case FULL_ROLL:
            springBack(time);
            break;
        case TAB_FOCUSED:
        // Purposeful fall through
        case NEW_TAB_OPENED:
            // Nothing to do.
            break;
        case DISCARD_ALL:
            mLayout.uiDoneClosingAllTabs(mTabModel.isIncognito());
            cleanupStackTabState();
            break;
        case UNDISCARD:
        // Purposeful fall through because if UNDISCARD animation updated DISCARD animation,
        // DISCARD animation clean up below is not called so UNDISCARD is responsible for
        // cleaning it up.
        case DISCARD:
            // Remove all dying tabs from mStackTabs.
            if (mStackTabs != null) {
                // Request for the model to be updated.
                for (int i = 0; i < mStackTabs.length; ++i) {
                    StackTab tab = mStackTabs[i];
                    if (tab.isDying()) {
                        mLayout.uiDoneClosingTab(
                                time, tab.getId(), true, mTabModel.isIncognito());
                    }
                }
            }
            cleanupStackTabState();
            break;
        default:
            break;
    }

    if (mOverviewAnimationType != OverviewAnimationType.NONE) {
        // sync the scrollTarget and scrollOffset;
        setScrollTarget(mScrollOffset, true);
        mOverviewAnimationType = OverviewAnimationType.NONE;
    }
    mTabAnimations = null;
    mViewAnimations = null;
}
 
Example 15
Source File: Stack.java    From delion with Apache License 2.0 4 votes vote down vote up
/**
 * Performs the necessary actions to finish the current animation.
 *
 * @param time The current time of the app in ms.
 */
private void finishAnimation(long time) {
    if (mTabAnimations != null) mTabAnimations.updateAndFinish();
    if (mViewAnimations != null) mViewAnimations.end();
    if (mTabAnimations != null || mViewAnimations != null) mLayout.onStackAnimationFinished();

    switch (mOverviewAnimationType) {
        case ENTER_STACK:
            mLayout.uiDoneEnteringStack();
            break;
        case FULL_ROLL:
            springBack(time);
            break;
        case TAB_FOCUSED:
        // Purposeful fall through
        case NEW_TAB_OPENED:
            // Nothing to do.
            break;
        case DISCARD_ALL:
            mLayout.uiDoneClosingAllTabs(mTabModel.isIncognito());
            cleanupStackTabState();
            break;
        case UNDISCARD:
        // Purposeful fall through because if UNDISCARD animation updated DISCARD animation,
        // DISCARD animation clean up below is not called so UNDISCARD is responsible for
        // cleaning it up.
        case DISCARD:
            // Remove all dying tabs from mStackTabs.
            if (mStackTabs != null) {
                // Request for the model to be updated.
                for (int i = 0; i < mStackTabs.length; ++i) {
                    StackTab tab = mStackTabs[i];
                    if (tab.isDying()) {
                        mLayout.uiDoneClosingTab(
                                time, tab.getId(), true, mTabModel.isIncognito());
                    }
                }
            }
            cleanupStackTabState();
            break;
        default:
            break;
    }

    if (mOverviewAnimationType != OverviewAnimationType.NONE) {
        // sync the scrollTarget and scrollOffset;
        setScrollTarget(mScrollOffset, true);
        mOverviewAnimationType = OverviewAnimationType.NONE;
    }
    mTabAnimations = null;
    mViewAnimations = null;
}
 
Example 16
Source File: Stack.java    From 365browser with Apache License 2.0 4 votes vote down vote up
/**
 * Performs the necessary actions to finish the current animation.
 *
 * @param time The current time of the app in ms.
 */
private void finishAnimation(long time) {
    if (mTabAnimations != null) mTabAnimations.updateAndFinish();
    if (mViewAnimations != null) mViewAnimations.end();
    if (mTabAnimations != null || mViewAnimations != null) mLayout.onStackAnimationFinished();

    switch (mOverviewAnimationType) {
        case ENTER_STACK:
            mLayout.uiDoneEnteringStack();
            break;
        case FULL_ROLL:
            springBack(time);
            break;
        case TAB_FOCUSED:
        // Purposeful fall through
        case NEW_TAB_OPENED:
            // Nothing to do.
            break;
        case DISCARD_ALL:
            mLayout.uiDoneClosingAllTabs(mTabModel.isIncognito());
            cleanupStackTabState();
            break;
        case UNDISCARD:
        // Purposeful fall through because if UNDISCARD animation updated DISCARD animation,
        // DISCARD animation clean up below is not called so UNDISCARD is responsible for
        // cleaning it up.
        case DISCARD:
            // Remove all dying tabs from mStackTabs.
            if (mStackTabs != null) {
                // Request for the model to be updated.
                for (int i = 0; i < mStackTabs.length; ++i) {
                    StackTab tab = mStackTabs[i];
                    if (tab.isDying()) {
                        mLayout.uiDoneClosingTab(
                                time, tab.getId(), true, mTabModel.isIncognito());
                    }
                }
            }
            cleanupStackTabState();
            break;
        default:
            break;
    }

    if (mOverviewAnimationType != OverviewAnimationType.NONE) {
        // sync the scrollTarget and scrollOffset. For ENTER_STACK animation, don't sync to
        // ensure the tab can tilt back.
        if (mOverviewAnimationType != OverviewAnimationType.ENTER_STACK) {
            setScrollTarget(mScrollOffset, true);
        }

        mOverviewAnimationType = OverviewAnimationType.NONE;
    }
    mTabAnimations = null;
    mViewAnimations = null;
}
 
Example 17
Source File: Stack.java    From 365browser with Apache License 2.0 4 votes vote down vote up
/**
 * Discards and updates the position based on the input event values.
 *
 * @param x       The x coordinate of the end of the drag event.
 * @param y       The y coordinate of the end of the drag event.
 * @param amountX The number of pixels dragged in the x direction since the last event.
 * @param amountY The number of pixels dragged in the y direction since the last event.
 */
private void discard(float x, float y, float amountX, float amountY) {
    if (mStackTabs == null
            || (mOverviewAnimationType != OverviewAnimationType.NONE
                       && mOverviewAnimationType != OverviewAnimationType.DISCARD
                       && mOverviewAnimationType != OverviewAnimationType.DISCARD_ALL
                       && mOverviewAnimationType != OverviewAnimationType.UNDISCARD)) {
        return;
    }

    if (mDiscardingTab == null) {
        if (!mInSwipe) {
            mDiscardingTab = getTabAtPositon(x, y);
        } else {
            if (mTabModel.index() < 0) return;
            mDiscardingTab = mStackTabs[mTabModel.index()];
        }

        if (mDiscardingTab != null) {
            cancelDiscardScrollingAnimation();

            // Make sure we are well within the tab in the discard direction.
            RectF target = mDiscardingTab.getLayoutTab().getClickTargetBounds();
            float distanceToEdge;
            float edgeToEdge;
            if (mCurrentMode == Orientation.PORTRAIT) {
                mDiscardDirection = 1.0f;
                distanceToEdge = Math.max(target.left - x, x - target.right);
                edgeToEdge = target.width();
            } else {
                mDiscardDirection = 2.0f - 4.0f * (x / mLayout.getWidth());
                mDiscardDirection = MathUtils.clamp(mDiscardDirection, -1.0f, 1.0f);
                distanceToEdge = Math.max(target.top - y, y - target.bottom);
                edgeToEdge = target.height();
            }

            float scaledDiscardX = x - mDiscardingTab.getLayoutTab().getX();
            float scaledDiscardY = y - mDiscardingTab.getLayoutTab().getY();
            mDiscardingTab.setDiscardOriginX(scaledDiscardX / mDiscardingTab.getScale());
            mDiscardingTab.setDiscardOriginY(scaledDiscardY / mDiscardingTab.getScale());
            mDiscardingTab.setDiscardFromClick(false);

            if (Math.abs(distanceToEdge) < DISCARD_SAFE_SELECTION_PCTG * edgeToEdge) {
                mDiscardingTab = null;
            }
        }
    }
    if (mDiscardingTab != null) {
        float deltaAmount = mCurrentMode == Orientation.PORTRAIT ? amountX : amountY;
        mDiscardingTab.addToDiscardAmount(deltaAmount);
    }
}
 
Example 18
Source File: Stack.java    From 365browser with Apache License 2.0 4 votes vote down vote up
/**
 * Evens out auto-magically the cards as the stack get scrolled.
 *
 * @param amount                The amount of scroll performed in pixel. The sign indicates the
 *                              direction.
 * @param allowReverseDirection Whether or not to allow corrections in the reverse direction of
 *                              the amount scrolled.
 * @return                      True if any tab had been 'visibly' moved.
 */
private boolean evenOutTabs(float amount, boolean allowReverseDirection) {
    if (mStackTabs == null || mOverviewAnimationType != OverviewAnimationType.NONE
            || mEvenOutProgress >= 1.0f || amount == 0) {
        return false;
    }
    boolean changed = false;
    boolean reverseScrolling = false;

    // The evening out process last until mEvenOutRate reaches 1.0. Tabs blend linearly
    // between the current position to a nice evenly scaled pattern. Because we do not store
    // the starting position for each tab we need more complicated math to do the blend.
    // The absoluteProgress is how much we need progress this step on the [0, 1] scale.
    float absoluteProgress = Math.min(Math.abs(amount) * mEvenOutRate, 1.0f - mEvenOutProgress);
    // The relativeProgress is how much we need to blend the target to the current to get there.
    float relativeProgress = absoluteProgress / (1.0f - mEvenOutProgress);

    float screenMax = getScrollDimensionSize();
    for (int i = 0; i < mStackTabs.length; ++i) {
        float source = mStackTabs[i].getScrollOffset();
        float target = screenToScroll(i * mSpacing);
        float sourceScreen = Math.min(screenMax, scrollToScreen(source + mScrollTarget));
        float targetScreen = Math.min(screenMax, scrollToScreen(target + mScrollTarget));
        // If the target and the current position matches on the screen then we snap to the
        // target.
        if (sourceScreen == targetScreen) {
            mStackTabs[i].setScrollOffset(target);
            continue;
        }
        float step = source + (target - source) * relativeProgress;
        float stepScreen = Math.min(screenMax, scrollToScreen(step + mScrollTarget));
        // If the step can be performed without noticing then we do it.
        if (sourceScreen == stepScreen) {
            mStackTabs[i].setScrollOffset(step);
            continue;
        }
        // If the scrolling goes in the same direction as the step then the motion is applied.
        if ((targetScreen - sourceScreen) * amount > 0 || allowReverseDirection) {
            mStackTabs[i].setScrollOffset(step);
            changed = true;
        } else {
            reverseScrolling = true;
        }
    }
    // Only account for progress if the scrolling was in the right direction. It assumes here
    // That if any of the tabs was going in the wrong direction then the progress is not
    // recorded at all. This is very conservative to avoid poping in the scrolling. It works
    // for now but might need to be revisited if we see artifacts.
    if (!reverseScrolling) {
        mEvenOutProgress += absoluteProgress;
    }
    return changed;
}
 
Example 19
Source File: Stack.java    From delion with Apache License 2.0 4 votes vote down vote up
/**
 * Evens out auto-magically the cards as the stack get scrolled.
 *
 * @param amount                The amount of scroll performed in pixel. The sign indicates the
 *                              direction.
 * @param allowReverseDirection Whether or not to allow corrections in the reverse direction of
 *                              the amount scrolled.
 * @return                      True if any tab had been 'visibly' moved.
 */
private boolean evenOutTabs(float amount, boolean allowReverseDirection) {
    if (mStackTabs == null || mOverviewAnimationType != OverviewAnimationType.NONE
            || mEvenOutProgress >= 1.0f || amount == 0) {
        return false;
    }
    boolean changed = false;
    boolean reverseScrolling = false;

    // The evening out process last until mEvenOutRate reaches 1.0. Tabs blend linearly
    // between the current position to a nice evenly scaled pattern. Because we do not store
    // the starting position for each tab we need more complicated math to do the blend.
    // The absoluteProgress is how much we need progress this step on the [0, 1] scale.
    float absoluteProgress = Math.min(Math.abs(amount) * mEvenOutRate, 1.0f - mEvenOutProgress);
    // The relativeProgress is how much we need to blend the target to the current to get there.
    float relativeProgress = absoluteProgress / (1.0f - mEvenOutProgress);

    float screenMax = getScrollDimensionSize();
    for (int i = 0; i < mStackTabs.length; ++i) {
        float source = mStackTabs[i].getScrollOffset();
        float target = screenToScroll(i * mSpacing);
        float sourceScreen = Math.min(screenMax, scrollToScreen(source + mScrollTarget));
        float targetScreen = Math.min(screenMax, scrollToScreen(target + mScrollTarget));
        // If the target and the current position matches on the screen then we snap to the
        // target.
        if (sourceScreen == targetScreen) {
            mStackTabs[i].setScrollOffset(target);
            continue;
        }
        float step = source + (target - source) * relativeProgress;
        float stepScreen = Math.min(screenMax, scrollToScreen(step + mScrollTarget));
        // If the step can be performed without noticing then we do it.
        if (sourceScreen == stepScreen) {
            mStackTabs[i].setScrollOffset(step);
            continue;
        }
        // If the scrolling goes in the same direction as the step then the motion is applied.
        if ((targetScreen - sourceScreen) * amount > 0 || allowReverseDirection) {
            mStackTabs[i].setScrollOffset(step);
            changed = true;
        } else {
            reverseScrolling = true;
        }
    }
    // Only account for progress if the scrolling was in the right direction. It assumes here
    // That if any of the tabs was going in the wrong direction then the progress is not
    // recorded at all. This is very conservative to avoid poping in the scrolling. It works
    // for now but might need to be revisited if we see artifacts.
    if (!reverseScrolling) {
        mEvenOutProgress += absoluteProgress;
    }
    return changed;
}
 
Example 20
Source File: Stack.java    From delion with Apache License 2.0 4 votes vote down vote up
/**
 * Discards and updates the position based on the input event values.
 *
 * @param x       The x coordinate of the end of the drag event.
 * @param y       The y coordinate of the end of the drag event.
 * @param amountX The number of pixels dragged in the x direction since the last event.
 * @param amountY The number of pixels dragged in the y direction since the last event.
 */
private void discard(float x, float y, float amountX, float amountY) {
    if (mStackTabs == null
            || (mOverviewAnimationType != OverviewAnimationType.NONE
                       && mOverviewAnimationType != OverviewAnimationType.DISCARD
                       && mOverviewAnimationType != OverviewAnimationType.DISCARD_ALL
                       && mOverviewAnimationType != OverviewAnimationType.UNDISCARD)) {
        return;
    }

    if (mDiscardingTab == null) {
        if (!mInSwipe) {
            mDiscardingTab = getTabAtPositon(x, y);
        } else {
            if (mTabModel.index() < 0) return;
            mDiscardingTab = mStackTabs[mTabModel.index()];
        }

        if (mDiscardingTab != null) {
            cancelDiscardScrollingAnimation();

            // Make sure we are well within the tab in the discard direction.
            RectF target = mDiscardingTab.getLayoutTab().getClickTargetBounds();
            float distanceToEdge;
            float edgeToEdge;
            if (mCurrentMode == Orientation.PORTRAIT) {
                mDiscardDirection = 1.0f;
                distanceToEdge = Math.max(target.left - x, x - target.right);
                edgeToEdge = target.width();
            } else {
                mDiscardDirection = 2.0f - 4.0f * (x / mLayout.getWidth());
                mDiscardDirection = MathUtils.clamp(mDiscardDirection, -1.0f, 1.0f);
                distanceToEdge = Math.max(target.top - y, y - target.bottom);
                edgeToEdge = target.height();
            }

            float scaledDiscardX = x - mDiscardingTab.getLayoutTab().getX();
            float scaledDiscardY = y - mDiscardingTab.getLayoutTab().getY();
            mDiscardingTab.setDiscardOriginX(scaledDiscardX / mDiscardingTab.getScale());
            mDiscardingTab.setDiscardOriginY(scaledDiscardY / mDiscardingTab.getScale());
            mDiscardingTab.setDiscardFromClick(false);

            if (Math.abs(distanceToEdge) < DISCARD_SAFE_SELECTION_PCTG * edgeToEdge) {
                mDiscardingTab = null;
            }
        }
    }
    if (mDiscardingTab != null) {
        float deltaAmount = mCurrentMode == Orientation.PORTRAIT ? amountX : amountY;
        mDiscardingTab.addToDiscardAmount(deltaAmount);
    }
}