package adefault.com.pointt; import android.content.Context; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.PointF; import android.media.Image; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import java.util.ArrayList; import java.util.Random; /** * Created by PedroOliveira on 19/10/16. */ class MyView extends View { private static final String TAG = "Point"; public static Matrix matrix = new Matrix(); public static Matrix savedMatrix = new Matrix(); // We can be in one of these 3 states static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; private static final float MIN_ZOOM = 1f; private static final float MAX_ZOOM = 4f; int mode = NONE; float scale = 1L; RelativeLayout lt = null; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; int width, height; ImageView view = null; Context mContext; public MyView(Context context, ImageView img, RelativeLayout lt) { super(context); this.view = img; this.lt = lt; mContext = context; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { LayoutInflater inflater = LayoutInflater.from(mContext); width = view.getWidth(); height = view.getHeight(); float nx = 0L; float ny = 0L; switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: // CLICAR APENAS >> criar um ponto (objeto) if (!MainActivity.getMode()) { savedMatrix.set(matrix); start.set(event.getX(), event.getY()); Log.d(TAG, "mode=DRAG"); mode = DRAG; } else { savedMatrix.set(matrix); mode = NONE; Point po = new Point(); po.x = (int) event.getX() - 15; //ofset para o centro da imagem coincidir com o local do toque po.y = (int) event.getY() - 15; //ofset para o centro da imagem coincidir com o local do toque float[] val = new float[9]; matrix.getValues(val); po.transX = val[Matrix.MTRANS_X]; po.transY = val[Matrix.MTRANS_Y]; po.scaleX = val[Matrix.MSCALE_X]; po.scaleY = val[Matrix.MSCALE_Y]; Log.e(TAG, "Tx_point_creation: " + po.transX + " Ty_point_creation: " + po.transY); MainActivity.addE(po); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30, 30); params.leftMargin = po.x; params.topMargin = po.y; View child = inflater.inflate(R.layout.i, null); child.setLayoutParams(params); child.setOnTouchListener(new ChoiceTouchListener(po)); // atribuir id ao ponto. idealmente, funcionará com o nome do prórpio ponto da variavel Random r = new Random(); int id = r.nextInt(10000); child.setId(id); po.id = id; po.child = child; add(child); } break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); if (oldDist > 10f) { midPoint(mid, event); mode = ZOOM; Log.d(TAG, "mode=ZOOM"); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; break; case MotionEvent.ACTION_MOVE: if (mode == DRAG && !MainActivity.getMode()) { matrix.set(savedMatrix); nx = (float) ((event.getX() - start.x) * 0.15); ny = (float) ((event.getY() - start.y) * 0.15); matrix.postTranslate(nx, ny); break; } else if (mode == ZOOM && !MainActivity.getMode()) { float newDist = spacing(event); if (newDist > 5f) { //savedMatrix.set(matrix); if (newDist / oldDist > 1) { scale = (float) 1.03; } else { scale = (float) ((float) 1 / 1.03); } Log.e(TAG, "scale: " + scale); float[] valuesTransformation = new float[9]; matrix.getValues(valuesTransformation); matrix.postScale(scale, scale, mid.x, mid.y); } } break; } matrix = limitZoom(matrix); matrix = limitDrag(matrix); savedMatrix.set(matrix); view.setImageMatrix(savedMatrix); ArrayList pointlist = (ArrayList) MainActivity.getPointList(); if (!pointlist.isEmpty() && !MainActivity.getMode()) { for (Point p : pointlist) { float[] valuesTransformation = new float[9]; matrix.getValues(valuesTransformation); float transformTX = valuesTransformation[Matrix.MTRANS_X]; float transformTY = valuesTransformation[Matrix.MTRANS_Y]; float transformSX = valuesTransformation[Matrix.MSCALE_X]; float transformSY = valuesTransformation[Matrix.MSCALE_Y]; float tx = -p.transX + transformTX; float ty = -p.transY + transformTY; Log.e(TAG, "Original TX: " + p.transX + " Original TY: " + p.transY); Log.e(TAG, "Transformation TX: " + transformTX + " Transformation TY: " + transformTY); Log.e(TAG, "TX: " + tx + " TY: " + ty); p.child.setTranslationX(tx); p.child.setTranslationY(ty); } } //invalidate(); return true; } /** * Determine the space between the first two fingers */ private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return (float) (Math.sqrt(x * x + y * y)); } /** * Calculate the mid point of the first two fingers */ private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } private Matrix limitZoom(Matrix m) { float[] values = new float[9]; m.getValues(values); float scaleX = values[Matrix.MSCALE_X]; float scaleY = values[Matrix.MSCALE_Y]; if (scaleX > MAX_ZOOM) { scaleX = MAX_ZOOM; } else if (scaleX < MIN_ZOOM) { scaleX = MIN_ZOOM; } if (scaleY > MAX_ZOOM) { scaleY = MAX_ZOOM; } else if (scaleY < MIN_ZOOM) { scaleY = MIN_ZOOM; } values[Matrix.MSCALE_X] = scaleX; values[Matrix.MSCALE_Y] = scaleY; m.setValues(values); return m; } private Matrix limitDrag(Matrix m) { float[] values = new float[9]; m.getValues(values); float transX = values[Matrix.MTRANS_X]; float transY = values[Matrix.MTRANS_Y]; float scaleX = values[Matrix.MSCALE_X]; float scaleY = values[Matrix.MSCALE_Y]; //--- limit moving to left --- float minX = (-width + 0) * (scaleX - 1); float minY = (-height + 0) * (scaleY - 1); //--- limit moving to right --- float maxX = minX + width * (scaleX - 1); float maxY = minY + height * (scaleY - 1); if (transX > maxX) { transX = maxX; } if (transX < minX) { transX = minX; } if (transY > maxY) { transY = maxY; } if (transY < minY) { transY = minY; } values[Matrix.MTRANS_X] = transX; values[Matrix.MTRANS_Y] = transY; m.setValues(values); return m; } private void add(View child) { lt.addView(child); } }