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
17package com.android.systemui.statusbar;
18
19import android.content.Context;
20import android.graphics.Canvas;
21import android.graphics.Rect;
22import android.graphics.drawable.AnimatedVectorDrawable;
23import android.graphics.drawable.Drawable;
24import android.os.SystemClock;
25import android.util.AttributeSet;
26import android.view.Choreographer;
27import android.view.View;
28import android.view.ViewGroup;
29import android.view.ViewRootImpl;
30import android.widget.Button;
31import com.android.systemui.R;
32import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
33
34public class DismissViewButton extends Button {
35    private AnimatedVectorDrawable mAnimatedDismissDrawable;
36    private final Drawable mStaticDismissDrawable;
37    private Drawable mActiveDrawable;
38
39    public DismissViewButton(Context context) {
40        this(context, null);
41    }
42
43    public DismissViewButton(Context context, AttributeSet attrs) {
44        this(context, attrs, 0);
45    }
46
47    public DismissViewButton(Context context, AttributeSet attrs, int defStyleAttr) {
48        this(context, attrs, defStyleAttr, 0);
49    }
50
51    public DismissViewButton(Context context, AttributeSet attrs, int defStyleAttr,
52            int defStyleRes) {
53        super(context, attrs, defStyleAttr, defStyleRes);
54        mAnimatedDismissDrawable = (AnimatedVectorDrawable) getContext().getResources().getDrawable(
55                R.drawable.dismiss_all_shape_animation).mutate();
56        mAnimatedDismissDrawable.setCallback(this);
57        mAnimatedDismissDrawable.setBounds(0,
58                0,
59                mAnimatedDismissDrawable.getIntrinsicWidth(),
60                mAnimatedDismissDrawable.getIntrinsicHeight());
61        mStaticDismissDrawable = getContext().getResources().getDrawable(
62                R.drawable.dismiss_all_shape);
63        mStaticDismissDrawable.setBounds(0,
64                0,
65                mStaticDismissDrawable.getIntrinsicWidth(),
66                mStaticDismissDrawable.getIntrinsicHeight());
67        mStaticDismissDrawable.setCallback(this);
68        mActiveDrawable = mStaticDismissDrawable;
69    }
70
71    @Override
72    protected void onDraw(Canvas canvas) {
73        super.onDraw(canvas);
74        canvas.save();
75        int drawableHeight = mActiveDrawable.getBounds().height();
76        boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
77        int dx = isRtl ? getWidth() / 2 + drawableHeight / 2 : getWidth() / 2 - drawableHeight / 2;
78        canvas.translate(dx, getHeight() / 2.0f + drawableHeight /
79                2.0f);
80        canvas.scale(isRtl ? -1.0f : 1.0f, -1.0f);
81        mActiveDrawable.draw(canvas);
82        canvas.restore();
83    }
84
85    @Override
86    public boolean performClick() {
87        if (!mAnimatedDismissDrawable.isRunning()) {
88            mActiveDrawable = mAnimatedDismissDrawable;
89            mAnimatedDismissDrawable.start();
90        }
91        return super.performClick();
92    }
93
94    @Override
95    protected boolean verifyDrawable(Drawable who) {
96        return super.verifyDrawable(who)
97                || who == mAnimatedDismissDrawable
98                || who == mStaticDismissDrawable;
99    }
100
101    @Override
102    public boolean hasOverlappingRendering() {
103        return false;
104    }
105
106    /**
107     * This method returns the drawing rect for the view which is different from the regular
108     * drawing rect, since we layout all children in the {@link NotificationStackScrollLayout} at
109     * position 0 and usually the translation is neglected. The standard implementation doesn't
110     * account for translation.
111     *
112     * @param outRect The (scrolled) drawing bounds of the view.
113     */
114    @Override
115    public void getDrawingRect(Rect outRect) {
116        super.getDrawingRect(outRect);
117        float translationX = ((ViewGroup) mParent).getTranslationX();
118        float translationY = ((ViewGroup) mParent).getTranslationY();
119        outRect.left += translationX;
120        outRect.right += translationX;
121        outRect.top += translationY;
122        outRect.bottom += translationY;
123    }
124
125    public void showButton() {
126        mActiveDrawable = mStaticDismissDrawable;
127        invalidate();
128    }
129
130    /**
131     * @return Whether the button is currently static and not being animated.
132     */
133    public boolean isButtonStatic() {
134        return mActiveDrawable == mStaticDismissDrawable;
135    }
136}
137