Merge "open grid task menu to the right of icon" into sc-v2-dev

This commit is contained in:
Thales Lima 2021-11-18 18:19:58 +00:00 committed by Android (Google) Code Review
commit bd1aec6721
5 changed files with 177 additions and 25 deletions

View File

@ -28,6 +28,7 @@
<dimen name="task_menu_item_corner_radius">4dp</dimen>
<dimen name="task_menu_spacing">2dp</dimen>
<dimen name="task_menu_width_grid">234dp</dimen>
<dimen name="task_menu_horizontal_padding">8dp</dimen>
<dimen name="overview_proactive_row_height">48dp</dimen>
<dimen name="overview_proactive_row_bottom_margin">16dp</dimen>

View File

@ -30,6 +30,7 @@ public class KtR {
public static final class dimen {
public static int task_menu_spacing = R.dimen.task_menu_spacing;
public static int task_menu_horizontal_padding = R.dimen.task_menu_horizontal_padding;
}
public static final class layout {

View File

@ -23,14 +23,18 @@ import android.graphics.Rect
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RectShape
import android.util.AttributeSet
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import com.android.launcher3.BaseDraggingActivity
import com.android.launcher3.DeviceProfile
import com.android.launcher3.InsettableFrameLayout
import com.android.launcher3.R
import com.android.launcher3.popup.ArrowPopup
import com.android.launcher3.popup.RoundedArrowDrawable
import com.android.launcher3.popup.SystemShortcut
import com.android.launcher3.util.Themes
import com.android.quickstep.KtR
@ -43,9 +47,13 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean {
val activity = BaseDraggingActivity
.fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
.fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
val taskMenuViewWithArrow = activity.layoutInflater
.inflate(KtR.layout.task_menu_with_arrow, activity.dragLayer, false) as TaskMenuViewWithArrow<*>
.inflate(
KtR.layout.task_menu_with_arrow,
activity.dragLayer,
false
) as TaskMenuViewWithArrow<*>
return taskMenuViewWithArrow.populateAndShowForTask(taskContainer)
}
@ -53,10 +61,21 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
init {
clipToOutline = true
shouldScaleArrow = true
// This synchronizes the arrow and menu to open at the same time
OPEN_CHILD_FADE_START_DELAY = OPEN_FADE_START_DELAY
OPEN_CHILD_FADE_DURATION = OPEN_FADE_DURATION
CLOSE_FADE_START_DELAY = CLOSE_CHILD_FADE_START_DELAY
CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION
}
private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid)
@ -65,6 +84,13 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
private lateinit var optionLayout: LinearLayout
private lateinit var taskContainer: TaskIdAttributeContainer
private var optionMeasuredHeight = 0
private val arrowHorizontalPadding: Int
get() = if (taskView.isFocusedTask)
resources.getDimensionPixelSize(KtR.dimen.task_menu_horizontal_padding)
else
0
override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0
override fun getTargetObjectLocation(outPos: Rect?) {
@ -147,7 +173,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
}
override fun assignMarginsAndBackgrounds(viewGroup: ViewGroup) {
assignMarginsAndBackgrounds(this, Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface))
assignMarginsAndBackgrounds(
this,
Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface)
)
}
override fun onCreateOpenAnimation(anim: AnimatorSet) {
@ -164,4 +193,90 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f)
)
}
/**
* Orients this container to the left or right of the given icon, aligning with the first option
* or second.
*
* These are the preferred orientations, in order (RTL prefers right-aligned over left):
* - Right and first option aligned
* - Right and second option aligned
* - Left and first option aligned
* - Left and second option aligned
*
* So we always align right if there is enough horizontal space
*/
override fun orientAboutObject() {
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
// Needed for offsets later
optionMeasuredHeight = optionLayout.getChildAt(0).measuredHeight
val extraHorizontalSpace = (mArrowHeight + mArrowOffsetVertical + arrowHorizontalPadding)
val widthWithArrow = measuredWidth + paddingLeft + paddingRight + extraHorizontalSpace
getTargetObjectLocation(mTempRect)
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
val rightAlignedMenuStartX = mTempRect.left - widthWithArrow
val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace
mIsLeftAligned = if (mIsRtl) {
rightAlignedMenuStartX + insets.left < 0
} else {
leftAlignedMenuStartX + (widthWithArrow - extraHorizontalSpace) + insets.left <
dragLayer.width - insets.right
}
var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX
// Offset y so that the arrow and first 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
// Insets are added later, so subtract them now.
menuStartX -= insets.left
menuStartY -= insets.top
setX(menuStartX.toFloat())
setY(menuStartY.toFloat())
val lp = layoutParams as FrameLayout.LayoutParams
val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams
lp.gravity = Gravity.TOP
arrowLp.gravity = lp.gravity
}
override fun addArrow() {
popupContainer.addView(mArrow)
mArrow.x = getArrowX()
mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2)
updateArrowColor()
// This is inverted (x = height, y = width) because the arrow is rotated
mArrow.pivotX = if (mIsLeftAligned) 0f else mArrowHeight.toFloat()
mArrow.pivotY = 0f
}
private fun getArrowX(): Float {
return if (mIsLeftAligned)
x - mArrowHeight
else
x + measuredWidth + mArrowOffsetVertical
}
override fun updateArrowColor() {
mArrow.background = RoundedArrowDrawable(
mArrowWidth.toFloat(),
mArrowHeight.toFloat(),
mArrowPointRadius.toFloat(),
mIsLeftAligned,
mArrowColor
)
elevation = mElevation
mArrow.elevation = mElevation
}
}

View File

@ -77,44 +77,45 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
extends AbstractFloatingView {
// Duration values (ms) for popup open and close animations.
private static final int OPEN_DURATION = 276;
private static final int OPEN_FADE_START_DELAY = 0;
private static final int OPEN_FADE_DURATION = 38;
private static final int OPEN_CHILD_FADE_START_DELAY = 38;
private static final int OPEN_CHILD_FADE_DURATION = 76;
protected int OPEN_DURATION = 276;
protected int OPEN_FADE_START_DELAY = 0;
protected int OPEN_FADE_DURATION = 38;
protected int OPEN_CHILD_FADE_START_DELAY = 38;
protected int OPEN_CHILD_FADE_DURATION = 76;
private static final int CLOSE_DURATION = 200;
private static final int CLOSE_FADE_START_DELAY = 140;
private static final int CLOSE_FADE_DURATION = 50;
private static final int CLOSE_CHILD_FADE_START_DELAY = 0;
private static final int CLOSE_CHILD_FADE_DURATION = 140;
protected int CLOSE_DURATION = 200;
protected int CLOSE_FADE_START_DELAY = 140;
protected int CLOSE_FADE_DURATION = 50;
protected int CLOSE_CHILD_FADE_START_DELAY = 0;
protected int CLOSE_CHILD_FADE_DURATION = 140;
// Index used to get background color when using local wallpaper color extraction,
private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_neutral2_800;
private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50;
private final Rect mTempRect = new Rect();
protected final Rect mTempRect = new Rect();
protected final LayoutInflater mInflater;
private final float mOutlineRadius;
protected final float mOutlineRadius;
protected final T mActivityContext;
protected final boolean mIsRtl;
private final int mArrowOffsetVertical;
private final int mArrowOffsetHorizontal;
private final int mArrowWidth;
private final int mArrowHeight;
private final int mArrowPointRadius;
private final View mArrow;
protected final int mArrowOffsetVertical;
protected final int mArrowOffsetHorizontal;
protected final int mArrowWidth;
protected final int mArrowHeight;
protected final int mArrowPointRadius;
protected final View mArrow;
private final int mMargin;
protected boolean mIsLeftAligned;
protected boolean mIsAboveIcon;
private int mGravity;
protected int mGravity;
protected AnimatorSet mOpenCloseAnimator;
protected boolean mDeferContainerRemoval;
protected boolean shouldScaleArrow = false;
private final GradientDrawable mRoundedTop;
private final GradientDrawable mRoundedBottom;
@ -122,10 +123,10 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
private Runnable mOnCloseCallback = () -> { };
// The rect string of the view that the arrow is attached to, in screen reference frame.
private int mArrowColor;
protected int mArrowColor;
protected final List<LocalColorExtractor> mColorExtractors;
private final float mElevation;
protected final float mElevation;
private final int mBackgroundColor;
private final String mIterateChildrenTag;
@ -729,6 +730,14 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
scale.setInterpolator(interpolator);
animatorSet.play(scale);
if (shouldScaleArrow) {
Animator arrowScaleAnimator = ObjectAnimator.ofFloat(mArrow, View.SCALE_Y,
scaleValues);
arrowScaleAnimator.setDuration(totalDuration);
arrowScaleAnimator.setInterpolator(interpolator);
animatorSet.play(arrowScaleAnimator);
}
fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet);
return animatorSet;

View File

@ -78,6 +78,32 @@ public class RoundedArrowDrawable extends Drawable {
mPath.transform(pathTransform);
}
/**
* Constructor for an arrow that points to the left or right.
*
* @param width of the arrow.
* @param height of the arrow.
* @param radius of the tip of the arrow.
* @param isPointingLeft or not.
* @param color to draw the triangle.
*/
public RoundedArrowDrawable(float width, float height, float radius, boolean isPointingLeft,
int color) {
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
// Make the drawable with the triangle pointing down...
addDownPointingRoundedTriangleToPath(width, height, radius, mPath);
// ... then rotate it to the side it needs to point.
Matrix pathTransform = new Matrix();
pathTransform.setRotate(isPointingLeft ? 90 : -90, width * 0.5f, height * 0.5f);
mPath.transform(pathTransform);
}
@Override
public void draw(Canvas canvas) {
canvas.drawPath(mPath, mPaint);