Bubbles: Honor screen density when drawing bubbles and attractors.
diff --git a/src/com/savoirfairelinux/sflphone/model/Attractor.java b/src/com/savoirfairelinux/sflphone/model/Attractor.java
index 5547dc8..51b1850 100644
--- a/src/com/savoirfairelinux/sflphone/model/Attractor.java
+++ b/src/com/savoirfairelinux/sflphone/model/Attractor.java
@@ -1,6 +1,10 @@
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 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;
}
-}
\ No newline at end of file
+
+ 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;
+ }
+
+ public Bitmap getBitmap() {
+ return img;
+ }
+
+}
diff --git a/src/com/savoirfairelinux/sflphone/model/Bubble.java b/src/com/savoirfairelinux/sflphone/model/Bubble.java
index 0dbd013..546bb3c 100644
--- a/src/com/savoirfairelinux/sflphone/model/Bubble.java
+++ b/src/com/savoirfairelinux/sflphone/model/Bubble.java
@@ -24,6 +24,7 @@
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 @@
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 @@
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 @@
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 @@
float tot_radius = this.radius + radius;
return dx*dx + dy*dy < tot_radius*tot_radius;
}
+
+ public void setDensity(float density)
+ {
+ this.density = density;
+ }
}
diff --git a/src/com/savoirfairelinux/sflphone/model/BubbleModel.java b/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
index 460d9e9..87d3718 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
@@ -1,6 +1,7 @@
package com.savoirfairelinux.sflphone.model;
import java.util.ArrayList;
+import java.util.List;
import android.graphics.PointF;
@@ -8,10 +9,10 @@
{
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 @@
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 @@
// 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 @@
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 @@
}
}
+
+
}
diff --git a/src/com/savoirfairelinux/sflphone/model/BubblesView.java b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
index 1243275..8ca439a 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubblesView.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
@@ -1,11 +1,12 @@
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 @@
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 @@
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;
- }
- }
- } 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;
+ synchronized (model) {
+ List<Bubble> bubbles = model.getBubbles();
+ final int n_bubbles = bubbles.size();
- b.setPos(event.getX(), event.getY());
- /*int hn = event.getHistorySize() - 2;
+ 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(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 @@
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 @@
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 @@
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);
}
}