Change single stroke focus outline to double stroke
Add paint for inner stroke, add padding for launcher widget
Bug: 327386149
Test: Manual
Flag: ACONFIG com.android.launcher3.enable_focus_outline Teamfood
Change-Id: I59cf1088209370b89f2faffdab80787f1b0c1e3b
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 57d1228..2e70a3d 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -43,6 +43,7 @@
<attr name="popupNotificationDotColor" format="color" />
<attr name="notificationDotColor" format="color" />
<attr name="focusOutlineColor" format="color" />
+ <attr name="focusInnerOutlineColor" format="color" />
<attr name="pageIndicatorDotColor" format="color" />
<attr name="folderPreviewColor" format="color" />
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c141095..1f602af 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -447,7 +447,11 @@
<dimen name="split_instructions_start_margin_cancel">8dp</dimen>
<dimen name="focus_outline_radius">16dp</dimen>
- <dimen name="focus_outline_stroke_width">3dp</dimen>
+ <dimen name="focus_inner_outline_radius">14dp</dimen>
+ <dimen name="focus_outline_stroke_width">2dp</dimen>
+ <!-- -4dp for double stroke focus outlines, -2dp for padding between outline and widget,
+ make it negative to outset the rect and leave space for drawing focus outline and padding -->
+ <dimen name="focus_rect_widget_outsets">-6dp</dimen>
<!-- Workspace grid visualization parameters -->
<dimen name="grid_visualization_rounding_radius">16dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 9fc393b..9e34e09 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -53,7 +53,8 @@
<item name="workspaceKeyShadowColor">#89000000</item>
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
<item name="pageIndicatorDotColor">@color/page_indicator_dot_color_light</item>
- <item name="focusOutlineColor">@color/material_color_on_secondary_container</item>
+ <item name="focusOutlineColor">@color/material_color_secondary_fixed</item>
+ <item name="focusInnerOutlineColor">@color/material_color_on_secondary_fixed_variant</item>
<item name="folderPreviewColor">@color/folder_preview_light</item>
<item name="folderBackgroundColor">@color/folder_background_light</item>
<item name="folderIconBorderColor">?android:attr/colorPrimary</item>
diff --git a/src/com/android/launcher3/keyboard/FocusIndicatorHelper.java b/src/com/android/launcher3/keyboard/FocusIndicatorHelper.java
index 3e320bd..72dc63e 100644
--- a/src/com/android/launcher3/keyboard/FocusIndicatorHelper.java
+++ b/src/com/android/launcher3/keyboard/FocusIndicatorHelper.java
@@ -31,9 +31,11 @@
implements OnFocusChangeListener {
public FocusIndicatorHelper(View container) {
- super(container, Flags.enableFocusOutline() ? Themes.getAttrColor(container.getContext(),
- R.attr.focusOutlineColor)
- : container.getResources().getColor(R.color.focused_background));
+ super(container,
+ Flags.enableFocusOutline() ? new int[]{Themes.getAttrColor(container.getContext(),
+ R.attr.focusOutlineColor), Themes.getAttrColor(container.getContext(),
+ R.attr.focusInnerOutlineColor)}
+ : new int[]{container.getResources().getColor(R.color.focused_background)});
}
@Override
diff --git a/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java b/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java
index a8cd03b..456cde8 100644
--- a/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java
+++ b/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java
@@ -74,7 +74,8 @@
private static final Rect sTempRect2 = new Rect();
private final View mContainer;
- protected final Paint mPaint;
+ protected final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Paint mInnerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final int mMaxAlpha;
private final Rect mDirtyRect = new Rect();
@@ -93,24 +94,31 @@
private ObjectAnimator mCurrentAnimation;
private float mAlpha;
private float mRadius;
+ private float mInnerRadius;
- public ItemFocusIndicatorHelper(View container, int color) {
+ public ItemFocusIndicatorHelper(View container, int... colors) {
mContainer = container;
- mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mPaint.setColor(0xFF000000 | color);
- if (Flags.enableFocusOutline()) {
+ mPaint.setColor(0xFF000000 | colors[0]);
+ if (Flags.enableFocusOutline() && colors.length > 1) {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(container.getResources().getDimensionPixelSize(
R.dimen.focus_outline_stroke_width));
mRadius = container.getResources().getDimensionPixelSize(
R.dimen.focus_outline_radius);
+
+ mInnerPaint.setStyle(Paint.Style.STROKE);
+ mInnerPaint.setColor(0xFF000000 | colors[1]);
+ mInnerPaint.setStrokeWidth(container.getResources().getDimensionPixelSize(
+ R.dimen.focus_outline_stroke_width));
+ mInnerRadius = container.getResources().getDimensionPixelSize(
+ R.dimen.focus_inner_outline_radius);
} else {
mPaint.setStyle(Paint.Style.FILL);
mRadius = container.getResources().getDimensionPixelSize(
R.dimen.grid_visualization_rounding_radius);
}
- mMaxAlpha = Color.alpha(color);
+ mMaxAlpha = Color.alpha(colors[0]);
setAlpha(0);
mShift = 0;
@@ -119,6 +127,7 @@
protected void setAlpha(float alpha) {
mAlpha = alpha;
mPaint.setAlpha((int) (mAlpha * mMaxAlpha));
+ mInnerPaint.setAlpha((int) (mAlpha * mMaxAlpha));
}
@Override
@@ -147,11 +156,18 @@
Rect newRect = getDrawRect();
if (newRect != null) {
if (Flags.enableFocusOutline()) {
- // Stroke is drawn with half outside and half inside the view. Inset by half
- // stroke width to move the whole stroke inside the view and avoid other views
- // occluding it
- int halfStrokeWidth = (int) mPaint.getStrokeWidth() / 2;
- newRect.inset(halfStrokeWidth, halfStrokeWidth);
+ int strokeWidth = (int) mPaint.getStrokeWidth();
+ // Inset for inner outline. Stroke is drawn with half outside and half inside
+ // the view. Inset by half stroke width to move the whole stroke inside the view
+ // and avoid other views occluding it. Inset one more stroke width to leave space
+ // for outer outline.
+ newRect.inset((int) (strokeWidth * 1.5), (int) (strokeWidth * 1.5));
+ c.drawRoundRect((float) newRect.left, (float) newRect.top,
+ (float) newRect.right, (float) newRect.bottom,
+ mInnerRadius, mInnerRadius, mInnerPaint);
+
+ // Inset outward for drawing outer outline
+ newRect.inset(-strokeWidth, -strokeWidth);
}
mDirtyRect.set(newRect);
c.drawRoundRect((float) mDirtyRect.left, (float) mDirtyRect.top,
diff --git a/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java b/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java
index f9bd343..4653bf1 100644
--- a/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java
+++ b/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java
@@ -27,6 +27,7 @@
public class ViewGroupFocusHelper extends FocusIndicatorHelper {
private final View mContainer;
+ private static final Rect sTempRect = new Rect();
public ViewGroupFocusHelper(View container) {
super(container);
@@ -35,18 +36,22 @@
@Override
public void viewToRect(View v, Rect outRect) {
- outRect.left = 0;
- outRect.top = 0;
+ // Using FocusedRect here allows views to provide their custom rect for drawing outline,
+ // e.g. making the Rect bigger than the content to leave some padding between view and
+ // outline
+ v.getFocusedRect(sTempRect);
+ outRect.left = sTempRect.left;
+ outRect.top = sTempRect.top;
computeLocationRelativeToContainer(v, outRect);
// If a view is scaled, its position will also shift accordingly. For optimization, only
// consider this for the last node.
- outRect.left += (1 - v.getScaleX()) * v.getWidth() / 2;
- outRect.top += (1 - v.getScaleY()) * v.getHeight() / 2;
+ outRect.left = (int) (outRect.left + (1 - v.getScaleX()) * sTempRect.width() / 2);
+ outRect.top = (int) (outRect.top + (1 - v.getScaleY()) * sTempRect.height() / 2);
- outRect.right = outRect.left + (int) (v.getScaleX() * v.getWidth());
- outRect.bottom = outRect.top + (int) (v.getScaleY() * v.getHeight());
+ outRect.right = outRect.left + (int) (v.getScaleX() * sTempRect.width());
+ outRect.bottom = outRect.top + (int) (v.getScaleY() * sTempRect.height());
}
private void computeLocationRelativeToContainer(View child, Rect outRect) {
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 2259e3c..c3e9ad6 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -92,6 +92,8 @@
private boolean mTrackingWidgetUpdate = false;
+ private int mFocusRectOutsets = 0;
+
public LauncherAppWidgetHostView(Context context) {
super(context);
mActivityContext = ActivityContext.lookupContext(context);
@@ -100,6 +102,8 @@
setBackgroundResource(R.drawable.widget_internal_focus_bg);
if (Flags.enableFocusOutline()) {
setDefaultFocusHighlightEnabled(false);
+ mFocusRectOutsets = context.getResources().getDimensionPixelSize(
+ R.dimen.focus_rect_widget_outsets);
}
if (Themes.getAttrBoolean(context, R.attr.isWorkspaceDarkText)) {
@@ -269,6 +273,13 @@
}
@Override
+ public void getFocusedRect(Rect r) {
+ super.getFocusedRect(r);
+ // Outset to a larger rect for drawing a padding between focus outline and widget
+ r.inset(mFocusRectOutsets, mFocusRectOutsets);
+ }
+
+ @Override
public void onTouchComplete() {
if (!mLongPressHelper.hasPerformedLongPress()) {
// If a long press has been performed, we don't want to clear the record of that since