blob: 927f4466ece16b9d0049ffe20f52677e27a7ca08 [file] [log] [blame]
package com.savoirfairelinux.sflphone.model;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.Log;
import com.savoirfairelinux.sflphone.R;
import com.savoirfairelinux.sflphone.adapters.ContactPictureLoader;
public class Bubble {
// A Bitmap object that is going to be passed to the BitmapShader
private Bitmap internalBMP, externalBMP;
public SipCall associated_call;
private PointF pos = new PointF();
private RectF bounds;
public float target_scale = 1.f;
private float radius;
private float scale = 1.f;
private float density = 1.f;
public PointF speed = new PointF(0, 0);
public PointF last_speed = new PointF();
public PointF attractor = null;
public boolean dragged = false;
public long last_drag;
public boolean expanded; // determine if we draw the buttons around the bubble
private Bitmap saved_photo;
private float expanded_radius;
public void setAttractor(PointF attractor) {
this.attractor = attractor;
}
public Bubble(Context context, SipCall call, float x, float y, float size) {
Bitmap photo = null;
if (call.getContact().getPhoto_id() > 0) {
photo = ContactPictureLoader.loadContactPhoto(context.getContentResolver(), call.getContact().getId());
} else {
photo = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_contact_picture);
}
saved_photo = photo;
internalBMP = Bitmap.createScaledBitmap(photo, (int) size, (int) size, false);
associated_call = call;
pos.set(x, y);
radius = internalBMP.getWidth() / 2;
expanded_radius = (float) (size * 1.5);
bounds = new RectF(pos.x - radius, pos.y - radius, pos.x + radius, pos.y + radius);
attractor = new PointF(x, y);
Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setStyle(Paint.Style.FILL);
Bitmap circle = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
Canvas circle_drawer = new Canvas(circle);
circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
externalBMP = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(externalBMP);
circlePaint.setFilterBitmap(false);
canvas.drawBitmap(internalBMP, 0, 0, circlePaint);
circlePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
canvas.drawBitmap(circle, 0, 0, circlePaint);
}
public Bitmap getBitmap() {
return externalBMP;
}
public RectF getBounds() {
return bounds;
}
public void set(float x, float y, float s) {
scale = s;
pos.x = x;
pos.y = y;
float rad = scale * getRadius() * density;
bounds.set(pos.x - rad, pos.y - rad, pos.x + rad, pos.y + rad);
}
public float getPosX() {
return pos.x;
}
public float getPosY() {
return pos.y;
}
public void setPos(float x, float y) {
set(x, y, scale);
}
public PointF getPos() {
return pos;
}
public float getScale() {
return scale;
}
public void setScale(float s) {
set(pos.x, pos.y, s);
}
public float getRadius() {
return expanded ? expanded_radius : radius;
}
/**
* Point intersection test.
*/
boolean intersects(float x, float y) {
float dx = x - pos.x;
float dy = y - pos.y;
return dx * dx + dy * dy < getRadius() * density * getRadius() * density;
}
/**
* Other circle intersection test.
*/
boolean intersects(float x, float y, float radius) {
float dx = x - pos.x, dy = y - pos.y;
float tot_radius = getRadius() + radius;
return dx * dx + dy * dy < tot_radius * tot_radius;
}
public void setDensity(float density) {
this.density = density;
}
public void expand() {
expanded = true;
internalBMP = Bitmap.createScaledBitmap(saved_photo, (int) (2 * radius), (int) (2 * radius), false);
bounds = new RectF(pos.x - getRadius(), pos.y - getRadius(), pos.x + getRadius(), pos.y + getRadius());
Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setAntiAlias(true);
circlePaint.setDither(true);
circlePaint.setStyle(Paint.Style.FILL);
circlePaint.setColor(Color.RED);
Bitmap circle = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
Canvas circle_drawer = new Canvas(circle);
circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
Canvas canvas = new Canvas(internalBMP);
circlePaint.setFilterBitmap(false);
canvas.drawBitmap(internalBMP, 0, 0, circlePaint);
circlePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
canvas.drawBitmap(circle, 0, 0, circlePaint);
circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
externalBMP = Bitmap.createBitmap((int) (getRadius() * 2), (int) (getRadius() * 2), Bitmap.Config.ARGB_8888);
Canvas canvasf = new Canvas(externalBMP);
Paint mPaintPath = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintPath.setStyle(Paint.Style.FILL);
mPaintPath.setColor(0xAA000000);
Paint fatality = new Paint(Paint.ANTI_ALIAS_FLAG);
fatality.setAntiAlias(true);
fatality.setDither(true);
fatality.setStyle(Paint.Style.FILL);
canvasf.drawOval(new RectF(0, 0, getRadius() * 2, getRadius() * 2), mPaintPath); // background with buttons
canvasf.drawBitmap(internalBMP, (float) (getRadius() - radius), (float) (getRadius() - radius), fatality);
}
public void retract() {
expanded = false;
internalBMP = Bitmap.createScaledBitmap(saved_photo, (int) (2 * radius), (int) (2 * radius), false);
bounds = new RectF(pos.x - getRadius(), pos.y - getRadius(), pos.x + getRadius(), pos.y + getRadius());
Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setAntiAlias(true);
circlePaint.setDither(true);
circlePaint.setStyle(Paint.Style.FILL);
Bitmap circle = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
Canvas circle_drawer = new Canvas(circle);
circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
externalBMP = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(externalBMP);
circlePaint.setFilterBitmap(false);
canvas.drawBitmap(internalBMP, 0, 0, circlePaint);
circlePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
canvas.drawBitmap(circle, 0, 0, circlePaint);
}
/**
* Compare bubbles based on call ID
*/
@Override
public boolean equals(Object c) {
if (c instanceof Bubble && ((Bubble) c).associated_call.getCallId().contentEquals(associated_call.getCallId())) {
return true;
}
return false;
}
/**
* When bubble is expanded we need to check on wich action button the user tap
*
* @param x
* @param y
* @return
*/
public int getAction(float x, float y) {
float relativeX = x - pos.x + externalBMP.getWidth() / 2;
float relativeY = y - pos.y + externalBMP.getHeight() / 2;
Log.i("Bubble","relativeX:"+relativeX);
Log.i("Bubble","relativeY:"+relativeY);
Log.i("Bubble","pos.x:"+pos.x);
Log.i("Bubble","pos.y:"+pos.y);
Log.i("Bubble","externalBMP.getWidth():"+externalBMP.getWidth());
Log.i("Bubble","externalBMP.getHeight():"+externalBMP.getHeight());
// Hold - Left
if (relativeX < externalBMP.getWidth() / 3 && relativeY > externalBMP.getHeight() / 3) {
return 1;
}
// Record - Right
if (relativeX > externalBMP.getWidth() * 2 / 3 && relativeY > externalBMP.getHeight() / 3) {
return 2;
}
// Transfer - Bottom
if (relativeY > externalBMP.getHeight() * 2 / 3) {
return 3;
}
return 0;
}
/**
* Always return the normal radius of the bubble
* @return
*/
public float getRetractedRadius() {
return radius;
}
public int getHoldStatus() {
if(associated_call.isOnHold())
return R.string.action_call_unhold;
else
return R.string.action_call_hold;
}
public int getRecordStatus() {
if(associated_call.isRecording())
return R.string.action_call_stop_record;
else
return R.string.action_call_record;
}
}