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