Replace taskbar hotseat with real hotseat when folder is open
- Seamlessly show real hotseat and hide taskbar hotseat, while
keeping rest of taskbar visible
- Update MultiValueAlpha to allow for taking max alpha instead
of blending, and use that for Hotseat
- Fix folder open bounds on home screen when taskbar is present
Test: Open folder from taskbar on home, can drag out items
Bug: 182079330
Bug: 171917176
Change-Id: I7c1983e3219b1341cf233260f0ccac9051c4dc14
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 95cdbdd..e263c7a 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -98,6 +98,9 @@
public static final int TYPE_HIDE_BACK_BUTTON = TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
| TYPE_SNACKBAR | TYPE_WIDGET_RESIZE_FRAME | TYPE_LISTENER;
+ // When these types of floating views are open, hide the taskbar hotseat and show the real one.
+ public static final int TYPE_REPLACE_TASKBAR_WITH_HOTSEAT = TYPE_FOLDER | TYPE_ACTION_POPUP;
+
public static final int TYPE_ACCESSIBLE = TYPE_ALL & ~TYPE_DISCOVERY_BOUNCE & ~TYPE_LISTENER
& ~TYPE_ALL_APPS_EDU;
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 2440854..fb7a99f 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -708,10 +708,11 @@
mInsets.top + availableHeightPx);
} else {
// Folders should only appear below the drop target bar and above the hotseat
+ int hotseatTop = isTaskbarPresent ? taskbarSize : hotseatBarSizePx;
return new Rect(mInsets.left + edgeMarginPx,
mInsets.top + dropTargetBarSizePx + edgeMarginPx,
mInsets.left + availableWidthPx - edgeMarginPx,
- mInsets.top + availableHeightPx - hotseatBarSizePx
+ mInsets.top + availableHeightPx - hotseatTop
- workspacePageIndicatorHeight - edgeMarginPx);
}
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index b2112ad..e5b75c1 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -29,6 +29,7 @@
import androidx.annotation.Nullable;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.MultiValueAlpha;
import java.util.function.Consumer;
@@ -37,6 +38,10 @@
*/
public class Hotseat extends CellLayout implements Insettable {
+ private static final int ALPHA_INDEX_STATE = 0;
+ private static final int ALPHA_INDEX_REPLACE_TASKBAR = 1;
+ private static final int NUM_ALPHA_CHANNELS = 2;
+
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHasVerticalHotseat;
private Workspace mWorkspace;
@@ -44,6 +49,8 @@
@Nullable
private Consumer<Boolean> mOnVisibilityAggregatedCallback;
+ private final MultiValueAlpha mMultiValueAlpha;
+
public Hotseat(Context context) {
this(context, null);
}
@@ -54,6 +61,8 @@
public Hotseat(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ mMultiValueAlpha = new MultiValueAlpha(this, NUM_ALPHA_CHANNELS, MultiValueAlpha.Mode.MAX);
+ mMultiValueAlpha.setUpdateVisibility(true);
}
/**
@@ -174,4 +183,12 @@
public View getFirstItemMatch(Workspace.ItemOperator itemOperator) {
return mWorkspace.getFirstMatch(new CellLayout[] { this }, itemOperator);
}
+
+ public MultiValueAlpha.AlphaProperty getStateAlpha() {
+ return mMultiValueAlpha.getProperty(ALPHA_INDEX_STATE);
+ }
+
+ public MultiValueAlpha.AlphaProperty getReplaceTaskbarAlpha() {
+ return mMultiValueAlpha.getProperty(ALPHA_INDEX_REPLACE_TASKBAR);
+ }
}
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 660eeab..d6d2f73 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -55,6 +55,7 @@
import com.android.launcher3.graphics.WorkspaceDragScrim;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.util.DynamicResource;
+import com.android.launcher3.util.MultiValueAlpha;
import com.android.systemui.plugins.ResourceProvider;
/**
@@ -143,8 +144,8 @@
}
float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
- propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha,
- config.getInterpolator(ANIM_HOTSEAT_FADE, fadeInterpolator));
+ propertySetter.setFloat(hotseat.getStateAlpha(), MultiValueAlpha.VALUE,
+ hotseatIconsAlpha, config.getInterpolator(ANIM_HOTSEAT_FADE, fadeInterpolator));
float workspacePageIndicatorAlpha = (elements & WORKSPACE_PAGE_INDICATOR) != 0 ? 1 : 0;
propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
workspacePageIndicatorAlpha, fadeInterpolator);
diff --git a/src/com/android/launcher3/util/MultiValueAlpha.java b/src/com/android/launcher3/util/MultiValueAlpha.java
index 5be9529..c79b1f6 100644
--- a/src/com/android/launcher3/util/MultiValueAlpha.java
+++ b/src/com/android/launcher3/util/MultiValueAlpha.java
@@ -42,16 +42,49 @@
}
};
+ /**
+ * Determines how each alpha should factor into the final alpha.
+ */
+ public enum Mode {
+ BLEND(1f) {
+ @Override
+ public float calculateNewAlpha(float currentAlpha, float otherAlpha) {
+ return currentAlpha * otherAlpha;
+ }
+ },
+
+ MAX(0f) {
+ @Override
+ public float calculateNewAlpha(float currentAlpha, float otherAlpha) {
+ return Math.max(currentAlpha, otherAlpha);
+ }
+ };
+
+ Mode(float startAlpha) {
+ mStartAlpha = startAlpha;
+ }
+
+ protected final float mStartAlpha;
+ protected abstract float calculateNewAlpha(float currentAlpha, float otherAlpha);
+ }
+
private final View mView;
private final AlphaProperty[] mMyProperties;
+ private final Mode mMode;
private int mValidMask;
// Whether we should change from INVISIBLE to VISIBLE and vice versa at low alpha values.
private boolean mUpdateVisibility;
public MultiValueAlpha(View view, int size) {
+ this(view, size, Mode.BLEND);
+ }
+
+ public MultiValueAlpha(View view, int size, Mode mode) {
mView = view;
mMyProperties = new AlphaProperty[size];
+ mMode = mode;
+ mView.setAlpha(mMode.mStartAlpha);
mValidMask = 0;
for (int i = 0; i < size; i++) {
@@ -79,9 +112,9 @@
private final int mMyMask;
- private float mValue = 1;
+ private float mValue = mMode.mStartAlpha;
// Factor of all other alpha channels, only valid if mMyMask is present in mValidMask.
- private float mOthers = 1;
+ private float mOthers = mMode.mStartAlpha;
AlphaProperty(int myMask) {
mMyMask = myMask;
@@ -94,10 +127,10 @@
if ((mValidMask & mMyMask) == 0) {
// Our cache value is not correct, recompute it.
- mOthers = 1;
+ mOthers = mMode.mStartAlpha;
for (AlphaProperty prop : mMyProperties) {
if (prop != this) {
- mOthers *= prop.mValue;
+ mOthers = mMode.calculateNewAlpha(mOthers, prop.mValue);
}
}
}
@@ -107,7 +140,7 @@
mValidMask = mMyMask;
mValue = value;
- mView.setAlpha(mOthers * mValue);
+ mView.setAlpha(mMode.calculateNewAlpha(mOthers, mValue));
if (mUpdateVisibility) {
AlphaUpdateListener.updateVisibility(mView);
}