Scale AppPair background on hover.

Fix: 342133586
Test: manual.
Flag: EXEMPT bugfix
Change-Id: I2846b5543076688a90e8b9067f848c59e4081ea2
This commit is contained in:
Pat Manning
2024-07-02 17:26:52 +01:00
parent 38b9e1438e
commit 19d5bc7a48
5 changed files with 96 additions and 0 deletions
+22
View File
@@ -380,6 +380,28 @@ public final class Utilities {
outPivot.y = dst.top + dst.height() * pivotYPct;
}
/**
* Scales a {@code RectF} in place about a specified pivot point.
*
* <p>This method modifies the given {@code RectF} directly to scale it proportionally
* by the given {@code scale}, while preserving its center at the specified
* {@code (pivotX, pivotY)} coordinates.
*
* @param rectF the {@code RectF} to scale, modified directly.
* @param pivotX the x-coordinate of the pivot point about which to scale.
* @param pivotY the y-coordinate of the pivot point about which to scale.
* @param scale the factor by which to scale the rectangle. Values less than 1 will
* shrink the rectangle, while values greater than 1 will enlarge it.
*/
public static void scaleRectFAboutPivot(RectF rectF, float pivotX, float pivotY, float scale) {
rectF.offset(-pivotX, -pivotY);
rectF.left *= scale;
rectF.top *= scale;
rectF.right *= scale;
rectF.bottom *= scale;
rectF.offset(pivotX, pivotY);
}
/**
* Maps t from one range to another range.
* @param t The value to map.
@@ -18,10 +18,12 @@ package com.android.launcher3.apppairs;
import static com.android.launcher3.BubbleTextView.DISPLAY_FOLDER;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -54,6 +56,26 @@ import java.util.function.Predicate;
public class AppPairIcon extends FrameLayout implements DraggableView, Reorderable {
private static final String TAG = "AppPairIcon";
// The duration of the scaling animation on hover enter/exit.
private static final int HOVER_SCALE_DURATION = 150;
// The default scale of the icon when not hovered.
private static final Float HOVER_SCALE_DEFAULT = 1f;
// The max scale of the icon when hovered.
private static final Float HOVER_SCALE_MAX = 1.1f;
// Animates the scale of the icon background on hover.
private static final FloatProperty<AppPairIcon> HOVER_SCALE_PROPERTY =
new FloatProperty<>("hoverScale") {
@Override
public void setValue(AppPairIcon view, float scale) {
view.mIconGraphic.setHoverScale(scale);
}
@Override
public Float get(AppPairIcon view) {
return view.mIconGraphic.getHoverScale();
}
};
// A view that holds the app pair icon graphic.
private AppPairIconGraphic mIconGraphic;
// A view that holds the app pair's title.
@@ -250,4 +272,14 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public void onHoverChanged(boolean hovered) {
super.onHoverChanged(hovered);
ObjectAnimator
.ofFloat(this, HOVER_SCALE_PROPERTY,
hovered ? HOVER_SCALE_MAX : HOVER_SCALE_DEFAULT)
.setDuration(HOVER_SCALE_DURATION)
.start();
}
}
@@ -26,6 +26,7 @@ import android.os.Build;
import androidx.annotation.NonNull;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.FastBitmapDrawable;
/**
@@ -128,6 +129,18 @@ public class AppPairIconDrawable extends Drawable {
height - (mP.getStandardIconPadding() + mP.getOuterPadding())
);
// Scale each background from its center edge closest to the center channel.
Utilities.scaleRectFAboutPivot(
leftSide,
leftSide.left + leftSide.width(),
leftSide.top + leftSide.centerY(),
mP.getHoverScale());
Utilities.scaleRectFAboutPivot(
rightSide,
rightSide.left,
rightSide.top + rightSide.centerY(),
mP.getHoverScale());
drawCustomRoundedRect(canvas, leftSide, new float[]{
mP.getBigRadius(), mP.getBigRadius(),
mP.getSmallRadius(), mP.getSmallRadius(),
@@ -163,6 +176,18 @@ public class AppPairIconDrawable extends Drawable {
height - (mP.getStandardIconPadding() + mP.getOuterPadding())
);
// Scale each background from its center edge closest to the center channel.
Utilities.scaleRectFAboutPivot(
topSide,
topSide.left + topSide.centerX(),
topSide.top + topSide.height(),
mP.getHoverScale());
Utilities.scaleRectFAboutPivot(
bottomSide,
bottomSide.left + bottomSide.centerX(),
bottomSide.top,
mP.getHoverScale());
drawCustomRoundedRect(canvas, topSide, new float[]{
mP.getBigRadius(), mP.getBigRadius(),
mP.getBigRadius(), mP.getBigRadius(),
@@ -64,6 +64,8 @@ class AppPairIconDrawingParams(val context: Context, container: Int) {
var isLeftRightSplit: Boolean = true
// The background paint color (based on container).
var bgColor: Int = 0
// The scale of the icon background while hovered.
var hoverScale: Float = 1f
init {
val activity: ActivityContext = ActivityContext.lookupContext(context)
@@ -139,4 +139,19 @@ constructor(context: Context, attrs: AttributeSet? = null) :
super.dispatchDraw(canvas)
drawable.draw(canvas)
}
/**
* Sets the scale of the icon background while hovered.
*/
fun setHoverScale(scale: Float) {
drawParams.hoverScale = scale
redraw()
}
/**
* Gets the scale of the icon background while hovered.
*/
fun getHoverScale(): Float {
return drawParams.hoverScale
}
}