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 17 package com.android.browser; 18 19 import android.app.ActionBar; 20 import android.app.Activity; 21 import android.content.res.Resources; 22 import android.graphics.Bitmap; 23 import android.graphics.drawable.BitmapDrawable; 24 import android.graphics.drawable.Drawable; 25 import android.graphics.drawable.LayerDrawable; 26 import android.graphics.drawable.PaintDrawable; 27 import android.os.Bundle; 28 import android.os.Handler; 29 import android.util.Log; 30 import android.view.ActionMode; 31 import android.view.Gravity; 32 import android.view.KeyEvent; 33 import android.view.Menu; 34 import android.view.MenuItem; 35 import android.view.View; 36 import android.view.ViewGroup; 37 import android.webkit.WebChromeClient.CustomViewCallback; 38 import android.webkit.WebView; 39 40 import java.util.List; 41 42 /** 43 * Ui for xlarge screen sizes 44 */ 45 public class XLargeUi extends BaseUi { 46 47 private static final String LOGTAG = "XLargeUi"; 48 49 private PaintDrawable mFaviconBackground; 50 51 private ActionBar mActionBar; 52 private TabBar mTabBar; 53 54 private NavigationBarTablet mNavBar; 55 56 private PieControlXLarge mPieControl; 57 private Handler mHandler; 58 59 /** 60 * @param browser 61 * @param controller 62 */ 63 public XLargeUi(Activity browser, UiController controller) { 64 super(browser, controller); 65 mHandler = new Handler(); 66 mNavBar = (NavigationBarTablet) mTitleBar.getNavigationBar(); 67 mTabBar = new TabBar(mActivity, mUiController, this); 68 mActionBar = mActivity.getActionBar(); 69 setupActionBar(); 70 setUseQuickControls(BrowserSettings.getInstance().useQuickControls()); 71 } 72 73 private void setupActionBar() { 74 mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 75 mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); 76 mActionBar.setCustomView(mTabBar); 77 } 78 79 public void showComboView(ComboViews startWith, Bundle extras) { 80 super.showComboView(startWith, extras); 81 if (mUseQuickControls) { 82 mActionBar.show(); 83 } 84 } 85 86 @Override 87 public void setUseQuickControls(boolean useQuickControls) { 88 mUseQuickControls = useQuickControls; 89 mTitleBar.setUseQuickControls(mUseQuickControls); 90 if (useQuickControls) { 91 checkTabCount(); 92 mPieControl = new PieControlXLarge(mActivity, mUiController, this); 93 mPieControl.attachToContainer(mContentView); 94 WebView web = getWebView(); 95 if (web != null) { 96 web.setEmbeddedTitleBar(null); 97 98 } 99 } else { 100 mActivity.getActionBar().show(); 101 if (mPieControl != null) { 102 mPieControl.removeFromContainer(mContentView); 103 } 104 WebView web = getWebView(); 105 if (web != null) { 106 if (mTitleBar.getParent() != null) { 107 ViewGroup p = (ViewGroup) mTitleBar.getParent(); 108 p.removeView(mTitleBar); 109 } 110 web.setEmbeddedTitleBar(mTitleBar); 111 } 112 setTitleGravity(Gravity.NO_GRAVITY); 113 } 114 mTabBar.setUseQuickControls(mUseQuickControls); 115 // We need to update the tabs with this change 116 for (Tab t : mTabControl.getTabs()) { 117 t.updateShouldCaptureThumbnails(); 118 } 119 updateUrlBarAutoShowManagerTarget(); 120 } 121 122 private void checkTabCount() { 123 if (mUseQuickControls) { 124 mHandler.post(new Runnable() { 125 public void run() { 126 mActionBar.hide(); 127 } 128 }); 129 } 130 } 131 132 @Override 133 public void onResume() { 134 super.onResume(); 135 mNavBar.clearCompletions(); 136 } 137 138 @Override 139 public void onDestroy() { 140 hideTitleBar(); 141 } 142 143 void stopWebViewScrolling() { 144 BrowserWebView web = (BrowserWebView) mUiController.getCurrentWebView(); 145 if (web != null) { 146 web.stopScroll(); 147 } 148 } 149 150 @Override 151 public boolean onPrepareOptionsMenu(Menu menu) { 152 MenuItem bm = menu.findItem(R.id.bookmarks_menu_id); 153 if (bm != null) { 154 bm.setVisible(false); 155 } 156 return true; 157 } 158 159 160 // WebView callbacks 161 162 @Override 163 public void onProgressChanged(Tab tab) { 164 int progress = tab.getLoadProgress(); 165 mTabBar.onProgress(tab, progress); 166 if (tab.inForeground()) { 167 mTitleBar.setProgress(progress); 168 } 169 } 170 171 @Override 172 public void addTab(Tab tab) { 173 mTabBar.onNewTab(tab); 174 } 175 176 protected void onAddTabCompleted(Tab tab) { 177 checkTabCount(); 178 } 179 180 @Override 181 public void setActiveTab(final Tab tab) { 182 mTitleBar.cancelTitleBarAnimation(true); 183 mTitleBar.setSkipTitleBarAnimations(true); 184 super.setActiveTab(tab); 185 BrowserWebView view = (BrowserWebView) tab.getWebView(); 186 // TabControl.setCurrentTab has been called before this, 187 // so the tab is guaranteed to have a webview 188 if (view == null) { 189 Log.e(LOGTAG, "active tab with no webview detected"); 190 return; 191 } 192 // Request focus on the top window. 193 if (mUseQuickControls) { 194 mPieControl.forceToTop(mContentView); 195 } else { 196 // check if title bar is already attached by animation 197 if (mTitleBar.getParent() == null) { 198 view.setEmbeddedTitleBar(mTitleBar); 199 } 200 } 201 mTabBar.onSetActiveTab(tab); 202 if (tab.isInVoiceSearchMode()) { 203 showVoiceTitleBar(tab.getVoiceDisplayTitle(), tab.getVoiceSearchResults()); 204 } else { 205 revertVoiceTitleBar(tab); 206 } 207 updateLockIconToLatest(tab); 208 tab.getTopWindow().requestFocus(); 209 mTitleBar.setSkipTitleBarAnimations(false); 210 } 211 212 @Override 213 public void updateTabs(List<Tab> tabs) { 214 mTabBar.updateTabs(tabs); 215 checkTabCount(); 216 } 217 218 @Override 219 public void removeTab(Tab tab) { 220 mTitleBar.cancelTitleBarAnimation(true); 221 mTitleBar.setSkipTitleBarAnimations(true); 222 super.removeTab(tab); 223 mTabBar.onRemoveTab(tab); 224 mTitleBar.setSkipTitleBarAnimations(false); 225 } 226 227 protected void onRemoveTabCompleted(Tab tab) { 228 checkTabCount(); 229 } 230 231 int getContentWidth() { 232 if (mContentView != null) { 233 return mContentView.getWidth(); 234 } 235 return 0; 236 } 237 238 @Override 239 public void editUrl(boolean clearInput) { 240 if (mUseQuickControls) { 241 mTitleBar.setShowProgressOnly(false); 242 } 243 super.editUrl(clearInput); 244 } 245 246 void stopEditingUrl() { 247 mTitleBar.getNavigationBar().stopEditingUrl(); 248 } 249 250 @Override 251 protected void showTitleBar() { 252 if (canShowTitleBar()) { 253 mTitleBar.show(); 254 } 255 } 256 257 @Override 258 protected void hideTitleBar() { 259 if (isTitleBarShowing()) { 260 mTitleBar.hide(); 261 } 262 } 263 264 @Override 265 protected void setTitleGravity(int gravity) { 266 if (!mUseQuickControls) { 267 super.setTitleGravity(gravity); 268 } 269 } 270 271 // action mode callbacks 272 273 @Override 274 public void onActionModeStarted(ActionMode mode) { 275 if (!mTitleBar.isEditingUrl()) { 276 // hide the title bar when CAB is shown 277 hideTitleBar(); 278 } 279 } 280 281 @Override 282 public void onActionModeFinished(boolean inLoad) { 283 checkTabCount(); 284 if (inLoad) { 285 // the titlebar was removed when the CAB was shown 286 // if the page is loading, show it again 287 if (mUseQuickControls) { 288 mTitleBar.setShowProgressOnly(true); 289 } 290 showTitleBar(); 291 } 292 } 293 294 @Override 295 protected void updateNavigationState(Tab tab) { 296 mNavBar.updateNavigationState(tab); 297 } 298 299 @Override 300 public void setUrlTitle(Tab tab) { 301 super.setUrlTitle(tab); 302 mTabBar.onUrlAndTitle(tab, tab.getUrl(), tab.getTitle()); 303 } 304 305 // Set the favicon in the title bar. 306 @Override 307 public void setFavicon(Tab tab) { 308 super.setFavicon(tab); 309 mTabBar.onFavicon(tab, tab.getFavicon()); 310 } 311 312 @Override 313 public void onHideCustomView() { 314 super.onHideCustomView(); 315 if (mUseQuickControls) { 316 checkTabCount(); 317 } 318 } 319 320 @Override 321 public boolean dispatchKey(int code, KeyEvent event) { 322 if (mActiveTab != null) { 323 WebView web = mActiveTab.getWebView(); 324 if (event.getAction() == KeyEvent.ACTION_DOWN) { 325 switch (code) { 326 case KeyEvent.KEYCODE_TAB: 327 case KeyEvent.KEYCODE_DPAD_UP: 328 case KeyEvent.KEYCODE_DPAD_LEFT: 329 if ((web != null) && web.hasFocus() && !mTitleBar.hasFocus()) { 330 editUrl(false); 331 return true; 332 } 333 } 334 boolean ctrl = event.hasModifiers(KeyEvent.META_CTRL_ON); 335 if (!ctrl && isTypingKey(event) && !mTitleBar.isEditingUrl()) { 336 editUrl(true); 337 return mContentView.dispatchKeyEvent(event); 338 } 339 } 340 } 341 return false; 342 } 343 344 private boolean isTypingKey(KeyEvent evt) { 345 return evt.getUnicodeChar() > 0; 346 } 347 348 TabBar getTabBar() { 349 return mTabBar; 350 } 351 352 @Override 353 public boolean shouldCaptureThumbnails() { 354 return mUseQuickControls; 355 } 356 357 private Drawable getFaviconBackground() { 358 if (mFaviconBackground == null) { 359 mFaviconBackground = new PaintDrawable(); 360 Resources res = mActivity.getResources(); 361 mFaviconBackground.getPaint().setColor( 362 res.getColor(R.color.tabFaviconBackground)); 363 mFaviconBackground.setCornerRadius( 364 res.getDimension(R.dimen.tab_favicon_corner_radius)); 365 } 366 return mFaviconBackground; 367 } 368 369 @Override 370 public Drawable getFaviconDrawable(Bitmap icon) { 371 Drawable[] array = new Drawable[2]; 372 array[0] = getFaviconBackground(); 373 if (icon == null) { 374 array[1] = mGenericFavicon; 375 } else { 376 array[1] = new BitmapDrawable(mActivity.getResources(), icon); 377 } 378 LayerDrawable d = new LayerDrawable(array); 379 d.setLayerInset(1, 2, 2, 2, 2); 380 return d; 381 } 382 383 } 384