1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3.widget;
18 
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Canvas;
22 import android.graphics.Paint;
23 import android.graphics.Rect;
24 import android.graphics.RectF;
25 import android.graphics.drawable.Drawable;
26 import android.util.AttributeSet;
27 import android.view.View;
28 
29 import com.android.launcher3.R;
30 import com.android.launcher3.Utilities;
31 
32 /**
33  * View that draws a bitmap horizontally centered. If the image width is greater than the view
34  * width, the image is scaled down appropriately.
35  */
36 public class WidgetImageView extends View {
37 
38     private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
39     private final RectF mDstRectF = new RectF();
40     private final int mBadgeMargin;
41 
42     private Bitmap mBitmap;
43     private Drawable mBadge;
44 
WidgetImageView(Context context)45     public WidgetImageView(Context context) {
46         this(context, null);
47     }
48 
WidgetImageView(Context context, AttributeSet attrs)49     public WidgetImageView(Context context, AttributeSet attrs) {
50         this(context, attrs, 0);
51     }
52 
WidgetImageView(Context context, AttributeSet attrs, int defStyle)53     public WidgetImageView(Context context, AttributeSet attrs, int defStyle) {
54         super(context, attrs, defStyle);
55 
56         mBadgeMargin = context.getResources()
57                 .getDimensionPixelSize(R.dimen.profile_badge_margin);
58     }
59 
setBitmap(Bitmap bitmap, Drawable badge)60     public void setBitmap(Bitmap bitmap, Drawable badge) {
61         mBitmap = bitmap;
62         mBadge = badge;
63         invalidate();
64     }
65 
getBitmap()66     public Bitmap getBitmap() {
67         return mBitmap;
68     }
69 
70     @Override
onDraw(Canvas canvas)71     protected void onDraw(Canvas canvas) {
72         if (mBitmap != null) {
73             updateDstRectF();
74             canvas.drawBitmap(mBitmap, null, mDstRectF, mPaint);
75 
76             // Only draw the badge if a preview was drawn.
77             if (mBadge != null) {
78                 mBadge.draw(canvas);
79             }
80         }
81     }
82 
83     /**
84      * Prevents the inefficient alpha view rendering.
85      */
86     @Override
hasOverlappingRendering()87     public boolean hasOverlappingRendering() {
88         return false;
89     }
90 
updateDstRectF()91     private void updateDstRectF() {
92         float myWidth = getWidth();
93         float myHeight = getHeight();
94         float bitmapWidth = mBitmap.getWidth();
95 
96         final float scale = bitmapWidth > myWidth ? myWidth / bitmapWidth : 1;
97         float scaledWidth = bitmapWidth * scale;
98         float scaledHeight = mBitmap.getHeight() * scale;
99 
100         mDstRectF.left = (myWidth - scaledWidth) / 2;
101         mDstRectF.right = (myWidth + scaledWidth) / 2;
102 
103         if (scaledHeight > myHeight) {
104             mDstRectF.top = 0;
105             mDstRectF.bottom = scaledHeight;
106         } else {
107             mDstRectF.top = (myHeight - scaledHeight) / 2;
108             mDstRectF.bottom = (myHeight + scaledHeight) / 2;
109         }
110 
111         if (mBadge != null) {
112             Rect bounds = mBadge.getBounds();
113             int left = Utilities.boundToRange(
114                     (int) (mDstRectF.right + mBadgeMargin - bounds.width()),
115                     mBadgeMargin, getWidth() - bounds.width());
116             int top = Utilities.boundToRange(
117                     (int) (mDstRectF.bottom + mBadgeMargin - bounds.height()),
118                     mBadgeMargin, getHeight() - bounds.height());
119             mBadge.setBounds(left, top, bounds.width() + left, bounds.height() + top);
120         }
121     }
122 
123     /**
124      * @return the bounds where the image was drawn.
125      */
getBitmapBounds()126     public Rect getBitmapBounds() {
127         updateDstRectF();
128         Rect rect = new Rect();
129         mDstRectF.round(rect);
130         return rect;
131     }
132 }
133