1/* 2 * Copyright (C) 2010 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.android.gallery3d.photoeditor.actions; 18 19import android.content.Context; 20import android.util.AttributeSet; 21 22import com.android.gallery3d.R; 23import com.android.gallery3d.photoeditor.PhotoView; 24import com.android.gallery3d.photoeditor.filters.RotateFilter; 25 26/** 27 * An action handling rotate effect. 28 */ 29public class RotateAction extends EffectAction { 30 31 private static final float DEFAULT_ANGLE = 0.0f; 32 private static final float DEFAULT_ROTATE_SPAN = 360.0f; 33 34 private RotateFilter filter; 35 private float rotateDegrees; 36 private Runnable queuedRotationChange; 37 private RotateView rotateView; 38 39 public RotateAction(Context context, AttributeSet attrs) { 40 super(context, attrs); 41 } 42 43 @Override 44 public void doBegin() { 45 filter = new RotateFilter(); 46 47 rotateView = factory.createRotateView(); 48 rotateView.setOnRotateChangeListener(new RotateView.OnRotateChangeListener() { 49 50 // Directly transform photo-view because running the rotate filter isn't fast enough. 51 PhotoView photoView = (PhotoView) rotateView.getRootView().findViewById( 52 R.id.photo_view); 53 54 @Override 55 public void onAngleChanged(float degrees, boolean fromUser){ 56 if (fromUser) { 57 rotateDegrees = degrees; 58 updateRotateFilter(false); 59 transformPhotoView(degrees); 60 } 61 } 62 63 @Override 64 public void onStartTrackingTouch() { 65 // no-op 66 } 67 68 @Override 69 public void onStopTrackingTouch() { 70 roundRotateDegrees(); 71 updateRotateFilter(false); 72 transformPhotoView(rotateDegrees); 73 rotateView.setRotatedAngle(rotateDegrees); 74 } 75 76 private void transformPhotoView(final float degrees) { 77 // Remove the outdated rotation change before queuing a new one. 78 if (queuedRotationChange != null) { 79 photoView.remove(queuedRotationChange); 80 } 81 queuedRotationChange = new Runnable() { 82 83 @Override 84 public void run() { 85 photoView.rotatePhoto(degrees); 86 } 87 }; 88 photoView.queue(queuedRotationChange); 89 } 90 }); 91 rotateView.setRotatedAngle(DEFAULT_ANGLE); 92 rotateView.setRotateSpan(DEFAULT_ROTATE_SPAN); 93 rotateDegrees = 0; 94 queuedRotationChange = null; 95 } 96 97 @Override 98 public void doEnd() { 99 rotateView.setOnRotateChangeListener(null); 100 // Round the current rotation degrees in case rotation tracking has not stopped yet. 101 roundRotateDegrees(); 102 updateRotateFilter(true); 103 } 104 105 /** 106 * Rounds rotate degrees to multiples of 90 degrees. 107 */ 108 private void roundRotateDegrees() { 109 if (rotateDegrees % 90 != 0) { 110 rotateDegrees = Math.round(rotateDegrees / 90) * 90; 111 } 112 } 113 114 private void updateRotateFilter(boolean outputFilter) { 115 filter.setAngle(rotateDegrees); 116 notifyFilterChanged(filter, outputFilter); 117 } 118} 119