nnttoo / android-multitouch-controller

Automatically exported from code.google.com/p/android-multitouch-controller
0 stars 0 forks source link

Cant change the image #4

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Tried to change the canvas drawing, storing, and modifying it
2. Tried to change the Bitmap
3. Tried to remake the multiController object.

What is the expected output? What do you see instead?
To change the initial image

Please provide any additional information below.

Is there a way to do this_

Original issue reported on code.google.com by care.n...@gmail.com on 16 Nov 2011 at 6:51

GoogleCodeExporter commented 9 years ago
Not quite sure what you're trying to do. Are you trying to view photos other 
than the ones that come with MTPhotoSortrDemo? Those are hard-wired...

Please give more information, such as what you were trying to accomplish, code 
snippets, etc.

Original comment by luke.hutch on 16 Nov 2011 at 6:58

GoogleCodeExporter commented 9 years ago
Let's picture the simple example that was posted in issues, (it can be the 
original, but for simplicity), if i have in the same activity, one button in 
the foreground, and in the background is the image of the MultitouchView, that 
can be dragged, rotated, etc... 
Now, i want than when i press the button it changes to another resource, 
bitmap, or whatever is better to explain this (according to the simple example 
it should be a bitmap)

About a code snippet, what i really want, well is very simple actually:

private Multitouch0View mTv;
onCreate{
mTv= new MTV0(MyActivity.this);
mTv.setImg(anyBitmap);
}

but changing the img in this case doesnt work.

similar with the points that i already mentioned before.

Original comment by care.n...@gmail.com on 16 Nov 2011 at 7:08

GoogleCodeExporter commented 9 years ago
In fact when doing this, and using logging to see what it is drawing, i get the 
same object id, that i had in the constructor, not the one i pass in the setter.

onDraw(Canvas canvas){
Log.e("onDraw", "Bitmap to draw: "+img);
...
}

So it is really not refreshing the one in the View, it may be that it get set 
again somewhere else in the code but i can't find where.

Original comment by care.n...@gmail.com on 16 Nov 2011 at 7:14

GoogleCodeExporter commented 9 years ago
There is no setImg anywhere in this code project. I'm not sure what you're 
referring to.

In interface MultiTouchObjectCanvas you have to implement public T 
getDraggableObjectAtPoint(PointInfo touchPoint) -- and you can return whatever 
you want from that method, including a new image object reference if the image 
gets updated.

Please let me know what I'm missing.

Original comment by luke.hutch on 16 Nov 2011 at 8:17

GoogleCodeExporter commented 9 years ago
The method setImg(Bitmap) is a simple setter, sorry i forgot to explain that:

public void setImg(Bitmap img) {
        this.img = img;
        Log.e("Set new Bitmap", "Bitmap recibido;¡: " +img);
    }
Inside of the view that implements the MultitouchObjectCanvas.

I'm implementing the getDraggableObjectAtPoint this way:

    public Object getDraggableObjectAtPoint(PointInfo pt) {
        Log.e("getDraggableObjectAtPoint", "Bitmap recibido;¡: " +img);
        return img;
    }

At this point the log returns me always the first image as i stated before, and 
i can't find where does it reset the image.

Thanks for the help luke, i'm pending of your answers.

Original comment by care.n...@gmail.com on 16 Nov 2011 at 8:40

GoogleCodeExporter commented 9 years ago
A little update:
Where seteada is a boolean that helps me know if i have changed the image.
    public void setImg(Bitmap img) {
        seteada=true;
        this.img = img;
        this.lastImage=img;
        Log.e("LALALAL", "Bitmap recibido;¡: " +img);
    }

On the getDraggableObjectAtPoint

    public Object getDraggableObjectAtPoint(PointInfo pt) {

        if (seteada){// 
            Log.e("getDraggableObjectAtPoint", "Bitmap new: " +lastImage);
            return lastImage;
        }else{
            Log.e("getDraggableObjectAtPoint", "Bitmap old: " +img);
            return img;
        }
    }

Always choose the Bitmap Old.

Just curious why is that.

Original comment by care.n...@gmail.com on 16 Nov 2011 at 8:49

GoogleCodeExporter commented 9 years ago
Well if you're always seeing "Bitmap old: XXXXXXXX", then that means that 
*your* code setImg() is not being run. If you ran it, then seteada would be set 
to true, and you would see "Bitmap new: XXXXXXXX". The only thing that has 
anything to do with my code is your implementation of 
getDraggableObjectAtPoint() in my interface, and that is clearly being called, 
because you're seeing the "Bitmap old: XXXXXXXX" message.

So, in summary, this is not a bug in my code. You're not correctly calling your 
own code for some reason. Please double-check the places you're supposed to be 
calling your own code setImg().

Original comment by luke.hutch on 16 Nov 2011 at 9:11

GoogleCodeExporter commented 9 years ago
You're wrong, why do you think that i'm putting the code of setImg, it runs, 
and shows in fact before the getDraggableObjectAtPoint.

It looks in the Logcat like

LALALALA: Bitmap recibido XXXXX1
getDraggableObjectAtPoint Bitmap old:XXXXX0

In fact i'm mentioning it because it is very odd.
Please don't mark this as invalid, cause i assure you that is not.

Original comment by care.n...@gmail.com on 16 Nov 2011 at 9:21

GoogleCodeExporter commented 9 years ago
OK, well you must have two different instances of objects that implement 
MultiTouchObjectCanvas then.  I suggest adding log lines to see if this is the 
case:

Where seteada is a boolean that helps me know if i have changed the image.
    public void setImg(Bitmap img) {
        seteada=true;
        this.img = img;
        this.lastImage=img;
        Log.e("LALALAL", "Bitmap recibido;¡: " +img);
        Log.e("LALALAL", "This object canvas: " + this);
    }

and

    public Object getDraggableObjectAtPoint(PointInfo pt) {
        Log.e("getDraggableObjectAtPoint", "This object canvas: " + this);

        if (seteada){// 
            Log.e("getDraggableObjectAtPoint", "Bitmap new: " +lastImage);
            return lastImage;
        }else{
            Log.e("getDraggableObjectAtPoint", "Bitmap old: " +img);
            return img;
        }
    }

If you see two different references to object canvases, then somehow you have 
instantiated the object twice and you're setting the field on an object canvas 
other than the one that you're passing to my multitouch controller.

Remember that the field img is your own field that you added to the class that 
implements this interface, so there's actually no way that my code could or 
would even touch that field.

Original comment by luke.hutch on 16 Nov 2011 at 9:29

GoogleCodeExporter commented 9 years ago
Are you sure that is that the problem?

package com.delete.me;

import android.app.Activity;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class DeleteMeActivity extends Activity {
    private MTV0 mTv;
    private Button click;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mTv= new MTV0(this);

        click = (Button) findViewById(R.id.boton);
        click.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                mTv.setImg(BitmapFactory.decodeResource(getResources(), R.drawable.icon3));
            }
        });
    }
}

This is my entire test code, of the activity, i don't really see how can i be 
doing a double instance.

Anyway, the other code that i'm using is this one:

);
        mLinePaintTouchPointCircle.setColor(Color.YELLOW);
        mLinePaintTouchPointCircle.setStrokeWidth(5);
        mLinePaintTouchPointCircle.setStyle(Style.STROKE);
        mLinePaintTouchPointCircle.setAntiAlias(true);
        setBackgroundColor(Color.BLACK);
    }

    public MTV0(Context context, AttributeSet attrs, int defStyle) {
        super(context,attrs,defStyle);
        Log.e(TAG,"Metodo 1");
        img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            mLinePaintTouchPointCircle.setColor(Color.YELLOW);
            mLinePaintTouchPointCircle.setStrokeWidth(5);
            mLinePaintTouchPointCircle.setStyle(Style.STROKE);
            mLinePaintTouchPointCircle.setAntiAlias(true);
            setBackgroundColor(Color.BLACK);
        }

    public MTV0(Context context, AttributeSet attrs) {
        super(context,attrs);
        Log.e(TAG,"Metodo 2");
        img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            mLinePaintTouchPointCircle.setColor(Color.YELLOW);
            mLinePaintTouchPointCircle.setStrokeWidth(5);
            mLinePaintTouchPointCircle.setStyle(Style.STROKE);
            mLinePaintTouchPointCircle.setAntiAlias(true);
            setBackgroundColor(Color.BLACK);
        }

    // ---------------------------------------------------------------------------------------------------

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
        canvas.drawPaint(paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC));
        Log.e("onDraw", "Bitmap pintado: " +img);

        canvas.save();
        canvas.scale(scale, scale, x, y);
        canvas.rotate(angle * 180.0f / (float) Math.PI, x, y);
        canvas.drawBitmap(img, x, y, null);
        canvas.restore();
        //drawMultitouchDebugMarks(canvas);
    }

    // ---------------------------------------------------------------------------------------------------

    /*private void drawMultitouchDebugMarks(Canvas canvas) {
        if (currTouchPoints.isDown()) {
            float[] xs = currTouchPoints.getXs();
            float[] ys = currTouchPoints.getYs();
            float[] pressures = currTouchPoints.getPressures();
            int numPoints = currTouchPoints.getNumTouchPoints();
            for (int i = 0; i < numPoints; i++)
                canvas.drawCircle(xs[i], ys[i], 50 + pressures[i] * 80, mLinePaintTouchPointCircle);
            if (numPoints == 2)
                canvas.drawLine(xs[0], ys[0], xs[1], ys[1], mLinePaintTouchPointCircle);
        }
    }*/

    // ---------------------------------------------------------------------------------------------------

    /** Pass touch events to the MT controller */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("onTouchEvent", "TEST: "+img);
        return multiTouchController.onTouchEvent(event);
    }

    /** Get the image that is under the single-touch point, or return null (canceling the drag op) if none */
    //public Object getDraggableObjectAtPoint(PointInfo pt) {
    public Object getDraggableObjectAtPoint(PointInfo pt) {
        Log.e("getDraggableObjectAtPoint", "This Object Canvas: " +this);

        if (seteada){// WTF?
            Log.e("getDraggableObjectAtPoint", "Bitmap nuevo: " +lastImage);
            return lastImage;
        }else{
            Log.e("getDraggableObjectAtPoint", "Bitmap viejo: " +img);
            return img;
        }
    }

    /**
     * Select an object for dragging. Called whenever an object is found to be under the point (non-null is returned by getDraggableObjectAtPoint())
     * and a drag operation is starting. Called with null when drag op ends.
     */
    public void selectObject(Object obj, PointInfo touchPoint) {
        Log.e("selectObject", "TEST: "+img);
        currTouchPoints.set(touchPoint);
        invalidate();
    }

    /** Get the current position and scale of the selected image. Called whenever a drag starts or is reset. */
    public void getPositionAndScale(Object obj, PositionAndScale objPosAndScaleOut) {
        Log.e("getPositionAndScale", "TEST: "+img);
        objPosAndScaleOut.set(x, y, true, scale, false, scale, scale, true, angle);
    }

    /** Set the position and scale of the dragged/stretched image. */
    public boolean setPositionAndScale(Object obj, PositionAndScale newPosAndScale, PointInfo touchPoint) {
        Log.e("setPositionAndScale", "TEST: "+img);
        currTouchPoints.set(touchPoint);
        x = newPosAndScale.getXOff();
        y = newPosAndScale.getYOff();
        scale = newPosAndScale.getScale();
        angle = newPosAndScale.getAngle();
        invalidate();
        return true;
    }
}

I'm not pretty sure where the double instance is to be honest, i'm still 
looking where it is. Have you tried to change the image? I mean you're the kind 
of person that is very smart, other way i will be using the lib i made, but 
maybe you miss this one, i'm not here with the intention of trolling of asking 
you to resolve my problems, but i DONT REALLY SEE where's the double instance 
(the Upper case is not for offending, i'm just getting desesperado :p)

Original comment by care.n...@gmail.com on 16 Nov 2011 at 10:16

GoogleCodeExporter commented 9 years ago
sorry for double post the MTV0 class is this one, bad copy paste:

package com.delete.me;

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.Paint.Style;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.delete.me.MultiTouchController.MultiTouchObjectCanvas;
import com.delete.me.MultiTouchController.PointInfo;
import com.delete.me.MultiTouchController.PositionAndScale;

public class MTV0 extends View implements MultiTouchObjectCanvas {

    private static final String TAG = ">>> MTV0";
    private MultiTouchController multiTouchController = new MultiTouchController(this);

    private PointInfo currTouchPoints = new PointInfo();

    private Paint mLinePaintTouchPointCircle = new Paint();
    private Bitmap img;
    private float x = 100;
    private float y = 100;;
    private float scale = 1;
    private float angle = 0;
    private boolean seteada=false;
    private Bitmap lastImage;   

    public Bitmap getImg() {
        return img;
    }

    public void setImg(Bitmap img) {
        seteada=true;
        this.img = img;
        this.lastImage=img;
        Log.e("LALALAL", "Bitmap recibido;¡: " +img);
        Log.e("LALALAL", "This Object Canvas: " +this);
    }

    // ---------------------------------------------------------------------------------------------------

    public MTV0(Context context) {
    super(context);
    Log.e(TAG,"Metodo 0");
    img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        mLinePaintTouchPointCircle.setColor(Color.YELLOW);
        mLinePaintTouchPointCircle.setStrokeWidth(5);
        mLinePaintTouchPointCircle.setStyle(Style.STROKE);
        mLinePaintTouchPointCircle.setAntiAlias(true);
        setBackgroundColor(Color.BLACK);
    }

    public MTV0(Context context, AttributeSet attrs, int defStyle) {
        super(context,attrs,defStyle);
        Log.e(TAG,"Metodo 1");
        img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            mLinePaintTouchPointCircle.setColor(Color.YELLOW);
            mLinePaintTouchPointCircle.setStrokeWidth(5);
            mLinePaintTouchPointCircle.setStyle(Style.STROKE);
            mLinePaintTouchPointCircle.setAntiAlias(true);
            setBackgroundColor(Color.BLACK);
        }

    public MTV0(Context context, AttributeSet attrs) {
        super(context,attrs);
        Log.e(TAG,"Metodo 2");
        img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            mLinePaintTouchPointCircle.setColor(Color.YELLOW);
            mLinePaintTouchPointCircle.setStrokeWidth(5);
            mLinePaintTouchPointCircle.setStyle(Style.STROKE);
            mLinePaintTouchPointCircle.setAntiAlias(true);
            setBackgroundColor(Color.BLACK);
        }

    // ---------------------------------------------------------------------------------------------------

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
        canvas.drawPaint(paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC));
        Log.e("onDraw", "Bitmap pintado: " +img);

        canvas.save();
        canvas.scale(scale, scale, x, y);
        canvas.rotate(angle * 180.0f / (float) Math.PI, x, y);
        canvas.drawBitmap(img, x, y, null);
        canvas.restore();
        //drawMultitouchDebugMarks(canvas);
    }

    // ---------------------------------------------------------------------------------------------------

    /*private void drawMultitouchDebugMarks(Canvas canvas) {
        if (currTouchPoints.isDown()) {
            float[] xs = currTouchPoints.getXs();
            float[] ys = currTouchPoints.getYs();
            float[] pressures = currTouchPoints.getPressures();
            int numPoints = currTouchPoints.getNumTouchPoints();
            for (int i = 0; i < numPoints; i++)
                canvas.drawCircle(xs[i], ys[i], 50 + pressures[i] * 80, mLinePaintTouchPointCircle);
            if (numPoints == 2)
                canvas.drawLine(xs[0], ys[0], xs[1], ys[1], mLinePaintTouchPointCircle);
        }
    }*/

    // ---------------------------------------------------------------------------------------------------

    /** Pass touch events to the MT controller */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("onTouchEvent", "TEST: "+img);
        return multiTouchController.onTouchEvent(event);
    }

    /** Get the image that is under the single-touch point, or return null (canceling the drag op) if none */
    //public Object getDraggableObjectAtPoint(PointInfo pt) {
    public Object getDraggableObjectAtPoint(PointInfo pt) {
        Log.e("getDraggableObjectAtPoint", "This Object Canvas: " +this);

        if (seteada){// WTF?
            Log.e("getDraggableObjectAtPoint", "Bitmap nuevo: " +lastImage);
            return lastImage;
        }else{
            Log.e("getDraggableObjectAtPoint", "Bitmap viejo: " +img);
            return img;
        }
    }

    /**
     * Select an object for dragging. Called whenever an object is found to be under the point (non-null is returned by getDraggableObjectAtPoint())
     * and a drag operation is starting. Called with null when drag op ends.
     */
    public void selectObject(Object obj, PointInfo touchPoint) {
        Log.e("selectObject", "TEST: "+img);
        currTouchPoints.set(touchPoint);
        invalidate();
    }

    /** Get the current position and scale of the selected image. Called whenever a drag starts or is reset. */
    public void getPositionAndScale(Object obj, PositionAndScale objPosAndScaleOut) {
        Log.e("getPositionAndScale", "TEST: "+img);
        objPosAndScaleOut.set(x, y, true, scale, false, scale, scale, true, angle);
    }

    /** Set the position and scale of the dragged/stretched image. */
    public boolean setPositionAndScale(Object obj, PositionAndScale newPosAndScale, PointInfo touchPoint) {
        Log.e("setPositionAndScale", "TEST: "+img);
        currTouchPoints.set(touchPoint);
        x = newPosAndScale.getXOff();
        y = newPosAndScale.getYOff();
        scale = newPosAndScale.getScale();
        angle = newPosAndScale.getAngle();
        invalidate();
        return true;
    }
}

Original comment by care.n...@gmail.com on 16 Nov 2011 at 10:20

GoogleCodeExporter commented 9 years ago
I've found it, and my friend is well dunno if it is android or your code... but 
theres a bug
The problem is that when i instanciate the MTV0 mTv it creates the constructor 
with the TAG METHOD 2, that method AFAIK is required by android when you create 
custom views, first instance, and when i initialize it, automatically creates a 
second instance. This is where the bug is living at, and it doesn't let the 
class to update the image...

So, what do you think?

Original comment by care.n...@gmail.com on 16 Nov 2011 at 10:41

GoogleCodeExporter commented 9 years ago
Hmm, maybe make the line

private MultiTouchController multiTouchController = new 
MultiTouchController(this);

Say just

private MultiTouchController multiTouchController;

and then at the end of all three of the constructors, initialize the controller 
with 

multiTouchController = new MultiTouchController(this);

?

I don't know why you would need to do that, possibly Views are instantiated in 
a weird way.

I also don't know how or when the other instance of MTV0 is being created.

I suggest setting a breakpoint at the constructor 
MultiTouchController(MultiTouchObjectCanvas), and observing where this 
constructor is called from. You should be able to quickly find the culprit.

Original comment by luke.hutch on 16 Nov 2011 at 10:53

GoogleCodeExporter commented 9 years ago
What i found is that the android create an instance automatically, so you mut 
avoid using the instance inside of your activity, and only making reference to 
the view that android is using

public class DeleteMeActivity extends Activity {
    //private MTV0 mTv;
    private Button click;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //mTv= new MTV0(this);

        click = (Button) findViewById(R.id.boton);
        click.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                ((MTV0) findViewById(R.id.mtv)).setImg(BitmapFactory.decodeResource(getResources(), R.drawable.icon3));
                //mTv.setImg(BitmapFactory.decodeResource(getResources(), R.drawable.icon3));
            }
        });
    }
}

Like this. It will work.

Anyway i tested your idea to see, but it will create different  instances not 
caring about where you make the new MultiTouchController.

Glad to check the code with you, anyway it this helps somehow to improve your 
code, let me know, interesnting what one can find of android every day :p

Original comment by care.n...@gmail.com on 16 Nov 2011 at 11:04

GoogleCodeExporter commented 9 years ago
But a last question, how do i refresh the image?, cause i need to move it to 
make it work!

Original comment by care.n...@gmail.com on 16 Nov 2011 at 11:05

GoogleCodeExporter commented 9 years ago
The class you defined is a View, so if you change something in it that is 
supposed to be redrawn, you need to call invalidate() just like with any sort 
of animation.

Original comment by luke.hutch on 16 Nov 2011 at 11:19

GoogleCodeExporter commented 9 years ago
Lol my bad, i was looking at other code problem, yes you're right, in the one i 
send is only to put an invalidate();
Well, that's all afaik.
Have a nice day

Original comment by care.n...@gmail.com on 17 Nov 2011 at 1:58