Home | History | Annotate | Download | only in ui
      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.ui;
     18 
     19 import android.app.Activity;
     20 import android.app.AlertDialog;
     21 import android.app.Dialog;
     22 import android.content.Context;
     23 import android.content.DialogInterface;
     24 import android.content.DialogInterface.OnDismissListener;
     25 import android.text.format.Formatter;
     26 import android.view.LayoutInflater;
     27 import android.view.View;
     28 import android.view.ViewGroup;
     29 import android.widget.BaseAdapter;
     30 import android.widget.ListView;
     31 import android.widget.TextView;
     32 
     33 import com.android.gallery3d.R;
     34 import com.android.gallery3d.app.GalleryActivity;
     35 import com.android.gallery3d.common.Utils;
     36 import com.android.gallery3d.data.MediaDetails;
     37 import com.android.gallery3d.ui.DetailsAddressResolver.AddressResolvingListener;
     38 import com.android.gallery3d.ui.DetailsHelper.CloseListener;
     39 import com.android.gallery3d.ui.DetailsHelper.DetailsSource;
     40 import com.android.gallery3d.ui.DetailsHelper.DetailsViewContainer;
     41 
     42 import java.util.ArrayList;
     43 import java.util.Map.Entry;
     44 
     45 public class DialogDetailsView implements DetailsViewContainer {
     46     @SuppressWarnings("unused")
     47     private static final String TAG = "DialogDetailsView";
     48 
     49     private final GalleryActivity mContext;
     50     private DetailsAdapter mAdapter;
     51     private MediaDetails mDetails;
     52     private final DetailsSource mSource;
     53     private int mIndex;
     54     private Dialog mDialog;
     55     private CloseListener mListener;
     56 
     57     public DialogDetailsView(GalleryActivity activity, DetailsSource source) {
     58         mContext = activity;
     59         mSource = source;
     60     }
     61 
     62     public void show() {
     63         reloadDetails(mSource.getIndex());
     64         mDialog.show();
     65     }
     66 
     67     public void hide() {
     68         mDialog.hide();
     69     }
     70 
     71     public void reloadDetails(int indexHint) {
     72         int index = mSource.findIndex(indexHint);
     73         if (index == -1) return;
     74         MediaDetails details = mSource.getDetails();
     75         if (details != null) {
     76             if (mIndex == index && mDetails == details) return;
     77             mIndex = index;
     78             mDetails = details;
     79             setDetails(details);
     80         }
     81     }
     82 
     83     private void setDetails(MediaDetails details) {
     84         mAdapter = new DetailsAdapter(details);
     85         String title = String.format(
     86                 mContext.getAndroidContext().getString(R.string.details_title),
     87                 mIndex + 1, mSource.size());
     88         ListView detailsList = (ListView) LayoutInflater.from(mContext.getAndroidContext()).inflate(
     89                 R.layout.details_list, null, false);
     90         detailsList.setAdapter(mAdapter);
     91         mDialog = new AlertDialog.Builder((Activity) mContext)
     92             .setView(detailsList)
     93             .setTitle(title)
     94             .setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
     95                 public void onClick(DialogInterface dialog, int whichButton) {
     96                     mDialog.dismiss();
     97                 }
     98             })
     99             .create();
    100 
    101         mDialog.setOnDismissListener(new OnDismissListener() {
    102             public void onDismiss(DialogInterface dialog) {
    103                 if (mListener != null) {
    104                     mListener.onClose();
    105                 }
    106             }
    107         });
    108     }
    109 
    110     private class DetailsAdapter extends BaseAdapter implements AddressResolvingListener {
    111         private final ArrayList<String> mItems;
    112         private int mLocationIndex;
    113 
    114         public DetailsAdapter(MediaDetails details) {
    115             Context context = mContext.getAndroidContext();
    116             mItems = new ArrayList<String>(details.size());
    117             mLocationIndex = -1;
    118             setDetails(context, details);
    119         }
    120 
    121         private void setDetails(Context context, MediaDetails details) {
    122             for (Entry<Integer, Object> detail : details) {
    123                 String value;
    124                 switch (detail.getKey()) {
    125                     case MediaDetails.INDEX_LOCATION: {
    126                         double[] latlng = (double[]) detail.getValue();
    127                         mLocationIndex = mItems.size();
    128                         value = DetailsHelper.resolveAddress(mContext, latlng, this);
    129                         break;
    130                     }
    131                     case MediaDetails.INDEX_SIZE: {
    132                         value = Formatter.formatFileSize(
    133                                 context, (Long) detail.getValue());
    134                         break;
    135                     }
    136                     case MediaDetails.INDEX_WHITE_BALANCE: {
    137                         value = "1".equals(detail.getValue())
    138                                 ? context.getString(R.string.manual)
    139                                 : context.getString(R.string.auto);
    140                         break;
    141                     }
    142                     case MediaDetails.INDEX_FLASH: {
    143                         MediaDetails.FlashState flash =
    144                                 (MediaDetails.FlashState) detail.getValue();
    145                         // TODO: camera doesn't fill in the complete values, show more information
    146                         // when it is fixed.
    147                         if (flash.isFlashFired()) {
    148                             value = context.getString(R.string.flash_on);
    149                         } else {
    150                             value = context.getString(R.string.flash_off);
    151                         }
    152                         break;
    153                     }
    154                     case MediaDetails.INDEX_EXPOSURE_TIME: {
    155                         value = (String) detail.getValue();
    156                         double time = Double.valueOf(value);
    157                         if (time < 1.0f) {
    158                             value = String.format("1/%d", (int) (0.5f + 1 / time));
    159                         } else {
    160                             int integer = (int) time;
    161                             time -= integer;
    162                             value = String.valueOf(integer) + "''";
    163                             if (time > 0.0001) {
    164                                 value += String.format(" 1/%d", (int) (0.5f + 1 / time));
    165                             }
    166                         }
    167                         break;
    168                     }
    169                     default: {
    170                         Object valueObj = detail.getValue();
    171                         // This shouldn't happen, log its key to help us diagnose the problem.
    172                         if (valueObj == null) {
    173                             Utils.fail("%s's value is Null",
    174                                     DetailsHelper.getDetailsName(context, detail.getKey()));
    175                         }
    176                         value = valueObj.toString();
    177                     }
    178                 }
    179                 int key = detail.getKey();
    180                 if (details.hasUnit(key)) {
    181                     value = String.format("%s : %s %s", DetailsHelper.getDetailsName(
    182                             context, key), value, context.getString(details.getUnit(key)));
    183                 } else {
    184                     value = String.format("%s : %s", DetailsHelper.getDetailsName(
    185                             context, key), value);
    186                 }
    187                 mItems.add(value);
    188             }
    189         }
    190 
    191         @Override
    192         public boolean areAllItemsEnabled() {
    193             return false;
    194         }
    195 
    196         @Override
    197         public boolean isEnabled(int position) {
    198             return false;
    199         }
    200 
    201         public int getCount() {
    202             return mItems.size();
    203         }
    204 
    205         public Object getItem(int position) {
    206             return mDetails.getDetail(position);
    207         }
    208 
    209         public long getItemId(int position) {
    210             return position;
    211         }
    212 
    213         public View getView(int position, View convertView, ViewGroup parent) {
    214             TextView tv;
    215             if (convertView == null) {
    216                 tv = (TextView) LayoutInflater.from(mContext.getAndroidContext()).inflate(
    217                         R.layout.details, parent, false);
    218             } else {
    219                 tv = (TextView) convertView;
    220             }
    221             tv.setText(mItems.get(position));
    222             return tv;
    223         }
    224 
    225         public void onAddressAvailable(String address) {
    226             mItems.set(mLocationIndex, address);
    227             notifyDataSetChanged();
    228         }
    229     }
    230 
    231     public void setCloseListener(CloseListener listener) {
    232         mListener = listener;
    233     }
    234 }
    235