TabBar.java revision c831b63308dd1f8ef71808db8344ca2566ba4ed4
1a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb/*
2a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * Copyright (C) 2010 The Android Open Source Project
3a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb *
4a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
5a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * you may not use this file except in compliance with the License.
6a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * You may obtain a copy of the License at
7a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb *
8a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
9a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb *
10a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * Unless required by applicable law or agreed to in writing, software
11a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
12a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * See the License for the specific language governing permissions and
14a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * limitations under the License.
15a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb */
16a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
17a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbpackage com.android.browser;
18a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
19b9a051bd9ed974c4d3d29a549bb7e00d8a95c33cJohn Reckimport com.android.browser.BrowserWebView.ScrollListener;
20ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb
212d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolbimport android.animation.Animator;
222d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolbimport android.animation.Animator.AnimatorListener;
232d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolbimport android.animation.AnimatorSet;
242d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolbimport android.animation.ObjectAnimator;
258233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.Activity;
26a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.content.Context;
27a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.content.res.Resources;
28a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.graphics.Bitmap;
292b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolbimport android.graphics.BitmapShader;
302b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolbimport android.graphics.Canvas;
31467af0a9e10715b86005992555d1c0a0654d136fMichael Kolbimport android.graphics.Matrix;
322b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolbimport android.graphics.Paint;
332b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolbimport android.graphics.Path;
342b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolbimport android.graphics.Shader;
35a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.graphics.drawable.BitmapDrawable;
36a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.graphics.drawable.Drawable;
37a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.graphics.drawable.LayerDrawable;
38a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.graphics.drawable.PaintDrawable;
39a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.ContextMenu;
40ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolbimport android.view.Gravity;
41a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.LayoutInflater;
42a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.MenuInflater;
43a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.View;
44a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.View.OnClickListener;
45a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.webkit.WebView;
46ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolbimport android.widget.ImageButton;
47a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.widget.ImageView;
48a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.widget.LinearLayout;
49a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.widget.TextView;
50a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
51a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport java.util.HashMap;
521bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolbimport java.util.List;
53a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport java.util.Map;
54a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
55a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb/**
56a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb * tabbed title bar for xlarge screen browser
57a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb */
58a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbpublic class TabBar extends LinearLayout
598233facddcc51865d612a919d450db6954aa48e3Michael Kolb        implements ScrollListener, OnClickListener {
60a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
61a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    private static final int PROGRESS_MAX = 100;
62a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
638233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Activity mActivity;
648233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private UiController mUiController;
658233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private TabControl mTabControl;
666670653d355fea0ae20dc51f6c693f994c4cbb54Michael Kolb    private XLargeUi mUi;
67a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
68ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    private final int mTabWidthSelected;
69ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    private final int mTabWidthUnselected;
70ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb
71a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    private TabScrollView mTabs;
728233facddcc51865d612a919d450db6954aa48e3Michael Kolb
73ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb    private ImageButton mNewTab;
74ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb    private int mButtonWidth;
75a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
7694827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb    private Map<Tab, TabView> mTabMap;
77a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
78aff60fb04857e9f9883d357939074b2eafc111e7John Reck    private Drawable mGenericFavicon;
79aff60fb04857e9f9883d357939074b2eafc111e7John Reck
80c83732158bca4667483ac414f071392698beb82eRomain Guy    private int mCurrentTextureWidth = 0;
81c83732158bca4667483ac414f071392698beb82eRomain Guy    private int mCurrentTextureHeight = 0;
82c83732158bca4667483ac414f071392698beb82eRomain Guy
832b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb    private Drawable mActiveDrawable;
842b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb    private Drawable mInactiveDrawable;
852b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb
86c83732158bca4667483ac414f071392698beb82eRomain Guy    private final Paint mActiveShaderPaint = new Paint();
87c83732158bca4667483ac414f071392698beb82eRomain Guy    private final Paint mInactiveShaderPaint = new Paint();
88dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb    private final Paint mFocusPaint = new Paint();
89c83732158bca4667483ac414f071392698beb82eRomain Guy    private final Matrix mActiveMatrix = new Matrix();
90c83732158bca4667483ac414f071392698beb82eRomain Guy    private final Matrix mInactiveMatrix = new Matrix();
91c83732158bca4667483ac414f071392698beb82eRomain Guy
92c83732158bca4667483ac414f071392698beb82eRomain Guy    private BitmapShader mActiveShader;
93c83732158bca4667483ac414f071392698beb82eRomain Guy    private BitmapShader mInactiveShader;
94c83732158bca4667483ac414f071392698beb82eRomain Guy
952b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb    private int mTabOverlap;
965a72f1858c2f73be3558c6cdaa2c84b4c36fa748Michael Kolb    private int mAddTabOverlap;
972b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb    private int mTabSliceWidth;
98376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb    private boolean mUseQuickControls;
992b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb
1006670653d355fea0ae20dc51f6c693f994c4cbb54Michael Kolb    public TabBar(Activity activity, UiController controller, XLargeUi ui) {
1018233facddcc51865d612a919d450db6954aa48e3Michael Kolb        super(activity);
1028233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity = activity;
1038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUiController = controller;
1048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mTabControl = mUiController.getTabControl();
1058233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi = ui;
1068233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Resources res = activity.getResources();
107ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        mTabWidthSelected = (int) res.getDimension(R.dimen.tab_width_selected);
108ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        mTabWidthUnselected = (int) res.getDimension(R.dimen.tab_width_unselected);
1092b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        mActiveDrawable = res.getDrawable(R.drawable.bg_urlbar);
1102b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        mInactiveDrawable = res.getDrawable(R.drawable.browsertab_inactive);
111a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
11294827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        mTabMap = new HashMap<Tab, TabView>();
11394827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        Resources resources = activity.getResources();
1148233facddcc51865d612a919d450db6954aa48e3Michael Kolb        LayoutInflater factory = LayoutInflater.from(activity);
115a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        factory.inflate(R.layout.tab_bar, this);
116f558f0d9372ecf4eeba86dd52bf67f38ff79c0b8Michael Kolb        setPadding(0, (int) res.getDimension(R.dimen.tab_padding_top), 0, 0);
117a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mTabs = (TabScrollView) findViewById(R.id.tabs);
118ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb        mNewTab = (ImageButton) findViewById(R.id.newtab);
119ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb        mNewTab.setOnClickListener(this);
120aff60fb04857e9f9883d357939074b2eafc111e7John Reck        mGenericFavicon = res.getDrawable(R.drawable.app_web_browser_sm);
121a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
1221bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb        updateTabs(mUiController.getTabs());
123ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb        mButtonWidth = -1;
1242b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        // tab dimensions
1252b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        mTabOverlap = (int) res.getDimension(R.dimen.tab_overlap);
1265a72f1858c2f73be3558c6cdaa2c84b4c36fa748Michael Kolb        mAddTabOverlap = (int) res.getDimension(R.dimen.tab_addoverlap);
1272b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        mTabSliceWidth = (int) res.getDimension(R.dimen.tab_slice);
128c83732158bca4667483ac414f071392698beb82eRomain Guy
129c83732158bca4667483ac414f071392698beb82eRomain Guy        mActiveShaderPaint.setStyle(Paint.Style.FILL);
130c83732158bca4667483ac414f071392698beb82eRomain Guy        mActiveShaderPaint.setAntiAlias(true);
131c83732158bca4667483ac414f071392698beb82eRomain Guy
132c83732158bca4667483ac414f071392698beb82eRomain Guy        mInactiveShaderPaint.setStyle(Paint.Style.FILL);
133c83732158bca4667483ac414f071392698beb82eRomain Guy        mInactiveShaderPaint.setAntiAlias(true);
134b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb
135dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mFocusPaint.setStyle(Paint.Style.STROKE);
136eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb        mFocusPaint.setStrokeWidth(res.getDimension(R.dimen.tab_focus_stroke));
137dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mFocusPaint.setAntiAlias(true);
138dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mFocusPaint.setColor(res.getColor(R.color.tabFocusHighlight));
139ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb    }
140ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb
141376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb    void setUseQuickControls(boolean useQuickControls) {
142376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb        mUseQuickControls = useQuickControls;
143467af0a9e10715b86005992555d1c0a0654d136fMichael Kolb        mNewTab.setVisibility(mUseQuickControls ? View.GONE
144467af0a9e10715b86005992555d1c0a0654d136fMichael Kolb                : View.VISIBLE);
145376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb    }
146376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb
147376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb    int getTabCount() {
148376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb        return mTabMap.size();
149376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb    }
150376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb
1511bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb    void updateTabs(List<Tab> tabs) {
1521bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb        mTabs.clearTabs();
1531bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb        mTabMap.clear();
1541bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb        for (Tab tab : tabs) {
15594827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            TabView tv = buildTabView(tab);
1562d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            mTabs.addTab(tv);
1571bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb        }
158c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mTabs.setSelectedTab(mTabControl.getCurrentPosition());
1591bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb    }
1601bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb
161ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb    @Override
1622b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb    protected void onMeasure(int hspec, int vspec) {
1632b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        super.onMeasure(hspec, vspec);
1642b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        int w = getMeasuredWidth();
1652b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        // adjust for new tab overlap
166467af0a9e10715b86005992555d1c0a0654d136fMichael Kolb        if (!mUseQuickControls) {
1675a72f1858c2f73be3558c6cdaa2c84b4c36fa748Michael Kolb            w -= mAddTabOverlap;
168467af0a9e10715b86005992555d1c0a0654d136fMichael Kolb        }
1692b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        setMeasuredDimension(w, getMeasuredHeight());
1702b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb    }
1712b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb
1722b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb    @Override
173ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
1742b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        // use paddingLeft and paddingTop
1752b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        int pl = getPaddingLeft();
1762b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        int pt = getPaddingTop();
177ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb        int sw = mTabs.getMeasuredWidth();
1782b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        int w = right - left - pl;
179b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb        if (mUseQuickControls) {
180b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb            mButtonWidth = 0;
181b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb        } else {
1825a72f1858c2f73be3558c6cdaa2c84b4c36fa748Michael Kolb            mButtonWidth = mNewTab.getMeasuredWidth() - mAddTabOverlap;
183b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb            if (w-sw < mButtonWidth) {
184b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb                sw = w - mButtonWidth;
185b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb            }
186ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb        }
1872b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        mTabs.layout(pl, pt, pl + sw, bottom - top);
1882b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        // adjust for overlap
189b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb        if (!mUseQuickControls) {
1905a72f1858c2f73be3558c6cdaa2c84b4c36fa748Michael Kolb            mNewTab.layout(pl + sw - mAddTabOverlap, pt,
1915a72f1858c2f73be3558c6cdaa2c84b4c36fa748Michael Kolb                    pl + sw + mButtonWidth - mAddTabOverlap, bottom - top);
192b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb        }
193a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
194a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
195a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    public void onClick(View view) {
196ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb        if (mNewTab == view) {
1978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mUiController.openTabToHomePage();
198ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb        } else if (mTabs.getSelectedTab() == view) {
199467af0a9e10715b86005992555d1c0a0654d136fMichael Kolb            if (mUseQuickControls) {
2007cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb                if (mUi.isTitleBarShowing() && !isLoading()) {
2017cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb                    mUi.stopEditingUrl();
2027cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb                    mUi.hideTitleBar();
203467af0a9e10715b86005992555d1c0a0654d136fMichael Kolb                } else {
204467af0a9e10715b86005992555d1c0a0654d136fMichael Kolb                    mUi.stopWebViewScrolling();
20546f987eca738a36e2c8382aaec6c7ef2ae2482aeMichael Kolb                    mUi.editUrl(false);
206467af0a9e10715b86005992555d1c0a0654d136fMichael Kolb                }
2077cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb            } else if (mUi.isTitleBarShowing() && !isLoading()) {
2087cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb                mUi.stopEditingUrl();
2097cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb                mUi.hideTitleBar();
210ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            } else {
211ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                showUrlBar();
212ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            }
213c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        } else if (view instanceof TabView) {
214c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            final Tab tab = ((TabView) view).mTab;
215ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb            int ix = mTabs.getChildIndex(view);
216ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb            if (ix >= 0) {
217ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb                mTabs.setSelectedTab(ix);
218c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mUiController.switchToTab(tab);
219ebba8b4e9dc4f78764d6cfb26738b54d04bc9d27Michael Kolb            }
220a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
221a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
222a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
223ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    private void showUrlBar() {
2248233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.stopWebViewScrolling();
2257cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb        mUi.showTitleBar();
226ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    }
227ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb
228376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb    void showTitleBarIndicator(boolean show) {
229a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb        Tab tab = mTabControl.getCurrentTab();
230a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb        if (tab != null) {
23194827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            TabView tv = mTabMap.get(tab);
23294827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            if (tv != null) {
23394827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb                tv.showIndicator(show);
234a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb            }
235a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb        }
236ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    }
237ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb
2387dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb    boolean showsTitleBarIndicator() {
2397dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb        Tab tab = mTabControl.getCurrentTab();
2407dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb        if (tab != null) {
2417dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb            TabView tv = mTabMap.get(tab);
2427dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb            if (tv != null) {
2437dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb                return tv.showsIndicator();
2447dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb            }
2457dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb        }
2467dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb        return false;
2477dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb    }
2487dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb
249ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    // callback after fake titlebar is shown
250a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    void onShowTitleBar() {
251a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb        showTitleBarIndicator(false);
252a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
253a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
254ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    // callback after fake titlebar is hidden
255a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    void onHideTitleBar() {
2568233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Tab tab = mTabControl.getCurrentTab();
2577cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb        WebView w = tab.getWebView();
2587cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb        if (w != null) {
2597cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb            showTitleBarIndicator(w.getVisibleTitleHeight() == 0);
2607cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb        }
261a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
262a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
263ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    // webview scroll listener
264ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb
265ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    @Override
2665ee018e25ecda8955f865cbf7b0b946bcad2b294Michael Kolb    public void onScroll(int visibleTitleHeight, boolean userInitiated) {
267376b54116e38b3b94c4d64663d1bff38352b0e59Michael Kolb        if (mUseQuickControls) return;
2688233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // isLoading is using the current tab, which initially might not be set yet
269dcf911c7cb1c3eeb8b073d69c2ccd96e6179b4a8John Reck        if (mTabControl.getCurrentTab() != null
270dcf911c7cb1c3eeb8b073d69c2ccd96e6179b4a8John Reck                && !isLoading()) {
271dcf911c7cb1c3eeb8b073d69c2ccd96e6179b4a8John Reck            if (visibleTitleHeight == 0) {
2725ee018e25ecda8955f865cbf7b0b946bcad2b294Michael Kolb                if (!showsTitleBarIndicator()
2735ee018e25ecda8955f865cbf7b0b946bcad2b294Michael Kolb                        && (!mUi.isEditingUrl() || userInitiated)) {
2747cdc4906fc5852297a9a254c3251ad2f4dead6eeMichael Kolb                    mUi.hideTitleBar();
2757dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb                    showTitleBarIndicator(true);
2767dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb                }
277dcf911c7cb1c3eeb8b073d69c2ccd96e6179b4a8John Reck            } else {
2787dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb                if (showsTitleBarIndicator()) {
2797dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb                    showTitleBarIndicator(false);
2807dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb                }
281ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            }
282ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        }
283ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb    }
284a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
285a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    @Override
286a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    public void createContextMenu(ContextMenu menu) {
2878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        MenuInflater inflater = mActivity.getMenuInflater();
288a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        inflater.inflate(R.menu.title_context, menu);
2898233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity.onCreateContextMenu(menu, this, null);
290a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
291a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
29294827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb    private TabView buildTabView(Tab tab) {
29394827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        TabView tabview = new TabView(mActivity, tab);
29494827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        mTabMap.put(tab, tabview);
29594827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        tabview.setOnClickListener(this);
29694827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        return tabview;
297a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
298a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
299c83732158bca4667483ac414f071392698beb82eRomain Guy    private static Bitmap getDrawableAsBitmap(Drawable drawable, int width, int height) {
300c83732158bca4667483ac414f071392698beb82eRomain Guy        Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
301c83732158bca4667483ac414f071392698beb82eRomain Guy        Canvas c = new Canvas(b);
302c83732158bca4667483ac414f071392698beb82eRomain Guy        drawable.setBounds(0, 0, width, height);
303c83732158bca4667483ac414f071392698beb82eRomain Guy        drawable.draw(c);
304c83732158bca4667483ac414f071392698beb82eRomain Guy        return b;
305b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb    }
306b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb
307a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    /**
308a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb     * View used in the tab bar
309a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb     */
310a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    class TabView extends LinearLayout implements OnClickListener {
311a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
31294827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        Tab mTab;
313a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        View mTabContent;
314a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        TextView mTitle;
315a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb        View mIndicator;
316ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb        View mIncognito;
317a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        ImageView mIconView;
318a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        ImageView mLock;
319a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        ImageView mClose;
320a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        boolean mSelected;
321a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        boolean mInLoad;
3222b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        Path mPath;
323eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb        Path mFocusPath;
3242b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        int[] mWindowPos;
325a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
326a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        /**
327a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb         * @param context
328a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb         */
32994827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        public TabView(Context context, Tab tab) {
330a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            super(context);
3312b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            setWillNotDraw(false);
3322b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            mPath = new Path();
333eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb            mFocusPath = new Path();
3342b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            mWindowPos = new int[2];
33594827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            mTab = tab;
336ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            setGravity(Gravity.CENTER_VERTICAL);
337ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            setOrientation(LinearLayout.HORIZONTAL);
33849f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb            setPadding(mTabOverlap, 0, mTabSliceWidth, 0);
339b1402a5c3e1617867c58d32d1fe9782cf6de423fBjorn Bringert            LayoutInflater inflater = LayoutInflater.from(getContext());
340ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            mTabContent = inflater.inflate(R.layout.tab_title, this, true);
341a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTitle = (TextView) mTabContent.findViewById(R.id.title);
342a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mIconView = (ImageView) mTabContent.findViewById(R.id.favicon);
343a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mLock = (ImageView) mTabContent.findViewById(R.id.lock);
344a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mClose = (ImageView) mTabContent.findViewById(R.id.close);
345a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mClose.setOnClickListener(this);
346ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb            mIncognito = mTabContent.findViewById(R.id.incognito);
347a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb            mIndicator = mTabContent.findViewById(R.id.chevron);
348a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mSelected = false;
349a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mInLoad = false;
350a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // update the status
35194827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            updateFromTab();
352a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
353a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
354a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb        void showIndicator(boolean show) {
3556a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb            if (mSelected) {
3566a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb                mIndicator.setVisibility(show ? View.VISIBLE : View.GONE);
35749f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
35849f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                if (show) {
35949f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                    lp.width = mTabWidthSelected + mIndicator.getWidth();
36049f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                } else {
36149f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                    lp.width = mTabWidthSelected;
36249f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                }
36349f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                lp.height =  LayoutParams.MATCH_PARENT;
36449f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                setLayoutParams(lp);
3656a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb            } else {
3666a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb                mIndicator.setVisibility(View.GONE);
3676a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb            }
368a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb        }
369a0e2a75fdba703260c02838c96d9d4008e914a1dMichael Kolb
3707dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb        boolean showsIndicator() {
3717dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb            return (mIndicator.getVisibility() == View.VISIBLE);
3727dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb        }
3737dad8f0c238853de01d5d200b306092b5cfa0026Michael Kolb
374a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        @Override
375a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        public void onClick(View v) {
376a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            if (v == mClose) {
377a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                closeTab();
378a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            }
379a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
380a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
38194827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        private void updateFromTab() {
38294827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            String displayTitle = mTab.getTitle();
38330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            if (displayTitle == null) {
38494827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb                displayTitle = mTab.getUrl();
385a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            }
38630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            setDisplayTitle(displayTitle);
38794827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            setProgress(mTab.getLoadProgress());
38894827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            if (mTab.getFavicon() != null) {
38994827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb                setFavicon(renderFavicon(mTab.getFavicon()));
390a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            }
39194827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            if (mTab != null) {
392ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb                mIncognito.setVisibility(
39394827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb                        mTab.isPrivateBrowsingEnabled() ?
394ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb                        View.VISIBLE : View.GONE);
395ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb            }
396a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
397a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
398a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        @Override
399b7b115e301334f813275aa13e7a2cc27bf15fe6aMichael Kolb        public void setActivated(boolean selected) {
400a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mSelected = selected;
401a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mClose.setVisibility(mSelected ? View.VISIBLE : View.GONE);
4026a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb            mIndicator.setVisibility(View.GONE);
4038233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mTitle.setTextAppearance(mActivity, mSelected ?
404c7485ae06c6d5d33c57a03d02bbeed54edb3c66fMichael Kolb                    R.style.TabTitleSelected : R.style.TabTitleUnselected);
405c7485ae06c6d5d33c57a03d02bbeed54edb3c66fMichael Kolb            setHorizontalFadingEdgeEnabled(!mSelected);
406b7b115e301334f813275aa13e7a2cc27bf15fe6aMichael Kolb            super.setActivated(selected);
4072b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
4082b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            lp.width = selected ? mTabWidthSelected : mTabWidthUnselected;
4092b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            lp.height =  LayoutParams.MATCH_PARENT;
4102b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            setLayoutParams(lp);
411dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb            setFocusable(!selected);
412dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb            postInvalidate();
413a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
414a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
415a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        void setDisplayTitle(String title) {
416a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTitle.setText(title);
417a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
418a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
419a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        void setFavicon(Drawable d) {
420a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mIconView.setImageDrawable(d);
421a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
422a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
423a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        void setLock(Drawable d) {
424a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            if (null == d) {
425a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mLock.setVisibility(View.GONE);
426a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            } else {
427a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mLock.setImageDrawable(d);
428a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mLock.setVisibility(View.VISIBLE);
429a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            }
430a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
431a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
432a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        void setProgress(int newProgress) {
433a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            if (newProgress >= PROGRESS_MAX) {
434a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mInLoad = false;
435a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            } else {
436a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                if (!mInLoad && getWindowToken() != null) {
437a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                    mInLoad = true;
438a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                }
439a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            }
440a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
441a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
442a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        private void closeTab() {
44394827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            if (mTab == mTabControl.getCurrentTab()) {
4448233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mUiController.closeCurrentTab();
445a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            } else {
44694827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb                mUiController.closeTab(mTab);
447a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            }
448a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
449a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
4502b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        @Override
4512b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        protected void onLayout(boolean changed, int l, int t, int r, int b) {
4522b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            super.onLayout(changed, l, t, r, b);
4532b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            setTabPath(mPath, 0, 0, r - l, b - t);
454eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb            setFocusPath(mFocusPath, 0, 0, r - l, b - t);
4552b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        }
456b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb
4572b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        @Override
4582b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        protected void dispatchDraw(Canvas canvas) {
459c83732158bca4667483ac414f071392698beb82eRomain Guy            if (mCurrentTextureWidth != mUi.getContentWidth() ||
460c83732158bca4667483ac414f071392698beb82eRomain Guy                    mCurrentTextureHeight != getHeight()) {
461c83732158bca4667483ac414f071392698beb82eRomain Guy                mCurrentTextureWidth = mUi.getContentWidth();
462c83732158bca4667483ac414f071392698beb82eRomain Guy                mCurrentTextureHeight = getHeight();
463c83732158bca4667483ac414f071392698beb82eRomain Guy
464c83732158bca4667483ac414f071392698beb82eRomain Guy                if (mCurrentTextureWidth > 0 && mCurrentTextureHeight > 0) {
465c83732158bca4667483ac414f071392698beb82eRomain Guy                    Bitmap activeTexture = getDrawableAsBitmap(mActiveDrawable,
466c83732158bca4667483ac414f071392698beb82eRomain Guy                            mCurrentTextureWidth, mCurrentTextureHeight);
467c83732158bca4667483ac414f071392698beb82eRomain Guy                    Bitmap inactiveTexture = getDrawableAsBitmap(mInactiveDrawable,
468c83732158bca4667483ac414f071392698beb82eRomain Guy                            mCurrentTextureWidth, mCurrentTextureHeight);
469c83732158bca4667483ac414f071392698beb82eRomain Guy
470c83732158bca4667483ac414f071392698beb82eRomain Guy                    mActiveShader = new BitmapShader(activeTexture,
471c83732158bca4667483ac414f071392698beb82eRomain Guy                            Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
472c83732158bca4667483ac414f071392698beb82eRomain Guy                    mActiveShaderPaint.setShader(mActiveShader);
473b4cafc564e00d422dde6d286fdc2df971180ab51Michael Kolb
474c83732158bca4667483ac414f071392698beb82eRomain Guy                    mInactiveShader = new BitmapShader(inactiveTexture,
475c83732158bca4667483ac414f071392698beb82eRomain Guy                            Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
476c83732158bca4667483ac414f071392698beb82eRomain Guy                    mInactiveShaderPaint.setShader(mInactiveShader);
477c83732158bca4667483ac414f071392698beb82eRomain Guy                }
478c83732158bca4667483ac414f071392698beb82eRomain Guy            }
47905902aa39843613ea93dd0c1b41d561d4ea85ff9Michael Kolb            // add some monkey protection
48005902aa39843613ea93dd0c1b41d561d4ea85ff9Michael Kolb            if ((mActiveShader != null) && (mInactiveShader != null)) {
48105902aa39843613ea93dd0c1b41d561d4ea85ff9Michael Kolb                int state = canvas.save();
48205902aa39843613ea93dd0c1b41d561d4ea85ff9Michael Kolb                getLocationInWindow(mWindowPos);
48305902aa39843613ea93dd0c1b41d561d4ea85ff9Michael Kolb                Paint paint = mSelected ? mActiveShaderPaint : mInactiveShaderPaint;
48405902aa39843613ea93dd0c1b41d561d4ea85ff9Michael Kolb                drawClipped(canvas, paint, mPath, mWindowPos[0]);
48505902aa39843613ea93dd0c1b41d561d4ea85ff9Michael Kolb                canvas.restoreToCount(state);
48605902aa39843613ea93dd0c1b41d561d4ea85ff9Michael Kolb            }
4872b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            super.dispatchDraw(canvas);
4882b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        }
4892b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb
490c83732158bca4667483ac414f071392698beb82eRomain Guy        private void drawClipped(Canvas canvas, Paint paint, Path clipPath, int left) {
491c83732158bca4667483ac414f071392698beb82eRomain Guy            // TODO: We should change the matrix/shader only when needed
492c83732158bca4667483ac414f071392698beb82eRomain Guy            final Matrix matrix = mSelected ? mActiveMatrix : mInactiveMatrix;
493c83732158bca4667483ac414f071392698beb82eRomain Guy            matrix.setTranslate(-left, 0.0f);
494c83732158bca4667483ac414f071392698beb82eRomain Guy            (mSelected ? mActiveShader : mInactiveShader).setLocalMatrix(matrix);
495c83732158bca4667483ac414f071392698beb82eRomain Guy            canvas.drawPath(clipPath, paint);
496dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb            if (isFocused()) {
497eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb                canvas.drawPath(mFocusPath, mFocusPaint);
498dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb            }
4992b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        }
5002b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb
5012b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        private void setTabPath(Path path, int l, int t, int r, int b) {
5022b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            path.reset();
5032b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            path.moveTo(l, b);
5042b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            path.lineTo(l, t);
5052b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            path.lineTo(r - mTabSliceWidth, t);
5062b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            path.lineTo(r, b);
5072b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb            path.close();
5082b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb        }
5092b5a13ab55991f55ab7afb107e4401c6fbb5ad64Michael Kolb
510eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb        private void setFocusPath(Path path, int l, int t, int r, int b) {
511eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb            path.reset();
512eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb            path.moveTo(l, b);
513eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb            path.lineTo(l, t);
514eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb            path.lineTo(r - mTabSliceWidth, t);
515eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb            path.lineTo(r, b);
516eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb        }
517eb7001c66f49babd2f52ebeedcf55421ffc2597dMichael Kolb
518a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
519a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
52049f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb    static Drawable createFaviconBackground(Context context) {
52149f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        PaintDrawable faviconBackground = new PaintDrawable();
52249f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        Resources res = context.getResources();
52349f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        faviconBackground.getPaint().setColor(context.getResources()
52449f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                .getColor(R.color.tabFaviconBackground));
52549f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        faviconBackground.setCornerRadius(
52649f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb                res.getDimension(R.dimen.tab_favicon_corner_radius));
52749f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        return faviconBackground;
52849f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb    }
52949f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb
53094827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb    private Drawable renderFavicon(Bitmap icon) {
53149f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        Drawable[] array = new Drawable[2];
53249f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        array[0] = createFaviconBackground(getContext());
53394827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        if (icon == null) {
53449f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb            array[1] = mGenericFavicon;
53594827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        } else {
53649f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb            array[1] = new BitmapDrawable(icon);
537a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
53894827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        LayerDrawable d = new LayerDrawable(array);
53949f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        d.setLayerInset(1, 2, 2, 2, 2);
54094827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        return d;
541a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
542a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
5432d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb    private void animateTabOut(final Tab tab, final TabView tv) {
5442d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        ObjectAnimator scalex = ObjectAnimator.ofFloat(tv, "scaleX", 1.0f, 0.0f);
5452d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        ObjectAnimator scaley = ObjectAnimator.ofFloat(tv, "scaleY", 1.0f, 0.0f);
54649f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        ObjectAnimator alpha = ObjectAnimator.ofFloat(tv, "alpha", 1.0f, 0.0f);
5472d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        AnimatorSet animator = new AnimatorSet();
54849f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        animator.playTogether(scalex, scaley, alpha);
5492d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        animator.setDuration(150);
5502d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        animator.addListener(new AnimatorListener() {
5512d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5522d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            @Override
5532d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            public void onAnimationCancel(Animator animation) {
5542d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            }
5552d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5562d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            @Override
5572d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            public void onAnimationEnd(Animator animation) {
5582d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb                mTabs.removeTab(tv);
5592d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb                mTabMap.remove(tab);
5608814d738ad840ea66f0e5a4733f53f2e3bd8d0ebMichael Kolb                mUi.onRemoveTabCompleted(tab);
5612d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            }
5622d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5632d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            @Override
5642d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            public void onAnimationRepeat(Animator animation) {
5652d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            }
5662d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5672d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            @Override
5682d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            public void onAnimationStart(Animator animation) {
5692d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            }
5702d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5712d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        });
5722d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        animator.start();
5732d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb    }
5742d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5752d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb    private void animateTabIn(final Tab tab, final TabView tv) {
57649f1583aba84ca4a5908b2185c734cf604ebb248Michael Kolb        ObjectAnimator scalex = ObjectAnimator.ofFloat(tv, "scaleX", 0.0f, 1.0f);
5772d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        scalex.setDuration(150);
5782d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        scalex.addListener(new AnimatorListener() {
5792d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5802d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            @Override
5812d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            public void onAnimationCancel(Animator animation) {
5822d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            }
5832d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5842d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            @Override
5852d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            public void onAnimationEnd(Animator animation) {
5868814d738ad840ea66f0e5a4733f53f2e3bd8d0ebMichael Kolb                mUi.onAddTabCompleted(tab);
5872d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            }
5882d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5892d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            @Override
5902d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            public void onAnimationRepeat(Animator animation) {
5912d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            }
5922d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5932d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            @Override
5942d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            public void onAnimationStart(Animator animation) {
5952d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb                mTabs.addTab(tv);
5962d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            }
5972d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
5982d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        });
5992d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        scalex.start();
6002d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb    }
6012d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb
602a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    // TabChangeListener implementation
603a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
6048233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onSetActiveTab(Tab tab) {
605c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        mTabs.setSelectedTab(mTabControl.getTabPosition(tab));
60694827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        TabView tv = mTabMap.get(tab);
60794827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        if (tv != null) {
60894827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            tv.setProgress(tv.mTab.getLoadProgress());
609a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // update the scroll state
610a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            WebView webview = tab.getWebView();
6116a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb            if (webview != null) {
6126a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb                int h = webview.getVisibleTitleHeight();
6135ee018e25ecda8955f865cbf7b0b946bcad2b294Michael Kolb                onScroll(h, true);
6146a85e2ae52f5e7592731cfcf1b98639ea2a03b62Michael Kolb            }
615a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
616a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
617a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
618a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    public void onFavicon(Tab tab, Bitmap favicon) {
61994827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        TabView tv = mTabMap.get(tab);
62094827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        if (tv != null) {
62194827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            tv.setFavicon(renderFavicon(favicon));
622a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
623a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
624a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
625a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    public void onNewTab(Tab tab) {
62694827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        TabView tv = buildTabView(tab);
6272d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        animateTabIn(tab, tv);
628a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
629a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
630a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    public void onProgress(Tab tab, int progress) {
63194827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        TabView tv = mTabMap.get(tab);
63294827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        if (tv != null) {
63394827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            tv.setProgress(progress);
634a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
635a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
636a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
637a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    public void onRemoveTab(Tab tab) {
63894827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        TabView tv = mTabMap.get(tab);
63994827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        if (tv != null) {
6402d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            animateTabOut(tab, tv);
6412d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        } else {
6422d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb            mTabMap.remove(tab);
643a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
644a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
645a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
646a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    public void onUrlAndTitle(Tab tab, String url, String title) {
64794827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        TabView tv = mTabMap.get(tab);
64894827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        if (tv != null) {
64994827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            if (title != null) {
65094827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb                tv.setDisplayTitle(title);
65194827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            } else if (url != null) {
65294827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb                tv.setDisplayTitle(UrlUtils.stripUrl(url));
65394827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            }
654a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
655a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
656a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
657a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    private boolean isLoading() {
65894827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        TabView tv = mTabMap.get(mTabControl.getCurrentTab());
65994827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb        if (tv != null) {
66094827b6f22830ba06a66a77d3c9da9143e6ecd12Michael Kolb            return tv.mInLoad;
6618233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
6628233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return false;
6638233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
664a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
665a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
666a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb}
667