PhoneUi.java revision 8f11d06710c2c2be8e441ffe07c8fcd1195057be
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.animation.Animator; 20import android.animation.Animator.AnimatorListener; 21import android.animation.AnimatorSet; 22import android.animation.ObjectAnimator; 23import android.app.Activity; 24import android.util.Log; 25import android.view.ActionMode; 26import android.view.Gravity; 27import android.view.KeyEvent; 28import android.view.Menu; 29import android.view.View; 30import android.webkit.WebView; 31import android.widget.FrameLayout; 32 33/** 34 * Ui for regular phone screen sizes 35 */ 36public class PhoneUi extends BaseUi { 37 38 private static final String LOGTAG = "PhoneUi"; 39 private static final float NAV_TAB_SCALE = 0.75f; 40 41 private TitleBarPhone mTitleBar; 42 private ActiveTabsPage mActiveTabsPage; 43 private boolean mUseQuickControls; 44 private PieControl mPieControl; 45 private NavScreen mNavScreen; 46 47 boolean mExtendedMenuOpen; 48 boolean mOptionsMenuOpen; 49 50 /** 51 * @param browser 52 * @param controller 53 */ 54 public PhoneUi(Activity browser, UiController controller) { 55 super(browser, controller); 56 mTitleBar = new TitleBarPhone(mActivity, mUiController, this, 57 mContentView); 58 // mTitleBar will be always be shown in the fully loaded mode on 59 // phone 60 mTitleBar.setProgress(100); 61 mActivity.getActionBar().hide(); 62 setUseQuickControls(BrowserSettings.getInstance().useQuickControls()); 63 } 64 65 @Override 66 public void hideComboView() { 67 super.hideComboView(); 68 mActivity.getActionBar().hide(); 69 } 70 71 // lifecycle 72 73 @Override 74 public void onPause() { 75 // FIXME: This removes the active tabs page and resets the menu to 76 // MAIN_MENU. A better solution might be to do this work in onNewIntent 77 // but then we would need to save it in onSaveInstanceState and restore 78 // it in onCreate/onRestoreInstanceState 79 if (mActiveTabsPage != null) { 80 mUiController.removeActiveTabsPage(true); 81 } 82 super.onPause(); 83 } 84 85 @Override 86 public void onDestroy() { 87 hideTitleBar(); 88 } 89 90 @Override 91 public void editUrl(boolean clearInput) { 92 if (mUseQuickControls) { 93 getTitleBar().setShowProgressOnly(false); 94 } 95 super.editUrl(clearInput); 96 } 97 98 @Override 99 public boolean onBackKey() { 100 if (mActiveTabsPage != null) { 101 // if tab page is showing, hide it 102 mUiController.removeActiveTabsPage(true); 103 return true; 104 } else if (mNavScreen != null) { 105 mNavScreen.close(); 106 return true; 107 } 108 return super.onBackKey(); 109 } 110 111 @Override 112 public boolean dispatchKey(int code, KeyEvent event) { 113 if (!isComboViewShowing()) { 114 switch (code) { 115 case KeyEvent.KEYCODE_MENU: 116 if (mNavScreen == null) { 117 showNavScreen(); 118 return true; 119 } else { 120 mNavScreen.close(); 121 return true; 122 } 123 } 124 } 125 return false; 126 } 127 128 @Override 129 public void onProgressChanged(Tab tab) { 130 if (tab.inForeground()) { 131 int progress = tab.getLoadProgress(); 132 mTitleBar.setProgress(progress); 133 if (progress == 100) { 134 if (!mOptionsMenuOpen || !mExtendedMenuOpen) { 135 hideTitleBar(); 136 if (mUseQuickControls) { 137 mTitleBar.setShowProgressOnly(false); 138 } 139 } 140 } else { 141 if (!mOptionsMenuOpen || mExtendedMenuOpen) { 142 if (mUseQuickControls && !mTitleBar.isEditingUrl()) { 143 mTitleBar.setShowProgressOnly(true); 144 setTitleGravity(Gravity.TOP); 145 } 146 showTitleBar(); 147 } 148 } 149 } 150 } 151 152 @Override 153 public void setActiveTab(final Tab tab) { 154 captureTab(mActiveTab); 155 super.setActiveTab(tab, true); 156 setActiveTab(tab, true); 157 } 158 159 @Override 160 void setActiveTab(Tab tab, boolean needsAttaching) { 161 BrowserWebView view = (BrowserWebView) tab.getWebView(); 162 // TabControl.setCurrentTab has been called before this, 163 // so the tab is guaranteed to have a webview 164 if (view == null) { 165 Log.e(LOGTAG, "active tab with no webview detected"); 166 return; 167 } 168 // Request focus on the top window. 169 if (mUseQuickControls) { 170 mPieControl.forceToTop(mContentView); 171 view.setScrollListener(null); 172 } else { 173 // check if title bar is already attached by animation 174 if (mTitleBar.getParent() == null) { 175 view.setEmbeddedTitleBar(mTitleBar); 176 } 177 } 178 if (tab.isInVoiceSearchMode()) { 179 showVoiceTitleBar(tab.getVoiceDisplayTitle(), tab.getVoiceSearchResults()); 180 } else { 181 revertVoiceTitleBar(tab); 182 } 183 updateLockIconToLatest(tab); 184 tab.getTopWindow().requestFocus(); 185 } 186 187 @Override 188 protected TitleBarBase getTitleBar() { 189 return mTitleBar; 190 } 191 192 // active tabs page 193 194 @Override 195 public void showActiveTabsPage() { 196 captureTab(mActiveTab); 197 mActiveTabsPage = new ActiveTabsPage(mActivity, mUiController); 198 mTitleBar.setVisibility(View.GONE); 199 hideTitleBar(); 200 mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS); 201 mActiveTabsPage.requestFocus(); 202 } 203 204 /** 205 * Remove the active tabs page. 206 */ 207 @Override 208 public void removeActiveTabsPage() { 209 mContentView.removeView(mActiveTabsPage); 210 mTitleBar.setVisibility(View.VISIBLE); 211 mActiveTabsPage = null; 212 } 213 214 @Override 215 public boolean showsWeb() { 216 return super.showsWeb() && mActiveTabsPage == null; 217 } 218 219 // menu handling callbacks 220 221 @Override 222 public void onContextMenuCreated(Menu menu) { 223 hideTitleBar(); 224 } 225 226 @Override 227 public void onContextMenuClosed(Menu menu, boolean inLoad) { 228 if (inLoad) { 229 showTitleBar(); 230 } 231 } 232 233 // action mode callbacks 234 235 @Override 236 public void onActionModeStarted(ActionMode mode) { 237 hideTitleBar(); 238 } 239 240 @Override 241 public void onActionModeFinished(boolean inLoad) { 242 if (inLoad) { 243 if (mUseQuickControls) { 244 mTitleBar.setShowProgressOnly(true); 245 } 246 showTitleBar(); 247 } 248 mActivity.getActionBar().hide(); 249 } 250 251 @Override 252 protected void setTitleGravity(int gravity) { 253 if (mUseQuickControls) { 254 FrameLayout.LayoutParams lp = 255 (FrameLayout.LayoutParams) getTitleBar().getLayoutParams(); 256 lp.gravity = gravity; 257 getTitleBar().setLayoutParams(lp); 258 } else { 259 super.setTitleGravity(gravity); 260 } 261 } 262 263 private void setUseQuickControls(boolean useQuickControls) { 264 mUseQuickControls = useQuickControls; 265 getTitleBar().setUseQuickControls(mUseQuickControls); 266 if (useQuickControls) { 267 mPieControl = new PieControl(mActivity, mUiController, this); 268 mPieControl.attachToContainer(mContentView); 269 WebView web = getWebView(); 270 if (web != null) { 271 web.setEmbeddedTitleBar(null); 272 } 273 } else { 274 if (mPieControl != null) { 275 mPieControl.removeFromContainer(mContentView); 276 } 277 WebView web = getWebView(); 278 if (web != null) { 279 web.setEmbeddedTitleBar(mTitleBar); 280 } 281 setTitleGravity(Gravity.NO_GRAVITY); 282 } 283 } 284 285 @Override 286 protected void captureTab(final Tab tab) { 287 if (mUseQuickControls) { 288 super.captureTab(tab); 289 } else { 290 captureTab(tab, 291 mActivity.getWindowManager().getDefaultDisplay().getWidth(), 292 mActivity.getWindowManager().getDefaultDisplay().getHeight()); 293 } 294 } 295 296 void showNavScreen() { 297 captureTab(mActiveTab); 298 mNavScreen = new NavScreen(mActivity, mUiController, this); 299 WebView web = getWebView(); 300 if (web != null) { 301 int w = web.getWidth(); 302 int h = web.getHeight(); 303 mNavScreen.setTabDimensions((int) (w * NAV_TAB_SCALE), 304 (int) (h * NAV_TAB_SCALE)); 305 } 306 // Add the custom view to its container. 307 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_GRAVITY_CENTER); 308 ObjectAnimator animx = ObjectAnimator.ofFloat(mContentView, 309 "scaleX", 1.0f, 0.85f); 310 ObjectAnimator animy = ObjectAnimator.ofFloat(mContentView, 311 "scaleY", 1.0f, 0.85f); 312 AnimatorSet anims = new AnimatorSet(); 313 anims.setDuration(200); 314 anims.addListener(new AnimatorListener() { 315 316 @Override 317 public void onAnimationCancel(Animator animation) { 318 finishShowNavScreen(); 319 } 320 321 @Override 322 public void onAnimationEnd(Animator animation) { 323 finishShowNavScreen(); 324 } 325 326 @Override 327 public void onAnimationRepeat(Animator animation) { 328 } 329 330 @Override 331 public void onAnimationStart(Animator animation) { 332 } 333 }); 334 anims.playTogether(animx, animy); 335 anims.start(); 336 } 337 338 private void finishShowNavScreen() { 339 // Hide the content view. 340 mContentView.setVisibility(View.GONE); 341 mContentView.setScaleX(1.0f); 342 mContentView.setScaleY(1.0f); 343 // Finally show the custom view container. 344 mCustomViewContainer.setVisibility(View.VISIBLE); 345 mCustomViewContainer.bringToFront(); 346 } 347 348 void hideNavScreen(boolean animateToPage) { 349 if (mNavScreen == null) return; 350 if (animateToPage) { 351 ObjectAnimator animx = ObjectAnimator.ofFloat(mNavScreen, "scaleX", 352 1.0f, 1.2f); 353 ObjectAnimator animy = ObjectAnimator.ofFloat(mNavScreen, "scaleY", 354 1.0f, 1.2f); 355 AnimatorSet anims = new AnimatorSet(); 356 anims.setDuration(200); 357 anims.addListener(new AnimatorListener() { 358 359 @Override 360 public void onAnimationCancel(Animator animation) { 361 finishHideNavScreen(); 362 } 363 364 @Override 365 public void onAnimationEnd(Animator animation) { 366 finishHideNavScreen(); 367 } 368 369 @Override 370 public void onAnimationRepeat(Animator animation) { 371 } 372 373 @Override 374 public void onAnimationStart(Animator animation) { 375 } 376 }); 377 anims.playTogether(animx, animy); 378 anims.start(); 379 } else { 380 finishHideNavScreen(); 381 } 382 383 } 384 385 private void finishHideNavScreen() { 386 // Hide the custom view. 387 mNavScreen.setVisibility(View.GONE); 388 // Remove the custom view from its container. 389 mCustomViewContainer.removeView(mNavScreen); 390 mNavScreen = null; 391 mCustomViewContainer.setVisibility(View.GONE); 392 // Show the content view. 393 mContentView.setVisibility(View.VISIBLE); 394 } 395 396} 397