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

Bubbles: Honor screen density when drawing bubbles and attractors.

parent 85704183
No related branches found
No related tags found
No related merge requests found
No preview for this file type
......@@ -36,12 +36,12 @@ as that of the covered work.
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/ongoingcall_pane"
android:id="@+id/calllist_pane"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/calllist_pane"
android:id="@+id/ongoingcall_pane"
android:layout_width="match_parent"
android:layout_height="match_parent" />
......
......@@ -11,26 +11,4 @@
android:layout_alignParentTop="true"
android:focusable="true" />
<!-- <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:weightSum="2" >
<Button
android:id="@+id/add_bubble"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Bubble" />
<Button
android:id="@+id/remove_bubble"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Remove Bubble" />
</LinearLayout> -->
</RelativeLayout>
\ No newline at end of file
......@@ -36,6 +36,7 @@ import java.util.HashMap;
import android.app.Activity;
import android.app.Fragment;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.RemoteException;
......@@ -54,264 +55,289 @@ import com.savoirfairelinux.sflphone.model.BubbleModel;
import com.savoirfairelinux.sflphone.model.BubblesView;
import com.savoirfairelinux.sflphone.model.CallContact;
import com.savoirfairelinux.sflphone.model.SipCall;
import com.savoirfairelinux.sflphone.service.CallManagerCallBack;
import com.savoirfairelinux.sflphone.service.ISipService;
public class CallFragment extends Fragment {
static final String TAG = "CallFragment";
private SipCall mCall;
static final String TAG = "CallFragment";
private BubblesView view;
private BubbleModel model;
private PointF screenCenter;
private DisplayMetrics metrics;
static final float BUBBLE_SIZE = 100;
private Callbacks mCallbacks = sDummyCallbacks;
private SipCall mCall;
private HashMap<CallContact, Bubble> contacts = new HashMap<CallContact, Bubble>();
private BubblesView view;
private BubbleModel model;
private PointF screenCenter;
private DisplayMetrics metrics;
private TextView contact_name_txt;
private Callbacks mCallbacks = sDummyCallbacks;
CallContact myself = CallContact.ContactBuilder.buildUserContact("Me");
private HashMap<CallContact, Bubble> contacts = new HashMap<CallContact, Bubble>();
@Override
public void onCreate(Bundle savedBundle) {
super.onCreate(savedBundle);
model = new BubbleModel(getResources().getDisplayMetrics().density);
metrics = getResources().getDisplayMetrics();
screenCenter = new PointF(metrics.widthPixels / 2, metrics.heightPixels / 3);
private TextView contact_name_txt;
Bundle b = getArguments();
private CallContact myself = CallContact.ContactBuilder.buildUserContact("Me");
mCall = b.getParcelable("CallInfo");
}
private Bitmap hangup_icon;
private Bitmap call_icon;
/**
* A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
@Override
public void onCreate(Bundle savedBundle) {
super.onCreate(savedBundle);
model = new BubbleModel(getResources().getDisplayMetrics().density);
metrics = getResources().getDisplayMetrics();
screenCenter = new PointF(metrics.widthPixels / 2, metrics.heightPixels / 3);
@Override
public void onSendMessage(SipCall call, String msg) {
Bundle b = getArguments();
}
mCall = b.getParcelable("CallInfo");
//mCall.
}
@Override
public void callContact(SipCall call) {
}
/**
* A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
@Override
public void onSendMessage(SipCall call, String msg) {
}
@Override
public void onCallAccepted(SipCall call) {
// TODO Auto-generated method stub
@Override
public void callContact(SipCall call) {
}
}
@Override
public void onCallAccepted(SipCall call) {
}
@Override
public void onCallRejected(SipCall call) {
// TODO Auto-generated method stub
@Override
public void onCallRejected(SipCall call) {
}
}
@Override
public void onCallEnded(SipCall call) {
}
@Override
public void onCallEnded(SipCall call) {
// TODO Auto-generated method stub
@Override
public void onCallSuspended(SipCall call) {
}
}
@Override
public void onCallResumed(SipCall call) {
}
@Override
public void onCallSuspended(SipCall call) {
// TODO Auto-generated method stub
@Override
public void onCalltransfered(SipCall call, String to) {
}
}
@Override
public void onRecordCall(SipCall call) {
}
@Override
public void onCallResumed(SipCall call) {
// TODO Auto-generated method stub
@Override
public ISipService getService() {
return null;
}
};
}
/**
* The Activity calling this fragment has to implement this interface
*
*/
public interface Callbacks {
@Override
public void onCalltransfered(SipCall call, String to) {
// TODO Auto-generated method stub
public ISipService getService();
}
public void callContact(SipCall call);
@Override
public void onRecordCall(SipCall call) {
// TODO Auto-generated method stub
public void onCallAccepted(SipCall call);
}
public void onCallRejected(SipCall call);
@Override
public ISipService getService() {
// TODO Auto-generated method stub
return null;
}
};
public void onCallEnded(SipCall call);
/**
* The Activity calling this fragment has to implement this interface
*
*/
public interface Callbacks {
public void onCallSuspended(SipCall call);
public ISipService getService();
public void onCallResumed(SipCall call);
public void callContact(SipCall call);
public void onCallAccepted(SipCall call);
public void onCallRejected(SipCall call);
public void onCallEnded(SipCall call);
public void onCallSuspended(SipCall call);
public void onCallResumed(SipCall call);
public void onCalltransfered(SipCall call, String to);
public void onRecordCall(SipCall call);
public void onSendMessage(SipCall call, String msg);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
@Override
public void onDetach() {
super.onDetach();
mCallbacks = sDummyCallbacks;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.frag_call, container, false);
view = (BubblesView) rootView.findViewById(R.id.main_view);
view.setModel(model);
Log.i(TAG, "Starting fragment for call " + mCall.getCallId());
mCall.printCallInfo();
if (mCall.isRinging()) {
initOutGoingCallDisplay();
}
if (mCall.isIncoming() && mCall.isRinging()) {
initIncomingCallDisplay();
}
try {
if (mCall.isOutGoing() && mCallbacks.getService().getCall(mCall.getCallId()) == null) {
mCallbacks.getService().placeCall(mCall);
initOutGoingCallDisplay();
} else if(mCall.isOutGoing() && mCall.isRinging()){
initOutGoingCallDisplay();
}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
if(mCall.isOngoing()){
initNormalStateDisplay();
}
return rootView;
}
private void initNormalStateDisplay() {
Log.i(TAG, "Start normal display");
// TODO off-thread image loading
Bubble contact_bubble, me;
if (mCall.getContacts().get(0).getPhoto_id() > 0) {
Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), mCall.getContacts().get(0).getId());
contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y, 150, photo);
} else {
contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y / 2 , 150, R.drawable.ic_contact_picture);
}
me = new Bubble(getActivity(), screenCenter.x, screenCenter.y * 3 / 2, 150, R.drawable.ic_contact_picture);
model.attractors.clear();
model.attractors.add(new Attractor(new PointF(metrics.widthPixels / 2, metrics.heightPixels * .8f), new Attractor.Callback() {
@Override
public void onBubbleSucked(Bubble b) {
Log.w(TAG, "Bubble sucked ! ");
mCallbacks.onCallEnded(mCall);
}
}));
contact_bubble.contact = mCall.getContacts().get(0);
me.contact = myself;
model.listBubbles.add(contact_bubble);
model.listBubbles.add(me);
contacts.put(mCall.getContacts().get(0), contact_bubble);
contacts.put(myself, me);
}
private void initIncomingCallDisplay() {
Log.i(TAG, "Start incoming display");
model.attractors.clear();
model.attractors.add(new Attractor(new PointF(3 * metrics.widthPixels / 4, metrics.heightPixels / 4), new Attractor.Callback() {
@Override
public void onBubbleSucked(Bubble b) {
mCallbacks.onCallAccepted(mCall);
}
}));
model.attractors.add(new Attractor(new PointF(metrics.widthPixels / 4, metrics.heightPixels / 4), new Attractor.Callback() {
@Override
public void onBubbleSucked(Bubble b) {
mCallbacks.onCallRejected(mCall);
}
}));
}
private void initOutGoingCallDisplay() {
Log.i(TAG, "Start outgoing display");
// TODO off-thread image loading
Bubble contact_bubble;
if (mCall.getContacts().get(0).getPhoto_id() > 0) {
Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), mCall.getContacts().get(0).getId());
contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y, 150, photo);
} else {
contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y, 150, R.drawable.ic_contact_picture);
}
model.attractors.clear();
model.attractors.add(new Attractor(new PointF(metrics.widthPixels / 2, metrics.heightPixels * .8f), new Attractor.Callback() {
@Override
public void onBubbleSucked(Bubble b) {
Log.w(TAG, "Bubble sucked ! ");
mCallbacks.onCallEnded(mCall);
}
}));
contact_bubble.contact = mCall.getContacts().get(0);
model.listBubbles.add(contact_bubble);
contacts.put(mCall.getContacts().get(0), contact_bubble);
}
public void changeCallState(String callID, String newState) {
Log.w(TAG, "Changing call state of "+callID);
mCall.printCallInfo();
if(callID != mCall.getCallId())
return;
mCall.setCallState(newState);
if(mCall.isOngoing()){
initNormalStateDisplay();
}
}
public void onCalltransfered(SipCall call, String to);
public void onRecordCall(SipCall call);
public void onSendMessage(SipCall call, String msg);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
@Override
public void onDetach() {
super.onDetach();
mCallbacks = sDummyCallbacks;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.frag_call, container, false);
view = (BubblesView) rootView.findViewById(R.id.main_view);
view.setModel(model);
hangup_icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_hangup);
call_icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_call);
Log.i(TAG, "Starting fragment for call " + mCall.getCallId());
mCall.printCallInfo();
if (mCall.isIncoming() && mCall.isRinging()) {
initIncomingCallDisplay();
} else {
if (mCall.isRinging()) {
initOutGoingCallDisplay();
}
try {
if (mCall.isOutGoing() && mCallbacks.getService().getCall(mCall.getCallId()) == null) {
mCallbacks.getService().placeCall(mCall);
initOutGoingCallDisplay();
} else if(mCall.isOutGoing() && mCall.isRinging()){
initOutGoingCallDisplay();
}
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
}
if(mCall.isOngoing()){
initNormalStateDisplay();
}
return rootView;
}
private void initNormalStateDisplay() {
Log.i(TAG, "Start normal display");
// TODO off-thread image loading
Bubble contact_bubble = getBubbleFor(mCall.getContacts().get(0), screenCenter.x, screenCenter.y);
Bubble me = getBubbleFor(myself, screenCenter.x, screenCenter.y * 3 / 2);
/* contact_bubble.setPos(screenCenter.x, screenCenter.y);
me.setPos(screenCenter.x, screenCenter.y * 3 / 2);*/
/*if (mCall.getContacts().get(0).getPhoto_id() > 0) {
Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), mCall.getContacts().get(0).getId());
contact_bubble = new Bubble(screenCenter.x, screenCenter.y, 150, photo);
} else {
contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y / 2 , 150, R.drawable.ic_contact_picture);
}
me = new Bubble(getActivity(), screenCenter.x, screenCenter.y * 3 / 2, 150, R.drawable.ic_contact_picture);
*/
model.clearAttractors();
model.addAttractor(new Attractor(new PointF(metrics.widthPixels / 2, metrics.heightPixels * .8f), 20, new Attractor.Callback() {
@Override
public void onBubbleSucked(Bubble b) {
Log.w(TAG, "Bubble sucked ! ");
mCallbacks.onCallEnded(mCall);
}
}, hangup_icon));
/* contact_bubble.contact = mCall.getContacts().get(0);
me.contact = myself;
model.addBubble(contact_bubble);
model.addBubble(me);
contacts.put(mCall.getContacts().get(0), contact_bubble);
contacts.put(myself, me);*/
}
private void initIncomingCallDisplay() {
Log.i(TAG, "Start incoming display");
Bubble contact_bubble = getBubbleFor(mCall.getContacts().get(0), screenCenter.x, screenCenter.y);
contacts.put(mCall.getContacts().get(0), contact_bubble);
model.clearAttractors();
model.addAttractor(new Attractor(new PointF(3 * metrics.widthPixels / 4, metrics.heightPixels / 4), 20, new Attractor.Callback() {
@Override
public void onBubbleSucked(Bubble b) {
mCallbacks.onCallAccepted(mCall);
}
}, call_icon));
model.addAttractor(new Attractor(new PointF(metrics.widthPixels / 4, metrics.heightPixels / 4), 20, new Attractor.Callback() {
@Override
public void onBubbleSucked(Bubble b) {
mCallbacks.onCallRejected(mCall);
}
}, hangup_icon));
}
private void initOutGoingCallDisplay() {
Log.i(TAG, "Start outgoing display");
// TODO off-thread image loading
Bubble contact_bubble = getBubbleFor(mCall.getContacts().get(0), screenCenter.x, screenCenter.y);
model.clearAttractors();
model.addAttractor(new Attractor(new PointF(metrics.widthPixels / 2, metrics.heightPixels * .8f), 20, new Attractor.Callback() {
@Override
public void onBubbleSucked(Bubble b) {
Log.w(TAG, "Bubble sucked ! ");
mCallbacks.onCallEnded(mCall);
}
}, hangup_icon));
/*contact_bubble.contact = mCall.getContacts().get(0);
model.addBubble(contact_bubble);
contacts.put(mCall.getContacts().get(0), contact_bubble);*/
}
/**
* Retrieves or create a bubble for a given contact.
* If the bubble exists, it is moved to the new location.
*
* @param contact The contact
* @param x Initial or new x position.
* @param y Initial or new y position.
* @return Bubble corresponding to the contact.
*/
private Bubble getBubbleFor(CallContact contact, float x, float y) {
Bubble contact_bubble = contacts.get(contact);
if(contact_bubble != null) {
contact_bubble.attractor.set(x, y);
return contact_bubble;
}
if (contact.getPhoto_id() > 0) {
Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), mCall.getContacts().get(0).getId());
contact_bubble = new Bubble(x, y, BUBBLE_SIZE, photo);
} else {
contact_bubble = new Bubble(x, y, BUBBLE_SIZE, getActivity(), R.drawable.ic_contact_picture);
}
contact_bubble.contact = contact;
model.addBubble(contact_bubble);
contacts.put(contact, contact_bubble);
return contact_bubble;
}
public void changeCallState(String callID, String newState) {
Log.w(TAG, "Changing call state of "+callID);
mCall.printCallInfo();
if(!callID.equals(mCall.getCallId()))
return;
mCall.setCallState(newState);
if(mCall.isOngoing()){
initNormalStateDisplay();
}
}
}
package com.savoirfairelinux.sflphone.model;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;
import android.graphics.RectF;
public class Attractor {
......@@ -8,10 +12,36 @@ public class Attractor {
public void onBubbleSucked(Bubble b);
}
PointF pos;
Callback callback;
public Attractor(PointF pos, Callback callback) {
final PointF pos;
final float radius;
final Callback callback;
private final Bitmap img;
private final RectF bounds = new RectF();
public Attractor(PointF pos, float radius, Callback callback, Bitmap img) {
this.pos = pos;
this.radius = radius;
this.callback = callback;
this.img = img;
}
public Attractor(PointF pos, float radius, Callback callback, Context c, int resId) {
this(pos, radius, callback, BitmapFactory.decodeResource(c.getResources(), resId));
}
public void setDensity(float density)
{
bounds.set(pos.x - radius*density, pos.y - radius*density, pos.x + radius*density, pos.y + radius*density);
}
public RectF getBounds() {
return bounds;
}
}
\ No newline at end of file
public Bitmap getBitmap() {
return img;
}
}
......@@ -24,6 +24,7 @@ public class Bubble
public float target_scale = 1.f;
private final 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;
......@@ -36,7 +37,7 @@ public class Bubble
this.attractor = attractor;
}
public Bubble(Context c, float x, float y, float rad, Bitmap photo) {
public Bubble(float x, float y, float rad, Bitmap photo) {
internalBMP = photo;
pos.set(x, y);
......@@ -68,18 +69,11 @@ public class Bubble
internalCanvas.drawBitmap(circle, 0, 0, mPaintPath);
}
public Bubble(Context c, float x, float y, float rad, int resID) {
public Bubble(float x, float y, float rad, Context c, int resID) {
// Initialize the bitmap object by loading an image from the resources folder
/*if (resID != -1)
internalBMP = BitmapFactory.decodeResource(c.getResources(), resID);
else
internalBMP = BitmapFactory.decodeResource(c.getResources(), R.drawable.ic_contact_picture);
*/
this(c, x, y, rad, BitmapFactory.decodeResource(c.getResources(), resID==-1 ? resID : R.drawable.ic_contact_picture));
this(x, y, rad, BitmapFactory.decodeResource(c.getResources(), resID==-1 ? resID : R.drawable.ic_contact_picture));
}
public Bitmap getBitmap() {
return externalBMP;
}
......@@ -92,7 +86,7 @@ public class Bubble
scale = s;
pos.x = x;
pos.y = y;
float rad = scale*radius;
float rad = scale*radius*density;
bounds.left = pos.x - rad;
bounds.right = pos.x + rad;
bounds.top = pos.y - rad;
......@@ -144,4 +138,9 @@ public class Bubble
float tot_radius = this.radius + radius;
return dx*dx + dy*dy < tot_radius*tot_radius;
}
public void setDensity(float density)
{
this.density = density;
}
}
package com.savoirfairelinux.sflphone.model;
import java.util.ArrayList;
import java.util.List;
import android.graphics.PointF;
......@@ -8,10 +9,10 @@ public class BubbleModel
{
private static final String TAG = BubbleModel.class.getSimpleName();
public long lastUpdate = 0;
private long lastUpdate = 0;
public int width, height;
public ArrayList<Bubble> listBubbles = new ArrayList<Bubble>();
public ArrayList<Attractor> attractors = new ArrayList<Attractor>();
private ArrayList<Bubble> bubbles = new ArrayList<Bubble>();
private ArrayList<Attractor> attractors = new ArrayList<Attractor>();
private static final double BUBBLE_RETURN_TIME_HALF_LIFE = .3;
private static final double BUBBLE_RETURN_TIME_LAMBDA = Math.log(2)/BUBBLE_RETURN_TIME_HALF_LIFE;
......@@ -42,6 +43,35 @@ public class BubbleModel
border_repulsion = BORDER_REPULSION*density;
}
public void addBubble(Bubble b) {
b.setDensity(density);
bubbles.add(b);
}
public List<Bubble> getBubbles()
{
return bubbles;
}
public void addAttractor(Attractor a) {
a.setDensity(density);
attractors.add(a);
}
public List<Attractor> getAttractors()
{
return attractors;
}
public void clearAttractors() {
attractors.clear();
}
public void clear() {
clearAttractors();
bubbles.clear();
}
public void update()
{
long now = System.nanoTime();
......@@ -60,8 +90,8 @@ public class BubbleModel
// Iterators should not be used in frequently called methods
// to avoid garbage collection glitches caused by iterator objects.
for(int i=0, n=listBubbles.size(); i<n; i++) {
Bubble b = listBubbles.get(i);
for(int i=0, n=bubbles.size(); i<n; i++) {
Bubble b = bubbles.get(i);
//Log.w(TAG, "update b");
if(!b.dragged) {
......@@ -134,7 +164,7 @@ public class BubbleModel
if(attractor != null && attractor_dist < attractor_dist_suck*attractor_dist_suck) {
attractor.callback.onBubbleSucked(b);
listBubbles.remove(b);
bubbles.remove(b);
n--;
}
}
......@@ -143,4 +173,6 @@ public class BubbleModel
}
}
}
package com.savoirfairelinux.sflphone.model;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
......@@ -47,7 +48,7 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
attractor_paint.setColor(Color.RED);
//attractor_paint.set
name_paint.setTextSize(20*textDensity);
name_paint.setTextSize(18*textDensity);
name_paint.setColor(0xFF303030);
name_paint.setTextAlign(Align.CENTER);
}
......@@ -134,46 +135,55 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
for (Bubble b : model.listBubbles) {
if (b.intersects(event.getX(), event.getY())) {
b.dragged = true;
b.last_drag = System.nanoTime();
b.setPos(event.getX(), event.getY());
b.target_scale = .8f;
synchronized (model) {
List<Bubble> bubbles = model.getBubbles();
final int n_bubbles = bubbles.size();
if (action == MotionEvent.ACTION_DOWN) {
for(int i=0; i<n_bubbles; i++) {
Bubble b = bubbles.get(i);
if (b.intersects(event.getX(), event.getY())) {
b.dragged = true;
b.last_drag = System.nanoTime();
b.setPos(event.getX(), event.getY());
b.target_scale = .8f;
}
}
}
} else if (action == MotionEvent.ACTION_MOVE) {
long now = System.nanoTime();
for (Bubble b : model.listBubbles) {
if (b.dragged) {
float x = event.getX(), y = event.getY();
float dt = (float) ((now-b.last_drag)/1000000000.);
float dx = x - b.getPosX(), dy = y - b.getPosY();
b.last_drag = now;
b.setPos(event.getX(), event.getY());
/*int hn = event.getHistorySize() - 2;
} else if (action == MotionEvent.ACTION_MOVE) {
long now = System.nanoTime();
for(int i=0; i<n_bubbles; i++) {
Bubble b = bubbles.get(i);
if (b.dragged) {
float x = event.getX(), y = event.getY();
float dt = (float) ((now-b.last_drag)/1000000000.);
float dx = x - b.getPosX(), dy = y - b.getPosY();
b.last_drag = now;
b.setPos(event.getX(), event.getY());
/*int hn = event.getHistorySize() - 2;
Log.w(TAG, "event.getHistorySize() : " + event.getHistorySize());
if(hn > 0) {
float dx = x-event.getHistoricalX(hn);
float dy = y-event.getHistoricalY(hn);
float dt = event.getHistoricalEventTime(hn)/1000.f;*/
b.speed.x = dx/dt;
b.speed.y = dy/dt;
//Log.w(TAG, "onTouch dx:" + b.speed.x + " dy:" + b.speed.y);
//}
return true;
b.speed.x = dx/dt;
b.speed.y = dy/dt;
//Log.w(TAG, "onTouch dx:" + b.speed.x + " dy:" + b.speed.y);
//}
return true;
}
}
}
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
for (Bubble b : model.listBubbles) {
if (b.dragged) {
b.dragged = false;
b.target_scale = 1.f;
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
for(int i=0; i<n_bubbles; i++) {
Bubble b = bubbles.get(i);
if (b.dragged) {
b.dragged = false;
b.target_scale = 1.f;
}
}
}
}
return true;
}
......@@ -212,9 +222,6 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
doDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null)
surfaceHolder.unlockCanvasAndPost(c);
}
......@@ -233,9 +240,6 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
model.width = width;
model.height = height;
}
// don't forget to resize the background image
// mBackgroundImage = Bitmap.createScaledBitmap(mBackgroundImage, width, height, true);
}
}
......@@ -244,23 +248,19 @@ public class BubblesView extends SurfaceView implements SurfaceHolder.Callback,
canvas.drawColor(Color.WHITE);
synchronized (model) {
for (int i = 0; i < model.attractors.size(); i++) {
Attractor a = model.attractors.get(i);
canvas.drawCircle(a.pos.x, a.pos.y, 10, attractor_paint);
List<Bubble> bubbles = model.getBubbles();
List<Attractor> attractors = model.getAttractors();
for (int i=0, n=attractors.size(); i < n; i++) {
Attractor a = attractors.get(i);
//canvas.drawCircle(a.pos.x, a.pos.y, 10, attractor_paint);
canvas.drawBitmap(a.getBitmap(), null, a.getBounds(), null);
}
for (int i = 0; i < model.listBubbles.size(); i++) {
Bubble b = model.listBubbles.get(i);
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);
for (int i=0, n=bubbles.size(); i<n; i++) {
Bubble b = bubbles.get(i);
//RectF bounds = new RectF(b.getBounds());
canvas.drawBitmap(b.getBitmap(), null, b.getBounds(), 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.
Finish editing this message first!
Please register or to comment