1 /* 2 * Copyright (C) 2018 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 17 package com.android.quickstep.views; 18 19 import android.content.Context; 20 import android.util.AttributeSet; 21 import android.util.FloatProperty; 22 import android.widget.Button; 23 24 import com.android.launcher3.DeviceProfile; 25 import com.android.launcher3.statemanager.StatefulActivity; 26 import com.android.launcher3.touch.PagedOrientationHandler; 27 28 public class ClearAllButton extends Button { 29 30 public static final FloatProperty<ClearAllButton> VISIBILITY_ALPHA = 31 new FloatProperty<ClearAllButton>("visibilityAlpha") { 32 @Override 33 public Float get(ClearAllButton view) { 34 return view.mVisibilityAlpha; 35 } 36 37 @Override 38 public void setValue(ClearAllButton view, float v) { 39 view.setVisibilityAlpha(v); 40 } 41 }; 42 43 public static final FloatProperty<ClearAllButton> DISMISS_ALPHA = 44 new FloatProperty<ClearAllButton>("dismissAlpha") { 45 @Override 46 public Float get(ClearAllButton view) { 47 return view.mDismissAlpha; 48 } 49 50 @Override 51 public void setValue(ClearAllButton view, float v) { 52 view.setDismissAlpha(v); 53 } 54 }; 55 56 private final StatefulActivity mActivity; 57 private float mScrollAlpha = 1; 58 private float mContentAlpha = 1; 59 private float mVisibilityAlpha = 1; 60 private float mDismissAlpha = 1; 61 private float mFullscreenProgress = 1; 62 private float mGridProgress = 1; 63 64 private boolean mIsRtl; 65 private float mNormalTranslationPrimary; 66 private float mFullscreenTranslationPrimary; 67 private float mGridTranslationPrimary; 68 private float mGridScrollOffset; 69 private float mScrollOffsetPrimary; 70 private float mSplitSelectScrollOffsetPrimary; 71 72 private int mSidePadding; 73 ClearAllButton(Context context, AttributeSet attrs)74 public ClearAllButton(Context context, AttributeSet attrs) { 75 super(context, attrs); 76 mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 77 mActivity = StatefulActivity.fromContext(context); 78 } 79 80 @Override onLayout(boolean changed, int left, int top, int right, int bottom)81 protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 82 super.onLayout(changed, left, top, right, bottom); 83 PagedOrientationHandler orientationHandler = getRecentsView().getPagedOrientationHandler(); 84 mSidePadding = orientationHandler.getClearAllSidePadding(getRecentsView(), mIsRtl); 85 } 86 getRecentsView()87 private RecentsView getRecentsView() { 88 return (RecentsView) getParent(); 89 } 90 91 @Override onRtlPropertiesChanged(int layoutDirection)92 public void onRtlPropertiesChanged(int layoutDirection) { 93 super.onRtlPropertiesChanged(layoutDirection); 94 mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 95 } 96 97 @Override hasOverlappingRendering()98 public boolean hasOverlappingRendering() { 99 return false; 100 } 101 setContentAlpha(float alpha)102 public void setContentAlpha(float alpha) { 103 if (mContentAlpha != alpha) { 104 mContentAlpha = alpha; 105 updateAlpha(); 106 } 107 } 108 setVisibilityAlpha(float alpha)109 public void setVisibilityAlpha(float alpha) { 110 if (mVisibilityAlpha != alpha) { 111 mVisibilityAlpha = alpha; 112 updateAlpha(); 113 } 114 } 115 setDismissAlpha(float alpha)116 public void setDismissAlpha(float alpha) { 117 if (mDismissAlpha != alpha) { 118 mDismissAlpha = alpha; 119 updateAlpha(); 120 } 121 } 122 onRecentsViewScroll(int scroll, boolean gridEnabled)123 public void onRecentsViewScroll(int scroll, boolean gridEnabled) { 124 RecentsView recentsView = getRecentsView(); 125 if (recentsView == null) { 126 return; 127 } 128 129 PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); 130 float orientationSize = orientationHandler.getPrimaryValue(getWidth(), getHeight()); 131 if (orientationSize == 0) { 132 return; 133 } 134 135 int clearAllScroll = recentsView.getClearAllScroll(); 136 int adjustedScrollFromEdge = Math.abs(scroll - clearAllScroll); 137 float shift = Math.min(adjustedScrollFromEdge, orientationSize); 138 mNormalTranslationPrimary = mIsRtl ? -shift : shift; 139 if (!gridEnabled) { 140 mNormalTranslationPrimary += mSidePadding; 141 } 142 applyPrimaryTranslation(); 143 applySecondaryTranslation(); 144 mScrollAlpha = 1 - shift / orientationSize; 145 updateAlpha(); 146 } 147 updateAlpha()148 private void updateAlpha() { 149 final float alpha = mScrollAlpha * mContentAlpha * mVisibilityAlpha * mDismissAlpha; 150 setAlpha(alpha); 151 setClickable(Math.min(alpha, 1) == 1); 152 } 153 setFullscreenTranslationPrimary(float fullscreenTranslationPrimary)154 public void setFullscreenTranslationPrimary(float fullscreenTranslationPrimary) { 155 mFullscreenTranslationPrimary = fullscreenTranslationPrimary; 156 applyPrimaryTranslation(); 157 } 158 setGridTranslationPrimary(float gridTranslationPrimary)159 public void setGridTranslationPrimary(float gridTranslationPrimary) { 160 mGridTranslationPrimary = gridTranslationPrimary; 161 applyPrimaryTranslation(); 162 } 163 setGridScrollOffset(float gridScrollOffset)164 public void setGridScrollOffset(float gridScrollOffset) { 165 mGridScrollOffset = gridScrollOffset; 166 } 167 setScrollOffsetPrimary(float scrollOffsetPrimary)168 public void setScrollOffsetPrimary(float scrollOffsetPrimary) { 169 mScrollOffsetPrimary = scrollOffsetPrimary; 170 } 171 setSplitSelectScrollOffsetPrimary(float splitSelectScrollOffsetPrimary)172 public void setSplitSelectScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) { 173 mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary; 174 } 175 getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled)176 public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { 177 float scrollAdjustment = 0; 178 if (fullscreenEnabled) { 179 scrollAdjustment += mFullscreenTranslationPrimary; 180 } 181 if (gridEnabled) { 182 scrollAdjustment += mGridTranslationPrimary + mGridScrollOffset; 183 } 184 scrollAdjustment += mScrollOffsetPrimary; 185 scrollAdjustment += mSplitSelectScrollOffsetPrimary; 186 return scrollAdjustment; 187 } 188 getOffsetAdjustment(boolean fullscreenEnabled, boolean gridEnabled)189 public float getOffsetAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { 190 return getScrollAdjustment(fullscreenEnabled, gridEnabled); 191 } 192 193 /** 194 * Adjust translation when this TaskView is about to be shown fullscreen. 195 * 196 * @param progress: 0 = no translation; 1 = translate according to TaskVIew translations. 197 */ setFullscreenProgress(float progress)198 public void setFullscreenProgress(float progress) { 199 mFullscreenProgress = progress; 200 applyPrimaryTranslation(); 201 } 202 203 /** 204 * Moves ClearAllButton between carousel and 2 row grid. 205 * 206 * @param gridProgress 0 = carousel; 1 = 2 row grid. 207 */ setGridProgress(float gridProgress)208 public void setGridProgress(float gridProgress) { 209 mGridProgress = gridProgress; 210 applyPrimaryTranslation(); 211 } 212 applyPrimaryTranslation()213 private void applyPrimaryTranslation() { 214 RecentsView recentsView = getRecentsView(); 215 if (recentsView == null) { 216 return; 217 } 218 219 PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); 220 orientationHandler.getPrimaryViewTranslate().set(this, 221 orientationHandler.getPrimaryValue(0f, getOriginalTranslationY()) 222 + mNormalTranslationPrimary + getFullscreenTrans( 223 mFullscreenTranslationPrimary) + getGridTrans(mGridTranslationPrimary)); 224 } 225 applySecondaryTranslation()226 private void applySecondaryTranslation() { 227 RecentsView recentsView = getRecentsView(); 228 if (recentsView == null) { 229 return; 230 } 231 232 PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); 233 orientationHandler.getSecondaryViewTranslate().set(this, 234 orientationHandler.getSecondaryValue(0f, getOriginalTranslationY())); 235 } 236 getFullscreenTrans(float endTranslation)237 private float getFullscreenTrans(float endTranslation) { 238 return mFullscreenProgress > 0 ? endTranslation : 0; 239 } 240 getGridTrans(float endTranslation)241 private float getGridTrans(float endTranslation) { 242 return mGridProgress > 0 ? endTranslation : 0; 243 } 244 245 /** 246 * Get the Y translation that is set in the original layout position, before scrolling. 247 */ getOriginalTranslationY()248 private float getOriginalTranslationY() { 249 DeviceProfile deviceProfile = mActivity.getDeviceProfile(); 250 return deviceProfile.overviewShowAsGrid 251 ? deviceProfile.overviewRowSpacing 252 : deviceProfile.overviewTaskThumbnailTopMarginPx / 2.0f; 253 } 254 } 255