Home | History | Annotate | Download | only in app
      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 {
     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 
     63         public ActionItem(int action, boolean applied, boolean enabled, int title,
     64                 int clusterBy) {
     65             this(action, applied, enabled, title, title, clusterBy);
     66         }
     67 
     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 
     94         public int getCount() {
     95             return sClusterItems.length;
     96         }
     97 
     98         public Object getItem(int position) {
     99             return sClusterItems[position];
    100         }
    101 
    102         public long getItemId(int position) {
    103             return sClusterItems[position].action;
    104         }
    105 
    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 
    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 
    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 
    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 
    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 
    156     public int getHeight() {
    157         return mActionBar != null ? mActionBar.getHeight() : 0;
    158     }
    159 
    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 
    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 
    178     public int getClusterTypeAction() {
    179         return sClusterItems[mCurrentIndex].action;
    180     }
    181 
    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.
    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 
    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 
    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 
    233     public void setTitle(String title) {
    234         if (mActionBar != null) mActionBar.setTitle(title);
    235     }
    236 
    237     public void setTitle(int titleId) {
    238         if (mActionBar != null) mActionBar.setTitle(titleId);
    239     }
    240 
    241     public void setSubtitle(String title) {
    242         if (mActionBar != null) mActionBar.setSubtitle(title);
    243     }
    244 
    245     public void show() {
    246         if (mActionBar != null) mActionBar.show();
    247     }
    248 
    249     public void hide() {
    250         if (mActionBar != null) mActionBar.hide();
    251     }
    252 
    253     public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
    254         if (mActionBar != null) mActionBar.addOnMenuVisibilityListener(listener);
    255     }
    256 
    257     public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
    258         if (mActionBar != null) mActionBar.removeOnMenuVisibilityListener(listener);
    259     }
    260 
    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
    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