1/*
2 * Copyright (C) 2011 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.launcher3;
18
19import android.animation.TimeInterpolator;
20import android.content.Context;
21import android.util.AttributeSet;
22import android.view.View;
23import android.view.ViewDebug;
24import android.view.ViewPropertyAnimator;
25import android.view.accessibility.AccessibilityManager;
26import android.view.animation.AccelerateInterpolator;
27import android.widget.LinearLayout;
28
29import com.android.launcher3.dragndrop.DragController;
30import com.android.launcher3.dragndrop.DragOptions;
31
32/*
33 * The top bar containing various drop targets: Delete/App Info/Uninstall.
34 */
35public class DropTargetBar extends LinearLayout implements DragController.DragListener {
36
37    protected static final int DEFAULT_DRAG_FADE_DURATION = 175;
38    protected static final TimeInterpolator DEFAULT_INTERPOLATOR = new AccelerateInterpolator();
39
40    private final Runnable mFadeAnimationEndRunnable = new Runnable() {
41
42        @Override
43        public void run() {
44            AccessibilityManager am = (AccessibilityManager)
45                    getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
46            boolean accessibilityEnabled = am.isEnabled();
47            AlphaUpdateListener.updateVisibility(DropTargetBar.this, accessibilityEnabled);
48        }
49    };
50
51    @ViewDebug.ExportedProperty(category = "launcher")
52    protected boolean mDeferOnDragEnd;
53
54    @ViewDebug.ExportedProperty(category = "launcher")
55    protected boolean mVisible = false;
56
57    private ViewPropertyAnimator mCurrentAnimation;
58
59    // Drop targets
60    private ButtonDropTarget mDeleteDropTarget;
61    private ButtonDropTarget mAppInfoDropTarget;
62    private ButtonDropTarget mUninstallDropTarget;
63
64    public DropTargetBar(Context context, AttributeSet attrs) {
65        super(context, attrs);
66    }
67
68    public DropTargetBar(Context context, AttributeSet attrs, int defStyle) {
69        super(context, attrs, defStyle);
70    }
71
72    @Override
73    protected void onFinishInflate() {
74        super.onFinishInflate();
75
76        // Get the individual components
77        mDeleteDropTarget = (ButtonDropTarget) findViewById(R.id.delete_target_text);
78        mAppInfoDropTarget = (ButtonDropTarget) findViewById(R.id.info_target_text);
79        mUninstallDropTarget = (ButtonDropTarget) findViewById(R.id.uninstall_target_text);
80
81        mDeleteDropTarget.setDropTargetBar(this);
82        mAppInfoDropTarget.setDropTargetBar(this);
83        mUninstallDropTarget.setDropTargetBar(this);
84
85        // Initialize with hidden state
86        setAlpha(0f);
87    }
88
89    public void setup(DragController dragController) {
90        dragController.addDragListener(this);
91        dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
92
93        dragController.addDragListener(mDeleteDropTarget);
94        dragController.addDragListener(mAppInfoDropTarget);
95        dragController.addDragListener(mUninstallDropTarget);
96
97        dragController.addDropTarget(mDeleteDropTarget);
98        dragController.addDropTarget(mAppInfoDropTarget);
99        dragController.addDropTarget(mUninstallDropTarget);
100    }
101
102    private void animateToVisibility(boolean isVisible) {
103        if (mVisible != isVisible) {
104            mVisible = isVisible;
105
106            // Cancel any existing animation
107            if (mCurrentAnimation != null) {
108                mCurrentAnimation.cancel();
109                mCurrentAnimation = null;
110            }
111
112            float finalAlpha = mVisible ? 1 : 0;
113            if (Float.compare(getAlpha(), finalAlpha) != 0) {
114                setVisibility(View.VISIBLE);
115                mCurrentAnimation = animate().alpha(finalAlpha)
116                        .setInterpolator(DEFAULT_INTERPOLATOR)
117                        .setDuration(DEFAULT_DRAG_FADE_DURATION)
118                        .withEndAction(mFadeAnimationEndRunnable);
119            }
120
121        }
122    }
123
124    /*
125     * DragController.DragListener implementation
126     */
127    @Override
128    public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
129        animateToVisibility(true);
130    }
131
132    /**
133     * This is called to defer hiding the delete drop target until the drop animation has completed,
134     * instead of hiding immediately when the drag has ended.
135     */
136    protected void deferOnDragEnd() {
137        mDeferOnDragEnd = true;
138    }
139
140    @Override
141    public void onDragEnd() {
142        if (!mDeferOnDragEnd) {
143            animateToVisibility(false);
144        } else {
145            mDeferOnDragEnd = false;
146        }
147    }
148}
149