1/*
2 * Copyright (C) 2013 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
17package com.android.gallery3d.filtershow.category;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.graphics.Bitmap;
22import android.graphics.BitmapFactory;
23import android.graphics.Canvas;
24import android.graphics.Color;
25import android.graphics.LinearGradient;
26import android.graphics.Matrix;
27import android.graphics.Paint;
28import android.graphics.Rect;
29import android.graphics.RectF;
30import android.graphics.Shader;
31import android.graphics.Typeface;
32import android.util.AttributeSet;
33import android.view.View;
34import com.android.gallery3d.R;
35
36public class IconView extends View {
37
38    public static final int VERTICAL = 0;
39    public static final int HORIZONTAL = 1;
40
41    private Paint mPaint = new Paint();
42    private int mTextColor;
43    private int mBackgroundColor;
44    private int mMargin = 16;
45    private int mOrientation = HORIZONTAL;
46    private int mTextSize = 32;
47    private Rect mTextBounds = new Rect();
48    private Bitmap mBitmap;
49    private Rect mBitmapBounds;
50    private String mText;
51    private boolean mUseOnlyDrawable = false;
52
53    public IconView(Context context, AttributeSet attrs) {
54        super(context, attrs);
55        setup(context);
56        int bitmapRsc = attrs.getAttributeResourceValue(
57                "http://schemas.android.com/apk/res/android", "src", 0);
58        Resources res = context.getResources();
59        Bitmap bitmap = BitmapFactory.decodeStream(res.openRawResource(bitmapRsc));
60        setBitmap(bitmap);
61        setUseOnlyDrawable(true);
62    }
63
64    public IconView(Context context) {
65        super(context);
66        setup(context);
67    }
68
69    private void setup(Context context) {
70        Resources res = getResources();
71        mTextColor = res.getColor(R.color.filtershow_categoryview_text);
72        mBackgroundColor = res.getColor(R.color.filtershow_categoryview_background);
73        mMargin = res.getDimensionPixelOffset(R.dimen.category_panel_margin);
74        mTextSize = res.getDimensionPixelSize(R.dimen.category_panel_text_size);
75    }
76
77    protected void computeTextPosition(String text) {
78        if (text == null) {
79            return;
80        }
81        mPaint.setTextSize(mTextSize);
82        if (getOrientation() == VERTICAL) {
83            text = text.toUpperCase();
84            // TODO: set this in xml
85            mPaint.setTypeface(Typeface.DEFAULT_BOLD);
86        }
87        mPaint.getTextBounds(text, 0, text.length(), mTextBounds);
88    }
89
90    public boolean needsCenterText() {
91        if (mOrientation == HORIZONTAL) {
92            return true;
93        }
94        return false;
95    }
96
97    protected void drawText(Canvas canvas, String text) {
98        if (text == null) {
99            return;
100        }
101        float textWidth = mPaint.measureText(text);
102        int x = (int) (canvas.getWidth() - textWidth - 2*mMargin);
103        if (needsCenterText()) {
104            x = (int) ((canvas.getWidth() - textWidth) / 2.0f);
105        }
106        if (x < 0) {
107            // If the text takes more than the view width,
108            // justify to the left.
109            x = mMargin;
110        }
111        int y = canvas.getHeight() - 2*mMargin;
112        canvas.drawText(text, x, y, mPaint);
113    }
114
115    protected void drawOutlinedText(Canvas canvas, String text) {
116        mPaint.setColor(getBackgroundColor());
117        mPaint.setStyle(Paint.Style.STROKE);
118        mPaint.setStrokeWidth(3);
119        drawText(canvas, text);
120        mPaint.setColor(getTextColor());
121        mPaint.setStyle(Paint.Style.FILL);
122        mPaint.setStrokeWidth(1);
123        drawText(canvas, text);
124    }
125
126    public int getOrientation() {
127        return mOrientation;
128    }
129
130    public void setOrientation(int orientation) {
131        mOrientation = orientation;
132    }
133
134    public int getMargin() {
135        return mMargin;
136    }
137
138    public int getTextSize() {
139        return mTextSize;
140    }
141
142    public int getTextColor() {
143        return mTextColor;
144    }
145
146    public int getBackgroundColor() {
147        return mBackgroundColor;
148    }
149
150    public void setText(String text) {
151        mText = text;
152    }
153
154    public String getText() {
155        return mText;
156    }
157
158    public void setBitmap(Bitmap bitmap) {
159        mBitmap = bitmap;
160    }
161
162    public void setUseOnlyDrawable(boolean value) {
163        mUseOnlyDrawable = value;
164    }
165
166    public Rect getBitmapBounds() {
167        return mBitmapBounds;
168    }
169
170    @Override
171    public CharSequence getContentDescription () {
172        return mText;
173    }
174
175    public boolean isHalfImage() {
176        return false;
177    }
178
179    public void computeBitmapBounds() {
180        if (mUseOnlyDrawable) {
181            mBitmapBounds = new Rect(mMargin/2, mMargin, getWidth() - mMargin/2,
182                    getHeight() - mTextSize - 2*mMargin);
183        } else {
184            if (getOrientation() == VERTICAL && isHalfImage()) {
185                mBitmapBounds = new Rect(mMargin/2, mMargin, getWidth()/2, getHeight());
186            } else {
187                mBitmapBounds = new Rect(mMargin/2, mMargin, getWidth() - mMargin/2, getHeight());
188            }
189        }
190    }
191
192    @Override
193    public void onDraw(Canvas canvas) {
194        mPaint.reset();
195        mPaint.setAntiAlias(true);
196        mPaint.setFilterBitmap(true);
197        canvas.drawColor(mBackgroundColor);
198        computeBitmapBounds();
199        computeTextPosition(getText());
200        if (mBitmap != null) {
201            canvas.save();
202            canvas.clipRect(mBitmapBounds);
203            Matrix m = new Matrix();
204            if (mUseOnlyDrawable) {
205                mPaint.setFilterBitmap(true);
206                m.setRectToRect(new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight()),
207                        new RectF(mBitmapBounds), Matrix.ScaleToFit.CENTER);
208            } else {
209                float scaleWidth = mBitmapBounds.width() / (float) mBitmap.getWidth();
210                float scaleHeight = mBitmapBounds.height() / (float) mBitmap.getHeight();
211                float scale = Math.max(scaleWidth, scaleHeight);
212                float dx = (mBitmapBounds.width() - (mBitmap.getWidth() * scale)) / 2f;
213                float dy = (mBitmapBounds.height() - (mBitmap.getHeight() * scale)) / 2f;
214                dx += mBitmapBounds.left;
215                dy += mBitmapBounds.top;
216                m.postScale(scale, scale);
217                m.postTranslate(dx, dy);
218            }
219
220            canvas.drawBitmap(mBitmap, m, mPaint);
221            canvas.restore();
222        }
223
224        if (!mUseOnlyDrawable) {
225            int startColor = Color.argb(0, 0, 0, 0);
226            int endColor = Color.argb(200, 0, 0, 0);
227            float start = getHeight() - 2 * mMargin - 2 * mTextSize;
228            float end = getHeight();
229            Shader shader = new LinearGradient(0, start, 0, end, startColor,
230                    endColor, Shader.TileMode.CLAMP);
231            mPaint.setShader(shader);
232            float startGradient = 0;
233            if (getOrientation() == VERTICAL && isHalfImage()) {
234                startGradient = getWidth()/2;
235            }
236            canvas.drawRect(new RectF(startGradient, start, getWidth(), end), mPaint);
237            mPaint.setShader(null);
238        }
239        drawOutlinedText(canvas, getText());
240    }
241}
242