1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.android.test.transform; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.graphics.Canvas; 22 import android.graphics.Matrix; 23 import android.graphics.drawable.Drawable; 24 import android.os.Bundle; 25 import android.util.DisplayMetrics; 26 import android.util.Log; 27 import android.view.MotionEvent; 28 import android.view.ScaleGestureDetector; 29 import android.view.View; 30 import android.widget.LinearLayout; 31 32 public class TransformTestActivity extends Activity { TransformTestActivity()33 public TransformTestActivity() { 34 super(); 35 init(false); 36 } 37 TransformTestActivity(boolean noCompat)38 public TransformTestActivity(boolean noCompat) { 39 super(); 40 init(noCompat); 41 } 42 init(boolean noCompat)43 public void init(boolean noCompat) { 44 45 } 46 47 @Override onCreate(Bundle savedInstanceState)48 protected void onCreate(Bundle savedInstanceState) { 49 super.onCreate(savedInstanceState); 50 51 this.setTitle(R.string.act_title); 52 LinearLayout root = new LinearLayout(this); 53 root.setOrientation(LinearLayout.VERTICAL); 54 55 TransformView view = new TransformView(getApplicationContext()); 56 Drawable drawable = getResources().getDrawable(R.drawable.logo); 57 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicWidth()); 58 view.setDrawable(drawable); 59 60 root.addView(view); 61 setContentView(root); 62 } 63 64 private class TransformView extends View { 65 private Drawable mDrawable; 66 private float mPosX; 67 private float mPosY; 68 private float mScale = 1.f; 69 private Matrix mMatrix; 70 private ScaleGestureDetector mDetector; 71 72 private float mLastX; 73 private float mLastY; 74 75 private class Listener implements ScaleGestureDetector.OnScaleGestureListener { 76 onScale(ScaleGestureDetector detector)77 public boolean onScale(ScaleGestureDetector detector) { 78 float scale = detector.getScaleFactor(); 79 80 Log.d("ttest", "Scale: " + scale); 81 82 // Limit the scale so our object doesn't get too big or disappear 83 if (mScale * scale > 0.1f) { 84 if (mScale * scale < 10.f) { 85 mScale *= scale; 86 } else { 87 mScale = 10.f; 88 } 89 } else { 90 mScale = 0.1f; 91 } 92 93 Log.d("ttest", "mScale: " + mScale + " mPos: (" + mPosX + ", " + mPosY + ")"); 94 95 float sizeX = mDrawable.getIntrinsicWidth()/2; 96 float sizeY = mDrawable.getIntrinsicHeight()/2; 97 float centerX = detector.getFocusX(); 98 float centerY = detector.getFocusY(); 99 float diffX = centerX - mPosX; 100 float diffY = centerY - mPosY; 101 diffX = diffX*scale - diffX; 102 diffY = diffY*scale - diffY; 103 mPosX -= diffX; 104 mPosY -= diffY; 105 mMatrix.reset(); 106 mMatrix.postTranslate(-sizeX, -sizeY); 107 mMatrix.postScale(mScale, mScale); 108 mMatrix.postTranslate(mPosX, mPosY); 109 110 invalidate(); 111 112 return true; 113 } 114 onScaleBegin(ScaleGestureDetector detector)115 public boolean onScaleBegin(ScaleGestureDetector detector) { 116 return true; 117 } 118 onScaleEnd(ScaleGestureDetector detector)119 public void onScaleEnd(ScaleGestureDetector detector) { 120 mLastX = detector.getFocusX(); 121 mLastY = detector.getFocusY(); 122 } 123 } 124 TransformView(Context context)125 public TransformView(Context context) { 126 super(context); 127 mMatrix = new Matrix(); 128 mDetector = new ScaleGestureDetector(context, new Listener()); 129 DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 130 mPosX = metrics.widthPixels/2; 131 mPosY = metrics.heightPixels/2; 132 } 133 setDrawable(Drawable d)134 public void setDrawable(Drawable d) { 135 mDrawable = d; 136 137 float sizeX = mDrawable.getIntrinsicWidth()/2; 138 float sizeY = mDrawable.getIntrinsicHeight()/2; 139 mMatrix.reset(); 140 mMatrix.postTranslate(-sizeX, -sizeY); 141 mMatrix.postScale(mScale, mScale); 142 mMatrix.postTranslate(mPosX, mPosY); 143 } 144 145 @Override onTouchEvent(MotionEvent event)146 public boolean onTouchEvent(MotionEvent event) { 147 mDetector.onTouchEvent(event); 148 149 // Handling single finger pan 150 if (!mDetector.isInProgress()) { 151 switch (event.getAction()) { 152 case MotionEvent.ACTION_DOWN: 153 mLastX = event.getX(); 154 mLastY = event.getY(); 155 break; 156 157 case MotionEvent.ACTION_MOVE: 158 final float x = event.getX(); 159 final float y = event.getY(); 160 mPosX += x - mLastX; 161 mPosY += y - mLastY; 162 mLastX = x; 163 mLastY = y; 164 165 float sizeX = mDrawable.getIntrinsicWidth()/2; 166 float sizeY = mDrawable.getIntrinsicHeight()/2; 167 168 mMatrix.reset(); 169 mMatrix.postTranslate(-sizeX, -sizeY); 170 mMatrix.postScale(mScale, mScale); 171 mMatrix.postTranslate(mPosX, mPosY); 172 invalidate(); 173 break; 174 } 175 } 176 177 return true; 178 } 179 180 @Override onDraw(Canvas canvas)181 public void onDraw(Canvas canvas) { 182 int saveCount = canvas.getSaveCount(); 183 canvas.save(); 184 canvas.concat(mMatrix); 185 mDrawable.draw(canvas); 186 canvas.restoreToCount(saveCount); 187 } 188 } 189 } 190