1 /* 2 * Copyright (C) 2012 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.android.gallery3d.filtershow.imageshow; 18 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.graphics.Canvas; 22 import android.graphics.RectF; 23 import android.util.AttributeSet; 24 import android.view.MotionEvent; 25 import android.view.ScaleGestureDetector; 26 import android.view.ScaleGestureDetector.OnScaleGestureListener; 27 28 import com.android.gallery3d.filtershow.editors.BasicEditor; 29 import com.android.gallery3d.filtershow.editors.EditorTinyPlanet; 30 import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation; 31 32 public class ImageTinyPlanet extends ImageShow { 33 private static final String LOGTAG = "ImageTinyPlanet"; 34 35 private float mTouchCenterX = 0; 36 private float mTouchCenterY = 0; 37 private float mCurrentX = 0; 38 private float mCurrentY = 0; 39 private float mCenterX = 0; 40 private float mCenterY = 0; 41 private float mStartAngle = 0; 42 private FilterTinyPlanetRepresentation mTinyPlanetRep; 43 private EditorTinyPlanet mEditorTinyPlanet; 44 private ScaleGestureDetector mScaleGestureDetector = null; 45 boolean mInScale = false; 46 RectF mDestRect = new RectF(); 47 48 OnScaleGestureListener mScaleGestureListener = new OnScaleGestureListener() { 49 private float mScale = 100; 50 @Override 51 public void onScaleEnd(ScaleGestureDetector detector) { 52 mInScale = false; 53 } 54 55 @Override 56 public boolean onScaleBegin(ScaleGestureDetector detector) { 57 mInScale = true; 58 mScale = mTinyPlanetRep.getValue(); 59 return true; 60 } 61 62 @Override 63 public boolean onScale(ScaleGestureDetector detector) { 64 int value = mTinyPlanetRep.getValue(); 65 mScale *= detector.getScaleFactor(); 66 value = (int) (mScale); 67 value = Math.min(mTinyPlanetRep.getMaximum(), value); 68 value = Math.max(mTinyPlanetRep.getMinimum(), value); 69 mTinyPlanetRep.setValue(value); 70 invalidate(); 71 mEditorTinyPlanet.commitLocalRepresentation(); 72 mEditorTinyPlanet.updateUI(); 73 return true; 74 } 75 }; 76 77 public ImageTinyPlanet(Context context) { 78 super(context); 79 mScaleGestureDetector = new ScaleGestureDetector(context, mScaleGestureListener); 80 } 81 82 public ImageTinyPlanet(Context context, AttributeSet attrs) { 83 super(context, attrs); 84 mScaleGestureDetector = new ScaleGestureDetector(context,mScaleGestureListener ); 85 } 86 87 protected static float angleFor(float dx, float dy) { 88 return (float) (Math.atan2(dx, dy) * 180 / Math.PI); 89 } 90 91 protected float getCurrentTouchAngle() { 92 if (mCurrentX == mTouchCenterX && mCurrentY == mTouchCenterY) { 93 return 0; 94 } 95 float dX1 = mTouchCenterX - mCenterX; 96 float dY1 = mTouchCenterY - mCenterY; 97 float dX2 = mCurrentX - mCenterX; 98 float dY2 = mCurrentY - mCenterY; 99 100 float angleA = angleFor(dX1, dY1); 101 float angleB = angleFor(dX2, dY2); 102 return (float) (((angleB - angleA) % 360) * Math.PI / 180); 103 } 104 105 @Override 106 public boolean onTouchEvent(MotionEvent event) { 107 float x = event.getX(); 108 float y = event.getY(); 109 mCurrentX = x; 110 mCurrentY = y; 111 mCenterX = getWidth() / 2; 112 mCenterY = getHeight() / 2; 113 mScaleGestureDetector.onTouchEvent(event); 114 if (mInScale) { 115 return true; 116 } 117 switch (event.getActionMasked()) { 118 case (MotionEvent.ACTION_DOWN): 119 mTouchCenterX = x; 120 mTouchCenterY = y; 121 mStartAngle = mTinyPlanetRep.getAngle(); 122 break; 123 124 case (MotionEvent.ACTION_MOVE): 125 mTinyPlanetRep.setAngle(mStartAngle + getCurrentTouchAngle()); 126 break; 127 } 128 invalidate(); 129 mEditorTinyPlanet.commitLocalRepresentation(); 130 return true; 131 } 132 133 public void setRepresentation(FilterTinyPlanetRepresentation tinyPlanetRep) { 134 mTinyPlanetRep = tinyPlanetRep; 135 } 136 137 public void setEditor(BasicEditor editorTinyPlanet) { 138 mEditorTinyPlanet = (EditorTinyPlanet) editorTinyPlanet; 139 } 140 141 @Override 142 public void onDraw(Canvas canvas) { 143 Bitmap bitmap = MasterImage.getImage().getHighresImage(); 144 if (bitmap == null) { 145 bitmap = MasterImage.getImage().getFilteredImage(); 146 } 147 148 if (bitmap != null) { 149 display(canvas, bitmap); 150 } 151 } 152 153 private void display(Canvas canvas, Bitmap bitmap) { 154 float sw = canvas.getWidth(); 155 float sh = canvas.getHeight(); 156 float iw = bitmap.getWidth(); 157 float ih = bitmap.getHeight(); 158 float nsw = sw; 159 float nsh = sh; 160 161 if (sw * ih > sh * iw) { 162 nsw = sh * iw / ih; 163 } else { 164 nsh = sw * ih / iw; 165 } 166 167 mDestRect.left = (sw - nsw) / 2; 168 mDestRect.top = (sh - nsh) / 2; 169 mDestRect.right = sw - mDestRect.left; 170 mDestRect.bottom = sh - mDestRect.top; 171 172 canvas.drawBitmap(bitmap, null, mDestRect, mPaint); 173 } 174 } 175