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
18package com.android.mail.ui;
19
20import android.animation.Animator;
21import android.animation.AnimatorListenerAdapter;
22import android.content.Context;
23import android.support.v7.widget.Toolbar;
24import android.util.AttributeSet;
25import android.view.View;
26import android.view.ViewGroup;
27import android.widget.TextView;
28
29import com.android.mail.R;
30import com.android.mail.analytics.Analytics;
31import com.android.mail.providers.Account;
32import com.android.mail.providers.AccountObserver;
33import com.android.mail.utils.ViewUtils;
34
35/**
36 * Custom toolbar that supports a custom view so we can display our search icon wherever we want.
37 */
38public class CustomViewToolbar extends Toolbar implements ViewMode.ModeChangeListener,
39        TwoPaneLayout.ConversationListLayoutListener {
40    private static final long FADE_ANIMATION_DURATION_MS = 150;
41
42    private ControllableActivity mActivity;
43    private ActivityController mController;
44    private ViewMode mViewMode;
45    private AccountObserver mAccountObserver = new AccountObserver() {
46        @Override
47        public void onChanged(Account newAccount) {
48            setSearchButtonVisibility(newAccount);
49        }
50    };
51
52    protected View mCustomView;
53    protected TextView mActionBarTitle;
54    protected View mSearchButton;
55
56    public CustomViewToolbar(Context context) {
57        super(context);
58    }
59
60    public CustomViewToolbar(Context context, AttributeSet attrs) {
61        super(context, attrs);
62    }
63
64    public void setController(ControllableActivity activity, ActivityController controller,
65            ViewMode viewMode) {
66        mActivity = activity;
67        mController = controller;
68        mViewMode = viewMode;
69        mViewMode.addListener(this);
70
71        mAccountObserver.initialize(mActivity.getAccountController());
72    }
73
74    @Override
75    protected void onFinishInflate() {
76        super.onFinishInflate();
77
78        mCustomView = findViewById(R.id.actionbar_custom_view);
79        mActionBarTitle = (TextView) findViewById(R.id.actionbar_title);
80        mSearchButton = findViewById(R.id.actionbar_search_button);
81
82        mSearchButton.setOnClickListener(new View.OnClickListener() {
83            @Override
84            public void onClick(View view) {
85                // Since search is no longer a menu item, log the search "menu" event here.
86                Analytics.getInstance().sendEvent(Analytics.EVENT_CATEGORY_MENU_ITEM,
87                        "search", "action_bar/" + mViewMode.getModeString(), 0);
88                mController.startSearch();
89            }
90        });
91    }
92
93    protected void onDestroy() {
94        mAccountObserver.unregisterAndDestroy();
95    }
96
97    /**
98     * Sets the search button visibility based on the current account.
99     */
100    private void setSearchButtonVisibility() {
101        setSearchButtonVisibility(mActivity.getAccountController().getAccount());
102    }
103
104    private void setSearchButtonVisibility(Account account) {
105        if (mSearchButton != null) {
106            final boolean visible = mController.shouldShowSearchMenuItem() &&
107                    account.supportsSearch();
108            mSearchButton.setVisibility(visible ? VISIBLE : INVISIBLE);
109        }
110    }
111
112    @Override
113    public void onViewModeChanged(int newMode) {
114        setSearchButtonVisibility();
115    }
116
117    @Override
118    public void onConversationListLayout(int xEnd, boolean drawerOpen) {
119        if (drawerOpen) {
120            mSearchButton.animate()
121                    .alpha(0f)
122                    .setDuration(FADE_ANIMATION_DURATION_MS)
123                    .setListener(new AnimatorListenerAdapter() {
124                        @Override
125                        public void onAnimationEnd(Animator animation) {
126                            mSearchButton.setVisibility(INVISIBLE);
127                        }
128                    });
129        } else {
130            setSearchButtonVisibility();
131            // setListener(null) is necessary because the animator carries the previously set
132            // listener over, aka the listener for fade out.
133            if (mSearchButton.isShown()) {
134                mSearchButton.animate()
135                        .alpha(1f)
136                        .setDuration(FADE_ANIMATION_DURATION_MS)
137                        .setListener(null);
138            }
139
140            final int[] coords = new int[2];
141            mCustomView.getLocationInWindow(coords);
142            final int newWidth;
143            if (ViewUtils.isViewRtl(this)) {
144                newWidth = coords[0] + mCustomView.getWidth() - xEnd;
145            } else {
146                newWidth = xEnd - coords[0];
147            }
148
149            // Only set the width if it's different than before so we avoid draw on layout pass.
150            if (mCustomView.getWidth() != newWidth) {
151                final ViewGroup.LayoutParams params = mCustomView.getLayoutParams();
152                params.width = newWidth;
153                mCustomView.setLayoutParams(params);
154            }
155        }
156    }
157
158    // OVERRIDE DEFAULT TOOLBAR TITLE FUNCTIONS SO THEY ARE RENDERED CORRECTLY.
159    // TODO: subtitles? we currently don't have any of those, but we will need to support them.
160
161    @Override
162    public void setTitle(int resId) {
163        setTitle(getResources().getString(resId));
164    }
165
166    @Override
167    public void setTitle(CharSequence title) {
168        mActionBarTitle.setText(title);
169    }
170
171    @Override
172    public void setTitleTextAppearance(Context context, int resId) {
173        mActionBarTitle.setTextAppearance(context, resId);
174    }
175
176    @Override
177    public void setTitleTextColor(int color) {
178        mActionBarTitle.setTextColor(color);
179    }
180}
181