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