* #23663 Integrated new drawing in App (check action bar icon)
diff --git a/src/com/savoirfairelinux/sflphone/client/BubblesViewActivity.java b/src/com/savoirfairelinux/sflphone/client/BubblesViewActivity.java
new file mode 100644
index 0000000..a59c46a
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/client/BubblesViewActivity.java
@@ -0,0 +1,36 @@
+package com.savoirfairelinux.sflphone.client;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.model.BubblesView;
+
+public class BubblesViewActivity extends Activity
+{
+
+ BubblesView view;
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.bubbleview_layout);
+
+ Button b = (Button) findViewById(R.id.add_bubble);
+ view = (BubblesView) findViewById(R.id.main_view);
+
+ b.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ view.addBubble();
+
+ }
+ });
+
+ }
+}
\ No newline at end of file
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
index 41650e5..fff2097 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
@@ -306,15 +306,18 @@
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- Log.i("SFLphone", "onOptionsItemSelected " + item.getItemId());
- if (item.getItemId() != 0) {
- // When the button is clicked, launch an activity through this intent
+ Log.i(TAG, "onOptionsItemSelected " + item.getItemId());
+ switch(item.getItemId()){
+ case R.id.menu_settings :
Intent launchPreferencesIntent = new Intent().setClass(this, SFLPhonePreferenceActivity.class);
-
- // Make it a subactivity so we know when it returns
startActivityForResult(launchPreferencesIntent, REQUEST_CODE_PREFERENCES);
+ break;
+ case R.id.menu_custom_draw:
+ Intent launchNewInterfaceIntent = new Intent().setClass(this, BubblesViewActivity.class);
+ startActivityForResult(launchNewInterfaceIntent, 0);
+ break;
}
-
+
return super.onOptionsItemSelected(item);
}
diff --git a/src/com/savoirfairelinux/sflphone/model/Bubble.java b/src/com/savoirfairelinux/sflphone/model/Bubble.java
new file mode 100644
index 0000000..55d7375
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/model/Bubble.java
@@ -0,0 +1,206 @@
+package com.savoirfairelinux.sflphone.model;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.graphics.Region;
+
+import com.savoirfairelinux.sflphone.R;
+
+public class Bubble extends Shape2d {
+
+ // Create a paint for the fill
+ private Paint mPaintPath, mBitmapPaint;
+
+ public Paint getmPaintPath() {
+ return mPaintPath;
+ }
+
+ public Paint getmBitmapPaint() {
+ return mBitmapPaint;
+ }
+
+ private float radius;
+
+ // A Bitmap object that is going to be passed to the BitmapShader
+ private Bitmap internalBMP, externalBMP;
+
+ public Bitmap getExternalBMP() {
+ return externalBMP;
+ }
+
+ Canvas internalCanvas;
+
+ // Two floats to store the touch position
+ private float posX;
+ private float posY;
+ Path path;
+
+ private RectF region;
+
+ private RectF bounds;
+
+ public RectF getBounds() {
+ return bounds;
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
+ private Bubble(Context c, float X, float Y, float rad, int resID) {
+ posX = X;
+ posY = Y;
+
+ // 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);
+ }
+ internalBMP = Bitmap.createScaledBitmap(internalBMP, (int) rad, (int) rad, false);
+ externalBMP = Bitmap.createBitmap(internalBMP.getWidth(), internalBMP.getHeight(), Bitmap.Config.ARGB_8888);
+
+ radius = externalBMP.getWidth() / 2;
+ path = new Path();
+
+ path.addCircle(radius, radius, radius, Path.Direction.CW);
+
+ bounds = new RectF(posX - radius, posY - radius, posX + radius, posY + radius);
+
+ mPaintPath = new Paint();
+ mPaintPath.setARGB(255, 200, 200, 200);
+ mPaintPath.setStyle(Paint.Style.FILL_AND_STROKE);
+ mPaintPath.setAntiAlias(true);
+
+ mBitmapPaint = new Paint();
+ mBitmapPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
+
+ internalCanvas = new Canvas(externalBMP);
+ internalCanvas.clipPath(path, Region.Op.INTERSECT);
+ internalCanvas.drawPath(path, mPaintPath);
+
+ RectF tmp = new RectF(0, 0, externalBMP.getWidth(), externalBMP.getHeight());
+ internalCanvas.drawBitmap(internalBMP, null, tmp, mBitmapPaint);
+
+ }
+
+ public float getPosX() {
+ return posX;
+ }
+
+ public void setPosX(float X) {
+ if (X + radius <= region.right && X - radius >= region.left)
+ this.posX = X;
+
+ path.reset();
+ path.addCircle(posX, posY, radius, Path.Direction.CW);
+ bounds.left = posX - radius;
+ bounds.right = posX + radius;
+ }
+
+ public void setPosY(float Y) {
+ if (Y + radius <= region.bottom && Y - radius >= region.top)
+ this.posY = Y;
+
+ path.reset();
+ path.addCircle(posX, posY, radius, Path.Direction.CW);
+ bounds.top = posY - radius;
+ bounds.bottom = posY + radius;
+ }
+
+ public float getPosY() {
+ return posY;
+ }
+
+ public float getRadius() {
+ return radius;
+ }
+
+ @Override
+ public String toString() {
+ String str = "Bounds :" + getLeft() + " " + getRight() + " " + getTop() + " " + getBottom() + " " + getHeight() + " " + getWidth() + " "
+ + posX + " " + posY;
+ return str;
+ }
+
+ /**
+ * A more readable way to create balls than using a 5 param constructor of all numbers.
+ */
+ public static class Builder {
+ private Context mContext;
+ private float mX = -1;
+ private float mY = -1;
+ private float mRadiusPixels = -1;
+ private int resID = -1;
+
+ public void setResID(int resID) {
+ this.resID = resID;
+ }
+
+ public Builder(Context c) {
+ mContext = c;
+ }
+
+ public Bubble create() {
+
+ if (mX < 0) {
+ throw new IllegalStateException("X must be set");
+ }
+ if (mY < 0) {
+ throw new IllegalStateException("Y must be stet");
+ }
+ if (mRadiusPixels <= 0) {
+ throw new IllegalStateException("radius must be set");
+ }
+ return new Bubble(mContext, mX, mY, mRadiusPixels, resID);
+ }
+
+ public Builder setX(float x) {
+ mX = x;
+ return this;
+ }
+
+ public Builder setY(float y) {
+ mY = y;
+ return this;
+ }
+
+ public Builder setRadiusPixels(float pixels) {
+ mRadiusPixels = pixels;
+ return this;
+ }
+ }
+
+ @Override
+ public float getLeft() {
+ return posX - radius;
+ }
+
+ @Override
+ public float getRight() {
+ return posX + radius;
+ }
+
+ @Override
+ public float getTop() {
+ return posY - radius;
+ }
+
+ @Override
+ public float getBottom() {
+ return posY + radius;
+ }
+
+ public void setRegion(int w, int h) {
+ region = new RectF(0, 0, w, h);
+
+ }
+
+}
diff --git a/src/com/savoirfairelinux/sflphone/model/BubblesView.java b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
new file mode 100644
index 0000000..4c35710
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
@@ -0,0 +1,100 @@
+package com.savoirfairelinux.sflphone.model; // 41 Post - Created by DimasTheDriver on May/24/2012 . Part of the 'Android - rendering a Path with a Bitmap fill' post. http://www.41post.com/?p=4766
+
+import java.util.ArrayList;
+
+import com.savoirfairelinux.sflphone.R;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class BubblesView extends View {
+
+ private static final String TAG = BubblesView.class.getSimpleName();
+
+ ArrayList<Bubble> listBubbles;
+
+ Paint paint;
+
+ private int width;
+
+ private int height;
+
+ public BubblesView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ listBubbles = new ArrayList<Bubble>();
+ Bubble.Builder builder = new Bubble.Builder(getContext());
+ builder.setRadiusPixels(200).setX(200).setY(300).setResID(R.drawable.me);
+ listBubbles.add(builder.create());
+
+ builder.setRadiusPixels(200).setX(200).setY(700).setResID(R.drawable.callee);
+ listBubbles.add(builder.create());
+ // This View can receive focus, so it can react to touch events.
+ this.setFocusable(true);
+
+ paint = new Paint();
+
+ paint.setStyle(Paint.Style.FILL);
+ paint.setColor(Color.BLACK);
+ paint.setAntiAlias(true);
+ paint.setStrokeWidth(3);
+
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ // Store the position of the touch event at 'posX' and 'posY'
+ if (event.getAction() == MotionEvent.ACTION_MOVE) {
+
+ for (Bubble b : listBubbles) {
+ if (b.isPointWithin(event.getX(), event.getY())) {
+ b.setPosX(event.getX());
+ b.setPosY(event.getY());
+ invalidate();
+ return true;
+ }
+ }
+
+ }
+ return true;
+ }
+
+ @Override
+ public void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ width = w;
+ height = h;
+ Log.i(TAG, "New Width " + w);
+ Log.i(TAG, "New Heigth " + h);
+ for (Bubble b : listBubbles) {
+ b.setRegion(w, h);
+ }
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+
+ canvas.drawColor(Color.GRAY);
+ // canvas.drawLine(a.getPosX(), a.getPosY(), b.getPosX(), b.getPosY(), paint);
+
+ for (Bubble b : listBubbles) {
+ canvas.drawBitmap(b.getExternalBMP(), null, b.getBounds(), null);
+ }
+
+ }
+
+ public void addBubble() {
+ Bubble.Builder builder = new Bubble.Builder(getContext());
+ builder.setRadiusPixels(200).setX(200).setY(300);
+ listBubbles.add(builder.create());
+ listBubbles.get(listBubbles.size()-1).setRegion(width, height);
+ invalidate();
+ }
+}
diff --git a/src/com/savoirfairelinux/sflphone/model/Shape2d.java b/src/com/savoirfairelinux/sflphone/model/Shape2d.java
new file mode 100644
index 0000000..06cee4e
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/model/Shape2d.java
@@ -0,0 +1,41 @@
+package com.savoirfairelinux.sflphone.model;
+
+public abstract class Shape2d {
+
+ public abstract float getLeft();
+ public abstract float getRight();
+ public abstract float getTop();
+ public abstract float getBottom();
+
+ /**
+ * @param other Another 2d shape
+ * @return Whether this shape is intersecting with the other.
+ */
+ public boolean isIntersecting(Shape2d other) {
+ return getLeft() <= other.getRight() && getRight() >= other.getLeft()
+ && getTop() <= other.getBottom() && getBottom() >= other.getTop();
+ }
+
+ /**
+ * @param x An x coordinate
+ * @param y A y coordinate
+ * @return Whether the point is within this shape
+ */
+ public boolean isPointWithin(float x, float y) {
+ return (x > getLeft() && x < getRight()
+ && y > getTop() && y < getBottom());
+
+ }
+
+ public float getArea() {
+ return getHeight() * getWidth();
+ }
+
+ public float getHeight() {
+ return getBottom() - getTop();
+ }
+
+ public float getWidth () {
+ return getRight() - getLeft();
+ }
+}
\ No newline at end of file