• 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;
18 
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.widget.ScrollView;
24 import android.widget.TextView;
25 
26 import com.android.photoeditor.actions.AutoFixAction;
27 import com.android.photoeditor.actions.ColorTemperatureAction;
28 import com.android.photoeditor.actions.CropAction;
29 import com.android.photoeditor.actions.CrossProcessAction;
30 import com.android.photoeditor.actions.DocumentaryAction;
31 import com.android.photoeditor.actions.DoodleAction;
32 import com.android.photoeditor.actions.DuotoneAction;
33 import com.android.photoeditor.actions.FillLightAction;
34 import com.android.photoeditor.actions.FilterAction;
35 import com.android.photoeditor.actions.FisheyeAction;
36 import com.android.photoeditor.actions.FlipAction;
37 import com.android.photoeditor.actions.GrainAction;
38 import com.android.photoeditor.actions.GrayscaleAction;
39 import com.android.photoeditor.actions.HighlightAction;
40 import com.android.photoeditor.actions.LomoishAction;
41 import com.android.photoeditor.actions.NegativeAction;
42 import com.android.photoeditor.actions.PosterizeAction;
43 import com.android.photoeditor.actions.RedEyeAction;
44 import com.android.photoeditor.actions.RotateAction;
45 import com.android.photoeditor.actions.SaturationAction;
46 import com.android.photoeditor.actions.SepiaAction;
47 import com.android.photoeditor.actions.ShadowAction;
48 import com.android.photoeditor.actions.SharpenAction;
49 import com.android.photoeditor.actions.StraightenAction;
50 import com.android.photoeditor.actions.TintAction;
51 import com.android.photoeditor.actions.VignetteAction;
52 import com.android.photoeditor.actions.WarmifyAction;
53 
54 import java.util.ArrayList;
55 import java.util.List;
56 
57 /**
58  * Scroll view that contains all effects for editing photo by mapping each effect to trigger one
59  * corresponding FilterAction.
60  */
61 public class EffectsBar extends ScrollView {
62 
63     private final List<Effect> effects = new ArrayList<Effect>();
64     private TextView effectName;
65 
EffectsBar(Context context, AttributeSet attrs)66     public EffectsBar(Context context, AttributeSet attrs) {
67         super(context, attrs);
68     }
69 
initialize(FilterStack filterStack, PhotoView photoView, ViewGroup tools)70     public void initialize(FilterStack filterStack, PhotoView photoView, ViewGroup tools) {
71         effects.add(new Effect(R.id.autofix_effect,
72                 new AutoFixAction(filterStack, tools)));
73 
74         effects.add(new Effect(R.id.crop_effect,
75                 new CropAction(filterStack, tools)));
76 
77         effects.add(new Effect(R.id.crossprocess_effect,
78                 new CrossProcessAction(filterStack, tools)));
79 
80         effects.add(new Effect(R.id.documentary_effect,
81                 new DocumentaryAction(filterStack, tools)));
82 
83         effects.add(new Effect(R.id.doodle_effect,
84                 new DoodleAction(filterStack, tools)));
85 
86         effects.add(new Effect(R.id.duotone_effect,
87                 new DuotoneAction(filterStack, tools)));
88 
89         effects.add(new Effect(R.id.filllight_effect,
90                 new FillLightAction(filterStack, tools)));
91 
92         effects.add(new Effect(R.id.fisheye_effect,
93                 new FisheyeAction(filterStack, tools)));
94 
95         effects.add(new Effect(R.id.flip_effect,
96                 new FlipAction(filterStack, tools)));
97 
98         effects.add(new Effect(R.id.grain_effect,
99                 new GrainAction(filterStack, tools)));
100 
101         effects.add(new Effect(R.id.grayscale_effect,
102                 new GrayscaleAction(filterStack, tools)));
103 
104         effects.add(new Effect(R.id.highlight_effect,
105                 new HighlightAction(filterStack, tools)));
106 
107         effects.add(new Effect(R.id.lomoish_effect,
108                 new LomoishAction(filterStack, tools)));
109 
110         effects.add(new Effect(R.id.negative_effect,
111                 new NegativeAction(filterStack, tools)));
112 
113         effects.add(new Effect(R.id.posterize_effect,
114                 new PosterizeAction(filterStack, tools)));
115 
116         effects.add(new Effect(R.id.redeye_effect,
117                 new RedEyeAction(filterStack, tools)));
118 
119         effects.add(new Effect(R.id.rotate_effect,
120                 new RotateAction(filterStack, tools)));
121 
122         effects.add(new Effect(R.id.saturation_effect,
123                 new SaturationAction(filterStack, tools)));
124 
125         effects.add(new Effect(R.id.sepia_effect,
126                 new SepiaAction(filterStack, tools)));
127 
128         effects.add(new Effect(R.id.shadow_effect,
129                 new ShadowAction(filterStack, tools)));
130 
131         effects.add(new Effect(R.id.sharpen_effect,
132                 new SharpenAction(filterStack, tools)));
133 
134         effects.add(new Effect(R.id.straighten_effect,
135                 new StraightenAction(filterStack, tools)));
136 
137         effects.add(new Effect(R.id.temperature_effect,
138                 new ColorTemperatureAction(filterStack, tools)));
139 
140         effects.add(new Effect(R.id.tint_effect,
141                 new TintAction(filterStack, tools)));
142 
143         effects.add(new Effect(R.id.vignette_effect,
144                 new VignetteAction(filterStack, tools)));
145 
146         effects.add(new Effect(R.id.warmify_effect,
147                 new WarmifyAction(filterStack, tools)));
148 
149         effectName = (TextView) tools.findViewById(R.id.action_effect_name);
150 
151         // Disable hardware acceleration on this view to make alpha animations work for idle fading.
152         setLayerType(View.LAYER_TYPE_SOFTWARE, null);
153 
154         setEnabled(false);
155     }
156 
effectsOff(Runnable runnableOnEffectsOff)157     public void effectsOff(Runnable runnableOnEffectsOff) {
158         for (Effect effect : effects) {
159             if (effect.on) {
160                 effect.turnOff(runnableOnEffectsOff);
161                 return;
162             }
163         }
164         // Just execute the runnable right away if all effects are already off.
165         if (runnableOnEffectsOff != null) {
166             runnableOnEffectsOff.run();
167         }
168     }
169 
hasEffectOn()170     public boolean hasEffectOn() {
171         for (Effect effect : effects) {
172             if (effect.on) {
173                 return true;
174             }
175         }
176         return false;
177     }
178 
179     private class Effect implements FilterAction.FilterActionListener {
180 
181         private final FilterAction action;
182         private final CharSequence name;
183         private final IconIndicator button;
184         private boolean on;
185         private Runnable runnableOnODone;
186 
Effect(int effectId, FilterAction action)187         public Effect(int effectId, FilterAction action) {
188             this.action = action;
189 
190             View view = findViewById(effectId);
191             name = ((TextView) view.findViewById(R.id.effect_label)).getText();
192             button = (IconIndicator) view.findViewById(R.id.effect_button);
193             button.setOnClickListener(new View.OnClickListener() {
194 
195                 @Override
196                 public void onClick(View v) {
197                     if (isEnabled()) {
198                         if (on) {
199                             turnOff(null);
200                         } else {
201                             // Have other effects done turning off first and then turn on itself.
202                             effectsOff(new Runnable() {
203 
204                                 @Override
205                                 public void run() {
206                                     turnOn();
207                                 }
208                             });
209                         }
210                     }
211                 }
212             });
213         }
214 
turnOn()215         private void turnOn() {
216             effectName.setText(name);
217             button.setMode("on");
218             on = true;
219             action.begin(this);
220         }
221 
turnOff(Runnable runnableOnODone)222         private void turnOff(Runnable runnableOnODone) {
223             this.runnableOnODone = runnableOnODone;
224             action.end();
225         }
226 
227         @Override
onDone()228         public void onDone() {
229             if (on) {
230                 effectName.setText("");
231                 button.setMode("off");
232                 on = false;
233 
234                 if (runnableOnODone != null) {
235                     runnableOnODone.run();
236                     runnableOnODone = null;
237                 }
238             }
239         }
240     }
241 }
242