Update app pair icon colors when switching containers

This CL updates the color for the app pair background, and adds a way for an app pair icon to redraw as a different color when switching containers.

Bug: 315731527
Flag: ACONFIG com.android.wm.shell.enable_app_pairs TRUNKFOOD
Test: Manual
Change-Id: I615cb95d51f7c4c120ad306246d9491bf4452229
This commit is contained in:
Jeremy Sim
2024-04-03 16:49:19 -07:00
parent a596f589c4
commit 05617cb11f
7 changed files with 49 additions and 27 deletions
+1
View File
@@ -52,6 +52,7 @@
<attr name="folderIconBorderColor" format="color" />
<attr name="folderTextColor" format="color" />
<attr name="folderHintTextColor" format="color" />
<attr name="appPairSurfaceInFolder" format="color" />
<attr name="isFolderDarkText" format="boolean" />
<attr name="workspaceAccentColor" format="color" />
<attr name="workspaceSurfaceColor" format="color" />
+2
View File
@@ -61,6 +61,7 @@
<item name="isFolderDarkText">true</item>
<item name="folderTextColor">@color/folder_text_color_light</item>
<item name="folderHintTextColor">@color/folder_hint_text_color_light</item>
<item name="appPairSurfaceInFolder">@color/material_color_surface_container_lowest</item>
<item name="loadingIconColor">#CCFFFFFF</item>
<item name="iconOnlyShortcutColor">?android:attr/textColorSecondary</item>
<item name="eduHalfSheetBGColor">?android:attr/colorAccent</item>
@@ -172,6 +173,7 @@
<item name="isFolderDarkText">false</item>
<item name="folderTextColor">@color/folder_text_color_dark</item>
<item name="folderHintTextColor">@color/folder_hint_text_color_dark</item>
<item name="appPairSurfaceInFolder">@color/material_color_surface_container_lowest</item>
<item name="isMainColorDark">true</item>
<item name="loadingIconColor">#99FFFFFF</item>
<item name="iconOnlyShortcutColor">#B3FFFFFF</item>
+20 -7
View File
@@ -16,6 +16,7 @@
package com.android.launcher3;
import static com.android.launcher3.BubbleTextView.DISPLAY_FOLDER;
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherState.ALL_APPS;
@@ -73,6 +74,7 @@ import com.android.app.animation.Interpolators;
import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.apppairs.AppPairIcon;
import com.android.launcher3.celllayout.CellInfo;
import com.android.launcher3.celllayout.CellLayoutLayoutParams;
import com.android.launcher3.celllayout.CellPosMapper;
@@ -241,6 +243,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
public static final int REORDER_TIMEOUT = 650;
protected final Alarm mReorderAlarm = new Alarm();
private PreviewBackground mFolderCreateBg;
/** The underlying view that we are dragging something over. */
private View mDragOverView = null;
private FolderIcon mDragOverFolderIcon = null;
private boolean mCreateUserFolderOnDrop = false;
private boolean mAddToExistingFolderOnDrop = false;
@@ -2381,6 +2385,11 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
if (mFolderCreateBg != null) {
mFolderCreateBg.animateToRest();
}
if (mDragOverView instanceof AppPairIcon api) {
api.getIconDrawableArea().onTemporaryContainerChange(null);
mDragOverView = null;
}
}
private void cleanupAddToFolder() {
@@ -2656,32 +2665,36 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
return;
}
final View dragOverView = mDragTargetLayout.getChildAt(mTargetCell[0], mTargetCell[1]);
mDragOverView = mDragTargetLayout.getChildAt(mTargetCell[0], mTargetCell[1]);
ItemInfo info = dragObject.dragInfo;
boolean userFolderPending = willCreateUserFolder(info, dragOverView, false);
boolean userFolderPending = willCreateUserFolder(info, mDragOverView, false);
if (mDragMode == DRAG_MODE_NONE && userFolderPending) {
mFolderCreateBg = new PreviewBackground();
mFolderCreateBg.setup(mLauncher, mLauncher, null,
dragOverView.getMeasuredWidth(), dragOverView.getPaddingTop());
mDragOverView.getMeasuredWidth(), mDragOverView.getPaddingTop());
// The full preview background should appear behind the icon
mFolderCreateBg.isClipping = false;
if (mDragOverView instanceof AppPairIcon api) {
api.getIconDrawableArea().onTemporaryContainerChange(DISPLAY_FOLDER);
}
mFolderCreateBg.animateToAccept(mDragTargetLayout, mTargetCell[0], mTargetCell[1]);
mDragTargetLayout.clearDragOutlines();
setDragMode(DRAG_MODE_CREATE_FOLDER);
if (dragObject.stateAnnouncer != null) {
dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper
.getDescriptionForDropOver(dragOverView, getContext()));
.getDescriptionForDropOver(mDragOverView, getContext()));
}
return;
}
boolean willAddToFolder = willAddToExistingUserFolder(info, dragOverView);
boolean willAddToFolder = willAddToExistingUserFolder(info, mDragOverView);
if (willAddToFolder && mDragMode == DRAG_MODE_NONE) {
mDragOverFolderIcon = ((FolderIcon) dragOverView);
mDragOverFolderIcon = ((FolderIcon) mDragOverView);
mDragOverFolderIcon.onDragEnter(info);
if (mDragTargetLayout != null) {
mDragTargetLayout.clearDragOutlines();
@@ -2690,7 +2703,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
if (dragObject.stateAnnouncer != null) {
dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper
.getDescriptionForDropOver(dragOverView, getContext()));
.getDescriptionForDropOver(mDragOverView, getContext()));
}
return;
}
@@ -181,6 +181,10 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
return mIconGraphic;
}
public int getContainer() {
return mContainer;
}
/**
* Ensures that both app icons in the pair are loaded in high resolution.
*/
@@ -20,6 +20,7 @@ import android.content.Context
import com.android.launcher3.BubbleTextView.DISPLAY_FOLDER
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
import com.android.launcher3.util.Themes
import com.android.launcher3.views.ActivityContext
class AppPairIconDrawingParams(val context: Context, container: Int) {
@@ -62,7 +63,7 @@ class AppPairIconDrawingParams(val context: Context, container: Int) {
// The app pair icon appears differently in portrait and landscape.
var isLeftRightSplit: Boolean = true
// The background paint color (based on container).
val bgColor: Int
var bgColor: Int = 0
init {
val activity: ActivityContext = ActivityContext.lookupContext(context)
@@ -77,7 +78,7 @@ class AppPairIconDrawingParams(val context: Context, container: Int) {
innerPadding = iconSize * INNER_PADDING_SCALE
memberIconSize = iconSize * MEMBER_ICON_SCALE
updateOrientation(dp)
bgColor = getBgColorForContainer(container)
updateBgColor(container)
}
/** Checks the device orientation and updates isLeftRightSplit accordingly. */
@@ -85,21 +86,13 @@ class AppPairIconDrawingParams(val context: Context, container: Int) {
isLeftRightSplit = dp.isLeftRightSplit
}
private fun getBgColorForContainer(container: Int): Int {
val color: Int
fun updateBgColor(container: Int) {
if (container == DISPLAY_FOLDER) {
val ta =
context.theme.obtainStyledAttributes(
intArrayOf(R.attr.materialColorSurfaceContainerLowest)
)
color = ta.getColor(0, 0)
ta.recycle()
bgColor = Themes.getAttrColor(context, R.attr.appPairSurfaceInFolder)
} else {
val ta = context.theme.obtainStyledAttributes(R.styleable.FolderIconPreview)
color = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0)
bgColor = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0)
ta.recycle()
}
return color
}
}
@@ -118,6 +118,15 @@ constructor(context: Context, attrs: AttributeSet? = null) :
redraw()
}
/**
* When the icon is temporary moved to a different colored surface, update the background color.
* Calling this method with [null] reverts the icon back to its default color.
*/
fun onTemporaryContainerChange(newContainer: Int?) {
drawParams.updateBgColor(newContainer ?: parentIcon.container)
redraw()
}
/**
* Gets this icon graphic's visual bounds, with respect to the parent icon's coordinate system.
*/
@@ -74,6 +74,13 @@ class AppPairInfo() : CollectionInfo() {
it.hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE)
}
/** Fetches high-res icons for member apps if needed. */
fun fetchHiResIconsIfNeeded(iconCache: IconCache) {
getAppContents().stream().filter(ItemInfoWithIcon::usingLowResIcon).forEach { member ->
iconCache.getTitleAndIcon(member, false)
}
}
/** Generates an ItemInfo for logging. */
override fun buildProto(cInfo: CollectionInfo?): LauncherAtom.ItemInfo {
val appPairIcon = LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size)
@@ -84,11 +91,4 @@ class AppPairInfo() : CollectionInfo() {
.setContainerInfo(getContainerInfo())
.build()
}
/** Fetches high-res icons for member apps if needed. */
fun fetchHiResIconsIfNeeded(iconCache: IconCache) {
getAppContents().stream().filter(ItemInfoWithIcon::usingLowResIcon).forEach { member ->
iconCache.getTitleAndIcon(member, false)
}
}
}