blob: 88830bec76194bedfdac00decceabddb4bbcb60c [file] [log] [blame]
Yuli Huang6a12ad72011-09-12 22:25:30 +08001/*
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;
18
19import android.content.Context;
20import android.util.AttributeSet;
21import android.view.LayoutInflater;
22import android.view.View;
23import android.view.ViewGroup;
24import android.widget.LinearLayout;
Yuli Huang6a12ad72011-09-12 22:25:30 +080025
26import com.android.gallery3d.R;
27import com.android.gallery3d.photoeditor.actions.EffectAction;
Yuli Huang6a12ad72011-09-12 22:25:30 +080028
29/**
30 * Effects bar that contains all effects and shows them in categorized views.
31 */
32public class EffectsBar extends LinearLayout {
33
Yuli Huangb5c54b62011-10-18 12:42:50 +080034 private final LayoutInflater inflater;
Yuli Huang6a12ad72011-09-12 22:25:30 +080035 private FilterStack filterStack;
Yuli Huangb5c54b62011-10-18 12:42:50 +080036 private EffectsMenu effectsMenu;
Yuli Huang6a12ad72011-09-12 22:25:30 +080037 private View effectsGallery;
Yuli Huang6a12ad72011-09-12 22:25:30 +080038 private EffectAction activeEffect;
39
40 public EffectsBar(Context context, AttributeSet attrs) {
41 super(context, attrs);
Yuli Huangb5c54b62011-10-18 12:42:50 +080042 inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Yuli Huang6a12ad72011-09-12 22:25:30 +080043 }
44
45 public void initialize(FilterStack filterStack) {
46 this.filterStack = filterStack;
Yuli Huang6a12ad72011-09-12 22:25:30 +080047
Yuli Huangb5c54b62011-10-18 12:42:50 +080048 effectsMenu = (EffectsMenu) findViewById(R.id.effects_menu);
49 effectsMenu.setOnToggleListener(new EffectsMenu.OnToggleListener() {
50
51 @Override
52 public boolean onToggle(boolean isSelected, final int effectsId) {
53 // Create and show effects-gallery only if the clicked toggle isn't selected or it's
54 // selected but showing an active effect instead of effects-gallery. Set the clicked
55 // toggle selected only when its effects-gallery will be created and shown.
56 boolean select = !isSelected || (effectsGallery == null);
57 exit(select ? new Runnable() {
58
59 @Override
60 public void run() {
61 createEffectsGallery(effectsId);
62 }
63 } : null);
64 return select;
65 }
66 });
Yuli Huang6a12ad72011-09-12 22:25:30 +080067 }
68
Yuli Huangb5c54b62011-10-18 12:42:50 +080069 private void createEffectsGallery(int effectsId) {
70 // Inflate scrollable effects-gallery and desired effects into effects-bar.
71 effectsGallery = inflater.inflate(R.layout.photoeditor_effects_gallery, this, false);
72 ViewGroup scrollView = (ViewGroup) effectsGallery.findViewById(R.id.scroll_view);
73 ViewGroup effects = (ViewGroup) inflater.inflate(effectsId, scrollView, false);
Jorge Ruesgaa901f882012-06-12 23:28:58 +020074 for (int i = effects.getChildCount()-1; i >= 0; i--) {
75 EffectAction effect = (EffectAction) effects.getChildAt(i);
76 if( !effect.isPresent() ){
77 effects.removeViewAt(i);
78 continue;
79 }
Jean-Baptiste Querue0279d32012-06-14 15:26:35 -070080 setupEffect(effect);
Yuli Huangb5c54b62011-10-18 12:42:50 +080081 }
82 scrollView.addView(effects);
83 scrollView.scrollTo(0, 0);
84 addView(effectsGallery, 0);
Yuli Huang6a12ad72011-09-12 22:25:30 +080085 }
86
Yuli Huangdc1b41c2011-12-02 19:55:05 +080087 private void setupEffect(final EffectAction effect) {
88 effect.setOnClickListener(new View.OnClickListener() {
Yuli Huang6a12ad72011-09-12 22:25:30 +080089
90 @Override
Yuli Huangdc1b41c2011-12-02 19:55:05 +080091 public void onClick(View v) {
Yuli Huang6a12ad72011-09-12 22:25:30 +080092 if (isEnabled()) {
93 // Set the clicked effect active before exiting effects-gallery.
94 activeEffect = effect;
95 exitEffectsGallery();
Yuli Huangdc1b41c2011-12-02 19:55:05 +080096 EffectAction.ActionListener listener = new EffectAction.ActionListener() {
Yuli Huang6a12ad72011-09-12 22:25:30 +080097
Yuli Huangdc1b41c2011-12-02 19:55:05 +080098 @Override
99 public void onOk() {
100 exit(null);
101 }
102 };
Yuli Huang26c03542011-12-03 03:23:52 +0800103 activeEffect.begin(getRootView(), filterStack, listener);
Yuli Huangdc1b41c2011-12-02 19:55:05 +0800104 }
Yuli Huang6a12ad72011-09-12 22:25:30 +0800105 }
106 });
107 }
108
Yuli Huang6a12ad72011-09-12 22:25:30 +0800109 private boolean exitEffectsGallery() {
110 if (effectsGallery != null) {
111 if (activeEffect != null) {
Yuli Huangb5c54b62011-10-18 12:42:50 +0800112 // Detach the active effect to prevent it stopping effects-gallery from gc.
Yuli Huangdc1b41c2011-12-02 19:55:05 +0800113 ((ViewGroup) activeEffect.getParent()).removeView(activeEffect);
Yuli Huang6a12ad72011-09-12 22:25:30 +0800114 }
115 removeView(effectsGallery);
116 effectsGallery = null;
117 return true;
118 }
119 return false;
120 }
121
122 private boolean exitActiveEffect(final Runnable runnableOnDone) {
123 if (activeEffect != null) {
Yuli Huang5cac6d52012-03-12 16:34:41 +0800124 final Toolbar toolbar = (Toolbar) getRootView().findViewById(R.id.toolbar);
125 toolbar.showSpinner();
Yuli Huang6a12ad72011-09-12 22:25:30 +0800126 activeEffect.end(new Runnable() {
127
128 @Override
129 public void run() {
Yuli Huang5cac6d52012-03-12 16:34:41 +0800130 toolbar.dismissSpinner();
Yuli Huang6a12ad72011-09-12 22:25:30 +0800131 activeEffect = null;
132 if (runnableOnDone != null) {
133 runnableOnDone.run();
134 }
135 }
136 });
137 return true;
138 }
139 return false;
140 }
141
142 /**
143 * Exits from effects gallery or the active effect; then executes the runnable if applicable.
144 *
145 * @return true if exiting from effects gallery or the active effect; otherwise, false.
146 */
147 public boolean exit(final Runnable runnableOnDone) {
148 // Exit effects-menu selected states.
Yuli Huangb5c54b62011-10-18 12:42:50 +0800149 effectsMenu.clearSelected();
Yuli Huang6a12ad72011-09-12 22:25:30 +0800150
151 if (exitActiveEffect(runnableOnDone)) {
152 return true;
153 }
154
155 boolean exited = exitEffectsGallery();
156 if (runnableOnDone != null) {
157 runnableOnDone.run();
158 }
159 return exited;
160 }
161}