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