| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package com.android.systemui.statusbar.stack; |
| |
| import java.util.ArrayList; |
| |
| /** |
| * A Functor which interpolates the stack distance linearly based on base values. |
| * The base values are based on an interpolation between a linear function and a |
| * quadratic function |
| */ |
| public class PiecewiseLinearIndentationFunctor extends StackIndentationFunctor { |
| |
| private final ArrayList<Float> mBaseValues; |
| private final float mLinearPart; |
| |
| /** |
| * @param maxItemsInStack The maximum number of items which should be visible at the same time, |
| * i.e the function returns totalTransitionDistance for the element with |
| * index maxItemsInStack |
| * @param peekSize The visual appearance of this is how far the cards in the stack peek |
| * out below the top card and it is measured in real pixels. |
| * Note that the visual appearance does not necessarily always correspond to |
| * the actual visual distance below the top card but is a maximum, |
| * achieved when the next card just starts transitioning into the stack and |
| * the stack is full. |
| * If distanceToPeekStart is 0, we directly start at the peek, otherwise the |
| * first element transitions between 0 and distanceToPeekStart. |
| * Visualization: |
| * --------------------------------------------------- --- |
| * | | | |
| * | FIRST ITEM | | <- distanceToPeekStart |
| * | | | |
| * |---------------------------------------------------| --- --- |
| * |__________________SECOND ITEM______________________| | <- peekSize |
| * |===================================================| _|_ |
| * |
| * @param distanceToPeekStart The distance to the start of the peak. |
| * @param linearPart The interpolation factor between the linear and the quadratic amount taken. |
| * This factor must be somewhere in [0 , 1] |
| */ |
| PiecewiseLinearIndentationFunctor(int maxItemsInStack, |
| int peekSize, |
| int distanceToPeekStart, |
| float linearPart) { |
| super(maxItemsInStack, peekSize, distanceToPeekStart); |
| mBaseValues = new ArrayList<Float>(maxItemsInStack+1); |
| initBaseValues(); |
| mLinearPart = linearPart; |
| } |
| |
| private void initBaseValues() { |
| int sumOfSquares = getSumOfSquares(mMaxItemsInStack-1); |
| int totalWeight = 0; |
| mBaseValues.add(0.0f); |
| for (int i = 0; i < mMaxItemsInStack - 1; i++) { |
| totalWeight += (mMaxItemsInStack - i - 1) * (mMaxItemsInStack - i - 1); |
| mBaseValues.add((float) totalWeight / sumOfSquares); |
| } |
| } |
| |
| /** |
| * Get the sum of squares up to and including n, i.e sum(i * i, 1, n) |
| * |
| * @param n the maximum square to include |
| * @return |
| */ |
| private int getSumOfSquares(int n) { |
| return n * (n + 1) * (2 * n + 1) / 6; |
| } |
| |
| @Override |
| public float getValue(float itemsBefore) { |
| if (mStackStartsAtPeek) { |
| // We directly start at the stack, so no initial interpolation. |
| itemsBefore++; |
| } |
| if (itemsBefore < 0) { |
| return 0; |
| } else if (itemsBefore >= mMaxItemsInStack) { |
| return mTotalTransitionDistance; |
| } |
| int below = (int) itemsBefore; |
| float partialIn = itemsBefore - below; |
| |
| if (below == 0) { |
| return mDistanceToPeekStart * partialIn; |
| } else { |
| float result = mDistanceToPeekStart; |
| float progress = mBaseValues.get(below - 1) * (1 - partialIn) |
| + mBaseValues.get(below) * partialIn; |
| result += (progress * (1 - mLinearPart) |
| + (itemsBefore - 1) / (mMaxItemsInStack - 1) * mLinearPart) * mPeekSize; |
| return result; |
| } |
| } |
| } |