1 /*
2  * Copyright (C) 2014 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.systemui.qs;
18 
19 import android.animation.Animator;
20 import android.animation.Animator.AnimatorListener;
21 import android.animation.AnimatorListenerAdapter;
22 import android.graphics.drawable.TransitionDrawable;
23 import android.view.View;
24 import android.view.ViewAnimationUtils;
25 
26 /** Helper for quick settings detail panel clip animations. **/
27 public class QSDetailClipper {
28 
29     private final View mDetail;
30     private final TransitionDrawable mBackground;
31 
32     private Animator mAnimator;
33 
QSDetailClipper(View detail)34     public QSDetailClipper(View detail) {
35         mDetail = detail;
36         mBackground = (TransitionDrawable) detail.getBackground();
37     }
38 
animateCircularClip(int x, int y, boolean in, AnimatorListener listener)39     public void animateCircularClip(int x, int y, boolean in, AnimatorListener listener) {
40         if (mAnimator != null) {
41             mAnimator.cancel();
42         }
43         final int w = mDetail.getWidth() - x;
44         final int h = mDetail.getHeight() - y;
45         int innerR = 0;
46         if (x < 0 || w < 0 || y < 0 || h < 0) {
47             innerR = Math.abs(x);
48             innerR = Math.min(innerR, Math.abs(y));
49             innerR = Math.min(innerR, Math.abs(w));
50             innerR = Math.min(innerR, Math.abs(h));
51         }
52         int r = (int) Math.ceil(Math.sqrt(x * x + y * y));
53         r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + y * y)));
54         r = (int) Math.max(r, Math.ceil(Math.sqrt(w * w + h * h)));
55         r = (int) Math.max(r, Math.ceil(Math.sqrt(x * x + h * h)));
56         if (in) {
57             mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, innerR, r);
58         } else {
59             mAnimator = ViewAnimationUtils.createCircularReveal(mDetail, x, y, r, innerR);
60         }
61         mAnimator.setDuration((long)(mAnimator.getDuration() * 1.5));
62         if (listener != null) {
63             mAnimator.addListener(listener);
64         }
65         if (in) {
66             mBackground.startTransition((int)(mAnimator.getDuration() * 0.6));
67             mAnimator.addListener(mVisibleOnStart);
68         } else {
69             mDetail.postDelayed(mReverseBackground, (long)(mAnimator.getDuration() * 0.65));
70             mAnimator.addListener(mGoneOnEnd);
71         }
72         mAnimator.start();
73     }
74 
75     private final Runnable mReverseBackground = new Runnable() {
76         @Override
77         public void run() {
78             if (mAnimator != null) {
79                 mBackground.reverseTransition((int)(mAnimator.getDuration() * 0.35));
80             }
81         }
82     };
83 
84     private final AnimatorListenerAdapter mVisibleOnStart = new AnimatorListenerAdapter() {
85         @Override
86         public void onAnimationStart(Animator animation) {
87             mDetail.setVisibility(View.VISIBLE);
88         }
89 
90         public void onAnimationEnd(Animator animation) {
91             mAnimator = null;
92         }
93     };
94 
95     private final AnimatorListenerAdapter mGoneOnEnd = new AnimatorListenerAdapter() {
96         @Override
97         public void onAnimationEnd(Animator animation) {
98             mDetail.setVisibility(View.GONE);
99             mBackground.resetTransition();
100             mAnimator = null;
101         };
102     };
103 
showBackground()104     public void showBackground() {
105         mBackground.showSecondLayer();
106     }
107 }
108