• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.gallery3d.photoeditor.actions;
18 
19 import android.content.Context;
20 import android.util.AttributeSet;
21 
22 import com.android.gallery3d.R;
23 import com.android.gallery3d.photoeditor.PhotoView;
24 import com.android.gallery3d.photoeditor.filters.FlipFilter;
25 
26 /**
27  * An action handling flip effect.
28  */
29 public class FlipAction extends EffectAction {
30 
31     private static final float DEFAULT_ANGLE = 0.0f;
32     private static final float DEFAULT_FLIP_SPAN = 180.0f;
33 
34     private FlipFilter filter;
35     private float horizontalFlipDegrees;
36     private float verticalFlipDegrees;
37     private Runnable queuedFlipChange;
38     private FlipView flipView;
39 
FlipAction(Context context, AttributeSet attrs)40     public FlipAction(Context context, AttributeSet attrs) {
41         super(context, attrs);
42     }
43 
44     @Override
doBegin()45     public void doBegin() {
46         filter = new FlipFilter();
47 
48         flipView = factory.createFlipView();
49         flipView.setOnFlipChangeListener(new FlipView.OnFlipChangeListener() {
50 
51             // Directly transform photo-view because running the flip filter isn't fast enough.
52             PhotoView photoView = (PhotoView) flipView.getRootView().findViewById(
53                     R.id.photo_view);
54 
55             @Override
56             public void onAngleChanged(float horizontalDegrees, float verticalDegrees,
57                     boolean fromUser) {
58                 if (fromUser) {
59                     horizontalFlipDegrees = horizontalDegrees;
60                     verticalFlipDegrees = verticalDegrees;
61                     updateFlipFilter(false);
62                     transformPhotoView(horizontalDegrees, verticalDegrees);
63                 }
64             }
65 
66             @Override
67             public void onStartTrackingTouch() {
68                 // no-op
69             }
70 
71             @Override
72             public void onStopTrackingTouch() {
73                 roundFlipDegrees();
74                 updateFlipFilter(false);
75                 transformPhotoView(horizontalFlipDegrees, verticalFlipDegrees);
76                 flipView.setFlippedAngles(horizontalFlipDegrees, verticalFlipDegrees);
77             }
78 
79             private void transformPhotoView(final float horizontalDegrees,
80                     final float verticalDegrees) {
81                 // Remove the outdated flip change before queuing a new one.
82                 if (queuedFlipChange != null) {
83                     photoView.remove(queuedFlipChange);
84                 }
85                 queuedFlipChange = new Runnable() {
86 
87                     @Override
88                     public void run() {
89                         photoView.flipPhoto(horizontalDegrees, verticalDegrees);
90                     }
91                 };
92                 photoView.queue(queuedFlipChange);
93             }
94         });
95         flipView.setFlippedAngles(DEFAULT_ANGLE, DEFAULT_ANGLE);
96         flipView.setFlipSpan(DEFAULT_FLIP_SPAN);
97         horizontalFlipDegrees = 0;
98         verticalFlipDegrees = 0;
99         queuedFlipChange = null;
100     }
101 
102     @Override
doEnd()103     public void doEnd() {
104         flipView.setOnFlipChangeListener(null);
105         // Round the current flip degrees in case flip tracking has not stopped yet.
106         roundFlipDegrees();
107         updateFlipFilter(true);
108     }
109 
110     /**
111      * Rounds flip degrees to multiples of 180 degrees.
112      */
roundFlipDegrees()113     private void roundFlipDegrees() {
114         if (horizontalFlipDegrees % 180 != 0) {
115             horizontalFlipDegrees = Math.round(horizontalFlipDegrees / 180) * 180;
116         }
117         if (verticalFlipDegrees % 180 != 0) {
118             verticalFlipDegrees = Math.round(verticalFlipDegrees / 180) * 180;
119         }
120     }
121 
updateFlipFilter(boolean outputFilter)122     private void updateFlipFilter(boolean outputFilter) {
123         // Flip the filter if the flipped degrees are at the opposite directions.
124         filter.setFlip(((int) horizontalFlipDegrees / 180) % 2 != 0,
125                 ((int) verticalFlipDegrees / 180) % 2 != 0);
126         notifyFilterChanged(filter, outputFilter);
127     }
128 }
129