blob: 378557e2ce9491f1eba63478e0e1290990348cf7 [file] [log] [blame]
Michael Kolba2b2ba82010-08-04 17:54:03 -07001/*
2 * Copyright (C) 2010 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 */
16
Bijan Amirzada41242f22014-03-21 12:12:18 -070017package com.android.browser;
Michael Kolba2b2ba82010-08-04 17:54:03 -070018
Michael Kolb2d59c322011-01-25 13:18:55 -080019import android.animation.Animator;
20import android.animation.Animator.AnimatorListener;
21import android.animation.AnimatorSet;
22import android.animation.ObjectAnimator;
Michael Kolb8233fac2010-10-26 16:08:53 -070023import android.app.Activity;
Michael Kolba2b2ba82010-08-04 17:54:03 -070024import android.content.Context;
Michael Kolb678afc82011-05-17 14:52:41 -070025import android.content.res.Configuration;
Michael Kolba2b2ba82010-08-04 17:54:03 -070026import android.content.res.Resources;
27import android.graphics.Bitmap;
Pankaj Gargf3f1b012014-11-26 14:52:22 -080028import android.graphics.BitmapShader;
Michael Kolb2b5a13a2010-12-09 14:13:42 -080029import android.graphics.Canvas;
Michael Kolb467af0a2011-01-11 13:09:49 -080030import android.graphics.Matrix;
Michael Kolb2b5a13a2010-12-09 14:13:42 -080031import android.graphics.Paint;
32import android.graphics.Path;
Pankaj Gargf3f1b012014-11-26 14:52:22 -080033import android.graphics.Shader;
Michael Kolba2b2ba82010-08-04 17:54:03 -070034import android.graphics.drawable.Drawable;
Michael Kolbed217742010-08-10 17:52:34 -070035import android.view.Gravity;
Michael Kolba2b2ba82010-08-04 17:54:03 -070036import android.view.LayoutInflater;
Michael Kolba2b2ba82010-08-04 17:54:03 -070037import android.view.View;
38import android.view.View.OnClickListener;
Michael Kolbed217742010-08-10 17:52:34 -070039import android.widget.ImageButton;
Michael Kolba2b2ba82010-08-04 17:54:03 -070040import android.widget.ImageView;
41import android.widget.LinearLayout;
42import android.widget.TextView;
43
Michael Kolba2b2ba82010-08-04 17:54:03 -070044import java.util.HashMap;
Michael Kolb1bf23132010-11-19 12:55:12 -080045import java.util.List;
Michael Kolba2b2ba82010-08-04 17:54:03 -070046import java.util.Map;
47
48/**
49 * tabbed title bar for xlarge screen browser
50 */
Michael Kolbb14ff2f2011-07-01 15:33:56 -070051public class TabBar extends LinearLayout implements OnClickListener {
Michael Kolba2b2ba82010-08-04 17:54:03 -070052
53 private static final int PROGRESS_MAX = 100;
54
Michael Kolb8233fac2010-10-26 16:08:53 -070055 private Activity mActivity;
56 private UiController mUiController;
57 private TabControl mTabControl;
Michael Kolb66706532010-12-12 19:50:22 -080058 private XLargeUi mUi;
Michael Kolba2b2ba82010-08-04 17:54:03 -070059
John Reck034637c2011-08-11 11:34:44 -070060 private int mTabWidth;
Michael Kolbed217742010-08-10 17:52:34 -070061
Michael Kolba2b2ba82010-08-04 17:54:03 -070062 private TabScrollView mTabs;
Michael Kolb8233fac2010-10-26 16:08:53 -070063
Michael Kolbebba8b42010-09-30 12:57:59 -070064 private ImageButton mNewTab;
65 private int mButtonWidth;
Michael Kolba2b2ba82010-08-04 17:54:03 -070066
Michael Kolb94827b62011-01-08 14:23:45 -080067 private Map<Tab, TabView> mTabMap;
Michael Kolba2b2ba82010-08-04 17:54:03 -070068
Romain Guyc8373212011-01-07 19:15:16 -080069 private int mCurrentTextureWidth = 0;
70 private int mCurrentTextureHeight = 0;
71
Enrico Ros1f5a0952014-11-18 20:15:48 -080072 ///private Drawable mActiveDrawable;
73 ///private Drawable mInactiveDrawable;
Michael Kolb2b5a13a2010-12-09 14:13:42 -080074
Romain Guyc8373212011-01-07 19:15:16 -080075 private final Paint mActiveShaderPaint = new Paint();
76 private final Paint mInactiveShaderPaint = new Paint();
Michael Kolbdc2ee1b2011-02-14 14:34:40 -080077 private final Paint mFocusPaint = new Paint();
Romain Guyc8373212011-01-07 19:15:16 -080078 private final Matrix mActiveMatrix = new Matrix();
79 private final Matrix mInactiveMatrix = new Matrix();
80
Pankaj Gargf3f1b012014-11-26 14:52:22 -080081 private BitmapShader mActiveShader;
82 private BitmapShader mInactiveShader;
Romain Guyc8373212011-01-07 19:15:16 -080083
Michael Kolb2b5a13a2010-12-09 14:13:42 -080084 private int mTabOverlap;
Michael Kolb5a72f182011-01-13 20:35:06 -080085 private int mAddTabOverlap;
Michael Kolb2b5a13a2010-12-09 14:13:42 -080086 private int mTabSliceWidth;
Michael Kolb2b5a13a2010-12-09 14:13:42 -080087
Michael Kolb66706532010-12-12 19:50:22 -080088 public TabBar(Activity activity, UiController controller, XLargeUi ui) {
Michael Kolb8233fac2010-10-26 16:08:53 -070089 super(activity);
90 mActivity = activity;
91 mUiController = controller;
92 mTabControl = mUiController.getTabControl();
93 mUi = ui;
94 Resources res = activity.getResources();
John Reck034637c2011-08-11 11:34:44 -070095 mTabWidth = (int) res.getDimension(R.dimen.tab_width);
Enrico Ros1f5a0952014-11-18 20:15:48 -080096 ///mActiveDrawable = res.getDrawable(R.drawable.bg_urlbar);
97 ///mInactiveDrawable = res.getDrawable(R.drawable.browsertab_inactive);
Michael Kolba2b2ba82010-08-04 17:54:03 -070098
Michael Kolb94827b62011-01-08 14:23:45 -080099 mTabMap = new HashMap<Tab, TabView>();
Michael Kolb8233fac2010-10-26 16:08:53 -0700100 LayoutInflater factory = LayoutInflater.from(activity);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700101 factory.inflate(R.layout.tab_bar, this);
Michael Kolbf558f0d2011-01-13 19:24:18 -0800102 setPadding(0, (int) res.getDimension(R.dimen.tab_padding_top), 0, 0);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700103 mTabs = (TabScrollView) findViewById(R.id.tabs);
Michael Kolbebba8b42010-09-30 12:57:59 -0700104 mNewTab = (ImageButton) findViewById(R.id.newtab);
105 mNewTab.setOnClickListener(this);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700106
Michael Kolb1bf23132010-11-19 12:55:12 -0800107 updateTabs(mUiController.getTabs());
Michael Kolbebba8b42010-09-30 12:57:59 -0700108 mButtonWidth = -1;
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800109 // tab dimensions
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800110 mTabOverlap = (int) res.getDimension(R.dimen.tab_overlap);
Michael Kolb5a72f182011-01-13 20:35:06 -0800111 mAddTabOverlap = (int) res.getDimension(R.dimen.tab_addoverlap);
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800112 mTabSliceWidth = (int) res.getDimension(R.dimen.tab_slice);
Romain Guyc8373212011-01-07 19:15:16 -0800113
114 mActiveShaderPaint.setStyle(Paint.Style.FILL);
115 mActiveShaderPaint.setAntiAlias(true);
116
117 mInactiveShaderPaint.setStyle(Paint.Style.FILL);
118 mInactiveShaderPaint.setAntiAlias(true);
Michael Kolbb4cafc52011-01-12 16:55:04 -0800119
Michael Kolbdc2ee1b2011-02-14 14:34:40 -0800120 mFocusPaint.setStyle(Paint.Style.STROKE);
Michael Kolbeb7001c2011-02-16 16:07:33 -0800121 mFocusPaint.setStrokeWidth(res.getDimension(R.dimen.tab_focus_stroke));
Michael Kolbdc2ee1b2011-02-14 14:34:40 -0800122 mFocusPaint.setAntiAlias(true);
123 mFocusPaint.setColor(res.getColor(R.color.tabFocusHighlight));
Michael Kolbebba8b42010-09-30 12:57:59 -0700124 }
125
Michael Kolb678afc82011-05-17 14:52:41 -0700126 @Override
127 public void onConfigurationChanged(Configuration config) {
128 super.onConfigurationChanged(config);
129 Resources res = mActivity.getResources();
John Reck034637c2011-08-11 11:34:44 -0700130 mTabWidth = (int) res.getDimension(R.dimen.tab_width);
Michael Kolb678afc82011-05-17 14:52:41 -0700131 // force update of tab bar
132 mTabs.updateLayout();
133 }
134
Michael Kolb376b5412010-12-15 11:52:57 -0800135 int getTabCount() {
136 return mTabMap.size();
137 }
138
Michael Kolb1bf23132010-11-19 12:55:12 -0800139 void updateTabs(List<Tab> tabs) {
140 mTabs.clearTabs();
141 mTabMap.clear();
142 for (Tab tab : tabs) {
Michael Kolb94827b62011-01-08 14:23:45 -0800143 TabView tv = buildTabView(tab);
Michael Kolb2d59c322011-01-25 13:18:55 -0800144 mTabs.addTab(tv);
Michael Kolb1bf23132010-11-19 12:55:12 -0800145 }
Michael Kolbc831b632011-05-11 09:30:34 -0700146 mTabs.setSelectedTab(mTabControl.getCurrentPosition());
Michael Kolb1bf23132010-11-19 12:55:12 -0800147 }
148
Michael Kolbebba8b42010-09-30 12:57:59 -0700149 @Override
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800150 protected void onMeasure(int hspec, int vspec) {
151 super.onMeasure(hspec, vspec);
152 int w = getMeasuredWidth();
153 // adjust for new tab overlap
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700154 w -= mAddTabOverlap;
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800155 setMeasuredDimension(w, getMeasuredHeight());
156 }
157
158 @Override
Michael Kolbebba8b42010-09-30 12:57:59 -0700159 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800160 // use paddingLeft and paddingTop
161 int pl = getPaddingLeft();
162 int pt = getPaddingTop();
Michael Kolbebba8b42010-09-30 12:57:59 -0700163 int sw = mTabs.getMeasuredWidth();
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800164 int w = right - left - pl;
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700165 mButtonWidth = mNewTab.getMeasuredWidth() - mAddTabOverlap;
166 if (w-sw < mButtonWidth) {
167 sw = w - mButtonWidth;
Michael Kolbebba8b42010-09-30 12:57:59 -0700168 }
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800169 mTabs.layout(pl, pt, pl + sw, bottom - top);
170 // adjust for overlap
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700171 mNewTab.layout(pl + sw - mAddTabOverlap, pt,
172 pl + sw + mButtonWidth - mAddTabOverlap, bottom - top);
173
Michael Kolba2b2ba82010-08-04 17:54:03 -0700174 }
175
176 public void onClick(View view) {
Michael Kolbebba8b42010-09-30 12:57:59 -0700177 if (mNewTab == view) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700178 mUiController.openTabToHomePage();
Michael Kolbebba8b42010-09-30 12:57:59 -0700179 } else if (mTabs.getSelectedTab() == view) {
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700180 if (mUi.isTitleBarShowing() && !isLoading()) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800181 mUi.stopEditingUrl();
182 mUi.hideTitleBar();
Michael Kolbed217742010-08-10 17:52:34 -0700183 } else {
184 showUrlBar();
185 }
Michael Kolbc831b632011-05-11 09:30:34 -0700186 } else if (view instanceof TabView) {
187 final Tab tab = ((TabView) view).mTab;
Michael Kolbebba8b42010-09-30 12:57:59 -0700188 int ix = mTabs.getChildIndex(view);
189 if (ix >= 0) {
190 mTabs.setSelectedTab(ix);
Michael Kolbc831b632011-05-11 09:30:34 -0700191 mUiController.switchToTab(tab);
Michael Kolbebba8b42010-09-30 12:57:59 -0700192 }
Michael Kolba2b2ba82010-08-04 17:54:03 -0700193 }
194 }
195
Michael Kolbed217742010-08-10 17:52:34 -0700196 private void showUrlBar() {
Michael Kolb8233fac2010-10-26 16:08:53 -0700197 mUi.stopWebViewScrolling();
Michael Kolb7cdc4902011-02-03 17:54:40 -0800198 mUi.showTitleBar();
Michael Kolba2b2ba82010-08-04 17:54:03 -0700199 }
200
Michael Kolb94827b62011-01-08 14:23:45 -0800201 private TabView buildTabView(Tab tab) {
202 TabView tabview = new TabView(mActivity, tab);
203 mTabMap.put(tab, tabview);
204 tabview.setOnClickListener(this);
Michael Kolb94827b62011-01-08 14:23:45 -0800205 return tabview;
Michael Kolba2b2ba82010-08-04 17:54:03 -0700206 }
207
Romain Guyc8373212011-01-07 19:15:16 -0800208 private static Bitmap getDrawableAsBitmap(Drawable drawable, int width, int height) {
209 Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
210 Canvas c = new Canvas(b);
211 drawable.setBounds(0, 0, width, height);
212 drawable.draw(c);
Dianne Hackborn43cfe8a2011-08-02 16:59:35 -0700213 c.setBitmap(null);
Romain Guyc8373212011-01-07 19:15:16 -0800214 return b;
Michael Kolbb4cafc52011-01-12 16:55:04 -0800215 }
216
Michael Kolba2b2ba82010-08-04 17:54:03 -0700217 /**
218 * View used in the tab bar
219 */
220 class TabView extends LinearLayout implements OnClickListener {
221
Michael Kolb94827b62011-01-08 14:23:45 -0800222 Tab mTab;
Michael Kolba2b2ba82010-08-04 17:54:03 -0700223 View mTabContent;
224 TextView mTitle;
Michael Kolbae62fd42010-08-18 16:33:28 -0700225 View mIncognito;
John Reck541f55a2011-06-07 16:34:43 -0700226 View mSnapshot;
Enrico Ros1f5a0952014-11-18 20:15:48 -0800227 ImageView mFaviconView;
Michael Kolba2b2ba82010-08-04 17:54:03 -0700228 ImageView mLock;
229 ImageView mClose;
230 boolean mSelected;
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800231 Path mPath;
Michael Kolbeb7001c2011-02-16 16:07:33 -0800232 Path mFocusPath;
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800233 int[] mWindowPos;
Michael Kolba2b2ba82010-08-04 17:54:03 -0700234
235 /**
236 * @param context
237 */
Michael Kolb94827b62011-01-08 14:23:45 -0800238 public TabView(Context context, Tab tab) {
Michael Kolba2b2ba82010-08-04 17:54:03 -0700239 super(context);
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800240 setWillNotDraw(false);
241 mPath = new Path();
Michael Kolbeb7001c2011-02-16 16:07:33 -0800242 mFocusPath = new Path();
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800243 mWindowPos = new int[2];
Michael Kolb94827b62011-01-08 14:23:45 -0800244 mTab = tab;
Michael Kolbed217742010-08-10 17:52:34 -0700245 setGravity(Gravity.CENTER_VERTICAL);
246 setOrientation(LinearLayout.HORIZONTAL);
Michael Kolb49f15832011-01-25 15:02:27 -0800247 setPadding(mTabOverlap, 0, mTabSliceWidth, 0);
Bjorn Bringertb1402a52010-10-12 10:53:12 +0100248 LayoutInflater inflater = LayoutInflater.from(getContext());
Michael Kolbed217742010-08-10 17:52:34 -0700249 mTabContent = inflater.inflate(R.layout.tab_title, this, true);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700250 mTitle = (TextView) mTabContent.findViewById(R.id.title);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800251 mFaviconView = (ImageView) mTabContent.findViewById(R.id.favicon);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700252 mLock = (ImageView) mTabContent.findViewById(R.id.lock);
253 mClose = (ImageView) mTabContent.findViewById(R.id.close);
254 mClose.setOnClickListener(this);
Michael Kolbae62fd42010-08-18 16:33:28 -0700255 mIncognito = mTabContent.findViewById(R.id.incognito);
John Reck541f55a2011-06-07 16:34:43 -0700256 mSnapshot = mTabContent.findViewById(R.id.snapshot);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700257 mSelected = false;
Michael Kolba2b2ba82010-08-04 17:54:03 -0700258 // update the status
Michael Kolb94827b62011-01-08 14:23:45 -0800259 updateFromTab();
Michael Kolba2b2ba82010-08-04 17:54:03 -0700260 }
261
262 @Override
263 public void onClick(View v) {
264 if (v == mClose) {
265 closeTab();
266 }
267 }
268
Michael Kolb94827b62011-01-08 14:23:45 -0800269 private void updateFromTab() {
270 String displayTitle = mTab.getTitle();
John Reck30c714c2010-12-16 17:30:34 -0800271 if (displayTitle == null) {
Michael Kolb94827b62011-01-08 14:23:45 -0800272 displayTitle = mTab.getUrl();
Michael Kolba2b2ba82010-08-04 17:54:03 -0700273 }
John Reck30c714c2010-12-16 17:30:34 -0800274 setDisplayTitle(displayTitle);
Michael Kolb94827b62011-01-08 14:23:45 -0800275 if (mTab.getFavicon() != null) {
John Reck034637c2011-08-11 11:34:44 -0700276 setFavicon(mUi.getFaviconDrawable(mTab.getFavicon()));
Michael Kolba2b2ba82010-08-04 17:54:03 -0700277 }
John Reck541f55a2011-06-07 16:34:43 -0700278 updateTabIcons();
279 }
280
281 private void updateTabIcons() {
282 mIncognito.setVisibility(
283 mTab.isPrivateBrowsingEnabled() ?
284 View.VISIBLE : View.GONE);
285 mSnapshot.setVisibility(mTab.isSnapshot()
286 ? View.VISIBLE : View.GONE);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700287 }
288
289 @Override
Michael Kolbb7b115e2010-09-25 16:59:37 -0700290 public void setActivated(boolean selected) {
Michael Kolba2b2ba82010-08-04 17:54:03 -0700291 mSelected = selected;
292 mClose.setVisibility(mSelected ? View.VISIBLE : View.GONE);
Sagar Dhawan37765532015-07-31 18:46:35 -0700293 mFaviconView.setVisibility((mSelected || mTab.isSnapshot()) ?
294 View.GONE : View.VISIBLE);
Michael Kolb8233fac2010-10-26 16:08:53 -0700295 mTitle.setTextAppearance(mActivity, mSelected ?
Michael Kolbc7485ae2010-09-03 10:10:58 -0700296 R.style.TabTitleSelected : R.style.TabTitleUnselected);
297 setHorizontalFadingEdgeEnabled(!mSelected);
Michael Kolbb7b115e2010-09-25 16:59:37 -0700298 super.setActivated(selected);
Michael Kolb678afc82011-05-17 14:52:41 -0700299 updateLayoutParams();
Michael Kolbdc2ee1b2011-02-14 14:34:40 -0800300 setFocusable(!selected);
301 postInvalidate();
Michael Kolba2b2ba82010-08-04 17:54:03 -0700302 }
303
Michael Kolb678afc82011-05-17 14:52:41 -0700304 public void updateLayoutParams() {
305 LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
John Reck034637c2011-08-11 11:34:44 -0700306 lp.width = mTabWidth;
Michael Kolb678afc82011-05-17 14:52:41 -0700307 lp.height = LayoutParams.MATCH_PARENT;
308 setLayoutParams(lp);
309 }
310
Michael Kolba2b2ba82010-08-04 17:54:03 -0700311 void setDisplayTitle(String title) {
312 mTitle.setText(title);
313 }
314
315 void setFavicon(Drawable d) {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800316 mFaviconView.setImageDrawable(d);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700317 }
318
319 void setLock(Drawable d) {
320 if (null == d) {
321 mLock.setVisibility(View.GONE);
322 } else {
323 mLock.setImageDrawable(d);
324 mLock.setVisibility(View.VISIBLE);
325 }
326 }
327
Michael Kolba2b2ba82010-08-04 17:54:03 -0700328 private void closeTab() {
Michael Kolb94827b62011-01-08 14:23:45 -0800329 if (mTab == mTabControl.getCurrentTab()) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700330 mUiController.closeCurrentTab();
Michael Kolba2b2ba82010-08-04 17:54:03 -0700331 } else {
Michael Kolb94827b62011-01-08 14:23:45 -0800332 mUiController.closeTab(mTab);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700333 }
334 }
335
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800336 @Override
337 protected void onLayout(boolean changed, int l, int t, int r, int b) {
338 super.onLayout(changed, l, t, r, b);
339 setTabPath(mPath, 0, 0, r - l, b - t);
Michael Kolbeb7001c2011-02-16 16:07:33 -0800340 setFocusPath(mFocusPath, 0, 0, r - l, b - t);
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800341 }
Michael Kolbb4cafc52011-01-12 16:55:04 -0800342
Pankaj Gargf3f1b012014-11-26 14:52:22 -0800343 @Override
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800344 protected void dispatchDraw(Canvas canvas) {
Romain Guyc8373212011-01-07 19:15:16 -0800345 if (mCurrentTextureWidth != mUi.getContentWidth() ||
346 mCurrentTextureHeight != getHeight()) {
347 mCurrentTextureWidth = mUi.getContentWidth();
348 mCurrentTextureHeight = getHeight();
349
350 if (mCurrentTextureWidth > 0 && mCurrentTextureHeight > 0) {
Pankaj Gargf3f1b012014-11-26 14:52:22 -0800351 Bitmap activeTexture = Bitmap.createBitmap(
352 mCurrentTextureWidth, mCurrentTextureHeight, Bitmap.Config.ARGB_8888);
353 activeTexture.eraseColor(getResources().
354 getColor(R.color.NavigationBarBackground));
355 Bitmap inactiveTexture = Bitmap.createBitmap(
356 mCurrentTextureWidth, mCurrentTextureHeight, Bitmap.Config.ARGB_8888);
357 inactiveTexture.eraseColor(getResources().
358 getColor(R.color.TabNavBackgroundColor));
Romain Guyc8373212011-01-07 19:15:16 -0800359
360 mActiveShader = new BitmapShader(activeTexture,
361 Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
362 mActiveShaderPaint.setShader(mActiveShader);
Michael Kolbb4cafc52011-01-12 16:55:04 -0800363
Romain Guyc8373212011-01-07 19:15:16 -0800364 mInactiveShader = new BitmapShader(inactiveTexture,
365 Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
366 mInactiveShaderPaint.setShader(mInactiveShader);
367 }
368 }
Michael Kolb05902aa2011-02-22 17:43:38 -0800369 // add some monkey protection
370 if ((mActiveShader != null) && (mInactiveShader != null)) {
371 int state = canvas.save();
372 getLocationInWindow(mWindowPos);
373 Paint paint = mSelected ? mActiveShaderPaint : mInactiveShaderPaint;
374 drawClipped(canvas, paint, mPath, mWindowPos[0]);
375 canvas.restoreToCount(state);
376 }
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800377 super.dispatchDraw(canvas);
378 }
379
Romain Guyc8373212011-01-07 19:15:16 -0800380 private void drawClipped(Canvas canvas, Paint paint, Path clipPath, int left) {
381 // TODO: We should change the matrix/shader only when needed
382 final Matrix matrix = mSelected ? mActiveMatrix : mInactiveMatrix;
383 matrix.setTranslate(-left, 0.0f);
384 (mSelected ? mActiveShader : mInactiveShader).setLocalMatrix(matrix);
385 canvas.drawPath(clipPath, paint);
Michael Kolbdc2ee1b2011-02-14 14:34:40 -0800386 if (isFocused()) {
Michael Kolbeb7001c2011-02-16 16:07:33 -0800387 canvas.drawPath(mFocusPath, mFocusPaint);
Michael Kolbdc2ee1b2011-02-14 14:34:40 -0800388 }
Pankaj Gargf3f1b012014-11-26 14:52:22 -0800389 }
Michael Kolb2b5a13a2010-12-09 14:13:42 -0800390
391 private void setTabPath(Path path, int l, int t, int r, int b) {
392 path.reset();
393 path.moveTo(l, b);
394 path.lineTo(l, t);
395 path.lineTo(r - mTabSliceWidth, t);
396 path.lineTo(r, b);
397 path.close();
398 }
399
Michael Kolbeb7001c2011-02-16 16:07:33 -0800400 private void setFocusPath(Path path, int l, int t, int r, int b) {
401 path.reset();
402 path.moveTo(l, b);
403 path.lineTo(l, t);
404 path.lineTo(r - mTabSliceWidth, t);
405 path.lineTo(r, b);
406 }
407
Michael Kolba2b2ba82010-08-04 17:54:03 -0700408 }
409
Michael Kolb2d59c322011-01-25 13:18:55 -0800410 private void animateTabOut(final Tab tab, final TabView tv) {
411 ObjectAnimator scalex = ObjectAnimator.ofFloat(tv, "scaleX", 1.0f, 0.0f);
412 ObjectAnimator scaley = ObjectAnimator.ofFloat(tv, "scaleY", 1.0f, 0.0f);
Michael Kolb49f15832011-01-25 15:02:27 -0800413 ObjectAnimator alpha = ObjectAnimator.ofFloat(tv, "alpha", 1.0f, 0.0f);
Michael Kolb2d59c322011-01-25 13:18:55 -0800414 AnimatorSet animator = new AnimatorSet();
Michael Kolb49f15832011-01-25 15:02:27 -0800415 animator.playTogether(scalex, scaley, alpha);
Michael Kolb2d59c322011-01-25 13:18:55 -0800416 animator.setDuration(150);
417 animator.addListener(new AnimatorListener() {
418
419 @Override
420 public void onAnimationCancel(Animator animation) {
421 }
422
423 @Override
424 public void onAnimationEnd(Animator animation) {
425 mTabs.removeTab(tv);
426 mTabMap.remove(tab);
427 }
428
429 @Override
430 public void onAnimationRepeat(Animator animation) {
431 }
432
433 @Override
434 public void onAnimationStart(Animator animation) {
435 }
436
437 });
438 animator.start();
439 }
440
441 private void animateTabIn(final Tab tab, final TabView tv) {
Michael Kolb49f15832011-01-25 15:02:27 -0800442 ObjectAnimator scalex = ObjectAnimator.ofFloat(tv, "scaleX", 0.0f, 1.0f);
Michael Kolb2d59c322011-01-25 13:18:55 -0800443 scalex.setDuration(150);
444 scalex.addListener(new AnimatorListener() {
445
446 @Override
447 public void onAnimationCancel(Animator animation) {
448 }
449
450 @Override
451 public void onAnimationEnd(Animator animation) {
452 }
453
454 @Override
455 public void onAnimationRepeat(Animator animation) {
456 }
457
458 @Override
459 public void onAnimationStart(Animator animation) {
460 mTabs.addTab(tv);
461 }
462
463 });
464 scalex.start();
465 }
466
Michael Kolba2b2ba82010-08-04 17:54:03 -0700467 // TabChangeListener implementation
468
Michael Kolb8233fac2010-10-26 16:08:53 -0700469 public void onSetActiveTab(Tab tab) {
Michael Kolbc831b632011-05-11 09:30:34 -0700470 mTabs.setSelectedTab(mTabControl.getTabPosition(tab));
Michael Kolba2b2ba82010-08-04 17:54:03 -0700471 }
472
Michael Kolba2b2ba82010-08-04 17:54:03 -0700473 public void onFavicon(Tab tab, Bitmap favicon) {
Michael Kolb94827b62011-01-08 14:23:45 -0800474 TabView tv = mTabMap.get(tab);
475 if (tv != null) {
John Reck034637c2011-08-11 11:34:44 -0700476 tv.setFavicon(mUi.getFaviconDrawable(favicon));
Michael Kolba2b2ba82010-08-04 17:54:03 -0700477 }
478 }
479
Michael Kolba2b2ba82010-08-04 17:54:03 -0700480 public void onNewTab(Tab tab) {
Michael Kolb94827b62011-01-08 14:23:45 -0800481 TabView tv = buildTabView(tab);
Michael Kolb2d59c322011-01-25 13:18:55 -0800482 animateTabIn(tab, tv);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700483 }
484
Michael Kolba2b2ba82010-08-04 17:54:03 -0700485 public void onRemoveTab(Tab tab) {
Michael Kolb94827b62011-01-08 14:23:45 -0800486 TabView tv = mTabMap.get(tab);
487 if (tv != null) {
Michael Kolb2d59c322011-01-25 13:18:55 -0800488 animateTabOut(tab, tv);
489 } else {
490 mTabMap.remove(tab);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700491 }
Michael Kolba2b2ba82010-08-04 17:54:03 -0700492 }
493
Michael Kolba2b2ba82010-08-04 17:54:03 -0700494 public void onUrlAndTitle(Tab tab, String url, String title) {
Michael Kolb94827b62011-01-08 14:23:45 -0800495 TabView tv = mTabMap.get(tab);
496 if (tv != null) {
497 if (title != null) {
498 tv.setDisplayTitle(title);
499 } else if (url != null) {
500 tv.setDisplayTitle(UrlUtils.stripUrl(url));
501 }
John Reck541f55a2011-06-07 16:34:43 -0700502 tv.updateTabIcons();
Michael Kolba2b2ba82010-08-04 17:54:03 -0700503 }
504 }
505
Michael Kolba2b2ba82010-08-04 17:54:03 -0700506 private boolean isLoading() {
Michael Kolb1c3a6d22011-12-15 15:28:49 -0800507 Tab tab = mTabControl.getCurrentTab();
508 if (tab != null) {
509 return tab.inPageLoad();
Michael Kolb8233fac2010-10-26 16:08:53 -0700510 } else {
511 return false;
512 }
Michael Kolba2b2ba82010-08-04 17:54:03 -0700513 }
514
Michael Kolba2b2ba82010-08-04 17:54:03 -0700515}