Loading quickstep/src/com/android/quickstep/views/IconView.java +8 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,14 @@ public class IconView extends View { return mDrawable; } public int getDrawableWidth() { return mDrawableWidth; } public int getDrawableHeight() { return mDrawableHeight; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); Loading quickstep/src/com/android/quickstep/views/RecentsView.java +10 −3 Original line number Diff line number Diff line Loading @@ -2612,10 +2612,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T clampToProgress(FINAL_FRAME, 0, 0.5f)); }); } boolean isTaskInBottomGridRow = showAsGrid() && !mTopRowIdSet.contains( taskView.getTaskViewId()) && taskView.getTaskViewId() != mFocusedTaskViewId; anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(isTaskInBottomGridRow ? ACCEL : FINAL_FRAME, 0, 0.5f)); clampToProgress(isOnGridBottomRow(taskView) ? ACCEL : FINAL_FRAME, 0, 0.5f)); FloatProperty<TaskView> secondaryViewTranslate = taskView.getSecondaryDissmissTranslationProperty(); int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView); Loading Loading @@ -4681,6 +4679,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return position != -1 ? position : bottomRowIdArray.indexOf(taskView.getTaskViewId()); } /** * @return true if the task in on the top of the grid */ public boolean isOnGridBottomRow(TaskView taskView) { return showAsGrid() && !mTopRowIdSet.contains(taskView.getTaskViewId()) && taskView.getTaskViewId() != mFocusedTaskViewId; } public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) { float degreesRotated; if (navbarRotation == 0) { Loading quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt +81 −19 Original line number Diff line number Diff line Loading @@ -45,7 +45,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { companion object { const val TAG = "TaskMenuViewWithArrow" fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean { fun showForTask( taskContainer: TaskIdAttributeContainer, alignSecondRow: Boolean = false ): Boolean { val activity = BaseDraggingActivity .fromContext<BaseDraggingActivity>(taskContainer.taskView.context) val taskMenuViewWithArrow = activity.layoutInflater Loading @@ -55,7 +58,7 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { false ) as TaskMenuViewWithArrow<*> return taskMenuViewWithArrow.populateAndShowForTask(taskContainer) return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignSecondRow) } } Loading @@ -78,6 +81,9 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION } private var alignSecondRow: Boolean = false private val extraSpaceForSecondRowAlignment: Int get() = if (alignSecondRow) optionMeasuredHeight else 0 private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid) private lateinit var taskView: TaskView Loading @@ -91,6 +97,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { else 0 private var iconView: IconView? = null private var scrim: View? = null private val scrimAlpha = 0.8f override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0 override fun getTargetObjectLocation(outPos: Rect?) { Loading @@ -112,18 +122,35 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { optionLayout = findViewById(KtR.id.menu_option_layout) } private fun populateAndShowForTask(taskContainer: TaskIdAttributeContainer): Boolean { private fun populateAndShowForTask( taskContainer: TaskIdAttributeContainer, alignSecondRow: Boolean ): Boolean { if (isAttachedToWindow) { return false } taskView = taskContainer.taskView this.taskContainer = taskContainer this.alignSecondRow = alignSecondRow if (!populateMenu()) return false addScrim() show() return true } private fun addScrim() { scrim = View(context).apply { layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT ) setBackgroundColor(Themes.getAttrColor(context, R.attr.overviewScrimColor)) alpha = 0f } popupContainer.addView(scrim) } /** @return true if successfully able to populate task view menu, false otherwise */ private fun populateMenu(): Boolean { Loading Loading @@ -180,19 +207,51 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { } override fun onCreateOpenAnimation(anim: AnimatorSet) { scrim?.let { anim.play( ObjectAnimator.ofFloat( taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, TaskView.MAX_PAGE_SCRIM_ALPHA ) ObjectAnimator.ofFloat(it, View.ALPHA, 0f, scrimAlpha) .setDuration(OPEN_DURATION.toLong()) ) } } override fun onCreateCloseAnimation(anim: AnimatorSet) { scrim?.let { anim.play( ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f) ObjectAnimator.ofFloat(it, View.ALPHA, scrimAlpha, 0f) .setDuration(CLOSE_DURATION.toLong()) ) } } override fun closeComplete() { super.closeComplete() popupContainer.removeView(scrim) popupContainer.removeView(iconView) } /** * Copy the iconView from taskView to dragLayer so it can stay on top of the scrim. * It needs to be called after [getTargetObjectLocation] because [mTempRect] needs to be * populated. */ private fun copyIconToDragLayer(insets: Rect) { iconView = IconView(context).apply { layoutParams = FrameLayout.LayoutParams( taskContainer.iconView.width, taskContainer.iconView.height ) x = mTempRect.left.toFloat() - insets.left y = mTempRect.top.toFloat() - insets.top drawable = taskContainer.iconView.drawable setDrawableSize( taskContainer.iconView.drawableWidth, taskContainer.iconView.drawableHeight ) } popupContainer.addView(iconView) } /** * Orients this container to the left or right of the given icon, aligning with the first option Loading @@ -217,7 +276,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { val dragLayer: InsettableFrameLayout = popupContainer val insets = dragLayer.insets // Put to the right of the icon if there is space, which means left aligned with the menu copyIconToDragLayer(insets) // Put this menu to the right of the icon if there is space, // which means the arrow is left aligned with the menu val rightAlignedMenuStartX = mTempRect.left - widthWithArrow val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace mIsLeftAligned = if (mIsRtl) { Loading @@ -229,18 +291,17 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX // Offset y so that the arrow and first row are center-aligned with the original icon. // Offset y so that the arrow and row are center-aligned with the original icon. val iconHeight = mTempRect.height() val optionHeight = optionMeasuredHeight val yOffset = (optionHeight - iconHeight) / 2 var menuStartY = mTempRect.top - yOffset val yOffset = (optionMeasuredHeight - iconHeight) / 2 var menuStartY = mTempRect.top - yOffset - extraSpaceForSecondRowAlignment // Insets are added later, so subtract them now. menuStartX -= insets.left menuStartY -= insets.top setX(menuStartX.toFloat()) setY(menuStartY.toFloat()) x = menuStartX.toFloat() y = menuStartY.toFloat() val lp = layoutParams as FrameLayout.LayoutParams val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams Loading @@ -251,7 +312,8 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { override fun addArrow() { popupContainer.addView(mArrow) mArrow.x = getArrowX() mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) + extraSpaceForSecondRowAlignment updateArrowColor() Loading quickstep/src/com/android/quickstep/views/TaskView.java +3 −1 Original line number Diff line number Diff line Loading @@ -840,7 +840,9 @@ public class TaskView extends FrameLayout implements Reusable { TaskIdAttributeContainer menuContainer = mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1]; if (mActivity.getDeviceProfile().overviewShowAsGrid) { return TaskMenuViewWithArrow.Companion.showForTask(menuContainer); boolean alignSecondRow = getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) && mActivity.getDeviceProfile().isLandscape; return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignSecondRow); } else { return TaskMenuView.showForTask(menuContainer); } Loading Loading
quickstep/src/com/android/quickstep/views/IconView.java +8 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,14 @@ public class IconView extends View { return mDrawable; } public int getDrawableWidth() { return mDrawableWidth; } public int getDrawableHeight() { return mDrawableHeight; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); Loading
quickstep/src/com/android/quickstep/views/RecentsView.java +10 −3 Original line number Diff line number Diff line Loading @@ -2612,10 +2612,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T clampToProgress(FINAL_FRAME, 0, 0.5f)); }); } boolean isTaskInBottomGridRow = showAsGrid() && !mTopRowIdSet.contains( taskView.getTaskViewId()) && taskView.getTaskViewId() != mFocusedTaskViewId; anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(isTaskInBottomGridRow ? ACCEL : FINAL_FRAME, 0, 0.5f)); clampToProgress(isOnGridBottomRow(taskView) ? ACCEL : FINAL_FRAME, 0, 0.5f)); FloatProperty<TaskView> secondaryViewTranslate = taskView.getSecondaryDissmissTranslationProperty(); int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView); Loading Loading @@ -4681,6 +4679,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return position != -1 ? position : bottomRowIdArray.indexOf(taskView.getTaskViewId()); } /** * @return true if the task in on the top of the grid */ public boolean isOnGridBottomRow(TaskView taskView) { return showAsGrid() && !mTopRowIdSet.contains(taskView.getTaskViewId()) && taskView.getTaskViewId() != mFocusedTaskViewId; } public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) { float degreesRotated; if (navbarRotation == 0) { Loading
quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt +81 −19 Original line number Diff line number Diff line Loading @@ -45,7 +45,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { companion object { const val TAG = "TaskMenuViewWithArrow" fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean { fun showForTask( taskContainer: TaskIdAttributeContainer, alignSecondRow: Boolean = false ): Boolean { val activity = BaseDraggingActivity .fromContext<BaseDraggingActivity>(taskContainer.taskView.context) val taskMenuViewWithArrow = activity.layoutInflater Loading @@ -55,7 +58,7 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { false ) as TaskMenuViewWithArrow<*> return taskMenuViewWithArrow.populateAndShowForTask(taskContainer) return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignSecondRow) } } Loading @@ -78,6 +81,9 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION } private var alignSecondRow: Boolean = false private val extraSpaceForSecondRowAlignment: Int get() = if (alignSecondRow) optionMeasuredHeight else 0 private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid) private lateinit var taskView: TaskView Loading @@ -91,6 +97,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { else 0 private var iconView: IconView? = null private var scrim: View? = null private val scrimAlpha = 0.8f override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0 override fun getTargetObjectLocation(outPos: Rect?) { Loading @@ -112,18 +122,35 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { optionLayout = findViewById(KtR.id.menu_option_layout) } private fun populateAndShowForTask(taskContainer: TaskIdAttributeContainer): Boolean { private fun populateAndShowForTask( taskContainer: TaskIdAttributeContainer, alignSecondRow: Boolean ): Boolean { if (isAttachedToWindow) { return false } taskView = taskContainer.taskView this.taskContainer = taskContainer this.alignSecondRow = alignSecondRow if (!populateMenu()) return false addScrim() show() return true } private fun addScrim() { scrim = View(context).apply { layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT ) setBackgroundColor(Themes.getAttrColor(context, R.attr.overviewScrimColor)) alpha = 0f } popupContainer.addView(scrim) } /** @return true if successfully able to populate task view menu, false otherwise */ private fun populateMenu(): Boolean { Loading Loading @@ -180,19 +207,51 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { } override fun onCreateOpenAnimation(anim: AnimatorSet) { scrim?.let { anim.play( ObjectAnimator.ofFloat( taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, TaskView.MAX_PAGE_SCRIM_ALPHA ) ObjectAnimator.ofFloat(it, View.ALPHA, 0f, scrimAlpha) .setDuration(OPEN_DURATION.toLong()) ) } } override fun onCreateCloseAnimation(anim: AnimatorSet) { scrim?.let { anim.play( ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f) ObjectAnimator.ofFloat(it, View.ALPHA, scrimAlpha, 0f) .setDuration(CLOSE_DURATION.toLong()) ) } } override fun closeComplete() { super.closeComplete() popupContainer.removeView(scrim) popupContainer.removeView(iconView) } /** * Copy the iconView from taskView to dragLayer so it can stay on top of the scrim. * It needs to be called after [getTargetObjectLocation] because [mTempRect] needs to be * populated. */ private fun copyIconToDragLayer(insets: Rect) { iconView = IconView(context).apply { layoutParams = FrameLayout.LayoutParams( taskContainer.iconView.width, taskContainer.iconView.height ) x = mTempRect.left.toFloat() - insets.left y = mTempRect.top.toFloat() - insets.top drawable = taskContainer.iconView.drawable setDrawableSize( taskContainer.iconView.drawableWidth, taskContainer.iconView.drawableHeight ) } popupContainer.addView(iconView) } /** * Orients this container to the left or right of the given icon, aligning with the first option Loading @@ -217,7 +276,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { val dragLayer: InsettableFrameLayout = popupContainer val insets = dragLayer.insets // Put to the right of the icon if there is space, which means left aligned with the menu copyIconToDragLayer(insets) // Put this menu to the right of the icon if there is space, // which means the arrow is left aligned with the menu val rightAlignedMenuStartX = mTempRect.left - widthWithArrow val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace mIsLeftAligned = if (mIsRtl) { Loading @@ -229,18 +291,17 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX // Offset y so that the arrow and first row are center-aligned with the original icon. // Offset y so that the arrow and row are center-aligned with the original icon. val iconHeight = mTempRect.height() val optionHeight = optionMeasuredHeight val yOffset = (optionHeight - iconHeight) / 2 var menuStartY = mTempRect.top - yOffset val yOffset = (optionMeasuredHeight - iconHeight) / 2 var menuStartY = mTempRect.top - yOffset - extraSpaceForSecondRowAlignment // Insets are added later, so subtract them now. menuStartX -= insets.left menuStartY -= insets.top setX(menuStartX.toFloat()) setY(menuStartY.toFloat()) x = menuStartX.toFloat() y = menuStartY.toFloat() val lp = layoutParams as FrameLayout.LayoutParams val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams Loading @@ -251,7 +312,8 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> { override fun addArrow() { popupContainer.addView(mArrow) mArrow.x = getArrowX() mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) + extraSpaceForSecondRowAlignment updateArrowColor() Loading
quickstep/src/com/android/quickstep/views/TaskView.java +3 −1 Original line number Diff line number Diff line Loading @@ -840,7 +840,9 @@ public class TaskView extends FrameLayout implements Reusable { TaskIdAttributeContainer menuContainer = mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1]; if (mActivity.getDeviceProfile().overviewShowAsGrid) { return TaskMenuViewWithArrow.Companion.showForTask(menuContainer); boolean alignSecondRow = getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) && mActivity.getDeviceProfile().isLandscape; return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignSecondRow); } else { return TaskMenuView.showForTask(menuContainer); } Loading