blob: 420fb6a87acb3d257db2a037e2cb77f0d9347b91 [file] [log] [blame]
alisionfe9cf712013-05-03 17:26:08 -04001package com.savoirfairelinux.sflphone.model;
2
3import android.content.Context;
4import android.graphics.Bitmap;
5import android.graphics.BitmapFactory;
6import android.graphics.Canvas;
alision2ec64f92013-06-17 17:28:58 -04007import android.graphics.Color;
alisionfe9cf712013-05-03 17:26:08 -04008import android.graphics.Paint;
Adrien Béraud25fc4092013-05-06 15:28:39 +10009import android.graphics.PointF;
alisionfe9cf712013-05-03 17:26:08 -040010import android.graphics.PorterDuff.Mode;
11import android.graphics.PorterDuffXfermode;
12import android.graphics.RectF;
alision34673e62013-06-25 14:40:07 -040013import android.util.Log;
alisionfe9cf712013-05-03 17:26:08 -040014
15import com.savoirfairelinux.sflphone.R;
alision34673e62013-06-25 14:40:07 -040016import com.savoirfairelinux.sflphone.adapters.ContactPictureLoader;
alisionfe9cf712013-05-03 17:26:08 -040017
alision2ec64f92013-06-17 17:28:58 -040018public 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
21 private Bitmap internalBMP, externalBMP;
alisionfe9cf712013-05-03 17:26:08 -040022
alision806e18e2013-06-21 15:30:17 -040023 public SipCall associated_call;
alision2ec64f92013-06-17 17:28:58 -040024 private PointF pos = new PointF();
25 private RectF bounds;
26 public float target_scale = 1.f;
27 private float radius;
28 private float scale = 1.f;
29 private float density = 1.f;
30 public PointF speed = new PointF(0, 0);
31 public PointF last_speed = new PointF();
32 public PointF attractor = null;
alisionfe9cf712013-05-03 17:26:08 -040033
alision2ec64f92013-06-17 17:28:58 -040034 public boolean dragged = false;
35 public long last_drag;
36 public boolean expanded; // determine if we draw the buttons around the bubble
37 private Bitmap saved_photo;
38 private float expanded_radius = 250;
alision4a0eb092013-05-07 13:52:03 -040039
alision2ec64f92013-06-17 17:28:58 -040040 public void setAttractor(PointF attractor) {
41 this.attractor = attractor;
42 }
Adrien Béraude0ef0c22013-05-18 01:56:27 +100043
alision34673e62013-06-25 14:40:07 -040044 public Bubble(Context context, SipCall call, float x, float y, float size) {
45
46 Bitmap photo = null;
47 if (call.getContact().getPhoto_id() > 0) {
48 photo = ContactPictureLoader.loadContactPhoto(context.getContentResolver(), call.getContact().getId());
49 } else {
50 photo = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_contact_picture);
51 }
52
alision2ec64f92013-06-17 17:28:58 -040053 saved_photo = photo;
54 internalBMP = Bitmap.createScaledBitmap(photo, (int) size, (int) size, false);
alision34673e62013-06-25 14:40:07 -040055
alision806e18e2013-06-21 15:30:17 -040056 associated_call = call;
alision2ec64f92013-06-17 17:28:58 -040057 pos.set(x, y);
alision34673e62013-06-25 14:40:07 -040058 radius = internalBMP.getWidth() / 2;
alision2ec64f92013-06-17 17:28:58 -040059 bounds = new RectF(pos.x - radius, pos.y - radius, pos.x + radius, pos.y + radius);
60 attractor = new PointF(x, y);
alisionfe9cf712013-05-03 17:26:08 -040061
alision2ec64f92013-06-17 17:28:58 -040062 Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
63 circlePaint.setStyle(Paint.Style.FILL);
alision34673e62013-06-25 14:40:07 -040064 Bitmap circle = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
alision2ec64f92013-06-17 17:28:58 -040065 Canvas circle_drawer = new Canvas(circle);
alision34673e62013-06-25 14:40:07 -040066 circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
alisionfe9cf712013-05-03 17:26:08 -040067
alision34673e62013-06-25 14:40:07 -040068 externalBMP = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
alision2ec64f92013-06-17 17:28:58 -040069 Canvas canvas = new Canvas(externalBMP);
alisionfe9cf712013-05-03 17:26:08 -040070
alision2ec64f92013-06-17 17:28:58 -040071 circlePaint.setFilterBitmap(false);
72 canvas.drawBitmap(internalBMP, 0, 0, circlePaint);
alisionfe9cf712013-05-03 17:26:08 -040073
alision2ec64f92013-06-17 17:28:58 -040074 circlePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
75 canvas.drawBitmap(circle, 0, 0, circlePaint);
76 }
Adrien Béraud25fc4092013-05-06 15:28:39 +100077
alision2ec64f92013-06-17 17:28:58 -040078 public Bitmap getBitmap() {
79 return externalBMP;
80 }
alisionfe9cf712013-05-03 17:26:08 -040081
alision2ec64f92013-06-17 17:28:58 -040082 public RectF getBounds() {
83 return bounds;
84 }
Adrien Béraud33268882013-05-18 03:41:15 +100085
alision2ec64f92013-06-17 17:28:58 -040086 public void set(float x, float y, float s) {
87 scale = s;
88 pos.x = x;
89 pos.y = y;
90 float rad = scale * getRadius() * density;
91 bounds.set(pos.x - rad, pos.y - rad, pos.x + rad, pos.y + rad);
92 }
Adrien Béraud25fc4092013-05-06 15:28:39 +100093
alision2ec64f92013-06-17 17:28:58 -040094 public float getPosX() {
95 return pos.x;
96 }
Adrien Béraud25fc4092013-05-06 15:28:39 +100097
alision2ec64f92013-06-17 17:28:58 -040098 public float getPosY() {
99 return pos.y;
100 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000101
alision2ec64f92013-06-17 17:28:58 -0400102 public void setPos(float x, float y) {
103 set(x, y, scale);
104 }
alisionfe9cf712013-05-03 17:26:08 -0400105
alision2ec64f92013-06-17 17:28:58 -0400106 public PointF getPos() {
107 return pos;
108 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000109
alision2ec64f92013-06-17 17:28:58 -0400110 public float getScale() {
111 return scale;
112 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000113
alision2ec64f92013-06-17 17:28:58 -0400114 public void setScale(float s) {
115 set(pos.x, pos.y, s);
116 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000117
alision2ec64f92013-06-17 17:28:58 -0400118 public float getRadius() {
119 return expanded ? expanded_radius : radius;
120 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000121
alision2ec64f92013-06-17 17:28:58 -0400122 /**
123 * Point intersection test.
124 */
125 boolean intersects(float x, float y) {
alision34673e62013-06-25 14:40:07 -0400126 float dx = x - pos.x;
127 float dy = y - pos.y;
alision50fa0722013-06-25 17:29:44 -0400128
alision34673e62013-06-25 14:40:07 -0400129 return dx * dx + dy * dy < getRadius() * density * getRadius() * density;
alision2ec64f92013-06-17 17:28:58 -0400130 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000131
alision2ec64f92013-06-17 17:28:58 -0400132 /**
133 * Other circle intersection test.
134 */
135 boolean intersects(float x, float y, float radius) {
136 float dx = x - pos.x, dy = y - pos.y;
137 float tot_radius = getRadius() + radius;
138 return dx * dx + dy * dy < tot_radius * tot_radius;
139 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000140
alision2ec64f92013-06-17 17:28:58 -0400141 public void setDensity(float density) {
142 this.density = density;
143 }
Adrien Béraud25fc4092013-05-06 15:28:39 +1000144
alision2ec64f92013-06-17 17:28:58 -0400145 public void expand(int i) {
Adrien Béraud0c9bd8f2013-05-30 16:16:57 +1000146
alision2ec64f92013-06-17 17:28:58 -0400147 expanded_radius = i;
148 expanded = true;
149 internalBMP = Bitmap.createScaledBitmap(saved_photo, (int) (2 * radius), (int) (2 * radius), false);
alision2ec64f92013-06-17 17:28:58 -0400150
151 bounds = new RectF(pos.x - getRadius(), pos.y - getRadius(), pos.x + getRadius(), pos.y + getRadius());
152
153 Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
alision34673e62013-06-25 14:40:07 -0400154 circlePaint.setAntiAlias(true);
155 circlePaint.setDither(true);
alision2ec64f92013-06-17 17:28:58 -0400156 circlePaint.setStyle(Paint.Style.FILL);
alision34673e62013-06-25 14:40:07 -0400157 circlePaint.setColor(Color.RED);
158
159 Bitmap circle = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
alision2ec64f92013-06-17 17:28:58 -0400160 Canvas circle_drawer = new Canvas(circle);
alision34673e62013-06-25 14:40:07 -0400161 circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
alision2ec64f92013-06-17 17:28:58 -0400162
alision34673e62013-06-25 14:40:07 -0400163 Canvas canvas = new Canvas(internalBMP);
alision2ec64f92013-06-17 17:28:58 -0400164 circlePaint.setFilterBitmap(false);
alision34673e62013-06-25 14:40:07 -0400165 canvas.drawBitmap(internalBMP, 0, 0, circlePaint);
166
167 circlePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
168 canvas.drawBitmap(circle, 0, 0, circlePaint);
169 circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
170
171 externalBMP = Bitmap.createBitmap((int) (getRadius() * 2), (int) (getRadius() * 2), Bitmap.Config.ARGB_8888);
172 Canvas canvasf = new Canvas(externalBMP);
alision2ec64f92013-06-17 17:28:58 -0400173
174 Paint mPaintPath = new Paint(Paint.ANTI_ALIAS_FLAG);
175 mPaintPath.setStyle(Paint.Style.FILL);
alision34673e62013-06-25 14:40:07 -0400176 mPaintPath.setColor(0xAA000000);
alision2ec64f92013-06-17 17:28:58 -0400177
alision34673e62013-06-25 14:40:07 -0400178 Paint fatality = new Paint(Paint.ANTI_ALIAS_FLAG);
179 fatality.setAntiAlias(true);
180 fatality.setDither(true);
181 fatality.setStyle(Paint.Style.FILL);
alision2ec64f92013-06-17 17:28:58 -0400182
alision34673e62013-06-25 14:40:07 -0400183 canvasf.drawOval(new RectF(0, 0, getRadius() * 2, getRadius() * 2), mPaintPath); // background with buttons
184 canvasf.drawBitmap(internalBMP, (float) (getRadius() - radius), (float) (getRadius() - radius), fatality);
alision2ec64f92013-06-17 17:28:58 -0400185
186 }
187
188 public void retract() {
189 expanded = false;
190 internalBMP = Bitmap.createScaledBitmap(saved_photo, (int) (2 * radius), (int) (2 * radius), false);
alision2ec64f92013-06-17 17:28:58 -0400191
192 bounds = new RectF(pos.x - getRadius(), pos.y - getRadius(), pos.x + getRadius(), pos.y + getRadius());
193
194 Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
alision34673e62013-06-25 14:40:07 -0400195 circlePaint.setAntiAlias(true);
196 circlePaint.setDither(true);
alision2ec64f92013-06-17 17:28:58 -0400197 circlePaint.setStyle(Paint.Style.FILL);
alision2ec64f92013-06-17 17:28:58 -0400198
alision34673e62013-06-25 14:40:07 -0400199 Bitmap circle = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
200 Canvas circle_drawer = new Canvas(circle);
201 circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
202
203 externalBMP = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
alision2ec64f92013-06-17 17:28:58 -0400204 Canvas canvas = new Canvas(externalBMP);
205
206 circlePaint.setFilterBitmap(false);
207 canvas.drawBitmap(internalBMP, 0, 0, circlePaint);
208
209 circlePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
210 canvas.drawBitmap(circle, 0, 0, circlePaint);
211
212 }
alision34673e62013-06-25 14:40:07 -0400213
214 /**
215 * When bubble is expanded we need to check on wich action button the user tap
216 *
217 * @param x
218 * @param y
219 * @return
220 */
221 public int getAction(float x, float y) {
222 float relativeX = x - pos.x + externalBMP.getWidth() / 2;
223 float relativeY = y - pos.y + externalBMP.getHeight() / 2;
224
225 Log.i("Bubble","relativeX:"+relativeX);
226 Log.i("Bubble","relativeY:"+relativeY);
227
228 Log.i("Bubble","pos.x:"+pos.x);
229 Log.i("Bubble","pos.y:"+pos.y);
230
231 Log.i("Bubble","externalBMP.getWidth():"+externalBMP.getWidth());
232 Log.i("Bubble","externalBMP.getHeight():"+externalBMP.getHeight());
233
234 // Hold - Left
235 if (relativeX < externalBMP.getWidth() / 3 && relativeY > externalBMP.getHeight() / 3) {
236 return 1;
237 }
238
239 // Record - Right
240 if (relativeX > externalBMP.getWidth() * 2 / 3 && relativeY > externalBMP.getHeight() / 3) {
241 return 2;
242 }
243
244 // Transfer - Bottom
245 if (relativeY > externalBMP.getHeight() * 2 / 3) {
246 return 3;
247 }
248 return 0;
249 }
alisionfe9cf712013-05-03 17:26:08 -0400250}