blob: bdfb8d02c917dbc8b0ea6524c1867093def3a176 [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 Lision064e1e02013-10-01 16:18:42 -040032package org.sflphone.model;
33
Alexandre Lisiond588bff2013-10-08 12:43:01 -040034import org.sflphone.R;
Alexandre Lision064e1e02013-10-01 16:18:42 -040035import org.sflphone.adapters.ContactPictureTask;
alisionfe9cf712013-05-03 17:26:08 -040036
37import android.content.Context;
38import android.graphics.Bitmap;
Alexandre Lisiond588bff2013-10-08 12:43:01 -040039import android.graphics.BitmapShader;
alisionfe9cf712013-05-03 17:26:08 -040040import android.graphics.Canvas;
alision2ec64f92013-06-17 17:28:58 -040041import android.graphics.Color;
alisionfe9cf712013-05-03 17:26:08 -040042import android.graphics.Paint;
Alexandre Lisiond588bff2013-10-08 12:43:01 -040043import android.graphics.Paint.Style;
Adrien Béraud25fc4092013-05-06 15:28:39 +100044import android.graphics.PointF;
alisionfe9cf712013-05-03 17:26:08 -040045import android.graphics.RectF;
Alexandre Lisiond588bff2013-10-08 12:43:01 -040046import android.graphics.Shader;
Alexandre Lisiond9c3f7f2013-10-30 15:20:55 -040047import android.view.MotionEvent;
alisionfe9cf712013-05-03 17:26:08 -040048
Alexandre Lision40954dc2013-10-09 15:24:03 -040049public abstract class Bubble {
alision806e18e2013-06-21 15:30:17 -040050
alision2ec64f92013-06-17 17:28:58 -040051 // A Bitmap object that is going to be passed to the BitmapShader
Alexandre Lision40954dc2013-10-09 15:24:03 -040052 protected Bitmap externalBMP;
alisionfe9cf712013-05-03 17:26:08 -040053
Alexandre Lision40954dc2013-10-09 15:24:03 -040054 protected PointF pos = new PointF();
55 protected RectF bounds;
alision2ec64f92013-06-17 17:28:58 -040056 public float target_scale = 1.f;
Alexandre Lision40954dc2013-10-09 15:24:03 -040057 protected float radius;
58 protected float scale = 1.f;
59 protected float density = 1.f;
alision2ec64f92013-06-17 17:28:58 -040060 public PointF speed = new PointF(0, 0);
61 public PointF last_speed = new PointF();
62 public PointF attractor = null;
Alexandre Lision40954dc2013-10-09 15:24:03 -040063 ActionDrawer act;
Alexandre Lision40954dc2013-10-09 15:24:03 -040064
Alexandre Lision68855472013-10-10 16:20:46 -040065 public boolean isUser;
alisionfe9cf712013-05-03 17:26:08 -040066
alision2ec64f92013-06-17 17:28:58 -040067 public boolean dragged = false;
Alexandre Lision6deda412013-09-25 13:21:22 -040068
Alexandre Lision0edf18c2013-09-23 17:35:50 -040069 public boolean markedToDie = false;
alision2ec64f92013-06-17 17:28:58 -040070 public long last_drag;
71 public boolean expanded; // determine if we draw the buttons around the bubble
Alexandre Lision40954dc2013-10-09 15:24:03 -040072 protected Bitmap saved_photo;
alision4a0eb092013-05-07 13:52:03 -040073
Alexandre Lision40954dc2013-10-09 15:24:03 -040074 public interface actions {
Alexandre Lision5cd659e2013-10-29 13:18:23 -040075 int OUT_OF_BOUNDS = -1;
Alexandre Lision40954dc2013-10-09 15:24:03 -040076 int NOTHING = 0;
77 int HOLD = 1;
78 int RECORD = 2;
79 int HANGUP = 3;
80 int MESSAGE = 4;
81 int TRANSFER = 5;
82 int MUTE = 6;
83 }
84
85 protected Context mContext;
Alexandre Lisiond588bff2013-10-08 12:43:01 -040086
alision2ec64f92013-06-17 17:28:58 -040087 public void setAttractor(PointF attractor) {
88 this.attractor = attractor;
89 }
Adrien Béraude0ef0c22013-05-18 01:56:27 +100090
Alexandre Lision40954dc2013-10-09 15:24:03 -040091 public Bubble(Context context, CallContact contact, float x, float y, float size) {
92 mContext = context;
alision2ec64f92013-06-17 17:28:58 -040093 pos.set(x, y);
Alexandre Lision68855472013-10-10 16:20:46 -040094 radius = size / 2; // 10 is the white stroke
Alexandre Lision40954dc2013-10-09 15:24:03 -040095 saved_photo = getContactPhoto(context, contact, (int) size);
96 generateBitmap();
97 attractor = new PointF(x, y);
Alexandre Lisiond5686032013-10-29 11:09:21 -040098 isUser = false;
Alexandre Lision40954dc2013-10-09 15:24:03 -040099 }
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400100
Alexandre Lision40954dc2013-10-09 15:24:03 -0400101 protected void generateBitmap() {
Alexandre Lision68855472013-10-10 16:20:46 -0400102
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400103 int w = saved_photo.getWidth(), h = saved_photo.getHeight();
104 if (w > h) {
105 w = h;
106 } else if (h > w) {
107 h = w;
108 }
Alexandre Lision68855472013-10-10 16:20:46 -0400109 externalBMP = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400110 BitmapShader shader;
111 shader = new BitmapShader(saved_photo, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
112
113 Paint paint = new Paint();
Alexandre Lision68855472013-10-10 16:20:46 -0400114 paint.setDither(true);
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400115 paint.setAntiAlias(true);
116 paint.setShader(shader);
117 Canvas internalCanvas = new Canvas(externalBMP);
Alexandre Lision68855472013-10-10 16:20:46 -0400118 internalCanvas.drawCircle(w / 2, h / 2, w / 2, paint);
Alexandre Lision40954dc2013-10-09 15:24:03 -0400119
Alexandre Lision2cd1ce42014-01-07 17:18:58 -0500120 Paint mLines = new Paint();
121 mLines.setStyle(Style.STROKE);
122 mLines.setStrokeWidth(8);
123 if(expanded)
124 mLines.setColor(mContext.getResources().getColor(R.color.sfl_blue_lines));
125 else
126 mLines.setColor(Color.WHITE);
127
128 mLines.setDither(true);
129 mLines.setAntiAlias(true);
130 internalCanvas.drawCircle(w / 2, h / 2, w / 2 - 4, mLines);
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400131
132 bounds = new RectF(pos.x - getRadius(), pos.y - getRadius(), pos.x + getRadius(), pos.y + getRadius());
Alexandre Lision68855472013-10-10 16:20:46 -0400133
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400134 }
alisionfe9cf712013-05-03 17:26:08 -0400135
Alexandre Lision40954dc2013-10-09 15:24:03 -0400136 protected Bitmap getContactPhoto(Context context, CallContact contact, int size) {
137 if (contact.getPhoto_id() > 0) {
138 return ContactPictureTask.loadContactPhoto(context.getContentResolver(), contact.getId());
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400139 } else {
Alexandre Lision2cd1ce42014-01-07 17:18:58 -0500140 return ContactPictureTask.decodeSampledBitmapFromResource(context.getResources(), R.drawable.ic_contact_picture, size, size);
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400141 }
alision2ec64f92013-06-17 17:28:58 -0400142 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000143
alision2ec64f92013-06-17 17:28:58 -0400144 public Bitmap getBitmap() {
145 return externalBMP;
146 }
alisionfe9cf712013-05-03 17:26:08 -0400147
alision2ec64f92013-06-17 17:28:58 -0400148 public RectF getBounds() {
149 return bounds;
150 }
Adrien Béraud33268882013-05-18 03:41:15 +1000151
Alexandre Lision40954dc2013-10-09 15:24:03 -0400152 public abstract void set(float x, float y, float s);
Adrien Béraud25fc4092013-05-06 15:28:39 +1000153
alision2ec64f92013-06-17 17:28:58 -0400154 public float getPosX() {
155 return pos.x;
156 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000157
alision2ec64f92013-06-17 17:28:58 -0400158 public float getPosY() {
159 return pos.y;
160 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000161
alision2ec64f92013-06-17 17:28:58 -0400162 public void setPos(float x, float y) {
163 set(x, y, scale);
164 }
alisionfe9cf712013-05-03 17:26:08 -0400165
alision2ec64f92013-06-17 17:28:58 -0400166 public PointF getPos() {
167 return pos;
168 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000169
alision2ec64f92013-06-17 17:28:58 -0400170 public float getScale() {
171 return scale;
172 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000173
alision2ec64f92013-06-17 17:28:58 -0400174 public void setScale(float s) {
175 set(pos.x, pos.y, s);
176 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000177
Alexandre Lision40954dc2013-10-09 15:24:03 -0400178 public abstract int getRadius();
Adrien Béraud6bbce912013-05-24 00:48:13 +1000179
alision2ec64f92013-06-17 17:28:58 -0400180 /**
181 * Point intersection test.
182 */
183 boolean intersects(float x, float y) {
alision34673e62013-06-25 14:40:07 -0400184 float dx = x - pos.x;
185 float dy = y - pos.y;
alision50fa0722013-06-25 17:29:44 -0400186
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400187 return dx * dx + dy * dy < getRadius() * getRadius();
alision2ec64f92013-06-17 17:28:58 -0400188 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000189
alision2ec64f92013-06-17 17:28:58 -0400190 /**
191 * Other circle intersection test.
192 */
193 boolean intersects(float x, float y, float radius) {
194 float dx = x - pos.x, dy = y - pos.y;
195 float tot_radius = getRadius() + radius;
196 return dx * dx + dy * dy < tot_radius * tot_radius;
197 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000198
alision2ec64f92013-06-17 17:28:58 -0400199 public void setDensity(float density) {
200 this.density = density;
201 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000202
Alexandre Lision40954dc2013-10-09 15:24:03 -0400203 public abstract void expand(int width, int height);
alision2ec64f92013-06-17 17:28:58 -0400204
205 public void retract() {
206 expanded = false;
Alexandre Lision40954dc2013-10-09 15:24:03 -0400207 generateBitmap();
alision2ec64f92013-06-17 17:28:58 -0400208 }
alisiondf1dac92013-06-27 17:35:53 -0400209
Alexandre Lision0edf18c2013-09-23 17:35:50 -0400210 public boolean isOnBorder(float w, float h) {
211 return (bounds.left < 0 || bounds.right > w || bounds.top < 0 || bounds.bottom > h);
212 }
213
alision729b0a22013-07-02 11:57:33 -0400214 /**
215 * Always return the normal radius of the bubble
alision91d28592013-07-02 14:33:53 -0400216 *
alision729b0a22013-07-02 11:57:33 -0400217 * @return
218 */
219 public float getRetractedRadius() {
220 return radius;
221 }
222
Alexandre Lision40954dc2013-10-09 15:24:03 -0400223 public abstract boolean getHoldStatus();
alision729b0a22013-07-02 11:57:33 -0400224
Alexandre Lision40954dc2013-10-09 15:24:03 -0400225 public abstract boolean getRecordStatus();
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400226
Alexandre Lision40954dc2013-10-09 15:24:03 -0400227 public abstract Bitmap getDrawerBitmap();
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400228
Alexandre Lision40954dc2013-10-09 15:24:03 -0400229 public abstract RectF getDrawerBounds();
Alexandre Lision68855472013-10-10 16:20:46 -0400230
231 protected abstract class ActionDrawer {
232
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400233 int mWidth, mHeight;
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400234 RectF bounds;
Alexandre Lision40954dc2013-10-09 15:24:03 -0400235 Bitmap img;
Alexandre Lisiond5ee3962013-11-08 15:37:28 -0500236 Paint mLines;
237 Paint mBackgroundPaint;
238 Paint mButtonPaint;
239 Paint mSelector;
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400240
Alexandre Lision40954dc2013-10-09 15:24:03 -0400241 public ActionDrawer(int w, int h) {
242
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400243 mWidth = w;
244 mHeight = h;
245 bounds = new RectF(0, 0, 0, 0);
Alexandre Lisiond5ee3962013-11-08 15:37:28 -0500246
247 mButtonPaint = new Paint();
248 mBackgroundPaint = new Paint();
249 mBackgroundPaint.setColor(mContext.getResources().getColor(R.color.sfl_blue_9));
250 mLines = new Paint();
251 mLines.setAntiAlias(true);
252 mLines.setStrokeWidth(2);
Alexandre Lision5702b372013-11-26 16:19:26 -0500253 mLines.setColor(mContext.getResources().getColor(R.color.sfl_blue_lines));
Alexandre Lisiond5ee3962013-11-08 15:37:28 -0500254
255 mSelector = new Paint();
256 mSelector.setStyle(Style.FILL);
257 mSelector.setColor(mContext.getResources().getColor(R.color.sfl_dark_blue));
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400258
Alexandre Lision40954dc2013-10-09 15:24:03 -0400259 }
Alexandre Lision68855472013-10-10 16:20:46 -0400260
Alexandre Lision40954dc2013-10-09 15:24:03 -0400261 /**
262 * When the bubble is expanded we need to check on wich action button the user tap
263 *
264 * @param x
265 * @param y
266 * @return
267 */
268 public abstract int getAction(float x, float y);
Alexandre Lision68855472013-10-10 16:20:46 -0400269
Alexandre Lision40954dc2013-10-09 15:24:03 -0400270 public void setBounds(float f, float y, float g, float h) {
271 bounds.set(f, y, g, h);
272 }
Alexandre Lision68855472013-10-10 16:20:46 -0400273
Alexandre Lisiond9c3f7f2013-10-30 15:20:55 -0400274 public abstract void generateBitmap(int action);
Alexandre Lision68855472013-10-10 16:20:46 -0400275
Alexandre Lision5cd659e2013-10-29 13:18:23 -0400276 public RectF getDrawerBounds() {
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400277 return bounds;
278 }
279
280 public void setBounds(RectF bounds) {
281 this.bounds = bounds;
282 }
283
Alexandre Lision40954dc2013-10-09 15:24:03 -0400284 public Bitmap getBitmap() {
285 return img;
286 }
287
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400288 public int getWidth() {
289 return mWidth;
290 }
291
292 public int getHeight() {
293 return mHeight;
294 }
Alexandre Lision68855472013-10-10 16:20:46 -0400295
296 public void adjustBounds(float x, float y) {
297
298 }
299
Alexandre Lisiond588bff2013-10-08 12:43:01 -0400300 }
Alexandre Lision40954dc2013-10-09 15:24:03 -0400301
302 public ActionDrawer getDrawer() {
303 return act;
304 }
Alexandre Lision68855472013-10-10 16:20:46 -0400305
Alexandre Lision40954dc2013-10-09 15:24:03 -0400306 public void setDrawer(ActionDrawer a) {
307 act = a;
308 }
309
Alexandre Lision68855472013-10-10 16:20:46 -0400310 public abstract String getName();
311
312 public abstract boolean callIDEquals(String call);
313
314 public abstract String getCallID();
315
316 public boolean isConference() {
317 return false;
318 }
Alexandre Lisionee2494d2013-10-09 17:14:00 -0400319
Alexandre Lisiond9c3f7f2013-10-30 15:20:55 -0400320 public abstract boolean onDown(MotionEvent event);
321
alisionfe9cf712013-05-03 17:26:08 -0400322}