12c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard/* 22c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * Copyright (C) 2012 The Android Open Source Project 32c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * 42c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * Licensed under the Apache License, Version 2.0 (the "License"); 52c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * you may not use this file except in compliance with the License. 62c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * You may obtain a copy of the License at 72c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * 82c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * http://www.apache.org/licenses/LICENSE-2.0 92c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * 102c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * Unless required by applicable law or agreed to in writing, software 112c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * distributed under the License is distributed on an "AS IS" BASIS, 122c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * See the License for the specific language governing permissions and 142c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * limitations under the License. 152c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard */ 162c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 172c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroardpackage com.android.gallery3d.filtershow.imageshow; 182c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 192c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroardimport android.content.Context; 2091d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport android.graphics.Bitmap; 2144a499a64158cd5a12f8e44655f82b68c33bf3b2John Hofordimport android.graphics.Canvas; 2291d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport android.graphics.RectF; 232c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroardimport android.util.AttributeSet; 242c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroardimport android.view.MotionEvent; 2591d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport android.view.ScaleGestureDetector; 2691d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport android.view.ScaleGestureDetector.OnScaleGestureListener; 272c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 28a93d5ee9c409e2328dcbe2326591436f8ac23146John Hofordimport com.android.gallery3d.filtershow.editors.BasicEditor; 2991d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport com.android.gallery3d.filtershow.editors.EditorTinyPlanet; 3044a499a64158cd5a12f8e44655f82b68c33bf3b2John Hofordimport com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation; 312c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 3263a7dac01d394523799939596b960cb03321798dJohn Hofordpublic class ImageTinyPlanet extends ImageShow { 3391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford private static final String LOGTAG = "ImageTinyPlanet"; 342c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 352c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard private float mTouchCenterX = 0; 362c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard private float mTouchCenterY = 0; 372c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard private float mCurrentX = 0; 382c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard private float mCurrentY = 0; 392c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard private float mCenterX = 0; 402c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard private float mCenterY = 0; 412c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard private float mStartAngle = 0; 4244a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford private FilterTinyPlanetRepresentation mTinyPlanetRep; 4391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford private EditorTinyPlanet mEditorTinyPlanet; 4491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford private ScaleGestureDetector mScaleGestureDetector = null; 4591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford boolean mInScale = false; 4691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford RectF mDestRect = new RectF(); 4791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford 4891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford OnScaleGestureListener mScaleGestureListener = new OnScaleGestureListener() { 4991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford private float mScale = 100; 5091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford @Override 5191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford public void onScaleEnd(ScaleGestureDetector detector) { 5291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mInScale = false; 5391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } 5491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford 5591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford @Override 5691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford public boolean onScaleBegin(ScaleGestureDetector detector) { 5791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mInScale = true; 5891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mScale = mTinyPlanetRep.getValue(); 5991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford return true; 6091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } 6191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford 6291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford @Override 6391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford public boolean onScale(ScaleGestureDetector detector) { 6491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford int value = mTinyPlanetRep.getValue(); 6591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mScale *= detector.getScaleFactor(); 6691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford value = (int) (mScale); 6791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford value = Math.min(mTinyPlanetRep.getMaximum(), value); 6891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford value = Math.max(mTinyPlanetRep.getMinimum(), value); 6991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mTinyPlanetRep.setValue(value); 7091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford invalidate(); 7191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mEditorTinyPlanet.commitLocalRepresentation(); 7291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mEditorTinyPlanet.updateUI(); 7391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford return true; 7491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } 7591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford }; 762c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 772c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard public ImageTinyPlanet(Context context) { 782c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard super(context); 7991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mScaleGestureDetector = new ScaleGestureDetector(context, mScaleGestureListener); 802c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard } 812c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 822c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard public ImageTinyPlanet(Context context, AttributeSet attrs) { 832c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard super(context, attrs); 8491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mScaleGestureDetector = new ScaleGestureDetector(context,mScaleGestureListener ); 852c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard } 862c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 872c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard protected static float angleFor(float dx, float dy) { 882c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard return (float) (Math.atan2(dx, dy) * 180 / Math.PI); 892c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard } 902c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 912c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard protected float getCurrentTouchAngle() { 922c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard if (mCurrentX == mTouchCenterX && mCurrentY == mTouchCenterY) { 932c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard return 0; 942c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard } 952c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard float dX1 = mTouchCenterX - mCenterX; 962c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard float dY1 = mTouchCenterY - mCenterY; 972c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard float dX2 = mCurrentX - mCenterX; 982c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard float dY2 = mCurrentY - mCenterY; 992c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 1002c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard float angleA = angleFor(dX1, dY1); 1012c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard float angleB = angleFor(dX2, dY2); 1022c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard return (float) (((angleB - angleA) % 360) * Math.PI / 180); 1032c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard } 1042c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard 1052c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard @Override 1062c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard public boolean onTouchEvent(MotionEvent event) { 1072c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard float x = event.getX(); 1082c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard float y = event.getY(); 1092c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard mCurrentX = x; 1102c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard mCurrentY = y; 1112c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard mCenterX = getWidth() / 2; 1122c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard mCenterY = getHeight() / 2; 11391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mScaleGestureDetector.onTouchEvent(event); 11491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford if (mInScale) { 11591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford return true; 11691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } 1172c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard switch (event.getActionMasked()) { 1182c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard case (MotionEvent.ACTION_DOWN): 1192c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard mTouchCenterX = x; 1202c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard mTouchCenterY = y; 12144a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford mStartAngle = mTinyPlanetRep.getAngle(); 1222c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard break; 12391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford 1242c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard case (MotionEvent.ACTION_MOVE): 12544a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford mTinyPlanetRep.setAngle(mStartAngle + getCurrentTouchAngle()); 1262c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard break; 1272c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard } 1282c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard invalidate(); 12944a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford mEditorTinyPlanet.commitLocalRepresentation(); 1302c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard return true; 1312c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard } 13244a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford 13344a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford public void setRepresentation(FilterTinyPlanetRepresentation tinyPlanetRep) { 13444a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford mTinyPlanetRep = tinyPlanetRep; 13544a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford } 13644a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford 137a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford public void setEditor(BasicEditor editorTinyPlanet) { 13891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mEditorTinyPlanet = (EditorTinyPlanet) editorTinyPlanet; 13944a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford } 14044a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford 14144a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford @Override 14244a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford public void onDraw(Canvas canvas) { 14391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford Bitmap bitmap = MasterImage.getImage().getHighresImage(); 14491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford if (bitmap == null) { 14591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford bitmap = MasterImage.getImage().getFilteredImage(); 14691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } 14791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford 14891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford if (bitmap != null) { 14991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford display(canvas, bitmap); 15091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } 15144a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford } 15244a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford 15391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford private void display(Canvas canvas, Bitmap bitmap) { 15491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford float sw = canvas.getWidth(); 15591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford float sh = canvas.getHeight(); 15691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford float iw = bitmap.getWidth(); 15791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford float ih = bitmap.getHeight(); 15891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford float nsw = sw; 15991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford float nsh = sh; 16091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford 16191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford if (sw * ih > sh * iw) { 16291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford nsw = sh * iw / ih; 16391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } else { 16491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford nsh = sw * ih / iw; 16591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } 16691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford 16791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mDestRect.left = (sw - nsw) / 2; 16891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mDestRect.top = (sh - nsh) / 2; 16991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mDestRect.right = sw - mDestRect.left; 17091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford mDestRect.bottom = sh - mDestRect.top; 17191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford 17291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford canvas.drawBitmap(bitmap, null, mDestRect, mPaint); 17391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford } 1742c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard} 175