Skip to content
Snippets Groups Projects
Commit 6bbce918 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

Bubble improvements

parent 7297bdbd
Branches
Tags
No related merge requests found
package com.savoirfairelinux.sflphone.client;
import android.app.Activity;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import com.savoirfairelinux.sflphone.R;
import com.savoirfairelinux.sflphone.model.Bubble;
import com.savoirfairelinux.sflphone.model.BubbleModel;
import com.savoirfairelinux.sflphone.model.BubblesView;
public class BubblesViewActivity extends Activity {
private static final String TAG = BubblesViewActivity.class.getSimpleName();
BubblesView view;
PointF screenCenter;
int radiusCalls;
double angle_part;
BubbleModel model;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bubbleview_layout);
model = new BubbleModel();
DisplayMetrics metrics = getResources().getDisplayMetrics();
screenCenter = new PointF(metrics.widthPixels / 2, metrics.heightPixels / 3);
radiusCalls = metrics.widthPixels / 2 - 150;
// model.listBubbles.add(new Bubble(this, metrics.widthPixels / 2, metrics.heightPixels / 4, 150, R.drawable.me));
// model.listBubbles.add(new Bubble(this, metrics.widthPixels / 2, metrics.heightPixels / 4 * 3, 150, R.drawable.callee));
view = (BubblesView) findViewById(R.id.main_view);
view.setModel(model);
/*
((Button) findViewById(R.id.add_bubble)).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
addBubble();
}
});
((Button) findViewById(R.id.remove_bubble)).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
removeBubble();
}
});
*/
}
public void addBubble() {
/*
* Bubble.Builder builder = new Bubble.Builder(getContext()); builder.setRadiusPixels(200).setX(200).setY(300);
*/
DisplayMetrics metrics = getResources().getDisplayMetrics();
Bubble b = new Bubble(this, metrics.widthPixels / 3, metrics.heightPixels / 4 * 3, 150, -1);
model.listBubbles.add(b);
angle_part = 2*Math.PI / model.listBubbles.size();
double dX = 0;
double dY = 0;
for (int i = 0; i < model.listBubbles.size(); ++i) {
dX = Math.cos(angle_part * i) * radiusCalls;
dY = Math.sin(angle_part * i) * radiusCalls;
Log.i(TAG, "dX " + dX + " dY " + dY);
model.listBubbles.get(i).setAttractor(new PointF((int) dX + screenCenter.x, (int) dY + screenCenter.y));
}
// listBubbles.get(listBubbles.size() - 1).setRegion(width, height);
}
public void removeBubble() {
if (model.listBubbles.isEmpty()) {
return;
}
/*
* Bubble.Builder builder = new Bubble.Builder(getContext()); builder.setRadiusPixels(200).setX(200).setY(300);
*/
// DisplayMetrics metrics = getResources().getDisplayMetrics();
// Bubble b = new Bubble(this, metrics.widthPixels / 3, metrics.heightPixels / 4 * 3, 150, -1);
synchronized (model) {
model.listBubbles.remove(model.listBubbles.size() - 1);
}
if (model.listBubbles.isEmpty()) {
return;
}
angle_part = 2*Math.PI / model.listBubbles.size();
Log.i(TAG, "Angle:" + angle_part);
double dX = 0;
double dY = 0;
for (int i = 0; i < model.listBubbles.size(); ++i) {
dX = Math.cos(angle_part * i) * radiusCalls;
dY = Math.sin(angle_part * i) * radiusCalls;
Log.i(TAG, "dX " + dX + " dY " + dY);
model.listBubbles.get(i).setAttractor(new PointF((int) dX + screenCenter.x, (int) dY + screenCenter.y));
}
// listBubbles.get(listBubbles.size() - 1).setRegion(width, height);
}
}
\ No newline at end of file
...@@ -42,7 +42,6 @@ import android.content.ComponentName; ...@@ -42,7 +42,6 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.drm.DrmStore.Action;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.PointF; import android.graphics.PointF;
import android.os.Bundle; import android.os.Bundle;
...@@ -60,17 +59,16 @@ import com.savoirfairelinux.sflphone.model.Bubble; ...@@ -60,17 +59,16 @@ import com.savoirfairelinux.sflphone.model.Bubble;
import com.savoirfairelinux.sflphone.model.BubbleModel; import com.savoirfairelinux.sflphone.model.BubbleModel;
import com.savoirfairelinux.sflphone.model.BubblesView; import com.savoirfairelinux.sflphone.model.BubblesView;
import com.savoirfairelinux.sflphone.model.CallContact; import com.savoirfairelinux.sflphone.model.CallContact;
import com.savoirfairelinux.sflphone.model.CallContact.Phone;
import com.savoirfairelinux.sflphone.model.SipCall; import com.savoirfairelinux.sflphone.model.SipCall;
import com.savoirfairelinux.sflphone.service.ISipClient; import com.savoirfairelinux.sflphone.service.ISipClient;
import com.savoirfairelinux.sflphone.service.ISipService; import com.savoirfairelinux.sflphone.service.ISipService;
import com.savoirfairelinux.sflphone.service.SipService; import com.savoirfairelinux.sflphone.service.SipService;
public class CallActivity extends Activity //implements IncomingCallFragment.ICallActionListener, OngoingCallFragment.ICallActionListener //OnClickListener public class CallActivity extends Activity
{ {
static final String TAG = "CallActivity"; static final String TAG = "CallActivity";
private ISipService service; private ISipService service;
private String pendingAction; private String pendingAction = null;
private SipCall mCall; private SipCall mCall;
private BubblesView view; private BubblesView view;
...@@ -78,7 +76,7 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa ...@@ -78,7 +76,7 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa
private PointF screenCenter; private PointF screenCenter;
private DisplayMetrics metrics; private DisplayMetrics metrics;
private HashMap<Bubble, CallContact> contacts = new HashMap<Bubble, CallContact>(); private HashMap<CallContact, Bubble> contacts = new HashMap<CallContact, Bubble>();
private ExecutorService infos_fetcher = Executors.newCachedThreadPool(); private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
...@@ -137,7 +135,7 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa ...@@ -137,7 +135,7 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.bubbleview_layout); setContentView(R.layout.bubbleview_layout);
model = new BubbleModel(); model = new BubbleModel(getResources().getDisplayMetrics().density);
metrics = getResources().getDisplayMetrics(); metrics = getResources().getDisplayMetrics();
screenCenter = new PointF(metrics.widthPixels / 2, metrics.heightPixels / 3); screenCenter = new PointF(metrics.widthPixels / 2, metrics.heightPixels / 3);
//radiusCalls = metrics.widthPixels / 2 - 150; //radiusCalls = metrics.widthPixels / 2 - 150;
...@@ -159,7 +157,7 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa ...@@ -159,7 +157,7 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa
//setCallStateDisplay(mCall.getCallStateString()); //setCallStateDisplay(mCall.getCallStateString());
pendingAction = b.getString("action"); pendingAction = b.getString("action");
if(pendingAction.equals("call")) { if(pendingAction != null && pendingAction.equals("call")) {
CallContact contact = b.getParcelable("CallContact"); CallContact contact = b.getParcelable("CallContact");
Log.i(TAG,"Calling "+ contact.getmDisplayName()); Log.i(TAG,"Calling "+ contact.getmDisplayName());
...@@ -189,7 +187,7 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa ...@@ -189,7 +187,7 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa
bindService(intent, mConnection, Context.BIND_AUTO_CREATE); bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
} else if(pendingAction.equals("incoming")) { } else if(pendingAction.equals("incoming")) {
callIncoming();
} }
/* /*
...@@ -219,8 +217,9 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa ...@@ -219,8 +217,9 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa
} }
})); }));
contact_bubble.contact = contact;
model.listBubbles.add(contact_bubble); model.listBubbles.add(contact_bubble);
contacts.put(contact_bubble, contact); contacts.put(contact, contact_bubble);
} }
private void callIncoming() { private void callIncoming() {
...@@ -259,22 +258,24 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa ...@@ -259,22 +258,24 @@ public class CallActivity extends Activity //implements IncomingCallFragment.ICa
service = ISipService.Stub.asInterface(binder); service = ISipService.Stub.asInterface(binder);
try { try {
service.registerClient(callback); service.registerClient(callback);
if(pendingAction.contentEquals("call")){ if(pendingAction != null && pendingAction.contentEquals("call")){
Log.i(TAG, "Placing call"); Log.i(TAG, "Placing call");
Random random = new Random(); CallContact contact = model.listBubbles.get(0).contact;
String callID = Integer.toString(random.nextInt());
String callID = Integer.toString(new Random().nextInt());
SipCall.CallInfo info = new SipCall.CallInfo(); SipCall.CallInfo info = new SipCall.CallInfo();
info.mCallID = callID; info.mCallID = callID;
info.mAccountID = service.getAccountList().get(1).toString(); info.mAccountID = service.getAccountList().get(0).toString();
info.mDisplayName = "Cool Guy!"; info.mDisplayName = contact.getmDisplayName();
info.mPhone = contacts.get(contacts.keySet().iterator().next()).getPhones().get(0).getNumber(); info.mPhone = contact.getSipPhone().getNumber();
info.mEmail = "coolGuy@coolGuy.com"; info.mEmail = contact.getmEmail();
info.mCallType = SipCall.CALL_TYPE_OUTGOING; info.mCallType = SipCall.CALL_TYPE_OUTGOING;
mCall = CallListReceiver.getCallInstance(info); mCall = CallListReceiver.getCallInstance(info);
service.placeCall(info.mAccountID, info.mCallID, info.mPhone); service.placeCall(info.mAccountID, info.mCallID, info.mPhone);
pendingAction = null;
} }
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());
......
...@@ -72,7 +72,6 @@ import android.widget.ToggleButton; ...@@ -72,7 +72,6 @@ import android.widget.ToggleButton;
import com.savoirfairelinux.sflphone.R; import com.savoirfairelinux.sflphone.R;
import com.savoirfairelinux.sflphone.account.AccountSelectionSpinner; import com.savoirfairelinux.sflphone.account.AccountSelectionSpinner;
import com.savoirfairelinux.sflphone.adapters.CallElementAdapter; import com.savoirfairelinux.sflphone.adapters.CallElementAdapter;
import com.savoirfairelinux.sflphone.client.BubblesViewActivity;
import com.savoirfairelinux.sflphone.client.CallActivity; import com.savoirfairelinux.sflphone.client.CallActivity;
import com.savoirfairelinux.sflphone.client.SFLPhoneHomeActivity; import com.savoirfairelinux.sflphone.client.SFLPhoneHomeActivity;
import com.savoirfairelinux.sflphone.client.SFLPhonePreferenceActivity; import com.savoirfairelinux.sflphone.client.SFLPhonePreferenceActivity;
......
...@@ -15,12 +15,15 @@ import com.savoirfairelinux.sflphone.R; ...@@ -15,12 +15,15 @@ import com.savoirfairelinux.sflphone.R;
public class Bubble public class Bubble
{ {
public CallContact contact;
// A Bitmap object that is going to be passed to the BitmapShader // A Bitmap object that is going to be passed to the BitmapShader
private Bitmap internalBMP, externalBMP; private Bitmap internalBMP, externalBMP;
private PointF pos = new PointF(); private PointF pos = new PointF();
private RectF bounds; private RectF bounds;
private float radius; public float target_scale = 1.f;
private final float radius;
private float scale = 1.f;
public PointF speed = new PointF(0, 0); public PointF speed = new PointF(0, 0);
public PointF last_speed = new PointF(); public PointF last_speed = new PointF();
public PointF attractor = null; public PointF attractor = null;
...@@ -85,6 +88,17 @@ public class Bubble ...@@ -85,6 +88,17 @@ public class Bubble
return bounds; return bounds;
} }
public void set(float x, float y, float s) {
scale = s;
pos.x = x;
pos.y = y;
float rad = scale*radius;
bounds.left = pos.x - rad;
bounds.right = pos.x + rad;
bounds.top = pos.y - rad;
bounds.bottom = pos.y + rad;
}
public float getPosX() { public float getPosX() {
return pos.x; return pos.x;
} }
...@@ -94,16 +108,7 @@ public class Bubble ...@@ -94,16 +108,7 @@ public class Bubble
} }
public void setPos(float x, float y) { public void setPos(float x, float y) {
pos.x = x; set(x, y, scale);
pos.y = y;
bounds.left = pos.x - radius;
bounds.right = pos.x + radius;
bounds.top = pos.y - radius;
bounds.bottom = pos.y + radius;
}
public float getRadius() {
return radius;
} }
public PointF getPos() public PointF getPos()
...@@ -111,6 +116,18 @@ public class Bubble ...@@ -111,6 +116,18 @@ public class Bubble
return pos; return pos;
} }
public float getScale() {
return scale;
}
public void setScale(float s) {
set(pos.x, pos.y, s);
}
public float getRadius() {
return radius;
}
/** /**
* Point intersection test. * Point intersection test.
*/ */
......
...@@ -3,7 +3,6 @@ package com.savoirfairelinux.sflphone.model; ...@@ -3,7 +3,6 @@ package com.savoirfairelinux.sflphone.model;
import java.util.ArrayList; import java.util.ArrayList;
import android.graphics.PointF; import android.graphics.PointF;
import android.util.Log;
public class BubbleModel public class BubbleModel
{ {
...@@ -14,18 +13,35 @@ public class BubbleModel ...@@ -14,18 +13,35 @@ public class BubbleModel
public ArrayList<Bubble> listBubbles = new ArrayList<Bubble>(); public ArrayList<Bubble> listBubbles = new ArrayList<Bubble>();
public ArrayList<Attractor> attractors = new ArrayList<Attractor>(); public ArrayList<Attractor> attractors = new ArrayList<Attractor>();
private static final float ATTRACTOR_DIST_SUCK = 20.f; private static final double BUBBLE_RETURN_TIME_HALF_LIFE = .3;
private static final double BUBBLE_RETURN_TIME_HALF_LIFE = .25;
private static final double BUBBLE_RETURN_TIME_LAMBDA = Math.log(2)/BUBBLE_RETURN_TIME_HALF_LIFE; private static final double BUBBLE_RETURN_TIME_LAMBDA = Math.log(2)/BUBBLE_RETURN_TIME_HALF_LIFE;
/*private static final float FRICTION_VISCOUS = .5f; // Viscous friction factor private static final double FRICTION_VISCOUS = Math.log(2)/.2f; // Viscous friction factor
private static final float BUBBLE_MAX_SPEED = 2500.f; // px.s-1 : Max target speed in px/sec
private static final float ATTRACTOR_SMOOTH_DIST = 50.f; // px : Size of the "gravity hole" around the attractor
private static final float ATTRACTOR_STALL_DIST = 15.f; // px : Size of the "gravity hole" flat bottom
private static final float ATTRACTOR_DIST_SUCK = 20.f; // px
private static final float BORDER_REPULSION = 60000; // px.s^-2
private final float border_repulsion;
private final float bubble_max_speed;
private final float attractor_smooth_dist;
private final float attractor_stall_dist;
private final float attractor_dist_suck;
private float density = 1.f;
public BubbleModel(float screen_density) {
this.density = screen_density;
attractor_dist_suck = ATTRACTOR_DIST_SUCK*density;
bubble_max_speed = BUBBLE_MAX_SPEED*density;
attractor_smooth_dist = ATTRACTOR_SMOOTH_DIST*density;
attractor_stall_dist = ATTRACTOR_STALL_DIST*density;
border_repulsion = BORDER_REPULSION*density;
}
private static final float BUBBLE_MAX_SPEED = 2500.f; // Max target speed in px/sec
private static final float ATTRACTOR_SMOOTH_DIST = 100.f;// Size of the "gravity hole" around the attractor
private static final float ATTRACTOR_STALL_DIST = 15.f; // Size of the "gravity hole" flat bottom
private static final float ATTRACTOR_ACCEL = 10.f; // Acceleration factor towards target speed
*/
public void update() public void update()
{ {
long now = System.nanoTime(); long now = System.nanoTime();
...@@ -65,75 +81,65 @@ public class BubbleModel ...@@ -65,75 +81,65 @@ public class BubbleModel
} }
} }
double edt = -Math.expm1(-BUBBLE_RETURN_TIME_LAMBDA*dt); //float friction_coef = 1.f-FRICTION_VISCOUS*dt;
double dx = (attractor_pos.x - bx) * edt; double friction_coef = 1+Math.expm1(-FRICTION_VISCOUS*ddt);
double dy = (attractor_pos.y - by) * edt;
// Log.w(TAG, "update dx="+dt+" dy="+dy);
b.setPos((float)(bx+dx), (float)(by+dy));
if(attractor != null && attractor_dist < ATTRACTOR_DIST_SUCK*ATTRACTOR_DIST_SUCK) {
attractor.callback.onBubbleSucked(b);
listBubbles.remove(b);
n--;
}
/* float bx=b.getPosX(), by=b.getPosY();
/// Apply viscous friction
float friction_coef = 1.f-FRICTION_VISCOUS*dt;
float tdx = b.attractor.x - bx, tdy = b.attractor.y - by;
float dist = (float) Math.sqrt(tdx*tdx + tdy*tdy);
float speed = (float)Math.sqrt(b.speed.x*b.speed.x + b.speed.y*b.speed.y);
b.speed.x *= friction_coef;
b.speed.y *= friction_coef;
if(speed > 10.f || dist > ATTRACTOR_STALL_DIST) {
dist = Math.max(1.f, dist); // Avoid division by 0
b.speed.x *= friction_coef; b.speed.x *= friction_coef;
b.speed.y *= friction_coef; b.speed.y *= friction_coef;
// Target speed (defines the "gravity hole") //if(attractor != null) {
float target_speed; float target_speed;
if(dist > ATTRACTOR_SMOOTH_DIST) float tdx = attractor_pos.x - bx, tdy = attractor_pos.y - by;
target_speed = BUBBLE_MAX_SPEED; float dist = Math.max(1.f, (float) Math.sqrt(tdx*tdx + tdy*tdy));
else if(dist < ATTRACTOR_STALL_DIST) if(dist > attractor_smooth_dist)
target_speed = bubble_max_speed;
else if(dist < attractor_stall_dist)
target_speed = 0; target_speed = 0;
else else {
target_speed = BUBBLE_MAX_SPEED/(ATTRACTOR_SMOOTH_DIST-ATTRACTOR_STALL_DIST)*(dist-ATTRACTOR_STALL_DIST); float a = (dist-attractor_stall_dist)/(attractor_smooth_dist-attractor_stall_dist);
target_speed = bubble_max_speed*a;
float target_speed_x = target_speed*tdx/dist; }
float target_speed_y = target_speed*tdy/dist; if(attractor != null) {
if(dist > attractor_smooth_dist)
// Acceleration b.target_scale = 1.f;
float ax = (target_speed_x-b.speed.x) * ATTRACTOR_ACCEL;// + 2*(b.last_speed.x-b.speed.x)*(1-FRICTION_VISCOUS)/FRICTION_VISCOUS*60.f; else if(dist < attractor_stall_dist)
float ay = (target_speed_y-b.speed.y) * ATTRACTOR_ACCEL;// + 2*(b.last_speed.y-b.speed.y)*(1-FRICTION_VISCOUS)/FRICTION_VISCOUS*60.f; b.target_scale = .2f;
else {
// Speed update float a = (dist-attractor_stall_dist)/(attractor_smooth_dist-attractor_stall_dist);
b.target_scale = a*.8f+.2f;
b.speed.x += ax*dt; }
b.speed.y += ay*dt;
b.last_speed.set(b.speed);
Log.w(TAG, "dist " + dist + " speed " + Math.sqrt(b.speed.x*b.speed.x + b.speed.y*b.speed.y) + " target speed "+target_speed);
// Position update }
float dx = b.speed.x * dt;
float dy = b.speed.y * dt;
b.setPos(bx+dx, by+dy);
// border repulsion
if(bx < 0 && b.speed.x < 0) {
b.speed.x += dt * border_repulsion;
} else if(bx > width && b.speed.x > 0) {
b.speed.x -= dt * border_repulsion;
}
if(by < 0 && b.speed.y < 0) {
b.speed.y += dt * border_repulsion;
} else if(by > height && b.speed.y > 0) {
b.speed.y -= dt * border_repulsion;
} }
// Prevent speed higher than BUBBLE_MAX_SPEED
float ds = (target_speed-speed)*dt;
// Set motion direction and speed b.speed.x += dt * target_speed * tdx/dist;
float nsr = (speed>BUBBLE_MAX_SPEED ? BUBBLE_MAX_SPEED : speed+ds)/(dist < 1.f ? 1.f : dist); b.speed.y += dt * target_speed * tdy/dist;
b.speed.x = tdx * nsr;
b.speed.y = tdy * nsr;*/
double edt = -Math.expm1(-BUBBLE_RETURN_TIME_LAMBDA*ddt);
double dx = (attractor_pos.x - bx) * edt + Math.min(bubble_max_speed, b.speed.x) * dt;
double dy = (attractor_pos.y - by) * edt + Math.min(bubble_max_speed, b.speed.y) * dt;
// Log.w(TAG, "update dx="+dt+" dy="+dy);
b.setPos((float)(bx+dx), (float)(by+dy));
if(attractor != null && attractor_dist < attractor_dist_suck*attractor_dist_suck) {
attractor.callback.onBubbleSucked(b);
listBubbles.remove(b);
n--;
} }
}
b.setScale(b.getScale() + (b.target_scale-b.getScale())*dt*10.f);
} }
} }
......
...@@ -4,6 +4,8 @@ import android.content.Context; ...@@ -4,6 +4,8 @@ import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.RectF;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.util.AttributeSet; import android.util.AttributeSet;
...@@ -22,11 +24,18 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -22,11 +24,18 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
private BubbleModel model; private BubbleModel model;
private Paint attractor_paint = new Paint(); private Paint attractor_paint = new Paint();
private Paint name_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float density;
private float textDensity;
public BubblesView(Context context, AttributeSet attrs) public BubblesView(Context context, AttributeSet attrs)
{ {
super(context, attrs); super(context, attrs);
density = getResources().getDisplayMetrics().density;
textDensity = getResources().getDisplayMetrics().scaledDensity;
SurfaceHolder holder = getHolder(); SurfaceHolder holder = getHolder();
holder.addCallback(this); holder.addCallback(this);
...@@ -38,6 +47,9 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -38,6 +47,9 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
attractor_paint.setColor(Color.RED); attractor_paint.setColor(Color.RED);
//attractor_paint.set //attractor_paint.set
name_paint.setTextSize(20*textDensity);
name_paint.setColor(0xFF303030);
name_paint.setTextAlign(Align.CENTER);
} }
private void createThread() private void createThread()
...@@ -127,13 +139,15 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -127,13 +139,15 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
if (b.intersects(event.getX(), event.getY())) { if (b.intersects(event.getX(), event.getY())) {
b.dragged = true; b.dragged = true;
b.last_drag = System.nanoTime(); b.last_drag = System.nanoTime();
b.setPos(event.getX(), event.getY());
b.target_scale = .8f;
} }
} }
} else if (action == MotionEvent.ACTION_MOVE) { } else if (action == MotionEvent.ACTION_MOVE) {
long now = System.nanoTime();
for (Bubble b : model.listBubbles) { for (Bubble b : model.listBubbles) {
if (b.dragged) { if (b.dragged) {
float x = event.getX(), y = event.getY(); float x = event.getX(), y = event.getY();
long now = System.nanoTime();
float dt = (float) ((now-b.last_drag)/1000000000.); float dt = (float) ((now-b.last_drag)/1000000000.);
float dx = x - b.getPosX(), dy = y - b.getPosY(); float dx = x - b.getPosX(), dy = y - b.getPosY();
b.last_drag = now; b.last_drag = now;
...@@ -156,6 +170,7 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -156,6 +170,7 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
for (Bubble b : model.listBubbles) { for (Bubble b : model.listBubbles) {
if (b.dragged) { if (b.dragged) {
b.dragged = false; b.dragged = false;
b.target_scale = 1.f;
} }
} }
} }
...@@ -236,7 +251,17 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback, ...@@ -236,7 +251,17 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
for (int i = 0; i < model.listBubbles.size(); i++) { for (int i = 0; i < model.listBubbles.size(); i++) {
Bubble b = model.listBubbles.get(i); Bubble b = model.listBubbles.get(i);
canvas.drawBitmap(b.getBitmap(), null, b.getBounds(), null); RectF bounds = new RectF(b.getBounds());
/*if(b.dragged) {
float width = bounds.left - bounds.right;
float red = width/4;
bounds.left += red;
bounds.right -= red;
bounds.top += red;
bounds.bottom -= red;
}*/
canvas.drawBitmap(b.getBitmap(), null, bounds, null);
canvas.drawText(b.contact.getmDisplayName(), b.getPosX(), b.getPosY()-50*density, name_paint);
} }
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment