Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2016 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.android.calculator2; |
| 18 | |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 19 | import android.animation.ArgbEvaluator; |
Aurimas Liutikas | 8c43f06 | 2018-03-28 08:10:28 -0700 | [diff] [blame^] | 20 | import androidx.recyclerview.widget.RecyclerView; |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 21 | import android.view.View; |
| 22 | import android.widget.TextView; |
| 23 | |
| 24 | /** |
| 25 | * Contains the logic for animating the recyclerview elements on drag. |
| 26 | */ |
| 27 | public final class DragController { |
| 28 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 29 | private static final String TAG = "DragController"; |
| 30 | |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 31 | private static final ArgbEvaluator mColorEvaluator = new ArgbEvaluator(); |
| 32 | |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 33 | // References to views from the Calculator Display. |
| 34 | private CalculatorFormula mDisplayFormula; |
| 35 | private CalculatorResult mDisplayResult; |
| 36 | private View mToolbar; |
| 37 | |
| 38 | private int mFormulaTranslationY; |
| 39 | private int mFormulaTranslationX; |
| 40 | private float mFormulaScale; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 41 | private float mResultScale; |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 42 | |
Annie Chin | fe7a410 | 2016-12-02 16:21:04 -0800 | [diff] [blame] | 43 | private float mResultTranslationY; |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 44 | private int mResultTranslationX; |
| 45 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 46 | private int mDisplayHeight; |
| 47 | |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 48 | private int mFormulaStartColor; |
| 49 | private int mFormulaEndColor; |
| 50 | |
| 51 | private int mResultStartColor; |
| 52 | private int mResultEndColor; |
| 53 | |
Annie Chin | 3614798 | 2016-12-01 15:07:34 -0800 | [diff] [blame] | 54 | // The padding at the bottom of the RecyclerView itself. |
| 55 | private int mBottomPaddingHeight; |
| 56 | |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 57 | private boolean mAnimationInitialized; |
| 58 | |
Annie Chin | 8861323 | 2017-01-04 12:21:52 -0800 | [diff] [blame] | 59 | private boolean mOneLine; |
Annie Chin | bfffafd | 2017-01-25 15:51:11 -0800 | [diff] [blame] | 60 | private boolean mIsDisplayEmpty; |
Annie Chin | 8861323 | 2017-01-04 12:21:52 -0800 | [diff] [blame] | 61 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 62 | private AnimationController mAnimationController; |
| 63 | |
| 64 | private Evaluator mEvaluator; |
| 65 | |
| 66 | public void setEvaluator(Evaluator evaluator) { |
| 67 | mEvaluator = evaluator; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 68 | } |
| 69 | |
Annie Chin | bfffafd | 2017-01-25 15:51:11 -0800 | [diff] [blame] | 70 | public void initializeController(boolean isResult, boolean oneLine, boolean isDisplayEmpty) { |
Annie Chin | 8861323 | 2017-01-04 12:21:52 -0800 | [diff] [blame] | 71 | mOneLine = oneLine; |
Annie Chin | bfffafd | 2017-01-25 15:51:11 -0800 | [diff] [blame] | 72 | mIsDisplayEmpty = isDisplayEmpty; |
| 73 | if (mIsDisplayEmpty) { |
Annie Chin | 94c1bd9 | 2016-11-23 13:39:56 -0800 | [diff] [blame] | 74 | // Empty display |
| 75 | mAnimationController = new EmptyAnimationController(); |
| 76 | } else if (isResult) { |
| 77 | // Result |
| 78 | mAnimationController = new ResultAnimationController(); |
| 79 | } else { |
| 80 | // There is something in the formula field. There may or may not be |
| 81 | // a quick result. |
| 82 | mAnimationController = new AnimationController(); |
| 83 | } |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 84 | } |
| 85 | |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 86 | public void setDisplayFormula(CalculatorFormula formula) { |
| 87 | mDisplayFormula = formula; |
| 88 | } |
| 89 | |
| 90 | public void setDisplayResult(CalculatorResult result) { |
| 91 | mDisplayResult = result; |
| 92 | } |
| 93 | |
| 94 | public void setToolbar(View toolbar) { |
| 95 | mToolbar = toolbar; |
| 96 | } |
| 97 | |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 98 | public void animateViews(float yFraction, RecyclerView recyclerView) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 99 | if (mDisplayFormula == null |
| 100 | || mDisplayResult == null |
| 101 | || mToolbar == null |
| 102 | || mEvaluator == null) { |
| 103 | // Bail if we aren't yet initialized. |
| 104 | return; |
| 105 | } |
| 106 | |
| 107 | final HistoryAdapter.ViewHolder vh = |
| 108 | (HistoryAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(0); |
| 109 | if (yFraction > 0 && vh != null) { |
Annie Chin | efa259a | 2016-11-23 14:15:15 -0800 | [diff] [blame] | 110 | recyclerView.setVisibility(View.VISIBLE); |
| 111 | } |
Annie Chin | bfffafd | 2017-01-25 15:51:11 -0800 | [diff] [blame] | 112 | if (vh != null && !mIsDisplayEmpty |
| 113 | && vh.getItemViewType() == HistoryAdapter.HISTORY_VIEW_TYPE) { |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 114 | final AlignedTextView formula = vh.getFormula(); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 115 | final CalculatorResult result = vh.getResult(); |
| 116 | final TextView date = vh.getDate(); |
Annie Chin | 3614798 | 2016-12-01 15:07:34 -0800 | [diff] [blame] | 117 | final View divider = vh.getDivider(); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 118 | |
| 119 | if (!mAnimationInitialized) { |
Annie Chin | 3614798 | 2016-12-01 15:07:34 -0800 | [diff] [blame] | 120 | mBottomPaddingHeight = recyclerView.getPaddingBottom(); |
| 121 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 122 | mAnimationController.initializeScales(formula, result); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 123 | |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 124 | mAnimationController.initializeColorAnimators(formula, result); |
| 125 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 126 | mAnimationController.initializeFormulaTranslationX(formula); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 127 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 128 | mAnimationController.initializeFormulaTranslationY(formula, result); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 129 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 130 | mAnimationController.initializeResultTranslationX(result); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 131 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 132 | mAnimationController.initializeResultTranslationY(result); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 133 | |
| 134 | mAnimationInitialized = true; |
| 135 | } |
| 136 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 137 | result.setScaleX(mAnimationController.getResultScale(yFraction)); |
| 138 | result.setScaleY(mAnimationController.getResultScale(yFraction)); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 139 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 140 | formula.setScaleX(mAnimationController.getFormulaScale(yFraction)); |
| 141 | formula.setScaleY(mAnimationController.getFormulaScale(yFraction)); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 142 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 143 | formula.setPivotX(formula.getWidth() - formula.getPaddingEnd()); |
| 144 | formula.setPivotY(formula.getHeight() - formula.getPaddingBottom()); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 145 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 146 | result.setPivotX(result.getWidth() - result.getPaddingEnd()); |
| 147 | result.setPivotY(result.getHeight() - result.getPaddingBottom()); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 148 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 149 | formula.setTranslationX(mAnimationController.getFormulaTranslationX(yFraction)); |
| 150 | formula.setTranslationY(mAnimationController.getFormulaTranslationY(yFraction)); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 151 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 152 | result.setTranslationX(mAnimationController.getResultTranslationX(yFraction)); |
| 153 | result.setTranslationY(mAnimationController.getResultTranslationY(yFraction)); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 154 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 155 | formula.setTextColor((int) mColorEvaluator.evaluate(yFraction, mFormulaStartColor, |
| 156 | mFormulaEndColor)); |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 157 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 158 | result.setTextColor((int) mColorEvaluator.evaluate(yFraction, mResultStartColor, |
| 159 | mResultEndColor)); |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 160 | |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 161 | date.setTranslationY(mAnimationController.getDateTranslationY(yFraction)); |
| 162 | divider.setTranslationY(mAnimationController.getDateTranslationY(yFraction)); |
Annie Chin | bfffafd | 2017-01-25 15:51:11 -0800 | [diff] [blame] | 163 | } else if (mIsDisplayEmpty) { |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 164 | // There is no current expression but we still need to collect information |
| 165 | // to translate the other viewholders. |
| 166 | if (!mAnimationInitialized) { |
| 167 | mAnimationController.initializeDisplayHeight(); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 168 | mAnimationInitialized = true; |
| 169 | } |
| 170 | } |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 171 | |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 172 | // Move up all ViewHolders above the current expression; if there is no current expression, |
| 173 | // we're translating all the viewholders. |
| 174 | for (int i = recyclerView.getChildCount() - 1; |
| 175 | i >= mAnimationController.getFirstTranslatedViewHolderIndex(); |
| 176 | --i) { |
| 177 | final RecyclerView.ViewHolder vh2 = |
| 178 | recyclerView.getChildViewHolder(recyclerView.getChildAt(i)); |
| 179 | if (vh2 != null) { |
| 180 | final View view = vh2.itemView; |
| 181 | if (view != null) { |
| 182 | view.setTranslationY( |
| 183 | mAnimationController.getHistoryElementTranslationY(yFraction)); |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 184 | } |
| 185 | } |
| 186 | } |
| 187 | } |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 188 | |
| 189 | /** |
Annie Chin | b2e9618 | 2016-11-28 13:14:54 -0800 | [diff] [blame] | 190 | * Reset all initialized values. |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 191 | */ |
Annie Chin | bfffafd | 2017-01-25 15:51:11 -0800 | [diff] [blame] | 192 | public void initializeAnimation(boolean isResult, boolean oneLine, boolean isDisplayEmpty) { |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 193 | mAnimationInitialized = false; |
Annie Chin | bfffafd | 2017-01-25 15:51:11 -0800 | [diff] [blame] | 194 | initializeController(isResult, oneLine, isDisplayEmpty); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 195 | } |
| 196 | |
| 197 | public interface AnimateTextInterface { |
| 198 | |
| 199 | void initializeDisplayHeight(); |
| 200 | |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 201 | void initializeColorAnimators(AlignedTextView formula, CalculatorResult result); |
| 202 | |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 203 | void initializeScales(AlignedTextView formula, CalculatorResult result); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 204 | |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 205 | void initializeFormulaTranslationX(AlignedTextView formula); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 206 | |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 207 | void initializeFormulaTranslationY(AlignedTextView formula, CalculatorResult result); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 208 | |
| 209 | void initializeResultTranslationX(CalculatorResult result); |
| 210 | |
| 211 | void initializeResultTranslationY(CalculatorResult result); |
| 212 | |
| 213 | float getResultTranslationX(float yFraction); |
| 214 | |
| 215 | float getResultTranslationY(float yFraction); |
| 216 | |
| 217 | float getResultScale(float yFraction); |
| 218 | |
| 219 | float getFormulaScale(float yFraction); |
| 220 | |
| 221 | float getFormulaTranslationX(float yFraction); |
| 222 | |
| 223 | float getFormulaTranslationY(float yFraction); |
| 224 | |
| 225 | float getDateTranslationY(float yFraction); |
| 226 | |
| 227 | float getHistoryElementTranslationY(float yFraction); |
| 228 | |
| 229 | // Return the lowest index of the first Viewholder to be translated upwards. |
| 230 | // If there is no current expression, we translate all the viewholders; otherwise, |
| 231 | // we start at index 1. |
| 232 | int getFirstTranslatedViewHolderIndex(); |
| 233 | } |
| 234 | |
| 235 | // The default AnimationController when Display is in INPUT state and DisplayFormula is not |
| 236 | // empty. There may or may not be a quick result. |
| 237 | public class AnimationController implements DragController.AnimateTextInterface { |
| 238 | |
| 239 | public void initializeDisplayHeight() { |
| 240 | // no-op |
| 241 | } |
| 242 | |
Annie Chin | 0e88baa | 2016-11-28 15:23:07 -0800 | [diff] [blame] | 243 | public void initializeColorAnimators(AlignedTextView formula, CalculatorResult result) { |
| 244 | mFormulaStartColor = mDisplayFormula.getCurrentTextColor(); |
| 245 | mFormulaEndColor = formula.getCurrentTextColor(); |
| 246 | |
| 247 | mResultStartColor = mDisplayResult.getCurrentTextColor(); |
| 248 | mResultEndColor = result.getCurrentTextColor(); |
| 249 | } |
| 250 | |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 251 | public void initializeScales(AlignedTextView formula, CalculatorResult result) { |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 252 | // Calculate the scale for the text |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 253 | mFormulaScale = mDisplayFormula.getTextSize() / formula.getTextSize(); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 254 | } |
| 255 | |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 256 | public void initializeFormulaTranslationY(AlignedTextView formula, |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 257 | CalculatorResult result) { |
Annie Chin | 8861323 | 2017-01-04 12:21:52 -0800 | [diff] [blame] | 258 | if (mOneLine) { |
| 259 | // Disregard result since we set it to GONE in the one-line case. |
| 260 | mFormulaTranslationY = |
| 261 | mDisplayFormula.getPaddingBottom() - formula.getPaddingBottom() |
| 262 | - mBottomPaddingHeight; |
| 263 | } else { |
| 264 | // Baseline of formula moves by the difference in formula bottom padding and the |
| 265 | // difference in result height. |
| 266 | mFormulaTranslationY = |
| 267 | mDisplayFormula.getPaddingBottom() - formula.getPaddingBottom() |
| 268 | + mDisplayResult.getHeight() - result.getHeight() |
| 269 | - mBottomPaddingHeight; |
| 270 | } |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 271 | } |
| 272 | |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 273 | public void initializeFormulaTranslationX(AlignedTextView formula) { |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 274 | // Right border of formula moves by the difference in formula end padding. |
| 275 | mFormulaTranslationX = mDisplayFormula.getPaddingEnd() - formula.getPaddingEnd(); |
| 276 | } |
| 277 | |
| 278 | public void initializeResultTranslationY(CalculatorResult result) { |
| 279 | // Baseline of result moves by the difference in result bottom padding. |
Annie Chin | 3614798 | 2016-12-01 15:07:34 -0800 | [diff] [blame] | 280 | mResultTranslationY = mDisplayResult.getPaddingBottom() - result.getPaddingBottom() |
| 281 | - mBottomPaddingHeight; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 282 | } |
| 283 | |
| 284 | public void initializeResultTranslationX(CalculatorResult result) { |
| 285 | mResultTranslationX = mDisplayResult.getPaddingEnd() - result.getPaddingEnd(); |
| 286 | } |
| 287 | |
| 288 | public float getResultTranslationX(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 289 | return mResultTranslationX * (yFraction - 1f); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 290 | } |
| 291 | |
| 292 | public float getResultTranslationY(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 293 | return mResultTranslationY * (yFraction - 1f); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 294 | } |
| 295 | |
| 296 | public float getResultScale(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 297 | return 1f; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 298 | } |
| 299 | |
| 300 | public float getFormulaScale(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 301 | return mFormulaScale + (1f - mFormulaScale) * yFraction; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 302 | } |
| 303 | |
| 304 | public float getFormulaTranslationX(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 305 | return mFormulaTranslationX * (yFraction - 1f); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 306 | } |
| 307 | |
| 308 | public float getFormulaTranslationY(float yFraction) { |
| 309 | // Scale linearly between -FormulaTranslationY and 0. |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 310 | return mFormulaTranslationY * (yFraction - 1f); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 311 | } |
| 312 | |
| 313 | public float getDateTranslationY(float yFraction) { |
| 314 | // We also want the date to start out above the visible screen with |
| 315 | // this distance decreasing as it's pulled down. |
Annie Chin | 5a2bebb | 2016-12-06 14:38:49 -0800 | [diff] [blame] | 316 | // Account for the scaled formula height. |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 317 | return -mToolbar.getHeight() * (1f - yFraction) |
Annie Chin | 5a2bebb | 2016-12-06 14:38:49 -0800 | [diff] [blame] | 318 | + getFormulaTranslationY(yFraction) |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 319 | - mDisplayFormula.getHeight() /getFormulaScale(yFraction) * (1f - yFraction); |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 320 | } |
| 321 | |
| 322 | public float getHistoryElementTranslationY(float yFraction) { |
| 323 | return getDateTranslationY(yFraction); |
| 324 | } |
| 325 | |
| 326 | public int getFirstTranslatedViewHolderIndex() { |
| 327 | return 1; |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | // The default AnimationController when Display is in RESULT state. |
| 332 | public class ResultAnimationController extends AnimationController |
| 333 | implements DragController.AnimateTextInterface { |
| 334 | @Override |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 335 | public void initializeScales(AlignedTextView formula, CalculatorResult result) { |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 336 | final float textSize = mDisplayResult.getTextSize() * mDisplayResult.getScaleX(); |
| 337 | mResultScale = textSize / result.getTextSize(); |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 338 | mFormulaScale = 1f; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 339 | } |
| 340 | |
| 341 | @Override |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 342 | public void initializeFormulaTranslationY(AlignedTextView formula, |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 343 | CalculatorResult result) { |
| 344 | // Baseline of formula moves by the difference in formula bottom padding and the |
| 345 | // difference in the result height. |
| 346 | mFormulaTranslationY = mDisplayFormula.getPaddingBottom() - formula.getPaddingBottom() |
Annie Chin | 3614798 | 2016-12-01 15:07:34 -0800 | [diff] [blame] | 347 | + mDisplayResult.getHeight() - result.getHeight() |
| 348 | - mBottomPaddingHeight; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 349 | } |
| 350 | |
| 351 | @Override |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 352 | public void initializeFormulaTranslationX(AlignedTextView formula) { |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 353 | // Right border of formula moves by the difference in formula end padding. |
| 354 | mFormulaTranslationX = mDisplayFormula.getPaddingEnd() - formula.getPaddingEnd(); |
| 355 | } |
| 356 | |
| 357 | @Override |
| 358 | public void initializeResultTranslationY(CalculatorResult result) { |
| 359 | // Baseline of result moves by the difference in result bottom padding. |
Annie Chin | fe7a410 | 2016-12-02 16:21:04 -0800 | [diff] [blame] | 360 | mResultTranslationY = mDisplayResult.getPaddingBottom() - result.getPaddingBottom() |
| 361 | - mDisplayResult.getTranslationY() |
| 362 | - mBottomPaddingHeight; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 363 | } |
| 364 | |
| 365 | @Override |
| 366 | public void initializeResultTranslationX(CalculatorResult result) { |
| 367 | mResultTranslationX = mDisplayResult.getPaddingEnd() - result.getPaddingEnd(); |
| 368 | } |
| 369 | |
| 370 | @Override |
| 371 | public float getResultTranslationX(float yFraction) { |
| 372 | return (mResultTranslationX * yFraction) - mResultTranslationX; |
| 373 | } |
| 374 | |
| 375 | @Override |
| 376 | public float getResultTranslationY(float yFraction) { |
| 377 | return (mResultTranslationY * yFraction) - mResultTranslationY; |
| 378 | } |
| 379 | |
| 380 | @Override |
| 381 | public float getFormulaTranslationX(float yFraction) { |
| 382 | return (mFormulaTranslationX * yFraction) - |
| 383 | mFormulaTranslationX; |
| 384 | } |
| 385 | |
| 386 | @Override |
| 387 | public float getFormulaTranslationY(float yFraction) { |
| 388 | return getDateTranslationY(yFraction); |
| 389 | } |
| 390 | |
| 391 | @Override |
| 392 | public float getResultScale(float yFraction) { |
| 393 | return mResultScale - (mResultScale * yFraction) + yFraction; |
| 394 | } |
| 395 | |
| 396 | @Override |
| 397 | public float getFormulaScale(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 398 | return 1f; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 399 | } |
| 400 | |
| 401 | @Override |
| 402 | public float getDateTranslationY(float yFraction) { |
| 403 | // We also want the date to start out above the visible screen with |
| 404 | // this distance decreasing as it's pulled down. |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 405 | return -mToolbar.getHeight() * (1f - yFraction) |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 406 | + (mResultTranslationY * yFraction) - mResultTranslationY |
| 407 | - mDisplayFormula.getPaddingTop() + |
| 408 | (mDisplayFormula.getPaddingTop() * yFraction); |
| 409 | } |
| 410 | |
| 411 | @Override |
| 412 | public int getFirstTranslatedViewHolderIndex() { |
| 413 | return 1; |
| 414 | } |
| 415 | } |
| 416 | |
| 417 | // The default AnimationController when Display is completely empty. |
| 418 | public class EmptyAnimationController extends AnimationController |
| 419 | implements DragController.AnimateTextInterface { |
| 420 | @Override |
| 421 | public void initializeDisplayHeight() { |
| 422 | mDisplayHeight = mToolbar.getHeight() + mDisplayResult.getHeight() |
| 423 | + mDisplayFormula.getHeight(); |
| 424 | } |
| 425 | |
| 426 | @Override |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 427 | public void initializeScales(AlignedTextView formula, CalculatorResult result) { |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 428 | // no-op |
| 429 | } |
| 430 | |
| 431 | @Override |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 432 | public void initializeFormulaTranslationY(AlignedTextView formula, |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 433 | CalculatorResult result) { |
| 434 | // no-op |
| 435 | } |
| 436 | |
| 437 | @Override |
Annie Chin | 8149c8c | 2016-11-28 13:44:09 -0800 | [diff] [blame] | 438 | public void initializeFormulaTranslationX(AlignedTextView formula) { |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 439 | // no-op |
| 440 | } |
| 441 | |
| 442 | @Override |
| 443 | public void initializeResultTranslationY(CalculatorResult result) { |
| 444 | // no-op |
| 445 | } |
| 446 | |
| 447 | @Override |
| 448 | public void initializeResultTranslationX(CalculatorResult result) { |
| 449 | // no-op |
| 450 | } |
| 451 | |
| 452 | @Override |
| 453 | public float getResultTranslationX(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 454 | return 0f; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 455 | } |
| 456 | |
| 457 | @Override |
| 458 | public float getResultTranslationY(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 459 | return 0f; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 460 | } |
| 461 | |
| 462 | @Override |
| 463 | public float getFormulaScale(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 464 | return 1f; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 465 | } |
| 466 | |
| 467 | @Override |
| 468 | public float getDateTranslationY(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 469 | return 0f; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 470 | } |
| 471 | |
| 472 | @Override |
| 473 | public float getHistoryElementTranslationY(float yFraction) { |
Justin Klaassen | 3929778 | 2016-12-19 09:11:38 -0800 | [diff] [blame] | 474 | return -mDisplayHeight * (1f - yFraction) - mBottomPaddingHeight; |
Annie Chin | bc00188 | 2016-11-09 19:41:21 -0800 | [diff] [blame] | 475 | } |
| 476 | |
| 477 | @Override |
| 478 | public int getFirstTranslatedViewHolderIndex() { |
| 479 | return 0; |
| 480 | } |
| 481 | } |
Annie Chin | d0f87d2 | 2016-10-24 09:04:12 -0700 | [diff] [blame] | 482 | } |