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