1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.browser;
17
18import android.animation.Animator;
19import android.animation.AnimatorListenerAdapter;
20import android.animation.AnimatorSet;
21import android.animation.ObjectAnimator;
22import android.content.Context;
23import android.content.Intent;
24import android.content.res.Configuration;
25import android.content.res.Resources;
26import android.graphics.Bitmap;
27import android.graphics.drawable.Drawable;
28import android.text.TextUtils;
29import android.util.AttributeSet;
30import android.view.View;
31import android.widget.ImageButton;
32import android.widget.ImageView;
33
34import com.android.browser.UI.ComboViews;
35import com.android.browser.UrlInputView.StateListener;
36
37public class NavigationBarTablet extends NavigationBarBase implements StateListener {
38
39    private Drawable mStopDrawable;
40    private Drawable mReloadDrawable;
41    private String mStopDescription;
42    private String mRefreshDescription;
43
44    private View mUrlContainer;
45    private ImageButton mBackButton;
46    private ImageButton mForwardButton;
47    private ImageView mStar;
48    private ImageView mUrlIcon;
49    private ImageView mSearchButton;
50    private ImageView mStopButton;
51    private View mAllButton;
52    private View mClearButton;
53    private View mVoiceButton;
54    private View mNavButtons;
55    private Drawable mFocusDrawable;
56    private Drawable mUnfocusDrawable;
57    private boolean mHideNavButtons;
58    private Drawable mFaviconDrawable;
59
60    public NavigationBarTablet(Context context) {
61        super(context);
62        init(context);
63    }
64
65    public NavigationBarTablet(Context context, AttributeSet attrs) {
66        super(context, attrs);
67        init(context);
68    }
69
70    public NavigationBarTablet(Context context, AttributeSet attrs, int defStyle) {
71        super(context, attrs, defStyle);
72        init(context);
73    }
74
75    private void init(Context context) {
76        Resources resources = context.getResources();
77        mStopDrawable = resources.getDrawable(R.drawable.ic_stop_holo_dark);
78        mReloadDrawable = resources.getDrawable(R.drawable.ic_refresh_holo_dark);
79        mStopDescription = resources.getString(R.string.accessibility_button_stop);
80        mRefreshDescription = resources.getString(R.string.accessibility_button_refresh);
81        mFocusDrawable = resources.getDrawable(
82                R.drawable.textfield_active_holo_dark);
83        mUnfocusDrawable = resources.getDrawable(
84                R.drawable.textfield_default_holo_dark);
85        mHideNavButtons = resources.getBoolean(R.bool.hide_nav_buttons);
86    }
87
88    @Override
89    protected void onFinishInflate() {
90        super.onFinishInflate();
91        mAllButton = findViewById(R.id.all_btn);
92        // TODO: Change enabled states based on whether you can go
93        // back/forward.  Probably should be done inside onPageStarted.
94        mNavButtons = findViewById(R.id.navbuttons);
95        mBackButton = (ImageButton) findViewById(R.id.back);
96        mForwardButton = (ImageButton) findViewById(R.id.forward);
97        mUrlIcon = (ImageView) findViewById(R.id.url_icon);
98        mStar = (ImageView) findViewById(R.id.star);
99        mStopButton = (ImageView) findViewById(R.id.stop);
100        mSearchButton = (ImageView) findViewById(R.id.search);
101        mClearButton = findViewById(R.id.clear);
102        mVoiceButton = findViewById(R.id.voice);
103        mUrlContainer = findViewById(R.id.urlbar_focused);
104        mBackButton.setOnClickListener(this);
105        mForwardButton.setOnClickListener(this);
106        mStar.setOnClickListener(this);
107        mAllButton.setOnClickListener(this);
108        mStopButton.setOnClickListener(this);
109        mSearchButton.setOnClickListener(this);
110        mClearButton.setOnClickListener(this);
111        mVoiceButton.setOnClickListener(this);
112        mUrlInput.setContainer(mUrlContainer);
113        mUrlInput.setStateListener(this);
114    }
115
116    public void onConfigurationChanged(Configuration config) {
117        super.onConfigurationChanged(config);
118        Resources res = mContext.getResources();
119        mHideNavButtons = res.getBoolean(R.bool.hide_nav_buttons);
120        if (mUrlInput.hasFocus()) {
121            if (mHideNavButtons && (mNavButtons.getVisibility() == View.VISIBLE)) {
122                int aw = mNavButtons.getMeasuredWidth();
123                mNavButtons.setVisibility(View.GONE);
124                mNavButtons.setAlpha(0f);
125                mNavButtons.setTranslationX(-aw);
126            } else if (!mHideNavButtons && (mNavButtons.getVisibility() == View.GONE)) {
127                mNavButtons.setVisibility(View.VISIBLE);
128                mNavButtons.setAlpha(1f);
129                mNavButtons.setTranslationX(0);
130            }
131        }
132    }
133
134    @Override
135    public void setTitleBar(TitleBar titleBar) {
136        super.setTitleBar(titleBar);
137        setFocusState(false);
138    }
139
140    void updateNavigationState(Tab tab) {
141        if (tab != null) {
142            mBackButton.setImageResource(tab.canGoBack()
143                    ? R.drawable.ic_back_holo_dark
144                    : R.drawable.ic_back_disabled_holo_dark);
145            mForwardButton.setImageResource(tab.canGoForward()
146                    ? R.drawable.ic_forward_holo_dark
147                    : R.drawable.ic_forward_disabled_holo_dark);
148        }
149        updateUrlIcon();
150    }
151
152    @Override
153    public void onTabDataChanged(Tab tab) {
154        super.onTabDataChanged(tab);
155        showHideStar(tab);
156    }
157
158    @Override
159    public void setCurrentUrlIsBookmark(boolean isBookmark) {
160        mStar.setActivated(isBookmark);
161    }
162
163    @Override
164    public void onClick(View v) {
165        if ((mBackButton == v) && (mUiController.getCurrentTab() != null)) {
166            mUiController.getCurrentTab().goBack();
167        } else if ((mForwardButton == v)  && (mUiController.getCurrentTab() != null)) {
168            mUiController.getCurrentTab().goForward();
169        } else if (mStar == v) {
170            Intent intent = mUiController.createBookmarkCurrentPageIntent(true);
171            if (intent != null) {
172                getContext().startActivity(intent);
173            }
174        } else if (mAllButton == v) {
175            mUiController.bookmarksOrHistoryPicker(ComboViews.Bookmarks);
176        } else if (mSearchButton == v) {
177            mBaseUi.editUrl(true, true);
178        } else if (mStopButton == v) {
179            stopOrRefresh();
180        } else if (mClearButton == v) {
181            clearOrClose();
182        } else if (mVoiceButton == v) {
183            mUiController.startVoiceRecognizer();
184        } else {
185            super.onClick(v);
186        }
187    }
188
189    private void clearOrClose() {
190        if (TextUtils.isEmpty(mUrlInput.getText())) {
191            // close
192            mUrlInput.clearFocus();
193        } else {
194            // clear
195            mUrlInput.setText("");
196        }
197    }
198
199    @Override
200    public void setFavicon(Bitmap icon) {
201        mFaviconDrawable = mBaseUi.getFaviconDrawable(icon);
202        updateUrlIcon();
203    }
204
205    void updateUrlIcon() {
206        if (mUrlInput.hasFocus()) {
207            mUrlIcon.setImageResource(R.drawable.ic_search_holo_dark);
208        } else {
209            if (mFaviconDrawable == null) {
210                mFaviconDrawable = mBaseUi.getFaviconDrawable(null);
211            }
212            mUrlIcon.setImageDrawable(mFaviconDrawable);
213        }
214    }
215
216    @Override
217    protected void setFocusState(boolean focus) {
218        super.setFocusState(focus);
219        if (focus) {
220            if (mHideNavButtons) {
221                hideNavButtons();
222            }
223            mSearchButton.setVisibility(View.GONE);
224            mStar.setVisibility(View.GONE);
225            mUrlIcon.setImageResource(R.drawable.ic_search_holo_dark);
226        } else {
227            if (mHideNavButtons) {
228                showNavButtons();
229            }
230            showHideStar(mUiController.getCurrentTab());
231            if (mTitleBar.useQuickControls()) {
232                mSearchButton.setVisibility(View.GONE);
233            } else {
234                mSearchButton.setVisibility(View.VISIBLE);
235            }
236            updateUrlIcon();
237        }
238        mUrlContainer.setBackgroundDrawable(focus
239                ? mFocusDrawable : mUnfocusDrawable);
240    }
241
242    private void stopOrRefresh() {
243        if (mUiController == null) return;
244        if (mTitleBar.isInLoad()) {
245            mUiController.stopLoading();
246        } else {
247            if (mUiController.getCurrentTopWebView() != null) {
248                mUiController.getCurrentTopWebView().reload();
249            }
250        }
251    }
252
253    @Override
254    public void onProgressStarted() {
255        mStopButton.setImageDrawable(mStopDrawable);
256        mStopButton.setContentDescription(mStopDescription);
257    }
258
259    @Override
260    public void onProgressStopped() {
261        mStopButton.setImageDrawable(mReloadDrawable);
262        mStopButton.setContentDescription(mRefreshDescription);
263    }
264
265    private AnimatorSet mAnimation;
266
267    private void hideNavButtons() {
268        if (mBaseUi.blockFocusAnimations()) {
269            mNavButtons.setVisibility(View.GONE);
270            return;
271        }
272        int awidth = mNavButtons.getMeasuredWidth();
273        Animator anim1 = ObjectAnimator.ofFloat(mNavButtons, View.TRANSLATION_X, 0, - awidth);
274        Animator anim2 = ObjectAnimator.ofInt(mUrlContainer, "left", mUrlContainer.getLeft(),
275                mUrlContainer.getPaddingLeft());
276        Animator anim3 = ObjectAnimator.ofFloat(mNavButtons, View.ALPHA, 1f, 0f);
277        mAnimation = new AnimatorSet();
278        mAnimation.playTogether(anim1, anim2, anim3);
279        mAnimation.addListener(new AnimatorListenerAdapter() {
280            @Override
281            public void onAnimationEnd(Animator animation) {
282                mNavButtons.setVisibility(View.GONE);
283                mAnimation = null;
284            }
285        });
286        mAnimation.setDuration(150);
287        mAnimation.start();
288    }
289
290    private void showNavButtons() {
291        if (mAnimation != null) {
292            mAnimation.cancel();
293        }
294        mNavButtons.setVisibility(View.VISIBLE);
295        mNavButtons.setTranslationX(0);
296        if (!mBaseUi.blockFocusAnimations()) {
297            int awidth = mNavButtons.getMeasuredWidth();
298            Animator anim1 = ObjectAnimator.ofFloat(mNavButtons,
299                    View.TRANSLATION_X, -awidth, 0);
300            Animator anim2 = ObjectAnimator.ofInt(mUrlContainer, "left", 0,
301                    awidth);
302            Animator anim3 = ObjectAnimator.ofFloat(mNavButtons, View.ALPHA,
303                    0f, 1f);
304            AnimatorSet combo = new AnimatorSet();
305            combo.playTogether(anim1, anim2, anim3);
306            combo.setDuration(150);
307            combo.start();
308        }
309    }
310
311    private void showHideStar(Tab tab) {
312        // hide the bookmark star for data URLs
313        if (tab != null && tab.inForeground()) {
314            int starVisibility = View.VISIBLE;
315            String url = tab.getUrl();
316            if (DataUri.isDataUri(url)) {
317                starVisibility = View.GONE;
318            }
319            mStar.setVisibility(starVisibility);
320        }
321    }
322
323    @Override
324    public void onStateChanged(int state) {
325        mVoiceButton.setVisibility(View.GONE);
326        switch(state) {
327        case STATE_NORMAL:
328            mClearButton.setVisibility(View.GONE);
329            break;
330        case STATE_HIGHLIGHTED:
331            mClearButton.setVisibility(View.GONE);
332            if ((mUiController != null) && mUiController.supportsVoice()) {
333                mVoiceButton.setVisibility(View.VISIBLE);
334            }
335            break;
336        case STATE_EDITED:
337            mClearButton.setVisibility(View.VISIBLE);
338            break;
339        }
340    }
341
342}
343