content: /*
   * 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.PopupContainerWithArrow.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);
      }
  }
  