GalleryActionBar.java revision 2bb717f1ea38e2ce33dd102a23afe6bfacb5675c
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.gallery3d.app;
18
19import android.annotation.TargetApi;
20import android.app.Activity;
21import android.app.AlertDialog;
22import android.content.Context;
23import android.content.DialogInterface;
24import android.content.Intent;
25import android.view.LayoutInflater;
26import android.view.Menu;
27import android.view.View;
28import android.view.ViewGroup;
29import android.widget.BaseAdapter;
30import android.widget.TextView;
31
32import com.android.gallery3d.R;
33import com.android.gallery3d.actionbar.ActionBarInterface;
34import com.android.gallery3d.actionbar.ActionBarInterface.OnMenuVisibilityListener;
35import com.android.gallery3d.actionbar.ActionBarUtils;
36import com.android.gallery3d.actionbar.MenuHolder;
37import com.android.gallery3d.common.ApiHelper;
38
39import java.util.ArrayList;
40
41public class GalleryActionBar implements ActionBarInterface.OnNavigationListener, MenuHolder {
42    @SuppressWarnings("unused")
43    private static final String TAG = "GalleryActionBar";
44
45    private ClusterRunner mClusterRunner;
46    private CharSequence[] mTitles;
47    private ArrayList<Integer> mActions;
48    private Context mContext;
49    private LayoutInflater mInflater;
50    private GalleryActivity mActivity;
51    private ActionBarInterface mActionBar;
52    private int mCurrentIndex;
53    private ClusterAdapter mAdapter = new ClusterAdapter();
54
55    public interface ClusterRunner {
56        public void doCluster(int id);
57    }
58
59    private static class ActionItem {
60        public int action;
61        public boolean enabled;
62        public boolean visible;
63        public int spinnerTitle;
64        public int dialogTitle;
65        public int clusterBy;
66
67        public ActionItem(int action, boolean applied, boolean enabled, int title,
68                int clusterBy) {
69            this(action, applied, enabled, title, title, clusterBy);
70        }
71
72        public ActionItem(int action, boolean applied, boolean enabled, int spinnerTitle,
73                int dialogTitle, int clusterBy) {
74            this.action = action;
75            this.enabled = enabled;
76            this.spinnerTitle = spinnerTitle;
77            this.dialogTitle = dialogTitle;
78            this.clusterBy = clusterBy;
79            this.visible = true;
80        }
81    }
82
83    private static final ActionItem[] sClusterItems = new ActionItem[] {
84        new ActionItem(FilterUtils.CLUSTER_BY_ALBUM, true, false, R.string.albums,
85                R.string.group_by_album),
86        new ActionItem(FilterUtils.CLUSTER_BY_LOCATION, true, false,
87                R.string.locations, R.string.location, R.string.group_by_location),
88        new ActionItem(FilterUtils.CLUSTER_BY_TIME, true, false, R.string.times,
89                R.string.time, R.string.group_by_time),
90        new ActionItem(FilterUtils.CLUSTER_BY_FACE, true, false, R.string.people,
91                R.string.group_by_faces),
92        new ActionItem(FilterUtils.CLUSTER_BY_TAG, true, false, R.string.tags,
93                R.string.group_by_tags)
94    };
95
96    private class ClusterAdapter extends BaseAdapter {
97
98        @Override
99        public int getCount() {
100            return sClusterItems.length;
101        }
102
103        @Override
104        public Object getItem(int position) {
105            return sClusterItems[position];
106        }
107
108        @Override
109        public long getItemId(int position) {
110            return sClusterItems[position].action;
111        }
112
113        @Override
114        public View getView(int position, View convertView, ViewGroup parent) {
115            if (convertView == null) {
116                convertView = mInflater.inflate(R.layout.action_bar_text,
117                        parent, false);
118            }
119            TextView view = (TextView) convertView;
120            view.setText(sClusterItems[position].spinnerTitle);
121            return convertView;
122        }
123    }
124
125    public static String getClusterByTypeString(Context context, int type) {
126        for (ActionItem item : sClusterItems) {
127            if (item.action == type) {
128                return context.getString(item.clusterBy);
129            }
130        }
131        return null;
132    }
133
134    public GalleryActionBar(GalleryActivity activity) {
135        mActionBar = ActionBarUtils.getActionBar((Activity) activity);
136        mContext = activity.getAndroidContext();
137        mActivity = activity;
138        mInflater = ((Activity) mActivity).getLayoutInflater();
139        mCurrentIndex = 0;
140    }
141
142    private void createDialogData() {
143        ArrayList<CharSequence> titles = new ArrayList<CharSequence>();
144        mActions = new ArrayList<Integer>();
145        for (ActionItem item : sClusterItems) {
146            if (item.enabled && item.visible) {
147                titles.add(mContext.getString(item.dialogTitle));
148                mActions.add(item.action);
149            }
150        }
151        mTitles = new CharSequence[titles.size()];
152        titles.toArray(mTitles);
153    }
154
155    public int getHeight() {
156        return mActionBar != null ? mActionBar.getHeight() : 0;
157    }
158
159    public void setClusterItemEnabled(int id, boolean enabled) {
160        for (ActionItem item : sClusterItems) {
161            if (item.action == id) {
162                item.enabled = enabled;
163                return;
164            }
165        }
166    }
167
168    public void setClusterItemVisibility(int id, boolean visible) {
169        for (ActionItem item : sClusterItems) {
170            if (item.action == id) {
171                item.visible = visible;
172                return;
173            }
174        }
175    }
176
177    public int getClusterTypeAction() {
178        return sClusterItems[mCurrentIndex].action;
179    }
180
181    public void enableClusterMenu(int action, ClusterRunner runner) {
182        if (mActionBar != null) {
183            // Don't set cluster runner until action bar is ready.
184            mClusterRunner = null;
185            mActionBar.setListNavigationCallbacks(mAdapter, this);
186            mActionBar.setNavigationMode(ActionBarInterface.NAVIGATION_MODE_LIST);
187            setSelectedAction(action);
188            mClusterRunner = runner;
189        }
190    }
191
192    // The only use case not to hideMenu in this method is to ensure
193    // all elements disappear at the same time when exiting gallery.
194    // hideMenu should always be true in all other cases.
195    public void disableClusterMenu(boolean hideMenu) {
196        if (mActionBar != null) {
197            mClusterRunner = null;
198            if (hideMenu) {
199                mActionBar.setNavigationMode(ActionBarInterface.NAVIGATION_MODE_STANDARD);
200            }
201        }
202    }
203
204    public void showClusterDialog(final ClusterRunner clusterRunner) {
205        createDialogData();
206        final ArrayList<Integer> actions = mActions;
207        new AlertDialog.Builder(mContext).setTitle(R.string.group_by).setItems(
208                mTitles, new DialogInterface.OnClickListener() {
209            @Override
210            public void onClick(DialogInterface dialog, int which) {
211                // Need to lock rendering when operations invoked by system UI (main thread) are
212                // modifying slot data used in GL thread for rendering.
213                mActivity.getGLRoot().lockRenderThread();
214                try {
215                    clusterRunner.doCluster(actions.get(which).intValue());
216                } finally {
217                    mActivity.getGLRoot().unlockRenderThread();
218                }
219            }
220        }).create().show();
221    }
222
223    @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
224    private void setHomeButtonEnabled(boolean enabled) {
225        if (ApiHelper.HAS_ACTION_BAR_SET_HOME_BUTTON_ENABLED) {
226            mActionBar.setHomeButtonEnabled(enabled);
227        }
228    }
229
230    public void setDisplayOptions(boolean displayHomeAsUp, boolean showTitle) {
231        if (mActionBar == null) return;
232        int options = 0;
233        if (displayHomeAsUp) options |= ActionBarInterface.DISPLAY_HOME_AS_UP;
234        if (showTitle) options |= ActionBarInterface.DISPLAY_SHOW_TITLE;
235
236        mActionBar.setDisplayOptions(options,
237                ActionBarInterface.DISPLAY_HOME_AS_UP | ActionBarInterface.DISPLAY_SHOW_TITLE);
238        mActionBar.setHomeButtonEnabled(displayHomeAsUp);
239    }
240
241    public void setTitle(String title) {
242        if (mActionBar != null) mActionBar.setTitle(title);
243    }
244
245    public void setTitle(int titleId) {
246        if (mActionBar != null) {
247            mActionBar.setTitle(mContext.getString(titleId));
248        }
249    }
250
251    public void setSubtitle(String title) {
252        if (mActionBar != null) mActionBar.setSubtitle(title);
253    }
254
255    public void show() {
256        if (mActionBar != null) mActionBar.show();
257    }
258
259    public void hide() {
260        if (mActionBar != null) mActionBar.hide();
261    }
262
263    public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
264        if (mActionBar != null) mActionBar.addOnMenuVisibilityListener(listener);
265    }
266
267    public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
268        if (mActionBar != null) mActionBar.removeOnMenuVisibilityListener(listener);
269    }
270
271    public boolean setSelectedAction(int type) {
272        if (mActionBar == null) return false;
273
274        for (int i = 0, n = sClusterItems.length; i < n; i++) {
275            ActionItem item = sClusterItems[i];
276            if (item.action == type) {
277                mActionBar.setSelectedNavigationItem(i);
278                mCurrentIndex = i;
279                return true;
280            }
281        }
282        return false;
283    }
284
285    @Override
286    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
287        if (itemPosition != mCurrentIndex && mClusterRunner != null) {
288            // Need to lock rendering when operations invoked by system UI (main thread) are
289            // modifying slot data used in GL thread for rendering.
290            mActivity.getGLRoot().lockRenderThread();
291            try {
292                mClusterRunner.doCluster(sClusterItems[itemPosition].action);
293            } finally {
294                mActivity.getGLRoot().unlockRenderThread();
295            }
296        }
297        return false;
298    }
299
300    public boolean hasShareMenuItem() {
301        return mActionBar == null ? false : mActionBar.hasShareMenuItem();
302    }
303
304    public void setShareIntent(Intent intent) {
305        mActionBar.setShareIntent(intent);
306    }
307
308    public boolean createActionMenu(Menu menu, int menuRes) {
309        return mActionBar.createActionMenu(menu, menuRes);
310    }
311
312    @Override
313    public void setMenuItemVisible(int menuItemId, boolean visible) {
314        mActionBar.setMenuItemVisible(menuItemId, visible);
315    }
316
317    @Override
318    public void setMenuItemTitle(int menuItemId, String title) {
319        mActionBar.setMenuItemTitle(menuItemId, title);
320    }
321
322    public void setMenuItemIntent(int menuItemId, Intent intent) {
323        mActionBar.setMenuItemIntent(menuItemId, intent);
324    }
325}
326