1/* 2 * Copyright (C) 2012 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 18package com.android.mail.browse; 19 20import android.content.Context; 21import android.util.AttributeSet; 22import android.view.View; 23import android.view.View.OnClickListener; 24import android.view.ViewGroup; 25import android.widget.LinearLayout; 26 27import com.android.mail.R; 28import com.android.mail.browse.ConversationViewAdapter.ConversationHeaderItem; 29import com.android.mail.providers.Conversation; 30import com.android.mail.providers.UIProvider; 31import com.android.mail.ui.ConversationUpdater; 32import com.android.mail.utils.LogTag; 33import com.android.mail.utils.LogUtils; 34import com.android.mail.utils.Utils; 35 36/** 37 * A view for the subject and folders in the conversation view. This container 38 * makes an attempt to combine subject and folders on the same horizontal line if 39 * there is enough room to fit both without wrapping. If they overlap, it 40 * adjusts the layout to position the folders below the subject. 41 */ 42public class ConversationViewHeader extends LinearLayout implements OnClickListener { 43 44 public interface ConversationViewHeaderCallbacks { 45 /** 46 * Called in response to a click on the folders region. 47 */ 48 void onFoldersClicked(); 49 50 /** 51 * Called when the height of the {@link ConversationViewHeader} changes. 52 * 53 * @param newHeight the new height in px 54 */ 55 void onConversationViewHeaderHeightChange(int newHeight); 56 } 57 58 private static final String LOG_TAG = LogTag.getLogTag(); 59 private SubjectAndFolderView mSubjectAndFolderView; 60 private StarView mStarView; 61 private ConversationViewHeaderCallbacks mCallbacks; 62 private ConversationAccountController mAccountController; 63 private ConversationUpdater mConversationUpdater; 64 private ConversationHeaderItem mHeaderItem; 65 private Conversation mConversation; 66 67 /** 68 * Instantiated from this layout: conversation_view_header.xml 69 * @param context 70 */ 71 public ConversationViewHeader(Context context) { 72 this(context, null); 73 } 74 75 public ConversationViewHeader(Context context, AttributeSet attrs) { 76 super(context, attrs); 77 } 78 79 @Override 80 protected void onFinishInflate() { 81 super.onFinishInflate(); 82 83 mSubjectAndFolderView = 84 (SubjectAndFolderView) findViewById(R.id.subject_and_folder_view); 85 mStarView = (StarView) findViewById(R.id.conversation_header_star); 86 mStarView.setOnClickListener(this); 87 } 88 89 public void setCallbacks(ConversationViewHeaderCallbacks callbacks, 90 ConversationAccountController accountController, 91 ConversationUpdater conversationUpdater) { 92 mCallbacks = callbacks; 93 mAccountController = accountController; 94 mConversationUpdater = conversationUpdater; 95 } 96 97 public void setSubject(final String subject) { 98 mSubjectAndFolderView.setSubject(subject); 99 } 100 101 public void setFolders(Conversation conv) { 102 mSubjectAndFolderView.setFolders(mCallbacks, mAccountController.getAccount(), conv); 103 } 104 105 public void setStarred(boolean isStarred) { 106 mStarView.setStarred(isStarred); 107 mStarView.setVisibility(View.VISIBLE); 108 } 109 110 public void bind(ConversationHeaderItem headerItem) { 111 mHeaderItem = headerItem; 112 mConversation = mHeaderItem.mConversation; 113 if (mSubjectAndFolderView != null) { 114 mSubjectAndFolderView.bind(headerItem); 115 } 116 mStarView.setVisibility(mConversation != null ? View.VISIBLE : View.INVISIBLE); 117 } 118 119 private int measureHeight() { 120 ViewGroup parent = (ViewGroup) getParent(); 121 if (parent == null) { 122 LogUtils.e(LOG_TAG, "Unable to measure height of conversation header"); 123 return getHeight(); 124 } 125 final int h = Utils.measureViewHeight(this, parent); 126 return h; 127 } 128 129 /** 130 * Update the conversation view header to reflect the updated conversation. 131 */ 132 public void onConversationUpdated(Conversation conv) { 133 // The only things we have to worry about when the conversation changes 134 // in the conversation header are the folders, priority indicators, and starred state. 135 // Updating these will resize the space for the header. 136 mConversation = conv; 137 setSubject(conv.subject); 138 setFolders(conv); 139 setStarred(conv.starred); 140 if (mHeaderItem != null) { 141 final int h = measureHeight(); 142 if (mHeaderItem.setHeight(h)) { 143 mCallbacks.onConversationViewHeaderHeightChange(h); 144 } 145 } 146 } 147 148 @Override 149 public void onClick(View v) { 150 final int id = v.getId(); 151 if (mConversation != null && id == R.id.conversation_header_star) { 152 mConversation.starred = !mConversation.starred; 153 setStarred(mConversation.starred); 154 mConversationUpdater.updateConversation(Conversation.listOf(mConversation), 155 UIProvider.ConversationColumns.STARRED, mConversation.starred); 156 } 157 158 } 159} 160