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 71 private int mSidePadding; 72 ClearAllButton(Context context, AttributeSet attrs)73 public ClearAllButton(Context context, AttributeSet attrs) { 74 super(context, attrs); 75 mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 76 mActivity = StatefulActivity.fromContext(context); 77 } 78 79 @Override onLayout(boolean changed, int left, int top, int right, int bottom)80 protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 81 super.onLayout(changed, left, top, right, bottom); 82 PagedOrientationHandler orientationHandler = getRecentsView().getPagedOrientationHandler(); 83 mSidePadding = orientationHandler.getClearAllSidePadding(getRecentsView(), mIsRtl); 84 } 85 getRecentsView()86 private RecentsView getRecentsView() { 87 return (RecentsView) getParent(); 88 } 89 90 @Override onRtlPropertiesChanged(int layoutDirection)91 public void onRtlPropertiesChanged(int layoutDirection) { 92 super.onRtlPropertiesChanged(layoutDirection); 93 mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 94 } 95 96 @Override hasOverlappingRendering()97 public boolean hasOverlappingRendering() { 98 return false; 99 } 100 getScrollAlpha()101 public float getScrollAlpha() { 102 return mScrollAlpha; 103 } 104 setContentAlpha(float alpha)105 public void setContentAlpha(float alpha) { 106 if (mContentAlpha != alpha) { 107 mContentAlpha = alpha; 108 updateAlpha(); 109 } 110 } 111 setVisibilityAlpha(float alpha)112 public void setVisibilityAlpha(float alpha) { 113 if (mVisibilityAlpha != alpha) { 114 mVisibilityAlpha = alpha; 115 updateAlpha(); 116 } 117 } 118 setDismissAlpha(float alpha)119 public void setDismissAlpha(float alpha) { 120 if (mDismissAlpha != alpha) { 121 mDismissAlpha = alpha; 122 updateAlpha(); 123 } 124 } 125 onRecentsViewScroll(int scroll, boolean gridEnabled)126 public void onRecentsViewScroll(int scroll, boolean gridEnabled) { 127 RecentsView recentsView = getRecentsView(); 128 if (recentsView == null) { 129 return; 130 } 131 132 PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); 133 float orientationSize = orientationHandler.getPrimaryValue(getWidth(), getHeight()); 134 if (orientationSize == 0) { 135 return; 136 } 137 138 int clearAllScroll = recentsView.getClearAllScroll(); 139 int adjustedScrollFromEdge = Math.abs(scroll - clearAllScroll); 140 float shift = Math.min(adjustedScrollFromEdge, orientationSize); 141 mNormalTranslationPrimary = mIsRtl ? -shift : shift; 142 if (!gridEnabled) { 143 mNormalTranslationPrimary += mSidePadding; 144 } 145 applyPrimaryTranslation(); 146 applySecondaryTranslation(); 147 float clearAllSpacing = 148 recentsView.getPageSpacing() + recentsView.getClearAllExtraPageSpacing(); 149 clearAllSpacing = mIsRtl ? -clearAllSpacing : clearAllSpacing; 150 mScrollAlpha = Math.max((clearAllScroll + clearAllSpacing - scroll) / clearAllSpacing, 0); 151 updateAlpha(); 152 } 153 updateAlpha()154 private void updateAlpha() { 155 final float alpha = mScrollAlpha * mContentAlpha * mVisibilityAlpha * mDismissAlpha; 156 setAlpha(alpha); 157 setClickable(Math.min(alpha, 1) == 1); 158 } 159 setFullscreenTranslationPrimary(float fullscreenTranslationPrimary)160 public void setFullscreenTranslationPrimary(float fullscreenTranslationPrimary) { 161 mFullscreenTranslationPrimary = fullscreenTranslationPrimary; 162 applyPrimaryTranslation(); 163 } 164 setGridTranslationPrimary(float gridTranslationPrimary)165 public void setGridTranslationPrimary(float gridTranslationPrimary) { 166 mGridTranslationPrimary = gridTranslationPrimary; 167 applyPrimaryTranslation(); 168 } 169 setGridScrollOffset(float gridScrollOffset)170 public void setGridScrollOffset(float gridScrollOffset) { 171 mGridScrollOffset = gridScrollOffset; 172 } 173 setScrollOffsetPrimary(float scrollOffsetPrimary)174 public void setScrollOffsetPrimary(float scrollOffsetPrimary) { 175 mScrollOffsetPrimary = scrollOffsetPrimary; 176 } 177 getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled)178 public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { 179 float scrollAdjustment = 0; 180 if (fullscreenEnabled) { 181 scrollAdjustment += mFullscreenTranslationPrimary; 182 } 183 if (gridEnabled) { 184 scrollAdjustment += mGridTranslationPrimary + mGridScrollOffset; 185 } 186 scrollAdjustment += mScrollOffsetPrimary; 187 return scrollAdjustment; 188 } 189 getOffsetAdjustment(boolean fullscreenEnabled, boolean gridEnabled)190 public float getOffsetAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { 191 return getScrollAdjustment(fullscreenEnabled, gridEnabled); 192 } 193 194 /** 195 * Adjust translation when this TaskView is about to be shown fullscreen. 196 * 197 * @param progress: 0 = no translation; 1 = translate according to TaskVIew translations. 198 */ setFullscreenProgress(float progress)199 public void setFullscreenProgress(float progress) { 200 mFullscreenProgress = progress; 201 applyPrimaryTranslation(); 202 } 203 204 /** 205 * Moves ClearAllButton between carousel and 2 row grid. 206 * 207 * @param gridProgress 0 = carousel; 1 = 2 row grid. 208 */ setGridProgress(float gridProgress)209 public void setGridProgress(float gridProgress) { 210 mGridProgress = gridProgress; 211 applyPrimaryTranslation(); 212 } 213 applyPrimaryTranslation()214 private void applyPrimaryTranslation() { 215 RecentsView recentsView = getRecentsView(); 216 if (recentsView == null) { 217 return; 218 } 219 220 PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); 221 orientationHandler.getPrimaryViewTranslate().set(this, 222 orientationHandler.getPrimaryValue(0f, getOriginalTranslationY()) 223 + mNormalTranslationPrimary + getFullscreenTrans( 224 mFullscreenTranslationPrimary) + getGridTrans(mGridTranslationPrimary)); 225 } 226 applySecondaryTranslation()227 private void applySecondaryTranslation() { 228 RecentsView recentsView = getRecentsView(); 229 if (recentsView == null) { 230 return; 231 } 232 233 PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); 234 orientationHandler.getSecondaryViewTranslate().set(this, 235 orientationHandler.getSecondaryValue(0f, getOriginalTranslationY())); 236 } 237 getFullscreenTrans(float endTranslation)238 private float getFullscreenTrans(float endTranslation) { 239 return mFullscreenProgress > 0 ? endTranslation : 0; 240 } 241 getGridTrans(float endTranslation)242 private float getGridTrans(float endTranslation) { 243 return mGridProgress > 0 ? endTranslation : 0; 244 } 245 246 /** 247 * Get the Y translation that is set in the original layout position, before scrolling. 248 */ getOriginalTranslationY()249 private float getOriginalTranslationY() { 250 DeviceProfile deviceProfile = mActivity.getDeviceProfile(); 251 return deviceProfile.isTablet 252 ? deviceProfile.overviewRowSpacing 253 : deviceProfile.overviewTaskThumbnailTopMarginPx / 2.0f; 254 } 255 } 256