blob: a8dcd0f06b2dd2ee93b16687b57aa9f1a1da047d [file] [log] [blame]
Winson Chung4c98d922011-05-31 16:50:48 -07001/*
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
Daniel Sandler325dc232013-06-05 22:57:57 -040017package com.android.launcher3;
Winson Chung4c98d922011-05-31 16:50:48 -070018
Winson Chung201bc822011-06-20 15:41:53 -070019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.ObjectAnimator;
Adam Cohenc2d6e892014-10-16 09:49:24 -070022import android.animation.ValueAnimator;
Winson Chung4c98d922011-05-31 16:50:48 -070023import android.content.Context;
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +010024import android.graphics.Rect;
Winson Chung4c98d922011-05-31 16:50:48 -070025import android.util.AttributeSet;
26import android.view.View;
Winson Chunga62e9fd2011-07-11 15:20:48 -070027import android.view.animation.AccelerateInterpolator;
Winson Chung4c98d922011-05-31 16:50:48 -070028import android.widget.FrameLayout;
29
Winson Chung4c98d922011-05-31 16:50:48 -070030/*
31 * Ths bar will manage the transition between the QSB search bar and the delete drop
32 * targets so that each of the individual IconDropTargets don't have to.
33 */
34public class SearchDropTargetBar extends FrameLayout implements DragController.DragListener {
35
Winson Chunga62e9fd2011-07-11 15:20:48 -070036 private static final int sTransitionInDuration = 200;
37 private static final int sTransitionOutDuration = 175;
Winson Chung4c98d922011-05-31 16:50:48 -070038
Winson Chung17f1bb82012-05-25 14:25:44 -070039 private ObjectAnimator mDropTargetBarAnim;
Adam Cohenc2d6e892014-10-16 09:49:24 -070040 private ValueAnimator mQSBSearchBarAnim;
Winson Chung17f1bb82012-05-25 14:25:44 -070041 private static final AccelerateInterpolator sAccelerateInterpolator =
42 new AccelerateInterpolator();
Winson Chung201bc822011-06-20 15:41:53 -070043
Winson Chungf0ea4d32011-06-06 14:27:16 -070044 private boolean mIsSearchBarHidden;
Winson Chung4c98d922011-05-31 16:50:48 -070045 private View mQSBSearchBar;
46 private View mDropTargetBar;
Winson Chunga62e9fd2011-07-11 15:20:48 -070047 private int mBarHeight;
Adam Cohend4d7aa52011-07-19 21:47:37 -070048 private boolean mDeferOnDragEnd = false;
Winson Chung4c98d922011-05-31 16:50:48 -070049
Sunny Goyalfa401a12015-04-10 13:45:42 -070050 // Drop targets
51 private ButtonDropTarget mInfoDropTarget;
52 private ButtonDropTarget mDeleteDropTarget;
53 private ButtonDropTarget mUninstallDropTarget;
54
Michael Jurka19e33472012-05-14 20:41:52 -070055 private boolean mEnableDropDownDropTargets;
Winson Chungc51db6a2011-10-05 11:44:49 -070056
Winson Chung4c98d922011-05-31 16:50:48 -070057 public SearchDropTargetBar(Context context, AttributeSet attrs) {
58 this(context, attrs, 0);
59 }
60
61 public SearchDropTargetBar(Context context, AttributeSet attrs, int defStyle) {
62 super(context, attrs, defStyle);
63 }
64
65 public void setup(Launcher launcher, DragController dragController) {
66 dragController.addDragListener(this);
Sunny Goyalfa401a12015-04-10 13:45:42 -070067 dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
68
Winson Chung4c98d922011-05-31 16:50:48 -070069 dragController.addDragListener(mInfoDropTarget);
70 dragController.addDragListener(mDeleteDropTarget);
Sunny Goyalfa401a12015-04-10 13:45:42 -070071 dragController.addDragListener(mUninstallDropTarget);
72
Winson Chung4c98d922011-05-31 16:50:48 -070073 dragController.addDropTarget(mInfoDropTarget);
74 dragController.addDropTarget(mDeleteDropTarget);
Sunny Goyalfa401a12015-04-10 13:45:42 -070075 dragController.addDropTarget(mUninstallDropTarget);
76
Winson Chung4c98d922011-05-31 16:50:48 -070077 mInfoDropTarget.setLauncher(launcher);
78 mDeleteDropTarget.setLauncher(launcher);
Sunny Goyalfa401a12015-04-10 13:45:42 -070079 mUninstallDropTarget.setLauncher(launcher);
Sunny Goyal594d76d2014-11-06 10:12:54 -080080 }
81
82 public void setQsbSearchBar(View qsb) {
83 mQSBSearchBar = qsb;
Adam Cohenc2d6e892014-10-16 09:49:24 -070084 if (mQSBSearchBar != null) {
85 if (mEnableDropDownDropTargets) {
86 mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
87 -mBarHeight);
88 } else {
89 mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
90 }
91 setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
Cristina Stancu476493b2013-08-07 17:20:14 +010092 } else {
Adam Cohenc2d6e892014-10-16 09:49:24 -070093 // Create a no-op animation of the search bar is null
94 mQSBSearchBarAnim = ValueAnimator.ofFloat(0, 0);
95 mQSBSearchBarAnim.setDuration(sTransitionInDuration);
Cristina Stancu476493b2013-08-07 17:20:14 +010096 }
Winson Chung4c98d922011-05-31 16:50:48 -070097 }
98
Winson Chungc7d2b602012-05-16 17:02:20 -070099 private void prepareStartAnimation(View v) {
Winson Chung17f1bb82012-05-25 14:25:44 -0700100 // Enable the hw layers before the animation starts (will be disabled in the onAnimationEnd
101 // callback below)
Adam Cohenc2d6e892014-10-16 09:49:24 -0700102 if (v != null) {
103 v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
104 }
Winson Chungc7d2b602012-05-16 17:02:20 -0700105 }
106
Adam Cohenc2d6e892014-10-16 09:49:24 -0700107 private void setupAnimation(ValueAnimator anim, final View v) {
Winson Chung17f1bb82012-05-25 14:25:44 -0700108 anim.setInterpolator(sAccelerateInterpolator);
109 anim.setDuration(sTransitionInDuration);
110 anim.addListener(new AnimatorListenerAdapter() {
Winson Chung315b3ba2012-05-11 10:51:32 -0700111 @Override
112 public void onAnimationEnd(Animator animation) {
Adam Cohenc2d6e892014-10-16 09:49:24 -0700113 if (v != null) {
114 v.setLayerType(View.LAYER_TYPE_NONE, null);
115 }
Winson Chung315b3ba2012-05-11 10:51:32 -0700116 }
117 });
118 }
119
Winson Chung4c98d922011-05-31 16:50:48 -0700120 @Override
121 protected void onFinishInflate() {
122 super.onFinishInflate();
123
124 // Get the individual components
Winson Chung4c98d922011-05-31 16:50:48 -0700125 mDropTargetBar = findViewById(R.id.drag_target_bar);
Winson Chunga6427b12011-07-27 10:53:39 -0700126 mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target_text);
127 mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target_text);
Sunny Goyalfa401a12015-04-10 13:45:42 -0700128 mUninstallDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.uninstall_target_text);
Winson Chunga62e9fd2011-07-11 15:20:48 -0700129
Adam Cohend4d7aa52011-07-19 21:47:37 -0700130 mInfoDropTarget.setSearchDropTargetBar(this);
131 mDeleteDropTarget.setSearchDropTargetBar(this);
Sunny Goyalfa401a12015-04-10 13:45:42 -0700132 mUninstallDropTarget.setSearchDropTargetBar(this);
Adam Cohend4d7aa52011-07-19 21:47:37 -0700133
Michael Jurka19e33472012-05-14 20:41:52 -0700134 mEnableDropDownDropTargets =
Winson Chunga62e9fd2011-07-11 15:20:48 -0700135 getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
Winson Chung201bc822011-06-20 15:41:53 -0700136
137 // Create the various fade animations
Michael Jurka19e33472012-05-14 20:41:52 -0700138 if (mEnableDropDownDropTargets) {
Winson Chung5f8afe62013-08-12 16:19:28 -0700139 LauncherAppState app = LauncherAppState.getInstance();
140 DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
141 mBarHeight = grid.searchBarSpaceHeightPx;
Winson Chunga62e9fd2011-07-11 15:20:48 -0700142 mDropTargetBar.setTranslationY(-mBarHeight);
Michael Jurka66b7d012013-11-06 16:37:34 +0100143 mDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "translationY",
Winson Chung17f1bb82012-05-25 14:25:44 -0700144 -mBarHeight, 0f);
Cristina Stancu476493b2013-08-07 17:20:14 +0100145
Winson Chung315b3ba2012-05-11 10:51:32 -0700146 } else {
147 mDropTargetBar.setAlpha(0f);
Michael Jurka66b7d012013-11-06 16:37:34 +0100148 mDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "alpha", 0f, 1f);
Winson Chunga62e9fd2011-07-11 15:20:48 -0700149 }
Winson Chung17f1bb82012-05-25 14:25:44 -0700150 setupAnimation(mDropTargetBarAnim, mDropTargetBar);
Winson Chung201bc822011-06-20 15:41:53 -0700151 }
152
Winson Chung043f2af2012-03-01 16:09:54 -0800153 public void finishAnimations() {
Winson Chung17f1bb82012-05-25 14:25:44 -0700154 prepareStartAnimation(mDropTargetBar);
155 mDropTargetBarAnim.reverse();
156 prepareStartAnimation(mQSBSearchBar);
157 mQSBSearchBarAnim.reverse();
Winson Chung4c98d922011-05-31 16:50:48 -0700158 }
159
160 /*
Winson Chungf0ea4d32011-06-06 14:27:16 -0700161 * Shows and hides the search bar.
162 */
163 public void showSearchBar(boolean animated) {
Mac Duy Hai8246a142013-10-16 13:46:04 +0100164 boolean needToCancelOngoingAnimation = mQSBSearchBarAnim.isRunning() && !animated;
165 if (!mIsSearchBarHidden && !needToCancelOngoingAnimation) return;
Winson Chungf0ea4d32011-06-06 14:27:16 -0700166 if (animated) {
Winson Chungc7d2b602012-05-16 17:02:20 -0700167 prepareStartAnimation(mQSBSearchBar);
Winson Chung17f1bb82012-05-25 14:25:44 -0700168 mQSBSearchBarAnim.reverse();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700169 } else {
Winson Chung17f1bb82012-05-25 14:25:44 -0700170 mQSBSearchBarAnim.cancel();
Adam Cohenc2d6e892014-10-16 09:49:24 -0700171 if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
Michael Jurka19e33472012-05-14 20:41:52 -0700172 mQSBSearchBar.setTranslationY(0);
Adam Cohenc2d6e892014-10-16 09:49:24 -0700173 } else if (mQSBSearchBar != null) {
Michael Jurka324dbdd2012-06-18 14:31:28 -0700174 mQSBSearchBar.setAlpha(1f);
Michael Jurka19e33472012-05-14 20:41:52 -0700175 }
Winson Chungf0ea4d32011-06-06 14:27:16 -0700176 }
177 mIsSearchBarHidden = false;
178 }
179 public void hideSearchBar(boolean animated) {
Mac Duy Hai8246a142013-10-16 13:46:04 +0100180 boolean needToCancelOngoingAnimation = mQSBSearchBarAnim.isRunning() && !animated;
181 if (mIsSearchBarHidden && !needToCancelOngoingAnimation) return;
Winson Chungf0ea4d32011-06-06 14:27:16 -0700182 if (animated) {
Winson Chungc7d2b602012-05-16 17:02:20 -0700183 prepareStartAnimation(mQSBSearchBar);
Winson Chung17f1bb82012-05-25 14:25:44 -0700184 mQSBSearchBarAnim.start();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700185 } else {
Winson Chung17f1bb82012-05-25 14:25:44 -0700186 mQSBSearchBarAnim.cancel();
Adam Cohenc2d6e892014-10-16 09:49:24 -0700187 if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
Winson Chung17f1bb82012-05-25 14:25:44 -0700188 mQSBSearchBar.setTranslationY(-mBarHeight);
Adam Cohenc2d6e892014-10-16 09:49:24 -0700189 } else if (mQSBSearchBar != null) {
Michael Jurka324dbdd2012-06-18 14:31:28 -0700190 mQSBSearchBar.setAlpha(0f);
Michael Jurka19e33472012-05-14 20:41:52 -0700191 }
Winson Chungf0ea4d32011-06-06 14:27:16 -0700192 }
193 mIsSearchBarHidden = true;
194 }
195
196 /*
197 * Gets various transition durations.
198 */
199 public int getTransitionInDuration() {
200 return sTransitionInDuration;
201 }
202 public int getTransitionOutDuration() {
203 return sTransitionOutDuration;
204 }
205
206 /*
Winson Chung4c98d922011-05-31 16:50:48 -0700207 * DragController.DragListener implementation
208 */
209 @Override
210 public void onDragStart(DragSource source, Object info, int dragAction) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800211 showDeleteTarget();
212 }
213
214 public void showDeleteTarget() {
Winson Chung4c98d922011-05-31 16:50:48 -0700215 // Animate out the QSB search bar, and animate in the drop target bar
Winson Chungc7d2b602012-05-16 17:02:20 -0700216 prepareStartAnimation(mDropTargetBar);
Winson Chung17f1bb82012-05-25 14:25:44 -0700217 mDropTargetBarAnim.start();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700218 if (!mIsSearchBarHidden) {
Winson Chungc7d2b602012-05-16 17:02:20 -0700219 prepareStartAnimation(mQSBSearchBar);
Winson Chung17f1bb82012-05-25 14:25:44 -0700220 mQSBSearchBarAnim.start();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700221 }
Winson Chung4c98d922011-05-31 16:50:48 -0700222 }
223
Adam Cohenc9735cf2015-01-23 16:11:55 -0800224 public void hideDeleteTarget() {
225 // Restore the QSB search bar, and animate out the drop target bar
226 prepareStartAnimation(mDropTargetBar);
227 mDropTargetBarAnim.reverse();
228 if (!mIsSearchBarHidden) {
229 prepareStartAnimation(mQSBSearchBar);
230 mQSBSearchBarAnim.reverse();
231 }
232 }
233
Adam Cohend4d7aa52011-07-19 21:47:37 -0700234 public void deferOnDragEnd() {
235 mDeferOnDragEnd = true;
236 }
237
Winson Chung4c98d922011-05-31 16:50:48 -0700238 @Override
239 public void onDragEnd() {
Adam Cohend4d7aa52011-07-19 21:47:37 -0700240 if (!mDeferOnDragEnd) {
Adam Cohenc9735cf2015-01-23 16:11:55 -0800241 hideDeleteTarget();
Adam Cohend4d7aa52011-07-19 21:47:37 -0700242 } else {
243 mDeferOnDragEnd = false;
Winson Chungf0ea4d32011-06-06 14:27:16 -0700244 }
Winson Chung4c98d922011-05-31 16:50:48 -0700245 }
Winson Chungc51db6a2011-10-05 11:44:49 -0700246
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +0100247 public Rect getSearchBarBounds() {
248 if (mQSBSearchBar != null) {
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +0100249 final int[] pos = new int[2];
250 mQSBSearchBar.getLocationOnScreen(pos);
251
252 final Rect rect = new Rect();
Michael Jurka629758f2012-06-14 16:18:21 -0700253 rect.left = pos[0];
254 rect.top = pos[1];
255 rect.right = pos[0] + mQSBSearchBar.getWidth();
256 rect.bottom = pos[1] + mQSBSearchBar.getHeight();
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +0100257 return rect;
258 } else {
259 return null;
260 }
261 }
Winson Chung4c98d922011-05-31 16:50:48 -0700262}