Home | History | Annotate | Download | only in ui
      1 /**
      2  * Copyright (C) 2014 Google Inc.
      3  * Licensed to The Android Open Source Project.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 package com.android.mail.ui;
     18 
     19 import android.content.Context;
     20 import android.support.annotation.LayoutRes;
     21 import android.util.AttributeSet;
     22 import android.view.LayoutInflater;
     23 import android.view.View;
     24 import android.widget.ImageView;
     25 import android.widget.LinearLayout;
     26 
     27 import com.android.mail.R;
     28 import com.android.mail.bitmap.AccountAvatarDrawable;
     29 import com.android.mail.content.ObjectCursor;
     30 import com.android.mail.providers.Account;
     31 import com.android.mail.providers.Folder;
     32 import com.google.common.collect.Lists;
     33 
     34 import java.util.List;
     35 
     36 /**
     37  * A smaller version of the account- and folder-switching drawer view for tablet UIs.
     38  */
     39 public class MiniDrawerView extends LinearLayout {
     40 
     41     private FolderListFragment mController;
     42     private final int mDrawWidth;
     43     // use the same dimen as AccountItemView to participate in recycling
     44     // TODO: but Material account switcher doesn't recycle...
     45     private final int mAvatarDecodeSize;
     46 
     47     private View mDotdotdot;
     48     private View mSpacer;
     49 
     50     private AccountItem mCurrentAccount;
     51     private final List<AccountItem> mRecentAccounts = Lists.newArrayList();
     52 
     53     private final LayoutInflater mInflater;
     54 
     55     private static final int NUM_RECENT_ACCOUNTS = 2;
     56 
     57     public MiniDrawerView(Context context) {
     58         this(context, null);
     59     }
     60 
     61     public MiniDrawerView(Context context, AttributeSet attrs) {
     62         super(context, attrs);
     63 
     64         mDrawWidth = getResources().getDimensionPixelSize(R.dimen.two_pane_drawer_width_mini);
     65         mAvatarDecodeSize = getResources().getDimensionPixelSize(R.dimen.account_avatar_dimension);
     66 
     67         mInflater = LayoutInflater.from(context);
     68     }
     69 
     70     @Override
     71     protected void onFinishInflate() {
     72         super.onFinishInflate();
     73 
     74         mCurrentAccount = new AccountItem((ImageView) findViewById(R.id.current_account_avatar));
     75         mSpacer = findViewById(R.id.spacer);
     76         mDotdotdot = findViewById(R.id.dotdotdot);
     77         mDotdotdot.setOnClickListener(new View.OnClickListener() {
     78             @Override
     79             public void onClick(View v) {
     80                 mController.toggleDrawerState();
     81             }
     82         });
     83     }
     84 
     85     public void setController(FolderListFragment flf) {
     86         mController = flf;
     87 
     88         if (!mController.isMiniDrawerEnabled()) {
     89             return;
     90         }
     91 
     92         // wait for the controller to set these up
     93         mCurrentAccount.setupDrawable();
     94     }
     95 
     96     public void refresh() {
     97         if (mController == null) {
     98             return;
     99         }
    100 
    101         final Account currentAccount = mController.getCurrentAccount();
    102         if (currentAccount != null) {
    103             mCurrentAccount.setAccount(currentAccount);
    104         }
    105 
    106         View child;
    107 
    108         // TODO: figure out the N most recent accounts, don't just take the first few
    109         final int removePos = indexOfChild(mSpacer) + 1;
    110         if (getChildCount() > removePos) {
    111             removeViews(removePos, getChildCount() - removePos);
    112         }
    113         final Account[] accounts = mController.getAllAccounts();
    114         int count = 0;
    115         for (Account a : accounts) {
    116             if (count >= NUM_RECENT_ACCOUNTS) {
    117                 break;
    118             }
    119             if (currentAccount.uri.equals(a.uri)) {
    120                 continue;
    121             }
    122             final ImageView iv = (ImageView) mInflater.inflate(
    123                     R.layout.mini_drawer_recent_account_item, this, false /* attachToRoot */);
    124             final AccountItem item = new AccountItem(iv);
    125             item.setupDrawable();
    126             item.setAccount(a);
    127             iv.setTag(item);
    128             addView(iv);
    129             count++;
    130         }
    131 
    132         // reset the inbox views for this account
    133         while ((child=getChildAt(1)) != mDotdotdot) {
    134             removeView(child);
    135         }
    136         final ObjectCursor<Folder> folderCursor = mController.getFoldersCursor();
    137         if (folderCursor != null && !folderCursor.isClosed()) {
    138             int pos = -1;
    139             int numInboxes = 0;
    140             while (folderCursor.moveToPosition(++pos)) {
    141                 final Folder f = folderCursor.getModel();
    142                 if (f.isInbox()) {
    143                     final ImageView iv = (ImageView) mInflater.inflate(
    144                             R.layout.mini_drawer_folder_item, this, false /* attachToRoot */);
    145                     iv.setTag(new FolderItem(f, iv));
    146                     addView(iv, 1 + numInboxes);
    147                     numInboxes++;
    148                 }
    149             }
    150         }
    151     }
    152 
    153     private class FolderItem implements View.OnClickListener {
    154         public final Folder folder;
    155         public final ImageView view;
    156 
    157         public FolderItem(Folder f, ImageView iv) {
    158             folder = f;
    159             view = iv;
    160             Folder.setIcon(folder, view);
    161             view.setOnClickListener(this);
    162         }
    163 
    164         @Override
    165         public void onClick(View v) {
    166             mController.onFolderSelected(folder, "mini-drawer");
    167         }
    168     }
    169 
    170     private class AccountItem implements View.OnClickListener {
    171         private Account mAccount;
    172         // FIXME: this codepath doesn't use GMS Core, resulting in inconsistent avatars
    173         // vs. ownerslib. switch to a generic photo getter+listener interface on FLF
    174         // so these drawables are obtainable regardless of how they are loaded.
    175         private AccountAvatarDrawable mDrawable;
    176         public final ImageView view;
    177 
    178         public AccountItem(ImageView iv) {
    179             view = iv;
    180             view.setOnClickListener(this);
    181         }
    182 
    183         public void setupDrawable() {
    184             mDrawable = new AccountAvatarDrawable(getResources(),
    185                     mController.getBitmapCache(), mController.getContactResolver());
    186             mDrawable.setDecodeDimensions(mAvatarDecodeSize, mAvatarDecodeSize);
    187             view.setImageDrawable(mDrawable);
    188         }
    189 
    190         public void setAccount(Account acct) {
    191             mAccount = acct;
    192             mDrawable.bind(mAccount.getSenderName(), mAccount.getEmailAddress());
    193         }
    194 
    195         @Override
    196         public void onClick(View v) {
    197             mController.onAccountSelected(mAccount);
    198         }
    199 
    200     }
    201 
    202 }
    203