• 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.photoeditor.actions;
18 
19 import android.view.View;
20 import android.view.ViewGroup;
21 import android.widget.Toast;
22 
23 import com.android.photoeditor.FilterStack;
24 import com.android.photoeditor.Photo;
25 import com.android.photoeditor.PhotoOutputCallback;
26 import com.android.photoeditor.PhotoView;
27 import com.android.photoeditor.R;
28 import com.android.photoeditor.SpinnerProgressDialog;
29 import com.android.photoeditor.filters.Filter;
30 
31 /**
32  * An action binding UI controls and filter operation for editing photo.
33  */
34 public abstract class FilterAction {
35 
36     /**
37      * Listens to when this FilterAction has done editing and should be ended.
38      */
39     public interface FilterActionListener {
40 
onDone()41         void onDone();
42     }
43 
44     protected final FilterStack filterStack;
45     protected final PhotoView photoView;
46     protected final ScaleWheel scaleWheel;
47     protected final ColorWheel colorWheel;
48     protected final DoodleView doodleView;
49     protected final TouchView touchView;
50     protected final RotateView rotateView;
51     protected final CropView cropView;
52     private final ViewGroup tools;
53 
54     private Toast tooltip;
55     private boolean pushedFilter;
56     private OutputCallback lastOutputCallback;
57     private FilterActionListener listener;
58 
FilterAction(FilterStack filterStack, ViewGroup tools)59     public FilterAction(FilterStack filterStack, ViewGroup tools) {
60         this.filterStack = filterStack;
61         this.tools = tools;
62 
63         photoView = (PhotoView) tools.findViewById(R.id.photo_view);
64         scaleWheel = (ScaleWheel) tools.findViewById(R.id.scale_wheel);
65         colorWheel = (ColorWheel) tools.findViewById(R.id.color_wheel);
66         doodleView = (DoodleView) tools.findViewById(R.id.doodle_view);
67         touchView = (TouchView) tools.findViewById(R.id.touch_view);
68         rotateView = (RotateView) tools.findViewById(R.id.rotate_view);
69         cropView = (CropView) tools.findViewById(R.id.crop_view);
70     }
71 
FilterAction(FilterStack filterStack, ViewGroup tools, int tooltipId)72     public FilterAction(FilterStack filterStack, ViewGroup tools, int tooltipId) {
73         this(filterStack, tools);
74 
75         tooltip = Toast.makeText(tools.getContext(), tooltipId, Toast.LENGTH_SHORT);
76     }
77 
notifyFilterChanged(Filter filter, boolean output)78     protected void notifyFilterChanged(Filter filter, boolean output) {
79         if (!pushedFilter && filter.isValid()) {
80             filterStack.pushFilter(filter);
81             pushedFilter = true;
82         }
83         if (pushedFilter && output) {
84             // Notify the stack to output the changed top filter.
85             lastOutputCallback = new OutputCallback();
86             filterStack.topFilterChanged(lastOutputCallback);
87         }
88     }
89 
begin(FilterActionListener listener)90     public void begin(FilterActionListener listener) {
91         this.listener = listener;
92         if (tooltip != null) {
93             tooltip.show();
94         }
95         onBegin();
96     }
97 
end()98     public void end() {
99         onEnd();
100 
101         // Wait till last output callback is done before finishing.
102         if ((lastOutputCallback == null) || lastOutputCallback.done) {
103             finish();
104         } else {
105             final SpinnerProgressDialog progressDialog = SpinnerProgressDialog.show(tools);
106             lastOutputCallback.runnableOnDone = new Runnable() {
107 
108                 @Override
109                 public void run() {
110                     progressDialog.dismiss();
111                     finish();
112                 }
113             };
114         }
115     }
116 
finish()117     private void finish() {
118         // Close the tooltip if it's still showing.
119         if ((tooltip != null) && (tooltip.getView().getParent() != null)) {
120             tooltip.cancel();
121         }
122         if (scaleWheel.getVisibility() == View.VISIBLE) {
123             scaleWheel.setOnScaleChangeListener(null);
124             scaleWheel.setVisibility(View.INVISIBLE);
125         }
126         if (colorWheel.getVisibility() == View.VISIBLE) {
127             colorWheel.setOnColorChangeListener(null);
128             colorWheel.setVisibility(View.INVISIBLE);
129         }
130         if (doodleView.getVisibility() == View.VISIBLE) {
131             doodleView.setOnDoodleChangeListener(null);
132             doodleView.setVisibility(View.INVISIBLE);
133         }
134         if (touchView.getVisibility() == View.VISIBLE) {
135             touchView.setSingleTapListener(null);
136             touchView.setSwipeListener(null);
137             touchView.setVisibility(View.INVISIBLE);
138         }
139         if (rotateView.getVisibility() == View.VISIBLE) {
140             rotateView.setOnAngleChangeListener(null);
141             rotateView.setVisibility(View.INVISIBLE);
142         }
143         if (cropView.getVisibility() == View.VISIBLE) {
144             cropView.setOnCropChangeListener(null);
145             cropView.setVisibility(View.INVISIBLE);
146         }
147         photoView.clipPhoto(null);
148         // Notify the listener that this action is done finishing.
149         listener.onDone();
150         listener = null;
151         lastOutputCallback = null;
152         pushedFilter = false;
153     }
154 
155     /**
156      * Called when the action is about to begin; subclasses should creates a specific filter and
157      * binds the filter to necessary UI controls here.
158      */
onBegin()159     protected abstract void onBegin();
160 
161     /**
162      * Called when the action is about to end; subclasses could do specific ending operations here.
163      */
onEnd()164     protected abstract void onEnd();
165 
166     /**
167      * Output callback for top filter changes.
168      */
169     private class OutputCallback implements PhotoOutputCallback {
170 
171         private boolean done;
172         private Runnable runnableOnDone;
173 
174         @Override
onReady(Photo photo)175         public void onReady(Photo photo) {
176             photoView.update(photo);
177             done = true;
178 
179             if (runnableOnDone != null) {
180                 runnableOnDone.run();
181             }
182         }
183     }
184 }
185