• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MiniDrawerView(Context context)57     public MiniDrawerView(Context context) {
58         this(context, null);
59     }
60 
MiniDrawerView(Context context, AttributeSet attrs)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
onFinishInflate()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 
setController(FolderListFragment flf)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 
refresh()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 
FolderItem(Folder f, ImageView iv)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
onClick(View v)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 
AccountItem(ImageView iv)178         public AccountItem(ImageView iv) {
179             view = iv;
180             view.setOnClickListener(this);
181         }
182 
setupDrawable()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 
setAccount(Account acct)190         public void setAccount(Account acct) {
191             mAccount = acct;
192             mDrawable.bind(mAccount.getSenderName(), mAccount.getEmailAddress());
193         }
194 
195         @Override
onClick(View v)196         public void onClick(View v) {
197             mController.onAccountSelected(mAccount);
198         }
199 
200     }
201 
202 }
203