diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-09-27 23:25:18 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-09-27 23:25:18 +0000 |
commit | 1cde8ddd7b0401824b8308b1a00f7353de10a223 (patch) | |
tree | a8e89b77c0b7c51a142975d224042c9e3368eb77 | |
parent | 32ba589c4df523972f6930f98edc64225c4b851b (diff) | |
parent | d8b78523caa4c1040b00cd8d2534f38d39243e31 (diff) | |
download | Launcher3-1cde8ddd7b0401824b8308b1a00f7353de10a223.tar.gz |
Snap for 9111705 from d8b78523caa4c1040b00cd8d2534f38d39243e31 to tm-qpr1-release
Change-Id: I0b2665d83be388ec57face595d0b3126846d029c
14 files changed, 127 insertions, 30 deletions
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index a90af046e3..1c345a6aa4 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -116,6 +116,11 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT private static final int FLAG_SCREEN_PINNING_ACTIVE = 1 << 11; private static final int FLAG_VOICE_INTERACTION_WINDOW_SHOWING = 1 << 12; private static final int FLAG_SMALL_SCREEN = 1 << 13; + private static final int FLAG_SLIDE_IN_VIEW_VISIBLE = 1 << 14; + + /** Flags where a UI could be over a slide in view, so the color override should be disabled. */ + private static final int FLAGS_SLIDE_IN_VIEW_ICON_COLOR_OVERRIDE_DISABLED = + FLAG_NOTIFICATION_SHADE_EXPANDED | FLAG_VOICE_INTERACTION_WINDOW_SHOWING; private static final String NAV_BUTTONS_SEPARATE_WINDOW_TITLE = "Taskbar Nav Buttons"; @@ -135,6 +140,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT private final ViewGroup mStartContextualContainer; private final int mLightIconColor; private final int mDarkIconColor; + /** Color to use for navigation bar buttons, if a slide in view is visible. */ + private final int mSlideInViewIconColor; private final AnimatedFloat mTaskbarNavButtonTranslationY = new AnimatedFloat( this::updateNavButtonTranslationY); @@ -149,6 +156,9 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT this::updateNavButtonDarkIntensity); private final AnimatedFloat mNavButtonDarkIntensityMultiplier = new AnimatedFloat( this::updateNavButtonDarkIntensity); + /** Overrides the navigation button color to {@code mSlideInViewIconColor} when {@code 1}. */ + private final AnimatedFloat mSlideInViewNavButtonColorOverride = new AnimatedFloat( + this::updateNavButtonDarkIntensity); private final RotationButtonListener mRotationButtonListener = new RotationButtonListener(); private final Rect mFloatingRotationButtonBounds = new Rect(); @@ -180,6 +190,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mLightIconColor = context.getColor(R.color.taskbar_nav_icon_light_color); mDarkIconColor = context.getColor(R.color.taskbar_nav_icon_dark_color); + // Can precompute color since dark theme change recreates taskbar. + mSlideInViewIconColor = Utilities.isDarkTheme(context) ? mLightIconColor : mDarkIconColor; } /** @@ -243,6 +255,11 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT flags -> (flags & FLAG_IME_VISIBLE) != 0 && !isInKidsMode, AnimatedFloat.VALUE, transForIme, defaultButtonTransY)); + mPropertyHolders.add(new StatePropertyHolder( + mSlideInViewNavButtonColorOverride, + flags -> ((flags & FLAG_SLIDE_IN_VIEW_VISIBLE) != 0) + && ((flags & FLAGS_SLIDE_IN_VIEW_ICON_COLOR_OVERRIDE_DISABLED) == 0))); + if (alwaysShowButtons) { initButtons(mNavButtonContainer, mEndContextualContainer, mControllers.navButtonController); @@ -524,6 +541,12 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT applyState(); } + /** {@code true} if a slide in view is currently visible over taskbar. */ + public void setSlideInViewVisible(boolean isSlideInViewVisible) { + updateStateForFlag(FLAG_SLIDE_IN_VIEW_VISIBLE, isSlideInViewVisible); + applyState(); + } + /** * Returns true if IME bar is visible */ @@ -669,8 +692,11 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT private void updateNavButtonDarkIntensity() { float darkIntensity = mTaskbarNavButtonDarkIntensity.value * mNavButtonDarkIntensityMultiplier.value; - int iconColor = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity, mLightIconColor, - mDarkIconColor); + ArgbEvaluator argbEvaluator = ArgbEvaluator.getInstance(); + int iconColor = (int) argbEvaluator.evaluate( + darkIntensity, mLightIconColor, mDarkIconColor); + iconColor = (int) argbEvaluator.evaluate( + mSlideInViewNavButtonColorOverride.value, iconColor, mSlideInViewIconColor); for (ImageView button : mAllButtons) { button.setImageTintList(ColorStateList.valueOf(iconColor)); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java index 32a3c10d87..454a2a4569 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java @@ -90,6 +90,9 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC mTaskbarEduView = (TaskbarEduView) mActivity.getLayoutInflater().inflate( R.layout.taskbar_edu, mActivity.getDragLayer(), false); mTaskbarEduView.init(new TaskbarEduCallbacks()); + mControllers.navbarButtonsViewController.setSlideInViewVisible(true); + mTaskbarEduView.setOnCloseBeginListener( + () -> mControllers.navbarButtonsViewController.setSlideInViewVisible(false)); mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null); mTaskbarEduView.show(); startAnim(createWaveAnim()); diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java index a1385c45c6..0372f67b75 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java @@ -41,6 +41,7 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.popup.PopupDataProvider; import com.android.launcher3.taskbar.BaseTaskbarContext; import com.android.launcher3.taskbar.TaskbarActivityContext; +import com.android.launcher3.taskbar.TaskbarControllers; import com.android.launcher3.taskbar.TaskbarDragController; import com.android.launcher3.taskbar.TaskbarStashController; import com.android.launcher3.testing.TestLogging; @@ -72,7 +73,7 @@ class TaskbarAllAppsContext extends BaseTaskbarContext { TaskbarAllAppsContext( TaskbarActivityContext taskbarContext, TaskbarAllAppsController windowController, - TaskbarStashController taskbarStashController) { + TaskbarControllers taskbarControllers) { super(taskbarContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null)); mTaskbarContext = taskbarContext; mWindowController = windowController; @@ -86,9 +87,10 @@ class TaskbarAllAppsContext extends BaseTaskbarContext { this, slideInView, windowController, - taskbarStashController); + taskbarControllers); mAppsView = slideInView.getAppsView(); + TaskbarStashController taskbarStashController = taskbarControllers.taskbarStashController; mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing(); mStashedTaskbarHeight = taskbarStashController.getStashedHeight(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java index 6c43e50156..1671a0f1d7 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java @@ -144,9 +144,7 @@ public final class TaskbarAllAppsController { // to catch invalid states. mControllers.getSharedState().allAppsVisible = true; - mAllAppsContext = new TaskbarAllAppsContext(mTaskbarContext, - this, - mControllers.taskbarStashController); + mAllAppsContext = new TaskbarAllAppsContext(mTaskbarContext, this, mControllers); mAllAppsContext.getDragController().init(mControllers); TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener); Optional.ofNullable(mAllAppsContext.getSystemService(WindowManager.class)) diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java index 0e62da3f63..9d48c8de89 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java @@ -30,13 +30,10 @@ import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.views.AbstractSlideInView; -import java.util.Optional; - /** Wrapper for taskbar all apps with slide-in behavior. */ public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarAllAppsContext> implements Insettable, DeviceProfile.OnDeviceProfileChangeListener { private TaskbarAllAppsContainerView mAppsView; - private OnCloseListener mOnCloseBeginListener; private float mShiftRange; public TaskbarAllAppsSlideInView(Context context, AttributeSet attrs) { @@ -72,14 +69,8 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarAllApp return mAppsView; } - /** Callback invoked when the view is beginning to close (e.g. close animation is started). */ - void setOnCloseBeginListener(OnCloseListener onCloseBeginListener) { - mOnCloseBeginListener = onCloseBeginListener; - } - @Override protected void handleClose(boolean animate) { - Optional.ofNullable(mOnCloseBeginListener).ifPresent(OnCloseListener::onSlideInViewClosed); handleClose(animate, ALL_APPS.getTransitionDuration(mActivityContext, false /* isToState */)); } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java index a39e872a8d..b0d3528e2c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java @@ -22,6 +22,8 @@ import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.appprediction.AppsDividerView; import com.android.launcher3.appprediction.PredictionRowView; +import com.android.launcher3.taskbar.NavbarButtonsViewController; +import com.android.launcher3.taskbar.TaskbarControllers; import com.android.launcher3.taskbar.TaskbarStashController; /** @@ -34,17 +36,19 @@ final class TaskbarAllAppsViewController { private final TaskbarAllAppsSlideInView mSlideInView; private final TaskbarAllAppsContainerView mAppsView; private final TaskbarStashController mTaskbarStashController; + private final NavbarButtonsViewController mNavbarButtonsViewController; TaskbarAllAppsViewController( TaskbarAllAppsContext context, TaskbarAllAppsSlideInView slideInView, TaskbarAllAppsController windowController, - TaskbarStashController taskbarStashController) { + TaskbarControllers taskbarControllers) { mContext = context; mSlideInView = slideInView; mAppsView = mSlideInView.getAppsView(); - mTaskbarStashController = taskbarStashController; + mTaskbarStashController = taskbarControllers.taskbarStashController; + mNavbarButtonsViewController = taskbarControllers.navbarButtonsViewController; setUpIconLongClick(); setUpAppDivider(); @@ -83,7 +87,9 @@ final class TaskbarAllAppsViewController { mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, true); mTaskbarStashController.applyState( ALL_APPS.getTransitionDuration(mContext, true /* isToState */)); + mNavbarButtonsViewController.setSlideInViewVisible(true); mSlideInView.setOnCloseBeginListener(() -> { + mNavbarButtonsViewController.setSlideInViewVisible(false); AbstractFloatingView.closeOpenContainer( mContext, AbstractFloatingView.TYPE_ACTION_POPUP); // Post in case view is closing due to gesture navigation. If a gesture is in progress, diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index dea4e4884c..6b616b1b07 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -255,7 +255,8 @@ public class RecentTasksList { TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size()); for (GroupedRecentTaskInfo rawTask : rawTasks) { if (rawTask.getType() == GroupedRecentTaskInfo.TYPE_FREEFORM) { - // TODO: add entry for freeform tasks + GroupTask desktopTask = createDesktopTask(rawTask); + allTasks.add(desktopTask); continue; } ActivityManager.RecentTaskInfo taskInfo1 = rawTask.getTaskInfo1(); @@ -283,6 +284,16 @@ public class RecentTasksList { return allTasks; } + private GroupTask createDesktopTask(GroupedRecentTaskInfo taskInfo) { + // TODO(b/244348395): create a subclass of GroupTask for desktop tile + // We need a single task information as the primary task. Use the first task + Task.TaskKey key = new Task.TaskKey(taskInfo.getTaskInfo1()); + Task task = new Task(key); + task.desktopTile = true; + task.topActivity = key.sourceComponent; + return new GroupTask(task, null, null); + } + private SplitConfigurationOptions.SplitBounds convertSplitBounds( SplitBounds shellSplitBounds) { return shellSplitBounds == null ? diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index dcf685a4de..3b2df315b1 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -58,6 +58,7 @@ import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationCon import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController; import com.android.systemui.shared.system.smartspace.SmartspaceState; import com.android.wm.shell.back.IBackAnimation; +import com.android.wm.shell.desktopmode.IDesktopMode; import com.android.wm.shell.floating.IFloatingTasks; import com.android.wm.shell.onehanded.IOneHanded; import com.android.wm.shell.pip.IPip; @@ -95,6 +96,7 @@ public class SystemUiProxy implements ISystemUiProxy { private IStartingWindow mStartingWindow; private IRecentTasks mRecentTasks; private IBackAnimation mBackAnimation; + private IDesktopMode mDesktopMode; private final DeathRecipient mSystemUiProxyDeathRecipient = () -> { MAIN_EXECUTOR.execute(() -> clearProxy()); }; @@ -169,7 +171,7 @@ public class SystemUiProxy implements ISystemUiProxy { IFloatingTasks floatingTasks, IOneHanded oneHanded, IShellTransitions shellTransitions, IStartingWindow startingWindow, IRecentTasks recentTasks, ISysuiUnlockAnimationController sysuiUnlockAnimationController, - IBackAnimation backAnimation) { + IBackAnimation backAnimation, IDesktopMode desktopMode) { unlinkToDeath(); mSystemUiProxy = proxy; mPip = pip; @@ -181,6 +183,7 @@ public class SystemUiProxy implements ISystemUiProxy { mSysuiUnlockAnimationController = sysuiUnlockAnimationController; mRecentTasks = recentTasks; mBackAnimation = backAnimation; + mDesktopMode = desktopMode; linkToDeath(); // re-attach the listeners once missing due to setProxy has not been initialized yet. if (mPipAnimationListener != null && mPip != null) { @@ -207,7 +210,7 @@ public class SystemUiProxy implements ISystemUiProxy { } public void clearProxy() { - setProxy(null, null, null, null, null, null, null, null, null, null); + setProxy(null, null, null, null, null, null, null, null, null, null, null); } // TODO(141886704): Find a way to remove this @@ -908,4 +911,19 @@ public class SystemUiProxy implements ISystemUiProxy { return false; } + + // + // Desktop Mode + // + + /** Call shell to show all apps active on the desktop */ + public void showDesktopApps() { + if (mDesktopMode != null) { + try { + mDesktopMode.showDesktopApps(); + } catch (RemoteException e) { + Log.w(TAG, "Failed call showDesktopApps", e); + } + } + } } diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index e207a1b73b..1999701f61 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -28,6 +28,7 @@ import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_RECENT_TASKS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_BACK_ANIMATION; +import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_DESKTOP_MODE; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_FLOATING_TASKS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_ONE_HANDED; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_PIP; @@ -111,6 +112,7 @@ import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController; import com.android.systemui.shared.tracing.ProtoTraceable; import com.android.wm.shell.back.IBackAnimation; +import com.android.wm.shell.desktopmode.IDesktopMode; import com.android.wm.shell.floating.IFloatingTasks; import com.android.wm.shell.onehanded.IOneHanded; import com.android.wm.shell.pip.IPip; @@ -184,10 +186,12 @@ public class TouchInteractionService extends Service bundle.getBinder(KEY_EXTRA_RECENT_TASKS)); IBackAnimation backAnimation = IBackAnimation.Stub.asInterface( bundle.getBinder(KEY_EXTRA_SHELL_BACK_ANIMATION)); + IDesktopMode desktopMode = IDesktopMode.Stub.asInterface( + bundle.getBinder(KEY_EXTRA_SHELL_DESKTOP_MODE)); MAIN_EXECUTOR.execute(() -> { SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy, pip, splitscreen, floatingTasks, onehanded, shellTransitions, startingWindow, - recentTasks, launcherUnlockAnimationController, backAnimation); + recentTasks, launcherUnlockAnimationController, backAnimation, desktopMode); TouchInteractionService.this.initInputMonitor("TISBinder#onInitialize()"); preloadOverview(true /* fromInit */); }); diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index a81f95f3ac..9720c2a92e 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -88,6 +88,7 @@ import com.android.launcher3.util.ViewPool.Reusable; import com.android.quickstep.RecentsModel; import com.android.quickstep.RemoteAnimationTargets; import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle; +import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskIconCache; import com.android.quickstep.TaskOverlayFactory; import com.android.quickstep.TaskThumbnailCache; @@ -708,6 +709,11 @@ public class TaskView extends FrameLayout implements Reusable { RecentsView recentsView = getRecentsView(); RemoteTargetHandle[] remoteTargetHandles = recentsView.mRemoteTargetHandles; RunnableList runnableList = new RunnableList(); + if (mTask != null && mTask.desktopTile) { + // clicked on desktop + SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(); + return runnableList; + } if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask() && remoteTargetHandles != null) { if (!mIsClickableAsLiveTile) { return runnableList; diff --git a/res/drawable/page_indicator.xml b/res/drawable/page_indicator.xml new file mode 100644 index 0000000000..c0ccc49250 --- /dev/null +++ b/res/drawable/page_indicator.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="?attr/folderPaginationColor"/> + <size android:width="@dimen/page_indicator_size" android:height="@dimen/page_indicator_size"/> +</shape>
\ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 5dae9f2ac4..47584e2baf 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -248,7 +248,7 @@ <!-- Folders --> <dimen name="page_indicator_dot_size">8dp</dimen> - <dimen name="page_indicator_current_page_indicator_size">10dp</dimen> + <dimen name="page_indicator_size">10dp</dimen> <dimen name="folder_cell_x_padding">9dp</dimen> diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java index fb51bf01a7..28e0b68b4c 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java @@ -30,6 +30,7 @@ import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.RectF; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Property; import android.view.View; @@ -84,9 +85,11 @@ public class PageIndicatorDots extends View implements PageIndicator { }; private final Paint mPaginationPaint; + private final Drawable mPageIndicatorDrawable; private final float mDotRadius; private final float mCircleGap; private final float mPageIndicatorSize; + private final float mPageIndicatorRadius; private final boolean mIsRtl; private int mNumPages; @@ -125,13 +128,22 @@ public class PageIndicatorDots extends View implements PageIndicator { mPaginationPaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor)); mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2; + if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { + mPageIndicatorSize = getResources().getDimension( + R.dimen.page_indicator_size); + mPageIndicatorRadius = mPageIndicatorSize / 2; + mPageIndicatorDrawable = context.getDrawable(R.drawable.page_indicator); + mPageIndicatorDrawable.setBounds(0, 0, (int) mPageIndicatorSize, + (int) mPageIndicatorSize); mCircleGap = DOT_GAP_FACTOR_FLOAT * mDotRadius; + } else { + mPageIndicatorSize = 0; + mPageIndicatorRadius = 0; + mPageIndicatorDrawable = null; mCircleGap = DOT_GAP_FACTOR * mDotRadius; } - mPageIndicatorSize = getResources().getDimension( - R.dimen.page_indicator_current_page_indicator_size); if (!SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { setOutlineProvider(new MyOutlineProver()); } @@ -308,16 +320,19 @@ public class PageIndicatorDots extends View implements PageIndicator { mPaginationPaint.setAlpha(PAGE_INDICATOR_ALPHA); if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { RectF currRect = getActiveRect(); - int scrollPerPage = getScrollPerPage(); + // Moves the canvas to start at the top left corner of the page indicator + canvas.translate(currRect.left, currRect.top); + + int scrollPerPage = getScrollPerPage(); // This IF is to avoid division by 0 if (scrollPerPage != 0) { int delta = mCurrentScroll % scrollPerPage; canvas.rotate((INDICATOR_ROTATION * delta) / scrollPerPage, - currRect.centerX(), currRect.centerY()); + mPageIndicatorRadius, mPageIndicatorRadius); } - canvas.drawRect(currRect, mPaginationPaint); + mPageIndicatorDrawable.draw(canvas); } else { canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint); } @@ -334,7 +349,7 @@ public class PageIndicatorDots extends View implements PageIndicator { float startXIndicator = ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2) - getOffset(); float indicatorPosition = startXIndicator + getIndicatorScrollDistance() - + (mPageIndicatorSize / 2); + + mPageIndicatorRadius; // If the indicator gets close enough to a dot then we change the radius // of the dot based on how close the indicator is to it. @@ -391,7 +406,7 @@ public class PageIndicatorDots extends View implements PageIndicator { * the indicator is centered in with the indicator circles */ private float getOffset() { - return (mPageIndicatorSize / 2) - mDotRadius; + return mPageIndicatorRadius - mDotRadius; } /** diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java index 47503b118e..f73347a7b2 100644 --- a/src/com/android/launcher3/views/AbstractSlideInView.java +++ b/src/com/android/launcher3/views/AbstractSlideInView.java @@ -33,6 +33,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.animation.Interpolator; +import androidx.annotation.Nullable; + import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; @@ -41,6 +43,7 @@ import com.android.launcher3.touch.SingleAxisSwipeDetector; import java.util.ArrayList; import java.util.List; +import java.util.Optional; /** * Extension of {@link AbstractFloatingView} with common methods for sliding in from bottom. @@ -79,6 +82,7 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext> protected float mTranslationShift = TRANSLATION_SHIFT_CLOSED; protected boolean mNoIntercept; + protected @Nullable OnCloseListener mOnCloseBeginListener; protected List<OnCloseListener> mOnCloseListeners = new ArrayList<>(); public AbstractSlideInView(Context context, AttributeSet attrs, int defStyleAttr) { @@ -204,6 +208,11 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext> } } + /** Callback invoked when the view is beginning to close (e.g. close animation is started). */ + public void setOnCloseBeginListener(@Nullable OnCloseListener onCloseBeginListener) { + mOnCloseBeginListener = onCloseBeginListener; + } + /** Registers an {@link OnCloseListener}. */ public void addOnCloseListener(OnCloseListener listener) { mOnCloseListeners.add(listener); @@ -213,6 +222,8 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext> if (!mIsOpen) { return; } + Optional.ofNullable(mOnCloseBeginListener).ifPresent(OnCloseListener::onSlideInViewClosed); + if (!animate) { mOpenCloseAnimator.cancel(); setTranslationShift(TRANSLATION_SHIFT_CLOSED); |