blob: 8331c73723d528dd815610263f787b3da8b02569 [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;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080021import android.animation.AnimatorSet;
22import android.animation.ObjectAnimator;
23import android.animation.TimeInterpolator;
Winson Chung4c98d922011-05-31 16:50:48 -070024import android.content.Context;
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +010025import android.graphics.Rect;
Winson Chung4c98d922011-05-31 16:50:48 -070026import android.util.AttributeSet;
27import android.view.View;
Winson Chung006ee262015-08-03 14:40:11 -070028import android.view.accessibility.AccessibilityManager;
Winson Chunga62e9fd2011-07-11 15:20:48 -070029import android.view.animation.AccelerateInterpolator;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080030import android.view.animation.DecelerateInterpolator;
Winson Chung4c98d922011-05-31 16:50:48 -070031
Vadim Tryshevfedca432015-08-19 17:55:02 -070032import com.android.launcher3.dragndrop.DragController;
Sunny Goyald1ea63f2015-08-05 12:32:47 -070033import com.android.launcher3.util.Thunk;
34
Winson Chung4c98d922011-05-31 16:50:48 -070035/*
Tony Wickhamb54c4a32015-09-11 08:40:20 -070036 * This bar will manage the transition between the QSB search bar and the delete/uninstall drop
37 * targets so that each of the individual ButtonDropTargets don't have to.
Winson Chung4c98d922011-05-31 16:50:48 -070038 */
Tony Wickhamb54c4a32015-09-11 08:40:20 -070039public class SearchDropTargetBar extends BaseDropTargetBar {
Winson Chung4c98d922011-05-31 16:50:48 -070040
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080041 private static final TimeInterpolator MOVE_DOWN_INTERPOLATOR = new DecelerateInterpolator(0.6f);
42 private static final TimeInterpolator MOVE_UP_INTERPOLATOR = new DecelerateInterpolator(1.5f);
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080043
Winson Chung006ee262015-08-03 14:40:11 -070044 /** The different states that the search bar space can be in. */
45 public enum State {
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080046 INVISIBLE (0f, 0f, 0f),
47 INVISIBLE_TRANSLATED (0f, 0f, -1f),
48 SEARCH_BAR (1f, 0f, 0f),
49 DROP_TARGET (0f, 1f, 0f);
Winson Chung4c98d922011-05-31 16:50:48 -070050
Winson Chung006ee262015-08-03 14:40:11 -070051 private final float mSearchBarAlpha;
52 private final float mDropTargetBarAlpha;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080053 private final float mTranslation;
Winson Chung006ee262015-08-03 14:40:11 -070054
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080055 State(float sbAlpha, float dtbAlpha, float translation) {
Winson Chung006ee262015-08-03 14:40:11 -070056 mSearchBarAlpha = sbAlpha;
57 mDropTargetBarAlpha = dtbAlpha;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080058 mTranslation = translation;
Winson Chung006ee262015-08-03 14:40:11 -070059 }
60
Winson Chung006ee262015-08-03 14:40:11 -070061 }
62
Winson Chung006ee262015-08-03 14:40:11 -070063
Winson Chung006ee262015-08-03 14:40:11 -070064 private State mState = State.SEARCH_BAR;
Sunny Goyald1ea63f2015-08-05 12:32:47 -070065 @Thunk View mQSB;
Winson Chung4c98d922011-05-31 16:50:48 -070066
Sunny Goyalfa401a12015-04-10 13:45:42 -070067 // Drop targets
Sunny Goyalfa401a12015-04-10 13:45:42 -070068 private ButtonDropTarget mDeleteDropTarget;
69 private ButtonDropTarget mUninstallDropTarget;
70
Winson Chung4c98d922011-05-31 16:50:48 -070071 public SearchDropTargetBar(Context context, AttributeSet attrs) {
72 this(context, attrs, 0);
73 }
74
75 public SearchDropTargetBar(Context context, AttributeSet attrs, int defStyle) {
76 super(context, attrs, defStyle);
77 }
78
Winson Chung4c98d922011-05-31 16:50:48 -070079 @Override
80 protected void onFinishInflate() {
81 super.onFinishInflate();
82
83 // Get the individual components
Winson Chunga6427b12011-07-27 10:53:39 -070084 mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target_text);
Tony Wickhamb54c4a32015-09-11 08:40:20 -070085 mUninstallDropTarget = (ButtonDropTarget) mDropTargetBar
86 .findViewById(R.id.uninstall_target_text);
Winson Chunga62e9fd2011-07-11 15:20:48 -070087
Tony Wickhamb54c4a32015-09-11 08:40:20 -070088 mDeleteDropTarget.setDropTargetBar(this);
89 mUninstallDropTarget.setDropTargetBar(this);
90 }
Adam Cohend4d7aa52011-07-19 21:47:37 -070091
Tony Wickhamb54c4a32015-09-11 08:40:20 -070092 @Override
93 public void setup(Launcher launcher, DragController dragController) {
94 dragController.addDragListener(this);
95 dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
Winson Chung006ee262015-08-03 14:40:11 -070096
Tony Wickhamb54c4a32015-09-11 08:40:20 -070097 dragController.addDragListener(mDeleteDropTarget);
98 dragController.addDragListener(mUninstallDropTarget);
99
100 dragController.addDropTarget(mDeleteDropTarget);
101 dragController.addDropTarget(mUninstallDropTarget);
102
103 mDeleteDropTarget.setLauncher(launcher);
104 mUninstallDropTarget.setLauncher(launcher);
105 }
106
107 @Override
Tony Wickham9aae47f2015-10-01 13:04:22 -0700108 public void showDropTargets() {
Tony Wickhamb54c4a32015-09-11 08:40:20 -0700109 animateToState(State.DROP_TARGET, DEFAULT_DRAG_FADE_DURATION);
110 }
111
112 @Override
Tony Wickham9aae47f2015-10-01 13:04:22 -0700113 public void hideDropTargets() {
Tony Wickhamb54c4a32015-09-11 08:40:20 -0700114 animateToState(State.SEARCH_BAR, DEFAULT_DRAG_FADE_DURATION);
Winson Chung201bc822011-06-20 15:41:53 -0700115 }
116
Winson Chung006ee262015-08-03 14:40:11 -0700117 public void setQsbSearchBar(View qsb) {
118 mQSB = qsb;
Winson Chung006ee262015-08-03 14:40:11 -0700119 }
120
121 /**
122 * Animates the current search bar state to a new state. If the {@param duration} is 0, then
123 * the state is applied immediately.
124 */
125 public void animateToState(State newState, int duration) {
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800126 animateToState(newState, duration, null);
127 }
128
129 public void animateToState(State newState, int duration, AnimatorSet animation) {
Winson Chung006ee262015-08-03 14:40:11 -0700130 if (mState != newState) {
131 mState = newState;
132
Sunny Goyal7c50b312016-02-10 12:26:23 -0800133 resetAnimation(duration);
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800134 if (duration > 0) {
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800135 animateAlpha(mDropTargetBar, mState.mDropTargetBarAlpha, DEFAULT_INTERPOLATOR);
136 } else {
137 mDropTargetBar.setAlpha(mState.mDropTargetBarAlpha);
138 AlphaUpdateListener.updateVisibility(mDropTargetBar, mAccessibilityEnabled);
139 }
Winson Chung006ee262015-08-03 14:40:11 -0700140
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800141 if (mQSB != null) {
142 boolean isVertical = ((Launcher) getContext()).getDeviceProfile()
143 .isVerticalBarLayout();
144 float translation = isVertical ? 0 : mState.mTranslation * getMeasuredHeight();
145
146 if (duration > 0) {
147 int translationChange = Float.compare(mQSB.getTranslationY(), translation);
148
149 animateAlpha(mQSB, mState.mSearchBarAlpha,
150 translationChange == 0 ? DEFAULT_INTERPOLATOR
151 : (translationChange < 0 ? MOVE_DOWN_INTERPOLATOR
152 : MOVE_UP_INTERPOLATOR));
153
154 if (translationChange != 0) {
155 mCurrentAnimation.play(
156 ObjectAnimator.ofFloat(mQSB, View.TRANSLATION_Y, translation));
157 }
158 } else {
159 mQSB.setTranslationY(translation);
160 mQSB.setAlpha(mState.mSearchBarAlpha);
161 AlphaUpdateListener.updateVisibility(mQSB, mAccessibilityEnabled);
162 }
163 }
164
165 // Start the final animation
166 if (duration > 0) {
167 if (animation != null) {
168 animation.play(mCurrentAnimation);
169 } else {
170 mCurrentAnimation.start();
171 }
172 }
Winson Chung006ee262015-08-03 14:40:11 -0700173 }
174 }
175
176 /**
Winson Chung006ee262015-08-03 14:40:11 -0700177 * @return the bounds of the QSB search bar.
178 */
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +0100179 public Rect getSearchBarBounds() {
Winson Chung006ee262015-08-03 14:40:11 -0700180 if (mQSB != null) {
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +0100181 final int[] pos = new int[2];
Winson Chung006ee262015-08-03 14:40:11 -0700182 mQSB.getLocationOnScreen(pos);
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +0100183
184 final Rect rect = new Rect();
Michael Jurka629758f2012-06-14 16:18:21 -0700185 rect.left = pos[0];
186 rect.top = pos[1];
Winson Chung006ee262015-08-03 14:40:11 -0700187 rect.right = pos[0] + mQSB.getWidth();
188 rect.bottom = pos[1] + mQSB.getHeight();
Mathew Inwoodcf7f63b2011-10-13 11:31:38 +0100189 return rect;
190 } else {
191 return null;
192 }
193 }
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700194
Tony Wickhamb54c4a32015-09-11 08:40:20 -0700195 @Override
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700196 public void enableAccessibleDrag(boolean enable) {
Winson Chung006ee262015-08-03 14:40:11 -0700197 if (mQSB != null) {
198 mQSB.setVisibility(enable ? View.GONE : View.VISIBLE);
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700199 }
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700200 mDeleteDropTarget.enableAccessibleDrag(enable);
201 mUninstallDropTarget.enableAccessibleDrag(enable);
202 }
Winson Chung4c98d922011-05-31 16:50:48 -0700203}