OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.toolbar; |
| 6 |
| 7 import android.annotation.SuppressLint; |
| 8 import android.content.Context; |
| 9 import android.graphics.Bitmap; |
| 10 import android.graphics.Canvas; |
| 11 import android.graphics.Rect; |
| 12 import android.graphics.drawable.Drawable; |
| 13 import android.os.SystemClock; |
| 14 import android.util.AttributeSet; |
| 15 import android.view.MotionEvent; |
| 16 import android.view.View; |
| 17 import android.view.ViewGroup; |
| 18 import android.widget.FrameLayout; |
| 19 import android.widget.ProgressBar; |
| 20 |
| 21 import com.google.android.apps.chrome.R; |
| 22 |
| 23 import org.chromium.chrome.browser.Tab; |
| 24 import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper; |
| 25 import org.chromium.chrome.browser.compositor.Invalidator; |
| 26 import org.chromium.chrome.browser.ntp.NewTabPage; |
| 27 import org.chromium.chrome.browser.omnibox.LocationBar; |
| 28 import org.chromium.chrome.browser.util.ViewUtils; |
| 29 import org.chromium.chrome.browser.widget.SmoothProgressBar; |
| 30 import org.chromium.chrome.browser.widget.TintedImageButton; |
| 31 import org.chromium.ui.UiUtils; |
| 32 |
| 33 /** |
| 34 * Layout class that contains the base shared logic for manipulating the toolbar
component. For |
| 35 * interaction that are not from Views inside Toolbar hierarchy all interactions
should be done |
| 36 * through {@link Toolbar} rather than using this class directly. |
| 37 */ |
| 38 abstract class ToolbarLayout extends FrameLayout implements Toolbar { |
| 39 protected static final int BACKGROUND_TRANSITION_DURATION_MS = 400; |
| 40 |
| 41 private Invalidator mInvalidator; |
| 42 |
| 43 private final int[] mTempPosition = new int[2]; |
| 44 |
| 45 /** |
| 46 * The ImageButton view that represents the menu button. |
| 47 */ |
| 48 protected TintedImageButton mMenuButton; |
| 49 private AppMenuButtonHelper mAppMenuButtonHelper; |
| 50 |
| 51 private ToolbarDataProvider mToolbarDataProvider; |
| 52 private ToolbarTabController mToolbarTabController; |
| 53 private SmoothProgressBar mProgressBar; |
| 54 |
| 55 private boolean mNativeLibraryReady; |
| 56 private boolean mUrlHasFocus; |
| 57 |
| 58 private long mFirstDrawTimeMs; |
| 59 |
| 60 protected final int mToolbarHeightWithoutShadow; |
| 61 |
| 62 /** |
| 63 * Basic constructor for {@link ToolbarLayout}. |
| 64 */ |
| 65 public ToolbarLayout(Context context, AttributeSet attrs) { |
| 66 super(context, attrs); |
| 67 mToolbarHeightWithoutShadow = getResources().getDimensionPixelOffset( |
| 68 R.dimen.toolbar_height_no_shadow); |
| 69 } |
| 70 |
| 71 @Override |
| 72 protected void onFinishInflate() { |
| 73 super.onFinishInflate(); |
| 74 |
| 75 mProgressBar = (SmoothProgressBar) findViewById(R.id.progress); |
| 76 if (mProgressBar != null) { |
| 77 removeView(mProgressBar); |
| 78 Drawable progressDrawable = mProgressBar.getProgressDrawable(); |
| 79 getFrameLayoutParams(mProgressBar).topMargin = mToolbarHeightWithout
Shadow |
| 80 - progressDrawable.getIntrinsicHeight(); |
| 81 } |
| 82 |
| 83 mMenuButton = (TintedImageButton) findViewById(R.id.menu_button); |
| 84 // Initialize the provider to an empty version to avoid null checking ev
erywhere. |
| 85 mToolbarDataProvider = new ToolbarDataProvider() { |
| 86 @Override |
| 87 public boolean isIncognito() { |
| 88 return false; |
| 89 } |
| 90 |
| 91 @Override |
| 92 public Tab getTab() { |
| 93 return null; |
| 94 } |
| 95 |
| 96 @Override |
| 97 public String getText() { |
| 98 return null; |
| 99 } |
| 100 |
| 101 @Override |
| 102 public boolean wouldReplaceURL() { |
| 103 return false; |
| 104 } |
| 105 |
| 106 @Override |
| 107 public NewTabPage getNewTabPageForCurrentTab() { |
| 108 return null; |
| 109 } |
| 110 |
| 111 @Override |
| 112 public int getLoadProgress() { |
| 113 return 0; |
| 114 } |
| 115 |
| 116 @Override |
| 117 public String getCorpusChipText() { |
| 118 return null; |
| 119 } |
| 120 |
| 121 @Override |
| 122 public int getPrimaryColor() { |
| 123 return 0; |
| 124 } |
| 125 |
| 126 @Override |
| 127 public boolean isUsingBrandColor() { |
| 128 return false; |
| 129 } |
| 130 }; |
| 131 } |
| 132 |
| 133 /** |
| 134 * Quick getter for LayoutParams for a View inside a FrameLayout. |
| 135 * @param view {@link View} to fetch the layout params for. |
| 136 * @return {@link LayoutParams} the given {@link View} is currently using. |
| 137 */ |
| 138 protected FrameLayout.LayoutParams getFrameLayoutParams(View view) { |
| 139 return ((FrameLayout.LayoutParams) view.getLayoutParams()); |
| 140 } |
| 141 |
| 142 @Override |
| 143 public void initialize(ToolbarDataProvider toolbarDataProvider, |
| 144 ToolbarTabController tabController, AppMenuButtonHelper appMenuButto
nHelper) { |
| 145 mToolbarDataProvider = toolbarDataProvider; |
| 146 mToolbarTabController = tabController; |
| 147 |
| 148 mMenuButton.setOnTouchListener(new OnTouchListener() { |
| 149 @Override |
| 150 @SuppressLint("ClickableViewAccessibility") |
| 151 public boolean onTouch(View v, MotionEvent event) { |
| 152 return mAppMenuButtonHelper.onTouch(v, event); |
| 153 } |
| 154 }); |
| 155 mAppMenuButtonHelper = appMenuButtonHelper; |
| 156 } |
| 157 |
| 158 /** |
| 159 * This function handles native dependent initialization for this class |
| 160 */ |
| 161 public void onNativeLibraryReady() { |
| 162 mNativeLibraryReady = true; |
| 163 } |
| 164 |
| 165 /** |
| 166 * @return The menu button view. |
| 167 */ |
| 168 protected View getMenuButton() { |
| 169 return mMenuButton; |
| 170 } |
| 171 |
| 172 /** |
| 173 * @return The {@link ProgressBar} this layout uses. |
| 174 */ |
| 175 SmoothProgressBar getProgressBar() { |
| 176 return mProgressBar; |
| 177 } |
| 178 |
| 179 @Override |
| 180 public void getPositionRelativeToContainer(View containerView, int[] positio
n) { |
| 181 ViewUtils.getRelativeDrawPosition(containerView, this, position); |
| 182 } |
| 183 |
| 184 /** |
| 185 * @return The helper for menu button UI interactions. |
| 186 */ |
| 187 protected AppMenuButtonHelper getMenuButtonHelper() { |
| 188 return mAppMenuButtonHelper; |
| 189 } |
| 190 |
| 191 /** |
| 192 * @return Whether or not the native library is loaded and ready. |
| 193 */ |
| 194 protected boolean isNativeLibraryReady() { |
| 195 return mNativeLibraryReady; |
| 196 } |
| 197 |
| 198 @Override |
| 199 protected void onDraw(Canvas canvas) { |
| 200 super.onDraw(canvas); |
| 201 recordFirstDrawTime(); |
| 202 } |
| 203 |
| 204 @Override |
| 205 protected void onAttachedToWindow() { |
| 206 super.onAttachedToWindow(); |
| 207 if (mProgressBar != null) { |
| 208 ViewGroup controlContainer = |
| 209 (ViewGroup) getRootView().findViewById(R.id.control_containe
r); |
| 210 int progressBarPosition = UiUtils.insertAfter( |
| 211 controlContainer, mProgressBar, (View) getParent()); |
| 212 assert progressBarPosition >= 0; |
| 213 } |
| 214 } |
| 215 |
| 216 /** |
| 217 * @return The provider for toolbar related data. |
| 218 */ |
| 219 protected ToolbarDataProvider getToolbarDataProvider() { |
| 220 return mToolbarDataProvider; |
| 221 } |
| 222 |
| 223 @Override |
| 224 public void setPaintInvalidator(Invalidator invalidator) { |
| 225 mInvalidator = invalidator; |
| 226 } |
| 227 |
| 228 /** |
| 229 * Triggers a paint but allows the {@link Invalidator} set by |
| 230 * {@link #setPaintInvalidator(Invalidator)} to decide when to actually inva
lidate. |
| 231 * @param client A {@link Invalidator.Client} instance that wants to be inva
lidated. |
| 232 */ |
| 233 protected void triggerPaintInvalidate(Invalidator.Client client) { |
| 234 if (mInvalidator == null) { |
| 235 client.doInvalidate(); |
| 236 } else { |
| 237 mInvalidator.invalidate(client); |
| 238 } |
| 239 } |
| 240 |
| 241 @Override |
| 242 public void setOnTabSwitcherClickHandler(OnClickListener listener) { } |
| 243 |
| 244 @Override |
| 245 public void setOnNewTabClickHandler(OnClickListener listener) { } |
| 246 |
| 247 @Override |
| 248 public void setBookmarkClickHandler(OnClickListener listener) { } |
| 249 |
| 250 @Override |
| 251 public void setHostedBackClickHandler(OnClickListener listener) { } |
| 252 |
| 253 /** |
| 254 * Gives inheriting classes the chance to update the visibility of the |
| 255 * back button. |
| 256 * @param canGoBack Whether or not the current tab has any history to go bac
k to. |
| 257 */ |
| 258 protected void updateBackButtonVisibility(boolean canGoBack) { } |
| 259 |
| 260 /** |
| 261 * Gives inheriting classes the chance to update the visibility of the |
| 262 * forward button. |
| 263 * @param canGoForward Whether or not the current tab has any history to go
forward to. |
| 264 */ |
| 265 protected void updateForwardButtonVisibility(boolean canGoForward) { } |
| 266 |
| 267 /** |
| 268 * Gives inheriting classes the chance to update the visibility of the |
| 269 * reload button. |
| 270 * @param isReloading Whether or not the current tab is loading. |
| 271 */ |
| 272 protected void updateReloadButtonVisibility(boolean isReloading) { } |
| 273 |
| 274 /** |
| 275 * Gives inheriting classes the chance to update the visibility of the |
| 276 * bookmark button. |
| 277 * @param isBookmarked Whether or not the current tab is already bookmarked. |
| 278 */ |
| 279 protected void updateBookmarkButtonVisibility(boolean isBookmarked) { } |
| 280 |
| 281 /** |
| 282 * Gives inheriting classes the chance to respond to |
| 283 * {@link org.chromium.chrome.browser.widget.findinpage.FindToolbar} state c
hanges. |
| 284 * @param showing Whether or not the {@code FindToolbar} will be showing. |
| 285 */ |
| 286 protected void handleFindToolbarStateChange(boolean showing) { } |
| 287 |
| 288 /** |
| 289 * Gives inheriting classes the chance to respond to accessibility state cha
nges. |
| 290 * @param enabled Whether or not accessibility is enabled. |
| 291 */ |
| 292 protected void onAccessibilityStatusChanged(boolean enabled) { } |
| 293 |
| 294 /** |
| 295 * Gives inheriting classes the chance to do the necessary UI operations aft
er Chrome is |
| 296 * restored to a previously saved state. |
| 297 */ |
| 298 protected void onStateRestored() { } |
| 299 |
| 300 /** |
| 301 * Gives inheriting classes the chance to update home button UI if home butt
on preference is |
| 302 * changed. |
| 303 * @param homeButtonEnabled Whether or not home button is enabled in prefere
nce. |
| 304 */ |
| 305 protected void onHomeButtonUpdate(boolean homeButtonEnabled) { } |
| 306 |
| 307 /** |
| 308 * Triggered when the current tab or model has changed. |
| 309 * <p> |
| 310 * As there are cases where you can select a model with no tabs (i.e. having
incognito |
| 311 * tabs but no normal tabs will still allow you to select the normal model),
this should |
| 312 * not guarantee that the model's current tab is non-null. |
| 313 */ |
| 314 protected void onTabOrModelChanged() { |
| 315 NewTabPage ntp = getToolbarDataProvider().getNewTabPageForCurrentTab(); |
| 316 if (ntp != null) getLocationBar().onTabLoadingNTP(ntp); |
| 317 |
| 318 getLocationBar().updateMicButtonState(); |
| 319 } |
| 320 |
| 321 /** |
| 322 * For extending classes to override and carry out the changes related with
the primary color |
| 323 * for the current tab changing. |
| 324 */ |
| 325 protected void onPrimaryColorChanged() { } |
| 326 |
| 327 @Override |
| 328 public void addCustomActionButton(Bitmap buttonSource, OnClickListener liste
ner) { } |
| 329 |
| 330 /** |
| 331 * Triggered when the content view for the specified tab has changed. |
| 332 */ |
| 333 protected void onTabContentViewChanged() { |
| 334 NewTabPage ntp = getToolbarDataProvider().getNewTabPageForCurrentTab(); |
| 335 if (ntp != null) getLocationBar().onTabLoadingNTP(ntp); |
| 336 } |
| 337 |
| 338 @Override |
| 339 public boolean isReadyForTextureCapture() { |
| 340 return true; |
| 341 } |
| 342 |
| 343 /** |
| 344 * @param attached Whether or not the web content is attached to the view he
irarchy. |
| 345 */ |
| 346 protected void setContentAttached(boolean attached) { } |
| 347 |
| 348 /** |
| 349 * Gives inheriting classes the chance to show or hide the TabSwitcher mode
of this toolbar. |
| 350 * @param inTabSwitcherMode Whether or not TabSwitcher mode should be shown
or hidden. |
| 351 * @param showToolbar Whether or not to show the normal toolbar while ani
mating. |
| 352 * @param delayAnimation Whether or not to delay the animation until after t
he transition has |
| 353 * finished (which can be detected by a call to |
| 354 * {@link #onTabSwitcherTransitionFinished()}). |
| 355 */ |
| 356 protected void setTabSwitcherMode( |
| 357 boolean inTabSwitcherMode, boolean showToolbar, boolean delayAnimati
on) { } |
| 358 |
| 359 /** |
| 360 * Gives inheriting classes the chance to update their state when the TabSwi
tcher transition has |
| 361 * finished. |
| 362 */ |
| 363 protected void onTabSwitcherTransitionFinished() { } |
| 364 |
| 365 /** |
| 366 * Gives inheriting classes the chance to update themselves based on the |
| 367 * number of tabs in the current TabModel. |
| 368 * @param numberOfTabs The number of tabs in the current model. |
| 369 */ |
| 370 protected void updateTabCountVisuals(int numberOfTabs) { } |
| 371 |
| 372 /** |
| 373 * Gives inheriting classes the chance to update themselves based on default
search engine |
| 374 * changes. |
| 375 */ |
| 376 protected void onDefaultSearchEngineChanged() { } |
| 377 |
| 378 @Override |
| 379 public void getLocationBarContentRect(Rect outRect) { |
| 380 View container = getLocationBar().getContainerView(); |
| 381 outRect.set(container.getPaddingLeft(), container.getPaddingTop(), |
| 382 container.getWidth() - container.getPaddingRight(), |
| 383 container.getHeight() - container.getPaddingBottom()); |
| 384 ViewUtils.getRelativeDrawPosition( |
| 385 this, getLocationBar().getContainerView(), mTempPosition); |
| 386 outRect.offset(mTempPosition[0], mTempPosition[1]); |
| 387 } |
| 388 |
| 389 @Override |
| 390 public void setTextureCaptureMode(boolean textureMode) { } |
| 391 |
| 392 @Override |
| 393 public boolean shouldIgnoreSwipeGesture() { |
| 394 return mUrlHasFocus |
| 395 || (mAppMenuButtonHelper != null && mAppMenuButtonHelper.isAppMe
nuActive()); |
| 396 } |
| 397 |
| 398 /** |
| 399 * @return Whether or not the url bar has focus. |
| 400 */ |
| 401 protected boolean urlHasFocus() { |
| 402 return mUrlHasFocus; |
| 403 } |
| 404 |
| 405 /** |
| 406 * Triggered when the URL input field has gained or lost focus. |
| 407 * @param hasFocus Whether the URL field has gained focus. |
| 408 */ |
| 409 protected void onUrlFocusChange(boolean hasFocus) { |
| 410 mUrlHasFocus = hasFocus; |
| 411 } |
| 412 |
| 413 protected boolean shouldShowMenuButton() { |
| 414 return true; |
| 415 } |
| 416 |
| 417 /** |
| 418 * Keeps track of the first time the toolbar is drawn. |
| 419 */ |
| 420 private void recordFirstDrawTime() { |
| 421 if (mFirstDrawTimeMs == 0) mFirstDrawTimeMs = SystemClock.elapsedRealtim
e(); |
| 422 } |
| 423 |
| 424 @Override |
| 425 public long getFirstDrawTime() { |
| 426 return mFirstDrawTimeMs; |
| 427 } |
| 428 |
| 429 /** |
| 430 * Notified when a navigation to a different page has occurred. |
| 431 */ |
| 432 protected void onNavigatedToDifferentPage() { |
| 433 } |
| 434 |
| 435 /** |
| 436 * Sets load progress. |
| 437 * @param progress The load progress between 0 and 100. |
| 438 */ |
| 439 protected void setLoadProgress(int progress) { |
| 440 if (mProgressBar != null) mProgressBar.setProgress(progress); |
| 441 } |
| 442 |
| 443 @Override |
| 444 public void finishAnimations() { } |
| 445 |
| 446 /** |
| 447 * @return The current View showing in the Tab. |
| 448 */ |
| 449 protected View getCurrentTabView() { |
| 450 Tab tab = mToolbarDataProvider.getTab(); |
| 451 if (tab != null) { |
| 452 return tab.getView(); |
| 453 } |
| 454 return null; |
| 455 } |
| 456 |
| 457 /** |
| 458 * @return Whether or not the toolbar is incognito. |
| 459 */ |
| 460 protected boolean isIncognito() { |
| 461 return mToolbarDataProvider.isIncognito(); |
| 462 } |
| 463 |
| 464 @Override |
| 465 public abstract LocationBar getLocationBar(); |
| 466 |
| 467 /** |
| 468 * Navigates the current Tab back. |
| 469 * @return Whether or not the current Tab did go back. |
| 470 */ |
| 471 protected boolean back() { |
| 472 getLocationBar().hideSuggestions(); |
| 473 return mToolbarTabController != null ? mToolbarTabController.back() : fa
lse; |
| 474 } |
| 475 |
| 476 /** |
| 477 * Navigates the current Tab forward. |
| 478 * @return Whether or not the current Tab did go forward. |
| 479 */ |
| 480 protected boolean forward() { |
| 481 getLocationBar().hideSuggestions(); |
| 482 return mToolbarTabController != null ? mToolbarTabController.forward() :
false; |
| 483 } |
| 484 |
| 485 /** |
| 486 * If the page is currently loading, this will trigger the tab to stop. If
the page is fully |
| 487 * loaded, this will trigger a refresh. |
| 488 * |
| 489 * <p>The buttons of the toolbar will be updated as a result of making this
call. |
| 490 */ |
| 491 protected void stopOrReloadCurrentTab() { |
| 492 getLocationBar().hideSuggestions(); |
| 493 if (mToolbarTabController != null) mToolbarTabController.stopOrReloadCur
rentTab(); |
| 494 } |
| 495 |
| 496 /** |
| 497 * Opens hompage in the current tab. |
| 498 */ |
| 499 protected void openHomepage() { |
| 500 getLocationBar().hideSuggestions(); |
| 501 if (mToolbarTabController != null) mToolbarTabController.openHomepage(); |
| 502 } |
| 503 } |
OLD | NEW |