diff options
Diffstat (limited to 'src/com/android/launcher3/apppairs/AppPairIconBackground.java')
-rw-r--r-- | src/com/android/launcher3/apppairs/AppPairIconBackground.java | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/com/android/launcher3/apppairs/AppPairIconBackground.java b/src/com/android/launcher3/apppairs/AppPairIconBackground.java new file mode 100644 index 0000000000..4e60ece170 --- /dev/null +++ b/src/com/android/launcher3/apppairs/AppPairIconBackground.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.apppairs; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.os.Build; + +import com.android.launcher3.R; + +/** + * A Drawable for the background behind the twin app icons (looks like two rectangles). + */ +class AppPairIconBackground extends Drawable { + // The underlying view that we are drawing this background on. + private final AppPairIconGraphic icon; + private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + + /** + * Null values to use with + * {@link Canvas#drawDoubleRoundRect(RectF, float[], RectF, float[], Paint)}, since there + * doesn't seem to be any other API for drawing rectangles with 4 different corner radii. + */ + private static final RectF EMPTY_RECT = new RectF(); + private static final float[] ARRAY_OF_ZEROES = new float[8]; + + AppPairIconBackground(Context context, AppPairIconGraphic iconGraphic) { + icon = iconGraphic; + // Set up background paint color + TypedArray ta = context.getTheme().obtainStyledAttributes(R.styleable.FolderIconPreview); + mBackgroundPaint.setStyle(Paint.Style.FILL); + mBackgroundPaint.setColor( + ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0)); + ta.recycle(); + } + + @Override + public void draw(Canvas canvas) { + if (icon.isLeftRightSplit()) { + drawLeftRightSplit(canvas); + } else { + drawTopBottomSplit(canvas); + } + } + + /** + * When device is in landscape, we draw the rectangles with a left-right split. + */ + private void drawLeftRightSplit(Canvas canvas) { + // Get the bounds where we will draw the background image + int width = getBounds().width(); + int height = getBounds().height(); + + // The left half of the background image, excluding center channel + RectF leftSide = new RectF( + 0, + 0, + (width / 2f) - (icon.getCenterChannelSize() / 2f), + height + ); + // The right half of the background image, excluding center channel + RectF rightSide = new RectF( + (width / 2f) + (icon.getCenterChannelSize() / 2f), + 0, + width, + height + ); + + drawCustomRoundedRect(canvas, leftSide, new float[]{ + icon.getBigRadius(), icon.getBigRadius(), + icon.getSmallRadius(), icon.getSmallRadius(), + icon.getSmallRadius(), icon.getSmallRadius(), + icon.getBigRadius(), icon.getBigRadius()}); + drawCustomRoundedRect(canvas, rightSide, new float[]{ + icon.getSmallRadius(), icon.getSmallRadius(), + icon.getBigRadius(), icon.getBigRadius(), + icon.getBigRadius(), icon.getBigRadius(), + icon.getSmallRadius(), icon.getSmallRadius()}); + } + + /** + * When device is in portrait, we draw the rectangles with a top-bottom split. + */ + private void drawTopBottomSplit(Canvas canvas) { + // Get the bounds where we will draw the background image + int width = getBounds().width(); + int height = getBounds().height(); + + // The top half of the background image, excluding center channel + RectF topSide = new RectF( + 0, + 0, + width, + (height / 2f) - (icon.getCenterChannelSize() / 2f) + ); + // The bottom half of the background image, excluding center channel + RectF bottomSide = new RectF( + 0, + (height / 2f) + (icon.getCenterChannelSize() / 2f), + width, + height + ); + + drawCustomRoundedRect(canvas, topSide, new float[]{ + icon.getBigRadius(), icon.getBigRadius(), + icon.getBigRadius(), icon.getBigRadius(), + icon.getSmallRadius(), icon.getSmallRadius(), + icon.getSmallRadius(), icon.getSmallRadius()}); + drawCustomRoundedRect(canvas, bottomSide, new float[]{ + icon.getSmallRadius(), icon.getSmallRadius(), + icon.getSmallRadius(), icon.getSmallRadius(), + icon.getBigRadius(), icon.getBigRadius(), + icon.getBigRadius(), icon.getBigRadius()}); + } + + /** + * Draws a rectangle with custom rounded corners. + * @param c The Canvas to draw on. + * @param rect The bounds of the rectangle. + * @param radii An array of 8 radii for the corners: top left x, top left y, top right x, top + * right y, bottom right x, and so on. + */ + private void drawCustomRoundedRect(Canvas c, RectF rect, float[] radii) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + // Canvas.drawDoubleRoundRect is supported from Q onward + c.drawDoubleRoundRect(rect, radii, EMPTY_RECT, ARRAY_OF_ZEROES, mBackgroundPaint); + } else { + // Fallback rectangle with uniform rounded corners + c.drawRoundRect(rect, icon.getBigRadius(), icon.getBigRadius(), mBackgroundPaint); + } + } + + @Override + public int getOpacity() { + return PixelFormat.OPAQUE; + } + + @Override + public void setAlpha(int i) { + // Required by Drawable but not used. + } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + // Required by Drawable but not used. + } +} |