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
17package com.android.camera.ui;
18
19import android.annotation.TargetApi;
20import android.content.Context;
21import android.util.AttributeSet;
22import android.util.Log;
23import android.view.View;
24import android.widget.AdapterView;
25import android.widget.GridView;
26import android.widget.SimpleAdapter;
27
28import com.android.camera.IconListPreference;
29import com.android.camera.R;
30
31import com.android.gallery3d.common.ApiHelper;
32
33import java.util.ArrayList;
34import java.util.HashMap;
35
36// A popup window that shows video effect setting. It has two grid view.
37// One shows the goofy face effects. The other shows the background replacer
38// effects.
39public class EffectSettingPopup extends AbstractSettingPopup implements
40        AdapterView.OnItemClickListener, View.OnClickListener {
41    private static final String TAG = "EffectSettingPopup";
42    private String mNoEffect;
43    private IconListPreference mPreference;
44    private Listener mListener;
45    private View mClearEffects;
46    private GridView mSillyFacesGrid;
47    private GridView mBackgroundGrid;
48
49    // Data for silly face items. (text, image, and preference value)
50    ArrayList<HashMap<String, Object>> mSillyFacesItem =
51            new ArrayList<HashMap<String, Object>>();
52
53    // Data for background replacer items. (text, image, and preference value)
54    ArrayList<HashMap<String, Object>> mBackgroundItem =
55            new ArrayList<HashMap<String, Object>>();
56
57
58    static public interface Listener {
59        public void onSettingChanged();
60    }
61
62    public EffectSettingPopup(Context context, AttributeSet attrs) {
63        super(context, attrs);
64        mNoEffect = context.getString(R.string.pref_video_effect_default);
65    }
66
67    @Override
68    protected void onFinishInflate() {
69        super.onFinishInflate();
70        mClearEffects = findViewById(R.id.clear_effects);
71        mClearEffects.setOnClickListener(this);
72        mSillyFacesGrid = (GridView) findViewById(R.id.effect_silly_faces);
73        mBackgroundGrid = (GridView) findViewById(R.id.effect_background);
74    }
75
76    public void initialize(IconListPreference preference) {
77        mPreference = preference;
78        Context context = getContext();
79        CharSequence[] entries = mPreference.getEntries();
80        CharSequence[] entryValues = mPreference.getEntryValues();
81        int[] iconIds = mPreference.getImageIds();
82        if (iconIds == null) {
83            iconIds = mPreference.getLargeIconIds();
84        }
85
86        // Set title.
87        mTitle.setText(mPreference.getTitle());
88
89        for(int i = 0; i < entries.length; ++i) {
90            String value = entryValues[i].toString();
91            if (value.equals(mNoEffect)) continue;  // no effect, skip it.
92            HashMap<String, Object> map = new HashMap<String, Object>();
93            map.put("value", value);
94            map.put("text", entries[i].toString());
95            if (iconIds != null) map.put("image", iconIds[i]);
96            if (value.startsWith("goofy_face")) {
97                mSillyFacesItem.add(map);
98            } else if (value.startsWith("backdropper")) {
99                mBackgroundItem.add(map);
100            }
101        }
102
103        boolean hasSillyFaces = mSillyFacesItem.size() > 0;
104        boolean hasBackground = mBackgroundItem.size() > 0;
105
106        // Initialize goofy face if it is supported.
107        if (hasSillyFaces) {
108            findViewById(R.id.effect_silly_faces_title).setVisibility(View.VISIBLE);
109            findViewById(R.id.effect_silly_faces_title_separator).setVisibility(View.VISIBLE);
110            mSillyFacesGrid.setVisibility(View.VISIBLE);
111            SimpleAdapter sillyFacesItemAdapter = new SimpleAdapter(context,
112                    mSillyFacesItem, R.layout.effect_setting_item,
113                    new String[] {"text", "image"},
114                    new int[] {R.id.text, R.id.image});
115            mSillyFacesGrid.setAdapter(sillyFacesItemAdapter);
116            mSillyFacesGrid.setOnItemClickListener(this);
117        }
118
119        if (hasSillyFaces && hasBackground) {
120            findViewById(R.id.effect_background_separator).setVisibility(View.VISIBLE);
121        }
122
123        // Initialize background replacer if it is supported.
124        if (hasBackground) {
125            findViewById(R.id.effect_background_title).setVisibility(View.VISIBLE);
126            findViewById(R.id.effect_background_title_separator).setVisibility(View.VISIBLE);
127            mBackgroundGrid.setVisibility(View.VISIBLE);
128            SimpleAdapter backgroundItemAdapter = new SimpleAdapter(context,
129                    mBackgroundItem, R.layout.effect_setting_item,
130                    new String[] {"text", "image"},
131                    new int[] {R.id.text, R.id.image});
132            mBackgroundGrid.setAdapter(backgroundItemAdapter);
133            mBackgroundGrid.setOnItemClickListener(this);
134        }
135
136        reloadPreference();
137    }
138
139    @Override
140    public void setVisibility(int visibility) {
141        if (visibility == View.VISIBLE) {
142            if (getVisibility() != View.VISIBLE) {
143                // Do not show or hide "Clear effects" button when the popup
144                // is already visible. Otherwise it looks strange.
145                boolean noEffect = mPreference.getValue().equals(mNoEffect);
146                mClearEffects.setVisibility(noEffect ? View.GONE : View.VISIBLE);
147            }
148            reloadPreference();
149        }
150        super.setVisibility(visibility);
151    }
152
153    // The value of the preference may have changed. Update the UI.
154    @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
155    @Override
156    public void reloadPreference() {
157        mBackgroundGrid.setItemChecked(mBackgroundGrid.getCheckedItemPosition(), false);
158        mSillyFacesGrid.setItemChecked(mSillyFacesGrid.getCheckedItemPosition(), false);
159
160        String value = mPreference.getValue();
161        if (value.equals(mNoEffect)) return;
162
163        for (int i = 0; i < mSillyFacesItem.size(); i++) {
164            if (value.equals(mSillyFacesItem.get(i).get("value"))) {
165                mSillyFacesGrid.setItemChecked(i, true);
166                return;
167            }
168        }
169
170        for (int i = 0; i < mBackgroundItem.size(); i++) {
171            if (value.equals(mBackgroundItem.get(i).get("value"))) {
172                mBackgroundGrid.setItemChecked(i, true);
173                return;
174            }
175        }
176
177        Log.e(TAG, "Invalid preference value: " + value);
178        mPreference.print();
179    }
180
181    public void setSettingChangedListener(Listener listener) {
182        mListener = listener;
183    }
184
185    @Override
186    public void onItemClick(AdapterView<?> parent, View view,
187            int index, long id) {
188        String value;
189        if (parent == mSillyFacesGrid) {
190            value = (String) mSillyFacesItem.get(index).get("value");
191        } else if (parent == mBackgroundGrid) {
192            value = (String) mBackgroundItem.get(index).get("value");
193        } else {
194            return;
195        }
196
197        // Tapping the selected effect will deselect it (clear effects).
198        if (value.equals(mPreference.getValue())) {
199            mPreference.setValue(mNoEffect);
200        } else {
201            mPreference.setValue(value);
202        }
203        reloadPreference();
204        if (mListener != null) mListener.onSettingChanged();
205    }
206
207    @Override
208    public void onClick(View v) {
209        // Clear the effect.
210        mPreference.setValue(mNoEffect);
211        reloadPreference();
212        if (mListener != null) mListener.onSettingChanged();
213    }
214}
215