diff --git a/quickstep/res/layout/overview_add_desktop_button.xml b/quickstep/res/layout/overview_add_desktop_button.xml index 2333dd149b..e36cf72414 100644 --- a/quickstep/res/layout/overview_add_desktop_button.xml +++ b/quickstep/res/layout/overview_add_desktop_button.xml @@ -18,7 +18,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apgk/res-auto" android:id="@+id/add_desktop_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="@dimen/add_desktop_button_size" + android:layout_height="@dimen/add_desktop_button_size" android:src="@drawable/ic_desktop_add" android:padding="10dp" /> \ No newline at end of file diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 493a5b8882..b25334365b 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -106,6 +106,9 @@ 24dp 2dp + + 56dp + 600dp diff --git a/quickstep/src/com/android/quickstep/views/AddDesktopButton.kt b/quickstep/src/com/android/quickstep/views/AddDesktopButton.kt index f973dd0b4a..1dab18a251 100644 --- a/quickstep/src/com/android/quickstep/views/AddDesktopButton.kt +++ b/quickstep/src/com/android/quickstep/views/AddDesktopButton.kt @@ -17,8 +17,11 @@ package com.android.quickstep.views import android.content.Context +import android.graphics.drawable.ShapeDrawable +import android.graphics.drawable.shapes.RoundRectShape import android.util.AttributeSet import android.widget.ImageButton +import com.android.launcher3.R /** * Button for supporting multiple desktop sessions. The button will be next to the first TaskView @@ -26,5 +29,21 @@ import android.widget.ImageButton */ class AddDesktopButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : ImageButton(context, attrs) { - // TODO(b/382057498): add this button the overview. + + override fun onFinishInflate() { + super.onFinishInflate() + + background = + ShapeDrawable().apply { + shape = + RoundRectShape( + FloatArray(8) { R.dimen.add_desktop_button_size.toFloat() }, + null, + null, + ) + setTint( + resources.getColor(android.R.color.system_surface_bright_light, context.theme) + ) + } + } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index cfad303e0b..e037045020 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -547,6 +547,8 @@ public abstract class RecentsView< private final int mSplitPlaceholderSize; private final int mSplitPlaceholderInset; private final ClearAllButton mClearAllButton; + @Nullable + private AddDesktopButton mAddDesktopButton = null; private final Rect mClearAllButtonDeadZoneRect = new Rect(); private final Rect mTaskViewDeadZoneRect = new Rect(); private final Rect mTopRowDeadZoneRect = new Rect(); @@ -902,6 +904,12 @@ public abstract class RecentsView< mClearAllButton = (ClearAllButton) LayoutInflater.from(context) .inflate(R.layout.overview_clear_all_button, this, false); mClearAllButton.setOnClickListener(this::dismissAllTasks); + + if (DesktopModeStatus.enableMultipleDesktops(mContext)) { + mAddDesktopButton = (AddDesktopButton) LayoutInflater.from(context).inflate( + R.layout.overview_add_desktop_button, this, false); + } + mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */, 10 /* initial size */); mGroupedTaskViewPool = new ViewPool<>(context, this, @@ -1880,7 +1888,7 @@ public abstract class RecentsView< } mLoadPlanEverApplied = true; if (taskGroups == null || taskGroups.isEmpty()) { - removeTasksViewsAndClearAllButton(); + removeAllTaskViews(); onTaskStackUpdated(); // With all tasks removed, touch handling in PagedView is disabled and we need to reset // touch state or otherwise values will be obsolete. @@ -1943,6 +1951,11 @@ public abstract class RecentsView< taskGroups = mUtils.sortDesktopTasksToFront(taskGroups); } + if (mAddDesktopButton != null) { + // Add `mAddDesktopButton` as the first child. + addView(mAddDesktopButton); + } + // Add views as children based on whether it's grouped or single task. Looping through // taskGroups backwards populates the thumbnail grid from least recent to most recent. for (int i = taskGroups.size() - 1; i >= 0; i--) { @@ -2088,13 +2101,14 @@ public abstract class RecentsView< return mModel.isLoadingTasksInBackground(); } - private void removeTasksViewsAndClearAllButton() { + private void removeAllTaskViews() { // This handles an edge case where applyLoadPlan happens during a gesture when the only // Task is one with excludeFromRecents, in which case we should not remove it. CollectionsKt .filter(getTaskViews(), taskView -> !isGestureActive() || !taskView.isRunningTask()) .forEach(this::removeView); if (!hasTaskViews()) { + removeView(mAddDesktopButton); removeView(mClearAllButton); } } @@ -2324,6 +2338,9 @@ public abstract class RecentsView< float taskAlignmentTranslationY = getTaskAlignmentTranslationY(); mClearAllButton.setTaskAlignmentTranslationY(taskAlignmentTranslationY); + if (mAddDesktopButton != null) { + mAddDesktopButton.setTranslationY(taskAlignmentTranslationY); + } updateGridProperties(); } @@ -3006,6 +3023,9 @@ public abstract class RecentsView< taskView = getTaskViewFromPool(TaskViewType.SINGLE); taskView.bind(runningTasks[0], mOrientationState, mTaskOverlayFactory); } + if (mAddDesktopButton != null && wasEmpty) { + addView(mAddDesktopButton); + } addView(taskView, getRunningTaskExpectedIndex(taskView)); runningTaskViewId = taskView.getTaskViewId(); if (wasEmpty) { @@ -3426,6 +3446,12 @@ public abstract class RecentsView< + snappedTaskNonGridScrollAdjustment); } + if (mAddDesktopButton != null) { + mAddDesktopButton.setTranslationX( + gridTranslations.get(getFirstTaskView()) - snappedTaskGridTranslationX + + snappedTaskNonGridScrollAdjustment); + } + final TaskView runningTask = getRunningTaskView(); if (showAsGrid() && enableGridOnlyOverview() && runningTask != null) { runActionOnRemoteHandles( @@ -4137,6 +4163,7 @@ public abstract class RecentsView< if (taskCount == 1) { removeViewInLayout(mClearAllButton); + removeViewInLayout(mAddDesktopButton); if (isHomeTaskDismissed) { updateEmptyMessage(); } else if (!mSplitSelectStateController.isSplitSelectActive()) { @@ -4468,7 +4495,7 @@ public abstract class RecentsView< finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, () -> { UI_HELPER_EXECUTOR.getHandler().post( ActivityManagerWrapper.getInstance()::removeAllRecentTasks); - removeTasksViewsAndClearAllButton(); + removeAllTaskViews(); startHome(); }); } @@ -4627,6 +4654,11 @@ public abstract class RecentsView< taskView.setStableAlpha(alpha); } mClearAllButton.setContentAlpha(mContentAlpha); + + // TODO(b/389209338): Handle the visibility of the `mAddDesktopButton`. + if (mAddDesktopButton != null) { + mAddDesktopButton.setAlpha(mContentAlpha); + } int alphaInt = Math.round(alpha * 255); mEmptyMessagePaint.setAlpha(alphaInt); mEmptyIcon.setAlpha(alphaInt); @@ -4923,9 +4955,11 @@ public abstract class RecentsView< + carouselHiddenOffsetSize; if (child instanceof TaskView taskView) { taskView.getPrimaryTaskOffsetTranslationProperty().set(taskView, totalTranslationX); - } else { + } else if (child instanceof ClearAllButton) { getPagedOrientationHandler().getPrimaryViewTranslate().set(child, totalTranslationX); + } else { + // TODO(b/389209581): Handle the page offsets update of the 'mAddDesktopButton'. } if (mEnableDrawingLiveTile && i == getRunningTaskIndex()) { runActionOnRemoteHandles( @@ -6104,6 +6138,13 @@ public abstract class RecentsView< outPageScrolls[clearAllIndex] = clearAllScroll; } + int addDesktopButtonIndex = indexOfChild(mAddDesktopButton); + if (addDesktopButtonIndex != -1 && addDesktopButtonIndex < outPageScrolls.length) { + outPageScrolls[addDesktopButtonIndex] = + newPageScrolls[addDesktopButtonIndex] + Math.round( + mAddDesktopButton.getTranslationX()); + } + int lastTaskScroll = getLastTaskScroll(clearAllScroll, clearAllWidth); getTaskViews().forEachWithIndexInParent((index, taskView) -> { float scrollDiff = taskView.getScrollAdjustment(showAsGrid); diff --git a/res/drawable/ic_desktop_add.xml b/res/drawable/ic_desktop_add.xml index fa5e0debf9..d31b04b858 100644 --- a/res/drawable/ic_desktop_add.xml +++ b/res/drawable/ic_desktop_add.xml @@ -14,8 +14,8 @@ ~ limitations under the License. -->