TabBar.java revision c7485ae06c6d5d33c57a03d02bbeed54edb3c66f
1/* 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 17package com.android.browser; 18 19import android.content.Context; 20import android.content.res.Resources; 21import android.graphics.Bitmap; 22import android.graphics.Color; 23import android.graphics.drawable.BitmapDrawable; 24import android.graphics.drawable.Drawable; 25import android.graphics.drawable.LayerDrawable; 26import android.graphics.drawable.PaintDrawable; 27import android.view.ContextMenu; 28import android.view.Gravity; 29import android.view.LayoutInflater; 30import android.view.MenuInflater; 31import android.view.View; 32import android.view.View.OnClickListener; 33import android.webkit.WebView; 34import android.widget.ImageButton; 35import android.widget.ImageView; 36import android.widget.LinearLayout; 37import android.widget.TextView; 38 39import com.android.browser.ScrollWebView.ScrollListener; 40import com.android.browser.TabControl.TabChangeListener; 41 42import java.util.HashMap; 43import java.util.Map; 44 45/** 46 * tabbed title bar for xlarge screen browser 47 */ 48public class TabBar extends LinearLayout 49 implements TabChangeListener, ScrollListener, OnClickListener { 50 51 private static final int PROGRESS_MAX = 100; 52 53 private BrowserActivity mBrowserActivity; 54 55 private final int mTabWidthSelected; 56 private final int mTabWidthUnselected; 57 58 private TitleBarXLarge mTitleBar; 59 60 private TabScrollView mTabs; 61 private TabControl mControl; 62 63 private Map<Tab, TabViewData> mTabMap; 64 65 private float mDensityScale; 66 private boolean mUserRequestedUrlbar; 67 private boolean mTitleVisible; 68 private boolean mShowUrlMode; 69 70 public TabBar(BrowserActivity context, TabControl tabcontrol, TitleBarXLarge titlebar) { 71 super(context); 72 Resources res = context.getResources(); 73 mTabWidthSelected = (int) res.getDimension(R.dimen.tab_width_selected); 74 mTabWidthUnselected = (int) res.getDimension(R.dimen.tab_width_unselected); 75 76 mTitleBar = titlebar; 77 mTitleBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 78 LayoutParams.WRAP_CONTENT)); 79 mDensityScale = context.getResources().getDisplayMetrics().density; 80 mTabMap = new HashMap<Tab, TabViewData>(); 81 mBrowserActivity = context; 82 mControl = tabcontrol; 83 Resources resources = context.getResources(); 84 LayoutInflater factory = LayoutInflater.from(context); 85 factory.inflate(R.layout.tab_bar, this); 86 mTabs = (TabScrollView) findViewById(R.id.tabs); 87 88 // TODO: Change enabled states based on whether you can go 89 // back/forward. Probably should be done inside onPageStarted. 90 91 // build tabs 92 int tabcount = mControl.getTabCount(); 93 for (int i = 0; i < tabcount; i++) { 94 Tab tab = mControl.getTab(i); 95 TabViewData data = buildTab(tab); 96 TabView tv = buildView(data); 97 } 98 mTabs.setSelectedTab(mControl.getCurrentIndex()); 99 100 // register the tab change listener 101 mControl.setOnTabChangeListener(this); 102 mUserRequestedUrlbar = false; 103 mTitleVisible = true; 104 } 105 106 public void onClick(View view) { 107 if (mTabs.getSelectedTab() == view) { 108 if (mBrowserActivity.isFakeTitleBarShowing() && !isLoading()) { 109 mBrowserActivity.hideFakeTitleBar(); 110 } else { 111 showUrlBar(); 112 } 113 // temporarily disabled 114 // mTitleBar.requestUrlInputFocus(); 115 } else { 116 TabViewData data = (TabViewData) view.getTag(); 117 int ix = mControl.getTabIndex(data.mTab); 118 mTabs.setSelectedTab(ix); 119 mBrowserActivity.switchToTab(ix); 120 } 121 } 122 123 private void showUrlBar() { 124 mBrowserActivity.stopScrolling(); 125 mBrowserActivity.showFakeTitleBar(); 126 mUserRequestedUrlbar = true; 127 } 128 129 private void setShowUrlMode(boolean showUrl) { 130 mShowUrlMode = showUrl; 131 } 132 133 // callback after fake titlebar is shown 134 void onShowTitleBar() { 135 setShowUrlMode(false); 136 } 137 138 // callback after fake titlebar is hidden 139 void onHideTitleBar() { 140 setShowUrlMode(!mTitleVisible); 141 Tab tab = mControl.getCurrentTab(); 142 tab.getWebView().requestFocus(); 143 mUserRequestedUrlbar = false; 144 } 145 146 // webview scroll listener 147 148 @Override 149 public void onScroll(boolean titleVisible) { 150 mTitleVisible = titleVisible; 151 if (!mShowUrlMode && !mTitleVisible && !isLoading()) { 152 if (mUserRequestedUrlbar) { 153 mBrowserActivity.hideFakeTitleBar(); 154 } else { 155 setShowUrlMode(true); 156 } 157 } else if (mTitleVisible && !isLoading()) { 158 if (mShowUrlMode) { 159 setShowUrlMode(false); 160 } 161 } 162 } 163 164 @Override 165 public void createContextMenu(ContextMenu menu) { 166 MenuInflater inflater = mBrowserActivity.getMenuInflater(); 167 inflater.inflate(R.menu.title_context, menu); 168 mBrowserActivity.onCreateContextMenu(menu, this, null); 169 } 170 171 private TabViewData buildTab(Tab tab) { 172 TabViewData data = new TabViewData(tab); 173 mTabMap.put(tab, data); 174 return data; 175 } 176 177 private TabView buildView(final TabViewData data) { 178 TabView tv = new TabView(mBrowserActivity, data); 179 tv.setTag(data); 180 tv.setOnClickListener(this); 181 mTabs.addTab(tv); 182 return tv; 183 } 184 185 /** 186 * View used in the tab bar 187 */ 188 class TabView extends LinearLayout implements OnClickListener { 189 190 TabViewData mTabData; 191 View mTabContent; 192 TextView mTitle; 193 View mIncognito; 194 ImageView mIconView; 195 ImageView mLock; 196 ImageView mClose; 197 boolean mSelected; 198 boolean mInLoad; 199 200 /** 201 * @param context 202 */ 203 public TabView(Context context, TabViewData tab) { 204 super(context); 205 mTabData = tab; 206 setGravity(Gravity.CENTER_VERTICAL); 207 setOrientation(LinearLayout.HORIZONTAL); 208 setBackgroundResource(R.drawable.tab_background); 209 LayoutInflater inflater = LayoutInflater.from(mContext); 210 mTabContent = inflater.inflate(R.layout.tab_title, this, true); 211 mTitle = (TextView) mTabContent.findViewById(R.id.title); 212 mIconView = (ImageView) mTabContent.findViewById(R.id.favicon); 213 mLock = (ImageView) mTabContent.findViewById(R.id.lock); 214 mClose = (ImageView) mTabContent.findViewById(R.id.close); 215 mClose.setOnClickListener(this); 216 mIncognito = mTabContent.findViewById(R.id.incognito); 217 mSelected = false; 218 mInLoad = false; 219 // update the status 220 updateFromData(); 221 } 222 223 @Override 224 public void onClick(View v) { 225 if (v == mClose) { 226 closeTab(); 227 } 228 } 229 230 private void updateFromData() { 231 mTabData.mTabView = this; 232 if (mTabData.mUrl != null) { 233 setDisplayTitle(mTabData.mUrl); 234 } 235 if (mTabData.mTitle != null) { 236 setDisplayTitle(mTabData.mTitle); 237 } 238 setProgress(mTabData.mProgress); 239 if (mTabData.mIcon != null) { 240 setFavicon(mTabData.mIcon); 241 } 242 if (mTabData.mLock != null) { 243 setLock(mTabData.mLock); 244 } 245 if (mTabData.mTab != null) { 246 mIncognito.setVisibility( 247 mTabData.mTab.getWebView().isPrivateBrowsingEnabled() ? 248 View.VISIBLE : View.GONE); 249 } 250 } 251 252 @Override 253 public void setSelected(boolean selected) { 254 mSelected = selected; 255 mClose.setVisibility(mSelected ? View.VISIBLE : View.GONE); 256 mTitle.setTextAppearance(mBrowserActivity, mSelected ? 257 R.style.TabTitleSelected : R.style.TabTitleUnselected); 258 setHorizontalFadingEdgeEnabled(!mSelected); 259 setFadingEdgeLength(50); 260 super.setSelected(selected); 261 setLayoutParams(new LayoutParams(selected ? 262 mTabWidthSelected : mTabWidthUnselected, 263 LayoutParams.MATCH_PARENT)); 264 } 265 266 void setDisplayTitle(String title) { 267 mTitle.setText(title); 268 } 269 270 void setFavicon(Drawable d) { 271 mIconView.setImageDrawable(d); 272 } 273 274 void setLock(Drawable d) { 275 if (null == d) { 276 mLock.setVisibility(View.GONE); 277 } else { 278 mLock.setImageDrawable(d); 279 mLock.setVisibility(View.VISIBLE); 280 } 281 } 282 283 void setTitleCompoundDrawables(Drawable left, Drawable top, 284 Drawable right, Drawable bottom) { 285 mTitle.setCompoundDrawables(left, top, right, bottom); 286 } 287 288 void setProgress(int newProgress) { 289 if (newProgress >= PROGRESS_MAX) { 290 mInLoad = false; 291 } else { 292 if (!mInLoad && getWindowToken() != null) { 293 mInLoad = true; 294 } 295 } 296 } 297 298 private void closeTab() { 299 if (mTabData.mTab == mControl.getCurrentTab()) { 300 mBrowserActivity.closeCurrentWindow(); 301 } else { 302 mBrowserActivity.closeTab(mTabData.mTab); 303 } 304 } 305 306 } 307 308 /** 309 * Store tab state within the title bar 310 */ 311 class TabViewData { 312 313 Tab mTab; 314 TabView mTabView; 315 int mProgress; 316 Drawable mIcon; 317 Drawable mLock; 318 String mTitle; 319 String mUrl; 320 321 TabViewData(Tab tab) { 322 mTab = tab; 323 } 324 325 void setUrlAndTitle(String url, String title) { 326 mUrl = url; 327 mTitle = title; 328 if (mTabView != null) { 329 if (title != null) { 330 mTabView.setDisplayTitle(title); 331 } else if (url != null) { 332 mTabView.setDisplayTitle(url); 333 } 334 } 335 } 336 337 void setProgress(int newProgress) { 338 mProgress = newProgress; 339 if (mTabView != null) { 340 mTabView.setProgress(mProgress); 341 } 342 } 343 344 void setFavicon(Bitmap icon) { 345 Drawable[] array = new Drawable[3]; 346 array[0] = new PaintDrawable(Color.BLACK); 347 array[1] = new PaintDrawable(Color.WHITE); 348 if (icon == null) { 349// array[2] = mGenericFavicon; 350 } else { 351 array[2] = new BitmapDrawable(icon); 352 } 353 LayerDrawable d = new LayerDrawable(array); 354 d.setLayerInset(1, 1, 1, 1, 1); 355 d.setLayerInset(2, 2, 2, 2, 2); 356 mIcon = d; 357 if (mTabView != null) { 358 mTabView.setFavicon(mIcon); 359 } 360 } 361 362 } 363 364 // TabChangeListener implementation 365 366 @Override 367 public void onCurrentTab(Tab tab) { 368 mTabs.setSelectedTab(mControl.getCurrentIndex()); 369 TabViewData tvd = mTabMap.get(tab); 370 if (tvd != null) { 371 tvd.setProgress(tvd.mProgress); 372 // update the scroll state 373 WebView webview = tab.getWebView(); 374 onScroll(webview.getVisibleTitleHeight() > 0); 375 } 376 } 377 378 @Override 379 public void onFavicon(Tab tab, Bitmap favicon) { 380 TabViewData tvd = mTabMap.get(tab); 381 if (tvd != null) { 382 tvd.setFavicon(favicon); 383 } 384 } 385 386 @Override 387 public void onNewTab(Tab tab) { 388 TabViewData tvd = buildTab(tab); 389 buildView(tvd); 390 } 391 392 @Override 393 public void onProgress(Tab tab, int progress) { 394 TabViewData tvd = mTabMap.get(tab); 395 if (tvd != null) { 396 tvd.setProgress(progress); 397 } 398 } 399 400 @Override 401 public void onRemoveTab(Tab tab) { 402 TabViewData tvd = mTabMap.get(tab); 403 TabView tv = tvd.mTabView; 404 if (tv != null) { 405 mTabs.removeTab(tv); 406 } 407 mTabMap.remove(tab); 408 } 409 410 @Override 411 public void onUrlAndTitle(Tab tab, String url, String title) { 412 TabViewData tvd = mTabMap.get(tab); 413 if (tvd != null) { 414 tvd.setUrlAndTitle(url, title); 415 } 416 } 417 418 @Override 419 public void onPageFinished(Tab tab) { 420 } 421 422 @Override 423 public void onPageStarted(Tab tab) { 424 } 425 426 427 private boolean isLoading() { 428 return mTabMap.get(mControl.getCurrentTab()).mTabView.mInLoad; 429 } 430 431} 432