package map; import android.graphics.Matrix; import android.graphics.PointF; import android.view.MotionEvent; /** * perform matrix transformations */ class TransformManager { private static final int POS_X = 0; private static final int POS_Y = 1; private static final int NONE = 0; private static final int ZOOM = 1; private static final int DRAG = 2; private int mode = NONE; private boolean zoom; private boolean drag; private final Matrix savedMatrix = new Matrix(); private final Matrix savedMatrix2 = new Matrix(); private final PointF mid = new PointF(); private final PointF mid2 = new PointF(); private float oldDist = 1f; private float lastPosX = 0; private float lastPosY = 0; //float lastScale = 1; public final Matrix matrix = new Matrix(); private int screenMode = 2; private final float[] value = new float[9]; private final int[] pos = new int[2]; private final float[] savedValue = new float[9]; public float currentScale; public float mapWidth; public float mapHeight; public float screenWidth; public float screenHeight; public void actionDown(float evX, float evY) { matrix.getValues(value); savedMatrix.set(matrix); lastPosX = evX; lastPosY = evY; } public void actionPointerDown(MotionEvent event) { oldDist = spacing(event); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); } } public void actionUp(float evX, float evY) { mode = NONE; matrix.getValues(value); pos[POS_X] = (int) ((evX - value[2]) / value[0]); pos[POS_Y] = (int) ((evY - value[5]) / value[0]); } public int[] currentPosition(float evX, float evY) { matrix.getValues(value); pos[POS_X] = (int) ((evX - value[2]) / value[0]); pos[POS_Y] = (int) ((evY - value[5]) / value[0]); return pos; } public void actionMove(int nbPointers, MotionEvent event) { if (nbPointers == 2) { matrix.set(savedMatrix); float newDist = spacing(event); float scale = newDist / oldDist; midPoint(mid2, event); if (mode == NONE && (scale > 1.20 || scale < 0.80) && zoom) mode = ZOOM; if (mode == NONE && (mid.x - mid2.x > 20 || mid.y - mid2.y > 20 || mid.x - mid2.x < -20 || mid.y - mid2.y < -20) && (scale < 1.20 && scale > 0.80) && drag) mode = DRAG; if (mode != DRAG && zoom) { matrix.postScale(scale, scale, mid.x, mid.y); //lastScale = scale; } //else matrix.postScale(lastScale, lastScale, mid.x, mid.y); if (mode != ZOOM && drag) { matrix.postTranslate((event.getX(0) + event.getX(1)) / 2 - mid.x, (event.getY(0) + event.getY(1)) / 2 - mid.y); lastPosX = event.getX() - mid.x; lastPosY = event.getY() - mid.y; } matrixTuning(); } } // rearrange the matrix private void matrixTuning() { matrix.getValues(value); savedMatrix2.getValues(savedValue); if (value[0] * currentScale > 1.5 || value[4] * currentScale > 1.5) { value[0] = 1.5f / currentScale; value[4] = 1.5f / currentScale; value[2] = savedValue[2]; value[5] = savedValue[5]; } if (value[0] * currentScale < 0.5 || value[4] * currentScale < 0.5) { value[0] = 0.5f / currentScale; value[4] = 0.5f / currentScale; value[2] = savedValue[2]; value[5] = savedValue[5]; } matrix.setValues(value); savedMatrix2.set(matrix); } // space between 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); } // mid point 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); } public void setScreenConfigScaling() { matrix.getValues(value); value[2] = 0; value[5] = 0; matrix.setValues(value); } public void setLandscapeMode() { screenMode = 2; matrix.getValues(value); value[0] = 1; value[4] = 1; value[2] = 0; value[5] = 0; matrix.setValues(value); } public void setZoom(boolean zoom) { this.zoom = zoom; } public void setDrag(boolean drag) { this.drag = drag; } }