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