blob: 7cb8cefa00a30a0bd9bbdea3ab1e059309a1326e [file] [log] [blame]
Alexandre Lision064e1e02013-10-01 16:18:42 -04001package org.sflphone.model;
2
Alexandre Lisiond588bff2013-10-08 12:43:01 -04003import org.sflphone.R;
Alexandre Lision064e1e02013-10-01 16:18:42 -04004import org.sflphone.adapters.ContactPictureTask;
alisionfe9cf712013-05-03 17:26:08 -04005
6import android.content.Context;
7import android.graphics.Bitmap;
Alexandre Lisiond588bff2013-10-08 12:43:01 -04008import android.graphics.BitmapShader;
alisionfe9cf712013-05-03 17:26:08 -04009import android.graphics.Canvas;
alision2ec64f92013-06-17 17:28:58 -040010import android.graphics.Color;
alisionfe9cf712013-05-03 17:26:08 -040011import android.graphics.Paint;
Alexandre Lisiond588bff2013-10-08 12:43:01 -040012import android.graphics.Paint.Style;
Adrien Béraud25fc4092013-05-06 15:28:39 +100013import android.graphics.PointF;
alisionfe9cf712013-05-03 17:26:08 -040014import android.graphics.RectF;
Alexandre Lisiond588bff2013-10-08 12:43:01 -040015import android.graphics.Shader;
Alexandre Lisiond9c3f7f2013-10-30 15:20:55 -040016import android.view.MotionEvent;
alisionfe9cf712013-05-03 17:26:08 -040017
Alexandre Lision40954dc2013-10-09 15:24:03 -040018public abstract class Bubble {
alision806e18e2013-06-21 15:30:17 -040019
alision2ec64f92013-06-17 17:28:58 -040020 // A Bitmap object that is going to be passed to the BitmapShader
Alexandre Lision40954dc2013-10-09 15:24:03 -040021 protected Bitmap externalBMP;
alisionfe9cf712013-05-03 17:26:08 -040022
Alexandre Lision40954dc2013-10-09 15:24:03 -040023 protected PointF pos = new PointF();
24 protected RectF bounds;
alision2ec64f92013-06-17 17:28:58 -040025 public float target_scale = 1.f;
Alexandre Lision40954dc2013-10-09 15:24:03 -040026 protected float radius;
27 protected float scale = 1.f;
28 protected float density = 1.f;
alision2ec64f92013-06-17 17:28:58 -040029 public PointF speed = new PointF(0, 0);
30 public PointF last_speed = new PointF();
31 public PointF attractor = null;
Alexandre Lision40954dc2013-10-09 15:24:03 -040032 ActionDrawer act;
Alexandre Lision40954dc2013-10-09 15:24:03 -040033
Alexandre Lision68855472013-10-10 16:20:46 -040034 public boolean isUser;
alisionfe9cf712013-05-03 17:26:08 -040035
alision2ec64f92013-06-17 17:28:58 -040036 public boolean dragged = false;
Alexandre Lision6deda412013-09-25 13:21:22 -040037
Alexandre Lision0edf18c2013-09-23 17:35:50 -040038 public boolean markedToDie = false;
alision2ec64f92013-06-17 17:28:58 -040039 public long last_drag;
40 public boolean expanded; // determine if we draw the buttons around the bubble
Alexandre Lision40954dc2013-10-09 15:24:03 -040041 protected Bitmap saved_photo;
alision4a0eb092013-05-07 13:52:03 -040042
Alexandre Lision40954dc2013-10-09 15:24:03 -040043 public interface actions {
Alexandre Lision5cd659e2013-10-29 13:18:23 -040044 int OUT_OF_BOUNDS = -1;
Alexandre Lision40954dc2013-10-09 15:24:03 -040045 int NOTHING = 0;
46 int HOLD = 1;
47 int RECORD = 2;
48 int HANGUP = 3;
49 int MESSAGE = 4;
50 int TRANSFER = 5;
51 int MUTE = 6;
52 }
53
54 protected Context mContext;
Alexandre Lisiond588bff2013-10-08 12:43:01 -040055
alision2ec64f92013-06-17 17:28:58 -040056 public void setAttractor(PointF attractor) {
57 this.attractor = attractor;
58 }
Adrien Béraude0ef0c22013-05-18 01:56:27 +100059
Alexandre Lision40954dc2013-10-09 15:24:03 -040060 public Bubble(Context context, CallContact contact, float x, float y, float size) {
61 mContext = context;
alision2ec64f92013-06-17 17:28:58 -040062 pos.set(x, y);
Alexandre Lision68855472013-10-10 16:20:46 -040063 radius = size / 2; // 10 is the white stroke
Alexandre Lision40954dc2013-10-09 15:24:03 -040064 saved_photo = getContactPhoto(context, contact, (int) size);
65 generateBitmap();
66 attractor = new PointF(x, y);
Alexandre Lisiond5686032013-10-29 11:09:21 -040067 isUser = false;
Alexandre Lision40954dc2013-10-09 15:24:03 -040068 }
Alexandre Lisiond588bff2013-10-08 12:43:01 -040069
Alexandre Lision40954dc2013-10-09 15:24:03 -040070 protected void generateBitmap() {
Alexandre Lision68855472013-10-10 16:20:46 -040071
Alexandre Lisiond588bff2013-10-08 12:43:01 -040072 int w = saved_photo.getWidth(), h = saved_photo.getHeight();
73 if (w > h) {
74 w = h;
75 } else if (h > w) {
76 h = w;
77 }
Alexandre Lision68855472013-10-10 16:20:46 -040078 externalBMP = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Alexandre Lisiond588bff2013-10-08 12:43:01 -040079 BitmapShader shader;
80 shader = new BitmapShader(saved_photo, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
81
82 Paint paint = new Paint();
Alexandre Lision68855472013-10-10 16:20:46 -040083 paint.setDither(true);
Alexandre Lisiond588bff2013-10-08 12:43:01 -040084 paint.setAntiAlias(true);
85 paint.setShader(shader);
86 Canvas internalCanvas = new Canvas(externalBMP);
Alexandre Lision68855472013-10-10 16:20:46 -040087 internalCanvas.drawCircle(w / 2, h / 2, w / 2, paint);
Alexandre Lision40954dc2013-10-09 15:24:03 -040088
89 Paint whiteStroke = new Paint();
90 whiteStroke.setStyle(Style.STROKE);
Alexandre Lision68855472013-10-10 16:20:46 -040091 whiteStroke.setStrokeWidth(8);
92 if (expanded) {
93 whiteStroke.setColor(mContext.getResources().getColor(R.color.sfl_action_blue));
94 } else {
95 whiteStroke.setColor(Color.WHITE);
96 }
97 whiteStroke.setDither(true);
98 whiteStroke.setAntiAlias(true);
99 internalCanvas.drawCircle(w / 2, h / 2, w / 2 - 4, whiteStroke);
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400100
101 bounds = new RectF(pos.x - getRadius(), pos.y - getRadius(), pos.x + getRadius(), pos.y + getRadius());
Alexandre Lision68855472013-10-10 16:20:46 -0400102
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400103 }
alisionfe9cf712013-05-03 17:26:08 -0400104
Alexandre Lision40954dc2013-10-09 15:24:03 -0400105 protected Bitmap getContactPhoto(Context context, CallContact contact, int size) {
106 if (contact.getPhoto_id() > 0) {
107 return ContactPictureTask.loadContactPhoto(context.getContentResolver(), contact.getId());
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400108 } else {
109 return ContactPictureTask.decodeSampledBitmapFromResource(context.getResources(), R.drawable.ic_contact_picture, (int) size, (int) size);
110 }
alision2ec64f92013-06-17 17:28:58 -0400111 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000112
alision2ec64f92013-06-17 17:28:58 -0400113 public Bitmap getBitmap() {
114 return externalBMP;
115 }
alisionfe9cf712013-05-03 17:26:08 -0400116
alision2ec64f92013-06-17 17:28:58 -0400117 public RectF getBounds() {
118 return bounds;
119 }
Adrien Béraud33268882013-05-18 03:41:15 +1000120
Alexandre Lision40954dc2013-10-09 15:24:03 -0400121 public abstract void set(float x, float y, float s);
Adrien Béraud25fc4092013-05-06 15:28:39 +1000122
alision2ec64f92013-06-17 17:28:58 -0400123 public float getPosX() {
124 return pos.x;
125 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000126
alision2ec64f92013-06-17 17:28:58 -0400127 public float getPosY() {
128 return pos.y;
129 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000130
alision2ec64f92013-06-17 17:28:58 -0400131 public void setPos(float x, float y) {
132 set(x, y, scale);
133 }
alisionfe9cf712013-05-03 17:26:08 -0400134
alision2ec64f92013-06-17 17:28:58 -0400135 public PointF getPos() {
136 return pos;
137 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000138
alision2ec64f92013-06-17 17:28:58 -0400139 public float getScale() {
140 return scale;
141 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000142
alision2ec64f92013-06-17 17:28:58 -0400143 public void setScale(float s) {
144 set(pos.x, pos.y, s);
145 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000146
Alexandre Lision40954dc2013-10-09 15:24:03 -0400147 public abstract int getRadius();
Adrien Béraud6bbce912013-05-24 00:48:13 +1000148
alision2ec64f92013-06-17 17:28:58 -0400149 /**
150 * Point intersection test.
151 */
152 boolean intersects(float x, float y) {
alision34673e62013-06-25 14:40:07 -0400153 float dx = x - pos.x;
154 float dy = y - pos.y;
alision50fa0722013-06-25 17:29:44 -0400155
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400156 return dx * dx + dy * dy < getRadius() * getRadius();
alision2ec64f92013-06-17 17:28:58 -0400157 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000158
alision2ec64f92013-06-17 17:28:58 -0400159 /**
160 * Other circle intersection test.
161 */
162 boolean intersects(float x, float y, float radius) {
163 float dx = x - pos.x, dy = y - pos.y;
164 float tot_radius = getRadius() + radius;
165 return dx * dx + dy * dy < tot_radius * tot_radius;
166 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000167
alision2ec64f92013-06-17 17:28:58 -0400168 public void setDensity(float density) {
169 this.density = density;
170 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000171
Alexandre Lision40954dc2013-10-09 15:24:03 -0400172 public abstract void expand(int width, int height);
alision2ec64f92013-06-17 17:28:58 -0400173
174 public void retract() {
175 expanded = false;
Alexandre Lision40954dc2013-10-09 15:24:03 -0400176 generateBitmap();
alision2ec64f92013-06-17 17:28:58 -0400177 }
alisiondf1dac92013-06-27 17:35:53 -0400178
Alexandre Lision0edf18c2013-09-23 17:35:50 -0400179 public boolean isOnBorder(float w, float h) {
180 return (bounds.left < 0 || bounds.right > w || bounds.top < 0 || bounds.bottom > h);
181 }
182
alision729b0a22013-07-02 11:57:33 -0400183 /**
184 * Always return the normal radius of the bubble
alision91d28592013-07-02 14:33:53 -0400185 *
alision729b0a22013-07-02 11:57:33 -0400186 * @return
187 */
188 public float getRetractedRadius() {
189 return radius;
190 }
191
Alexandre Lision40954dc2013-10-09 15:24:03 -0400192 public abstract boolean getHoldStatus();
alision729b0a22013-07-02 11:57:33 -0400193
Alexandre Lision40954dc2013-10-09 15:24:03 -0400194 public abstract boolean getRecordStatus();
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400195
Alexandre Lision40954dc2013-10-09 15:24:03 -0400196 public abstract Bitmap getDrawerBitmap();
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400197
Alexandre Lision40954dc2013-10-09 15:24:03 -0400198 public abstract RectF getDrawerBounds();
Alexandre Lision68855472013-10-10 16:20:46 -0400199
200 protected abstract class ActionDrawer {
201
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400202 int mWidth, mHeight;
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400203 RectF bounds;
Alexandre Lision40954dc2013-10-09 15:24:03 -0400204 Bitmap img;
Alexandre Lisiond5ee3962013-11-08 15:37:28 -0500205 Paint mLines;
206 Paint mBackgroundPaint;
207 Paint mButtonPaint;
208 Paint mSelector;
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400209
Alexandre Lision40954dc2013-10-09 15:24:03 -0400210 public ActionDrawer(int w, int h) {
211
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400212 mWidth = w;
213 mHeight = h;
214 bounds = new RectF(0, 0, 0, 0);
Alexandre Lisiond5ee3962013-11-08 15:37:28 -0500215
216 mButtonPaint = new Paint();
217 mBackgroundPaint = new Paint();
218 mBackgroundPaint.setColor(mContext.getResources().getColor(R.color.sfl_blue_9));
219 mLines = new Paint();
220 mLines.setAntiAlias(true);
221 mLines.setStrokeWidth(2);
222 mLines.setColor(mContext.getResources().getColor(R.color.transparent_grey));
223
224 mSelector = new Paint();
225 mSelector.setStyle(Style.FILL);
226 mSelector.setColor(mContext.getResources().getColor(R.color.sfl_dark_blue));
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400227
Alexandre Lision40954dc2013-10-09 15:24:03 -0400228 }
Alexandre Lision68855472013-10-10 16:20:46 -0400229
Alexandre Lision40954dc2013-10-09 15:24:03 -0400230 /**
231 * When the bubble is expanded we need to check on wich action button the user tap
232 *
233 * @param x
234 * @param y
235 * @return
236 */
237 public abstract int getAction(float x, float y);
Alexandre Lision68855472013-10-10 16:20:46 -0400238
Alexandre Lision40954dc2013-10-09 15:24:03 -0400239 public void setBounds(float f, float y, float g, float h) {
240 bounds.set(f, y, g, h);
241 }
Alexandre Lision68855472013-10-10 16:20:46 -0400242
Alexandre Lisiond9c3f7f2013-10-30 15:20:55 -0400243 public abstract void generateBitmap(int action);
Alexandre Lision68855472013-10-10 16:20:46 -0400244
Alexandre Lision5cd659e2013-10-29 13:18:23 -0400245 public RectF getDrawerBounds() {
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400246 return bounds;
247 }
248
249 public void setBounds(RectF bounds) {
250 this.bounds = bounds;
251 }
252
Alexandre Lision40954dc2013-10-09 15:24:03 -0400253 public Bitmap getBitmap() {
254 return img;
255 }
256
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400257 public int getWidth() {
258 return mWidth;
259 }
260
261 public int getHeight() {
262 return mHeight;
263 }
Alexandre Lision68855472013-10-10 16:20:46 -0400264
265 public void adjustBounds(float x, float y) {
266
267 }
268
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400269 }
Alexandre Lision40954dc2013-10-09 15:24:03 -0400270
271 public ActionDrawer getDrawer() {
272 return act;
273 }
Alexandre Lision68855472013-10-10 16:20:46 -0400274
Alexandre Lision40954dc2013-10-09 15:24:03 -0400275 public void setDrawer(ActionDrawer a) {
276 act = a;
277 }
278
Alexandre Lision68855472013-10-10 16:20:46 -0400279 public abstract String getName();
280
281 public abstract boolean callIDEquals(String call);
282
283 public abstract String getCallID();
284
285 public boolean isConference() {
286 return false;
287 }
Alexandre Lisionee2494d2013-10-09 17:14:00 -0400288
Alexandre Lisiond9c3f7f2013-10-30 15:20:55 -0400289 public abstract boolean onDown(MotionEvent event);
290
alisionfe9cf712013-05-03 17:26:08 -0400291}