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
17package com.google.android.test.transform;
18
19import android.app.Activity;
20import android.content.Context;
21import android.graphics.Canvas;
22import android.graphics.Matrix;
23import android.graphics.drawable.Drawable;
24import android.os.Bundle;
25import android.util.DisplayMetrics;
26import android.util.Log;
27import android.view.MotionEvent;
28import android.view.ScaleGestureDetector;
29import android.view.View;
30import android.widget.LinearLayout;
31
32public class TransformTestActivity extends Activity {
33    public TransformTestActivity() {
34        super();
35        init(false);
36    }
37
38    public TransformTestActivity(boolean noCompat) {
39        super();
40        init(noCompat);
41    }
42
43    public void init(boolean noCompat) {
44
45    }
46
47    @Override
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
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
115            public boolean onScaleBegin(ScaleGestureDetector detector) {
116                return true;
117            }
118
119            public void onScaleEnd(ScaleGestureDetector detector) {
120                mLastX = detector.getFocusX();
121                mLastY = detector.getFocusY();
122            }
123        }
124
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
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
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
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