blob: cb16039a20f22f49ec08e4b8a2834175e7c3d757 [file] [log] [blame]
Alexandre Lisiona8b78722013-12-13 10:18:33 -05001/*
Alexandre Lisionc1024c02014-01-06 11:12:53 -05002 * Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
Alexandre Lisiona8b78722013-12-13 10:18:33 -05003 *
4 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * Additional permission under GNU GPL version 3 section 7:
21 *
22 * If you modify this program, or any covered work, by linking or
23 * combining it with the OpenSSL project's OpenSSL library (or a
24 * modified version of that library), containing parts covered by the
25 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
26 * grants you additional permission to convey the resulting work.
27 * Corresponding Source for a non-source form of such a combination
28 * shall include the source code for the parts of OpenSSL used as well
29 * as that of the covered work.
30 */
31
Alexandre Lision21b4bed2013-11-07 10:53:02 -050032package org.sflphone.views;
33
34import android.annotation.SuppressLint;
35import android.content.Context;
36import android.graphics.Bitmap;
37import android.graphics.BitmapShader;
38import android.graphics.Canvas;
39import android.graphics.Color;
40import android.graphics.Paint;
41import android.graphics.Shader;
42import android.graphics.drawable.BitmapDrawable;
43import android.util.AttributeSet;
44import android.widget.ImageView;
45
46public class CircularImageView extends ImageView
47{
48 private int borderWidth = 4;
49 private int viewWidth;
50 private int viewHeight;
51 private Bitmap image;
52 private Paint paint;
53 private Paint paintBorder;
54 private BitmapShader shader;
55
56 public CircularImageView(Context context)
57 {
58 super(context);
59 setup();
60 }
61
62 public CircularImageView(Context context, AttributeSet attrs)
63 {
64 super(context, attrs);
65 setup();
66 }
67
68 public CircularImageView(Context context, AttributeSet attrs, int defStyle)
69 {
70 super(context, attrs, defStyle);
71 setup();
72 }
73
74 private void setup()
75 {
76 // init paint
77 paint = new Paint();
78 paint.setAntiAlias(true);
79
80 paintBorder = new Paint();
81 setBorderColor(Color.WHITE);
82 paintBorder.setAntiAlias(true);
83 this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
84 paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
85 }
86
87 public void setBorderWidth(int borderWidth)
88 {
89 this.borderWidth = borderWidth;
90 this.invalidate();
91 }
92
93 public void setBorderColor(int borderColor)
94 {
95 if (paintBorder != null)
96 paintBorder.setColor(borderColor);
97
98 this.invalidate();
99 }
100
101 private void loadBitmap()
102 {
103 BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
104
105 if (bitmapDrawable != null)
106 image = bitmapDrawable.getBitmap();
107 }
108
109 @SuppressLint("DrawAllocation")
110 @Override
111 public void onDraw(Canvas canvas)
112 {
113 // load the bitmap
114 loadBitmap();
115
116 // init shader
117 if (image != null)
118 {
119 shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
120 paint.setShader(shader);
121 int circleCenter = viewWidth / 2;
122
123 // circleCenter is the x or y of the view's center
124 // radius is the radius in pixels of the cirle to be drawn
125 // paint contains the shader that will texture the shape
126 canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - 4.0f, paintBorder);
127 canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - 4.0f, paint);
128 }
129 }
130
131 @Override
132 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
133 {
134 int width = measureWidth(widthMeasureSpec);
135 int height = measureHeight(heightMeasureSpec, widthMeasureSpec);
136
137 viewWidth = width - (borderWidth * 2);
138 viewHeight = height - (borderWidth * 2);
139
140 setMeasuredDimension(width, height);
141 }
142
143 private int measureWidth(int measureSpec)
144 {
145 int result = 0;
146 int specMode = MeasureSpec.getMode(measureSpec);
147 int specSize = MeasureSpec.getSize(measureSpec);
148
149 if (specMode == MeasureSpec.EXACTLY)
150 {
151 // We were told how big to be
152 result = specSize;
153 }
154 else
155 {
156 // Measure the text
157 result = viewWidth;
158 }
159
160 return result;
161 }
162
163 private int measureHeight(int measureSpecHeight, int measureSpecWidth)
164 {
165 int result = 0;
166 int specMode = MeasureSpec.getMode(measureSpecHeight);
167 int specSize = MeasureSpec.getSize(measureSpecHeight);
168
169 if (specMode == MeasureSpec.EXACTLY)
170 {
171 // We were told how big to be
172 result = specSize;
173 }
174 else
175 {
176 // Measure the text (beware: ascent is a negative number)
177 result = viewHeight;
178 }
179
180 return (result + 2);
181 }
182}