blob: 153e3acc69d48ca8d9bdf0dfa2e44be170a2e419 [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
17package com.android.launcher2;
18
Winson Chung201bc822011-06-20 15:41:53 -070019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
Winson Chunga62e9fd2011-07-11 15:20:48 -070021import android.animation.AnimatorSet;
Winson Chung201bc822011-06-20 15:41:53 -070022import android.animation.ObjectAnimator;
Winson Chung4c98d922011-05-31 16:50:48 -070023import android.content.Context;
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +010024import android.graphics.Rect;
Winson Chungc51db6a2011-10-05 11:44:49 -070025import android.graphics.drawable.Drawable;
Winson Chung4c98d922011-05-31 16:50:48 -070026import android.util.AttributeSet;
27import android.view.View;
Winson Chunga62e9fd2011-07-11 15:20:48 -070028import android.view.animation.AccelerateInterpolator;
29import android.view.animation.DecelerateInterpolator;
Winson Chung4c98d922011-05-31 16:50:48 -070030import android.widget.FrameLayout;
31
32import com.android.launcher.R;
33
34/*
35 * Ths bar will manage the transition between the QSB search bar and the delete drop
36 * targets so that each of the individual IconDropTargets don't have to.
37 */
38public class SearchDropTargetBar extends FrameLayout implements DragController.DragListener {
39
Winson Chunga62e9fd2011-07-11 15:20:48 -070040 private static final int sTransitionInDuration = 200;
41 private static final int sTransitionOutDuration = 175;
Winson Chung4c98d922011-05-31 16:50:48 -070042
Winson Chung315b3ba2012-05-11 10:51:32 -070043 private ObjectAnimator mDropTargetBarFadeInAnim;
44 private ObjectAnimator mDropTargetBarFadeOutAnim;
Winson Chung201bc822011-06-20 15:41:53 -070045 private ObjectAnimator mQSBSearchBarFadeInAnim;
46 private ObjectAnimator mQSBSearchBarFadeOutAnim;
47
Winson Chungf0ea4d32011-06-06 14:27:16 -070048 private boolean mIsSearchBarHidden;
Winson Chung4c98d922011-05-31 16:50:48 -070049 private View mQSBSearchBar;
50 private View mDropTargetBar;
Winson Chung61fa4192011-06-12 15:15:29 -070051 private ButtonDropTarget mInfoDropTarget;
52 private ButtonDropTarget mDeleteDropTarget;
Winson Chunga62e9fd2011-07-11 15:20:48 -070053 private int mBarHeight;
Adam Cohend4d7aa52011-07-19 21:47:37 -070054 private boolean mDeferOnDragEnd = false;
Winson Chung4c98d922011-05-31 16:50:48 -070055
Winson Chungc51db6a2011-10-05 11:44:49 -070056 private Drawable mPreviousBackground;
57
Winson Chung4c98d922011-05-31 16:50:48 -070058 public SearchDropTargetBar(Context context, AttributeSet attrs) {
59 this(context, attrs, 0);
60 }
61
62 public SearchDropTargetBar(Context context, AttributeSet attrs, int defStyle) {
63 super(context, attrs, defStyle);
64 }
65
66 public void setup(Launcher launcher, DragController dragController) {
67 dragController.addDragListener(this);
68 dragController.addDragListener(mInfoDropTarget);
69 dragController.addDragListener(mDeleteDropTarget);
70 dragController.addDropTarget(mInfoDropTarget);
71 dragController.addDropTarget(mDeleteDropTarget);
Winson Chung043f2af2012-03-01 16:09:54 -080072 dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
Winson Chung4c98d922011-05-31 16:50:48 -070073 mInfoDropTarget.setLauncher(launcher);
74 mDeleteDropTarget.setLauncher(launcher);
75 }
76
Winson Chung315b3ba2012-05-11 10:51:32 -070077 private void prepareAnimation(ObjectAnimator in, ObjectAnimator out, final View v) {
78 in.setInterpolator(new AccelerateInterpolator());
79 in.setDuration(sTransitionInDuration);
80 in.addListener(new AnimatorListenerAdapter() {
81 @Override
82 public void onAnimationStart(Animator animation) {
83 v.setVisibility(View.VISIBLE);
84 }
85 });
86 out.setInterpolator(new DecelerateInterpolator());
87 out.setDuration(sTransitionOutDuration);
88 out.addListener(new AnimatorListenerAdapter() {
89 @Override
90 public void onAnimationEnd(Animator animation) {
91 v.setVisibility(View.INVISIBLE);
92 v.setLayerType(View.LAYER_TYPE_NONE, null);
93 }
94 });
95 }
96
Winson Chung4c98d922011-05-31 16:50:48 -070097 @Override
98 protected void onFinishInflate() {
99 super.onFinishInflate();
100
101 // Get the individual components
102 mQSBSearchBar = findViewById(R.id.qsb_search_bar);
103 mDropTargetBar = findViewById(R.id.drag_target_bar);
Winson Chunga6427b12011-07-27 10:53:39 -0700104 mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target_text);
105 mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target_text);
Winson Chunga62e9fd2011-07-11 15:20:48 -0700106 mBarHeight = getResources().getDimensionPixelSize(R.dimen.qsb_bar_height);
107
Adam Cohend4d7aa52011-07-19 21:47:37 -0700108 mInfoDropTarget.setSearchDropTargetBar(this);
109 mDeleteDropTarget.setSearchDropTargetBar(this);
110
Winson Chunga62e9fd2011-07-11 15:20:48 -0700111 boolean enableDropDownDropTargets =
112 getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
Winson Chung201bc822011-06-20 15:41:53 -0700113
114 // Create the various fade animations
Winson Chunga62e9fd2011-07-11 15:20:48 -0700115 if (enableDropDownDropTargets) {
116 mDropTargetBar.setTranslationY(-mBarHeight);
Winson Chung315b3ba2012-05-11 10:51:32 -0700117 mDropTargetBarFadeInAnim = ObjectAnimator.ofFloat(mDropTargetBar, "translationY", 0f);
118 mDropTargetBarFadeOutAnim = ObjectAnimator.ofFloat(mDropTargetBar, "translationY",
119 -mBarHeight);
120 mQSBSearchBarFadeInAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "translationY", 0);
121 mQSBSearchBarFadeOutAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "translationY",
122 -mBarHeight);
123 } else {
124 mDropTargetBar.setAlpha(0f);
125 mDropTargetBarFadeInAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 1f);
126 mDropTargetBarFadeOutAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 0f);
127 mQSBSearchBarFadeInAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 1f);
128 mQSBSearchBarFadeOutAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 0f);
Winson Chunga62e9fd2011-07-11 15:20:48 -0700129 }
Winson Chung315b3ba2012-05-11 10:51:32 -0700130 prepareAnimation(mDropTargetBarFadeInAnim, mDropTargetBarFadeOutAnim, mDropTargetBar);
131 prepareAnimation(mQSBSearchBarFadeInAnim, mQSBSearchBarFadeOutAnim, mQSBSearchBar);
Winson Chung201bc822011-06-20 15:41:53 -0700132 }
133
Winson Chung043f2af2012-03-01 16:09:54 -0800134 public void finishAnimations() {
135 mDropTargetBarFadeInAnim.end();
136 mDropTargetBarFadeOutAnim.end();
137 mQSBSearchBarFadeInAnim.end();
138 mQSBSearchBarFadeOutAnim.end();
139 }
140
Winson Chung201bc822011-06-20 15:41:53 -0700141 private void cancelAnimations() {
142 mDropTargetBarFadeInAnim.cancel();
143 mDropTargetBarFadeOutAnim.cancel();
144 mQSBSearchBarFadeInAnim.cancel();
145 mQSBSearchBarFadeOutAnim.cancel();
Winson Chung4c98d922011-05-31 16:50:48 -0700146 }
147
148 /*
Winson Chungf0ea4d32011-06-06 14:27:16 -0700149 * Shows and hides the search bar.
150 */
151 public void showSearchBar(boolean animated) {
Winson Chung201bc822011-06-20 15:41:53 -0700152 cancelAnimations();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700153 if (animated) {
Winson Chung201bc822011-06-20 15:41:53 -0700154 mQSBSearchBarFadeInAnim.start();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700155 } else {
Winson Chung201bc822011-06-20 15:41:53 -0700156 mQSBSearchBar.setVisibility(View.VISIBLE);
Winson Chungf0ea4d32011-06-06 14:27:16 -0700157 mQSBSearchBar.setAlpha(1f);
Winson Chung73b36a82012-05-14 11:03:49 -0700158 mQSBSearchBar.setTranslationY(0);
Winson Chungf0ea4d32011-06-06 14:27:16 -0700159 }
160 mIsSearchBarHidden = false;
161 }
162 public void hideSearchBar(boolean animated) {
Winson Chung201bc822011-06-20 15:41:53 -0700163 cancelAnimations();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700164 if (animated) {
Winson Chung201bc822011-06-20 15:41:53 -0700165 mQSBSearchBarFadeOutAnim.start();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700166 } else {
Michael Jurka81efbad2011-11-03 13:50:45 -0700167 mQSBSearchBar.setVisibility(View.INVISIBLE);
Winson Chungf0ea4d32011-06-06 14:27:16 -0700168 mQSBSearchBar.setAlpha(0f);
Winson Chung73b36a82012-05-14 11:03:49 -0700169 mQSBSearchBar.setTranslationY(0);
Winson Chungf0ea4d32011-06-06 14:27:16 -0700170 }
171 mIsSearchBarHidden = true;
172 }
173
174 /*
175 * Gets various transition durations.
176 */
177 public int getTransitionInDuration() {
178 return sTransitionInDuration;
179 }
180 public int getTransitionOutDuration() {
181 return sTransitionOutDuration;
182 }
183
184 /*
Winson Chung4c98d922011-05-31 16:50:48 -0700185 * DragController.DragListener implementation
186 */
187 @Override
188 public void onDragStart(DragSource source, Object info, int dragAction) {
189 // Animate out the QSB search bar, and animate in the drop target bar
Winson Chunga62e9fd2011-07-11 15:20:48 -0700190 mDropTargetBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
191 mDropTargetBar.buildLayer();
192 mDropTargetBarFadeOutAnim.cancel();
Winson Chung201bc822011-06-20 15:41:53 -0700193 mDropTargetBarFadeInAnim.start();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700194 if (!mIsSearchBarHidden) {
Winson Chunga62e9fd2011-07-11 15:20:48 -0700195 mQSBSearchBarFadeInAnim.cancel();
Winson Chung201bc822011-06-20 15:41:53 -0700196 mQSBSearchBarFadeOutAnim.start();
Winson Chungf0ea4d32011-06-06 14:27:16 -0700197 }
Winson Chung4c98d922011-05-31 16:50:48 -0700198 }
199
Adam Cohend4d7aa52011-07-19 21:47:37 -0700200 public void deferOnDragEnd() {
201 mDeferOnDragEnd = true;
202 }
203
Winson Chung4c98d922011-05-31 16:50:48 -0700204 @Override
205 public void onDragEnd() {
Adam Cohend4d7aa52011-07-19 21:47:37 -0700206 if (!mDeferOnDragEnd) {
207 // Restore the QSB search bar, and animate out the drop target bar
208 mDropTargetBarFadeInAnim.cancel();
209 mDropTargetBarFadeOutAnim.start();
210 if (!mIsSearchBarHidden) {
211 mQSBSearchBarFadeOutAnim.cancel();
212 mQSBSearchBarFadeInAnim.start();
213 }
214 } else {
215 mDeferOnDragEnd = false;
Winson Chungf0ea4d32011-06-06 14:27:16 -0700216 }
Winson Chung4c98d922011-05-31 16:50:48 -0700217 }
Winson Chungc51db6a2011-10-05 11:44:49 -0700218
219 public void onSearchPackagesChanged(boolean searchVisible, boolean voiceVisible) {
220 if (mQSBSearchBar != null) {
221 Drawable bg = mQSBSearchBar.getBackground();
222 if (bg != null && (!searchVisible && !voiceVisible)) {
223 // Save the background and disable it
224 mPreviousBackground = bg;
225 mQSBSearchBar.setBackgroundResource(0);
226 } else if (mPreviousBackground != null && (searchVisible || voiceVisible)) {
227 // Restore the background
Michael Jurka3a9fced2012-04-13 14:44:29 -0700228 mQSBSearchBar.setBackground(mPreviousBackground);
Winson Chungc51db6a2011-10-05 11:44:49 -0700229 }
230 }
231 }
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +0100232
233 public Rect getSearchBarBounds() {
234 if (mQSBSearchBar != null) {
235 final float appScale = mQSBSearchBar.getContext().getResources()
236 .getCompatibilityInfo().applicationScale;
237 final int[] pos = new int[2];
238 mQSBSearchBar.getLocationOnScreen(pos);
239
240 final Rect rect = new Rect();
241 rect.left = (int) (pos[0] * appScale + 0.5f);
242 rect.top = (int) (pos[1] * appScale + 0.5f);
243 rect.right = (int) ((pos[0] + mQSBSearchBar.getWidth()) * appScale + 0.5f);
244 rect.bottom = (int) ((pos[1] + mQSBSearchBar.getHeight()) * appScale + 0.5f);
245 return rect;
246 } else {
247 return null;
248 }
249 }
Winson Chung4c98d922011-05-31 16:50:48 -0700250}