blob: 75c3f26cfdfb216a5c21f1c2f0ffb8da0ac3abe1 [file] [log] [blame]
/*
* Copyright (C) 2017 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.popup;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.popup.BaseActionPopup.RoundedCornerFlags;
import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_BOTTOM_CORNERS;
import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_TOP_CORNERS;
/**
* An abstract {@link FrameLayout} that contains content for {@link PopupContainerWithArrow}.
*/
public abstract class PopupItemView extends FrameLayout {
protected final Rect mPillRect;
protected @RoundedCornerFlags int mRoundedCorners;
protected final boolean mIsRtl;
protected View mIconView;
private final Paint mBackgroundClipPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
private final Matrix mMatrix = new Matrix();
private Bitmap mRoundedCornerBitmap;
public PopupItemView(Context context) {
this(context, null, 0);
}
public PopupItemView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PopupItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mPillRect = new Rect();
// Initialize corner clipping Bitmap and Paint.
int radius = (int) getBackgroundRadius();
mRoundedCornerBitmap = Bitmap.createBitmap(radius, radius, Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas();
canvas.setBitmap(mRoundedCornerBitmap);
canvas.drawArc(0, 0, radius*2, radius*2, 180, 90, true, mBackgroundClipPaint);
mBackgroundClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mIsRtl = Utilities.isRtl(getResources());
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mIconView = findViewById(R.id.popup_item_icon);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mPillRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (mRoundedCorners == 0) {
super.dispatchDraw(canvas);
return;
}
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null);
super.dispatchDraw(canvas);
// Clip children to this item's rounded corners.
int cornerWidth = mRoundedCornerBitmap.getWidth();
int cornerHeight = mRoundedCornerBitmap.getHeight();
int cornerCenterX = Math.round(cornerWidth / 2f);
int cornerCenterY = Math.round(cornerHeight / 2f);
if ((mRoundedCorners & ROUNDED_TOP_CORNERS) != 0) {
// Clip top left corner.
mMatrix.reset();
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
// Clip top right corner.
mMatrix.setRotate(90, cornerCenterX, cornerCenterY);
mMatrix.postTranslate(canvas.getWidth() - cornerWidth, 0);
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
}
if ((mRoundedCorners & ROUNDED_BOTTOM_CORNERS) != 0) {
// Clip bottom right corner.
mMatrix.setRotate(180, cornerCenterX, cornerCenterY);
mMatrix.postTranslate(canvas.getWidth() - cornerWidth, canvas.getHeight() - cornerHeight);
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
// Clip bottom left corner.
mMatrix.setRotate(270, cornerCenterX, cornerCenterY);
mMatrix.postTranslate(0, canvas.getHeight() - cornerHeight);
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
}
canvas.restoreToCount(saveCount);
}
/**
* Creates a round rect drawable (with the specified corners unrounded)
* and sets it as this View's background.
*/
public void setBackgroundWithCorners(int color, @RoundedCornerFlags int roundedCorners) {
mRoundedCorners = roundedCorners;
float rTop = (roundedCorners & ROUNDED_TOP_CORNERS) == 0 ? 0 : getBackgroundRadius();
float rBot = (roundedCorners & ROUNDED_BOTTOM_CORNERS) == 0 ? 0 : getBackgroundRadius();
float[] radii = new float[] {rTop, rTop, rTop, rTop, rBot, rBot, rBot, rBot};
ShapeDrawable roundRectBackground = new ShapeDrawable(new RoundRectShape(radii, null, null));
roundRectBackground.getPaint().setColor(color);
setBackground(roundRectBackground);
}
protected float getBackgroundRadius() {
return getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius);
}
}