OSDN Git Service

Fix image icons on Razr M.
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / ui / IconButton.java
1 /*
2  * Copyright (C) 2012 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.gallery3d.filtershow.ui;
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.drawable.BitmapDrawable;
25 import android.util.AttributeSet;
26 import android.widget.Button;
27
28 /**
29  * Class of buttons with both an image icon and text.
30  */
31 public class IconButton extends Button {
32
33     private Bitmap mImageMirror = null;
34     private Bitmap mIcon = null;
35
36     private boolean stale_icon = true;
37
38     public IconButton(Context context) {
39         this(context, null);
40     }
41
42     public IconButton(Context context, AttributeSet attrs) {
43         this(context, attrs, 0);
44     }
45
46     public IconButton(Context context, AttributeSet attrs, int defStyle) {
47         super(context, attrs, defStyle);
48         BitmapDrawable ic = (BitmapDrawable) getCompoundDrawables()[1];
49
50         if (ic != null) {
51             mImageMirror = ic.getBitmap();
52         }
53     }
54
55     /**
56      * Set the image that the button icon will use.  The image bitmap will be scaled
57      * and cropped into the largest square bitmap that will fit cleanly within the
58      * IconButton's layout.
59      *
60      * @param image image that icon will be set to before next draw.
61      */
62     public void setIcon(Bitmap image) {
63         mImageMirror = image;
64         stale_icon = true;
65         invalidate();
66     }
67
68     /**
69      * Creates and sets button icon. Only call after layout.
70      *
71      * @param image bitmap to use as icon
72      */
73     private boolean makeAndSetIcon(Bitmap image) {
74         int size = getGoodIconSideSize();
75         if (size > 0) {
76             return setImageIcon(makeImageIcon(image, size, size));
77         }
78         return false;
79     }
80
81     /**
82      * Sets icon.
83      *
84      * @param image bitmap to set the icon to.
85      */
86     private boolean setImageIcon(Bitmap image) {
87         if (image == null) {
88             return false;
89         }
90         mIcon = image;
91         this.setCompoundDrawablesWithIntrinsicBounds(null,
92                 new BitmapDrawable(getResources(), mIcon), null, null);
93         return true;
94     }
95
96     /**
97      * Generate an icon bitmap from a given bitmap.
98      *
99      * @param image bitmap to use as button icon
100      * @param width icon width
101      * @param height icon height
102      * @return the scaled/cropped icon bitmap
103      */
104     private Bitmap makeImageIcon(Bitmap image, int width, int height) {
105         Rect destination = new Rect(0, 0, width, height);
106         Bitmap bmap = Bitmap.createBitmap(width, height,
107                 Bitmap.Config.ARGB_8888);
108         drawImage(bmap, image, destination);
109         return bmap;
110     }
111
112     /**
113      * Finds a side length for the (square) icon that fits within the button.
114      * Only call after layout.
115      *
116      * @return icon side length
117      */
118     private int getGoodIconSideSize() {
119         Paint p = getPaint();
120         Rect bounds = new Rect();
121         String s = getText().toString();
122         p.getTextBounds(s, 0, s.length(), bounds);
123         int inner_padding = 2 * getCompoundDrawablePadding();
124         int vert = getHeight() - getPaddingTop() - getPaddingBottom() - bounds.height()
125                 - inner_padding;
126         int horiz = getWidth() - getPaddingLeft() - getPaddingRight() - inner_padding;
127         return Math.min(vert, horiz);
128     }
129
130     @Override
131     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
132         super.onSizeChanged(w, h, oldw, oldh);
133         if (w != oldw || h != oldh) {
134             stale_icon = true;
135         }
136     }
137
138     @Override
139     protected void onDraw(Canvas canvas) {
140         if (stale_icon && mImageMirror != null && mImageMirror.getHeight() > 0
141                 && mImageMirror.getWidth() > 0) {
142             stale_icon = !makeAndSetIcon(mImageMirror);
143         }
144         super.onDraw(canvas);
145     }
146
147     /**
148      * Draws the src image into the destination rectangle within the dst bitmap.
149      * If src is a non-square image, clips to be a square before drawing into dst.
150      *
151      * @param dst  bitmap being drawn on.
152      * @param src  bitmap to draw into dst.
153      * @param destination  square in dst in which to draw src.
154      */
155     protected static void drawImage(Bitmap dst, Bitmap src, Rect destination) {
156         if (src != null && dst != null && src.getWidth() > 0 && dst.getWidth() > 0
157                 && src.getHeight() > 0 && dst.getHeight() > 0) {
158             Canvas canvas = new Canvas(dst);
159             int iw = src.getWidth();
160             int ih = src.getHeight();
161             int x = 0;
162             int y = 0;
163             int size = 0;
164             Rect source = null;
165             if (iw > ih) {
166                 size = ih;
167                 x = (int) ((iw - size) / 2.0f);
168                 y = 0;
169             } else {
170                 size = iw;
171                 x = 0;
172                 y = (int) ((ih - size) / 2.0f);
173             }
174             source = new Rect(x, y, x + size, y + size);
175             canvas.drawBitmap(src, source, destination, new Paint());
176         }
177     }
178
179 }