1/*
2 * Copyright (C) 2011 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 com.android.camera.CameraPreference.OnPreferenceChangedListener;
20import com.android.camera.IconListPreference;
21import com.android.camera.ListPreference;
22import com.android.camera.PreferenceGroup;
23import com.android.camera.CameraSettings;
24import com.android.camera.R;
25
26import android.content.Context;
27import android.util.AttributeSet;
28import android.view.View;
29import android.widget.ImageView;
30import android.widget.RelativeLayout;
31
32import java.util.ArrayList;
33
34/**
35 * A view that contains camera setting indicators.
36 */
37public abstract class IndicatorControl extends RelativeLayout implements
38        IndicatorButton.Listener, OtherSettingsPopup.Listener, Rotatable {
39    private static final String TAG = "IndicatorControl";
40    public static final int MODE_CAMERA = 0;
41    public static final int MODE_VIDEO = 1;
42
43    private OnPreferenceChangedListener mListener;
44    protected OnIndicatorEventListener mOnIndicatorEventListener;
45    protected CameraPicker mCameraPicker;
46
47    private PreferenceGroup mPreferenceGroup;
48    private int mOrientation = 0;
49
50    protected int mCurrentMode = MODE_CAMERA;
51
52    ArrayList<AbstractIndicatorButton> mIndicators =
53            new ArrayList<AbstractIndicatorButton>();
54
55    public void setListener(OnPreferenceChangedListener listener) {
56        mListener = listener;
57        if (mCameraPicker != null) mCameraPicker.setListener(listener);
58    }
59
60    public IndicatorControl(Context context, AttributeSet attrs) {
61        super(context, attrs);
62    }
63
64    public void setOrientation(int orientation) {
65        mOrientation = orientation;
66        int count = getChildCount();
67        for (int i = 0 ; i < count ; ++i) {
68            View view = getChildAt(i);
69            if (view instanceof Rotatable) {
70                ((Rotatable) view).setOrientation(orientation);
71            }
72        }
73    }
74
75    public void setOnIndicatorEventListener(OnIndicatorEventListener listener) {
76        mOnIndicatorEventListener = listener;
77    }
78
79    public void setPreferenceGroup(PreferenceGroup group) {
80        mPreferenceGroup = group;
81        // Preset the current mode from the title of preference group.
82        String title = group.getTitle();
83        if (title.equals(getContext().getString(
84                R.string.pref_camcorder_settings_category))) {
85            mCurrentMode = MODE_VIDEO;
86        }
87    }
88
89    protected void addControls(String[] keys, String[] otherSettingKeys) {
90        if (keys != null) {
91            for (int i = 0; i < keys.length; i++) {
92                IconListPreference pref =
93                        (IconListPreference) mPreferenceGroup.findPreference(keys[i]);
94                if (pref != null) {
95                    addIndicator(getContext(), pref);
96                }
97            }
98        }
99
100        // Add other settings indicator.
101        if (otherSettingKeys != null) {
102            addOtherSettingIndicator(getContext(),
103                    R.drawable.ic_menu_overflow, otherSettingKeys);
104        }
105    }
106
107    protected void initializeCameraPicker() {
108        ListPreference pref = mPreferenceGroup.findPreference(
109                CameraSettings.KEY_CAMERA_ID);
110        if (pref == null) return;
111        mCameraPicker = new CameraPicker(getContext());
112        mCameraPicker.initialize(pref);
113        addView(mCameraPicker);
114    }
115
116    @Override
117    public boolean shouldDelayChildPressedState() {
118        // Return false so the pressed feedback of the back/front camera switch
119        // can be showed right away.
120        return false;
121    }
122
123    public IndicatorButton addIndicator(Context context, IconListPreference pref) {
124        IndicatorButton b = new IndicatorButton(context, pref);
125        b.setSettingChangedListener(this);
126        b.setContentDescription(pref.getTitle());
127        addView(b);
128        mIndicators.add(b);
129        return b;
130    }
131
132    public OtherSettingIndicatorButton addOtherSettingIndicator(Context context,
133            int resId, String[] keys) {
134        OtherSettingIndicatorButton b = new OtherSettingIndicatorButton(
135                context, resId, mPreferenceGroup, keys);
136        b.setSettingChangedListener(this);
137        b.setContentDescription(getResources().getString(
138                R.string.pref_camera_settings_category));
139        addView(b);
140        mIndicators.add(b);
141        return b;
142    }
143
144    @Override
145    public void onRestorePreferencesClicked() {
146        if (mListener != null) {
147            mListener.onRestorePreferencesClicked();
148        }
149    }
150
151    @Override
152    public void onSettingChanged() {
153        if (mListener != null) {
154            mListener.onSharedPreferenceChanged();
155        }
156    }
157
158    public boolean dismissSettingPopup() {
159        for (AbstractIndicatorButton v: mIndicators) {
160            if (v.dismissPopup()) {
161                invalidate();
162                return true;
163            }
164        }
165        return false;
166    }
167
168    public View getActiveSettingPopup() {
169        for (AbstractIndicatorButton v: mIndicators) {
170            View result = v.getPopupWindow();
171            if (result != null) return result;
172        }
173        return null;
174    }
175
176    // Scene mode may override other camera settings (ex: flash mode).
177    public void overrideSettings(final String ... keyvalues) {
178        if (keyvalues.length % 2 != 0) {
179            throw new IllegalArgumentException();
180        }
181
182        for (AbstractIndicatorButton b: mIndicators) {
183            b.overrideSettings(keyvalues);
184        }
185    }
186
187    public void reloadPreferences() {
188        mPreferenceGroup.reloadValue();
189        for (AbstractIndicatorButton b: mIndicators) {
190            b.reloadPreference();
191        }
192    }
193
194    @Override
195    public void setEnabled(boolean enabled) {
196        super.setEnabled(enabled);
197        final int count = getChildCount();
198        for (int i = 0; i < count; i++) {
199            View v = getChildAt(i);
200            // Zoom buttons and shutter button are controlled by the activity.
201            if (v instanceof AbstractIndicatorButton) {
202                v.setEnabled(enabled);
203                // Show or hide the indicator buttons during recording.
204                if (mCurrentMode == MODE_VIDEO) {
205                    v.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
206                }
207            }
208        }
209        if (mCameraPicker != null) {
210            mCameraPicker.setEnabled(enabled);
211            if (mCurrentMode == MODE_VIDEO) {
212                mCameraPicker.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
213            }
214        }
215    }
216}
217