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