Home | History | Annotate | Download | only in photoeditor
      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 
     66     public EffectsBar(Context context, AttributeSet attrs) {
     67         super(context, attrs);
     68     }
     69 
     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 
    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 
    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 
    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 
    215         private void turnOn() {
    216             effectName.setText(name);
    217             button.setMode("on");
    218             on = true;
    219             action.begin(this);
    220         }
    221 
    222         private void turnOff(Runnable runnableOnODone) {
    223             this.runnableOnODone = runnableOnODone;
    224             action.end();
    225         }
    226 
    227         @Override
    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