mobile/android/base/toolbar/ToolbarDisplayLayout.java

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 package org.mozilla.gecko.toolbar;
michael@0 7
michael@0 8 import org.mozilla.gecko.AboutPages;
michael@0 9 import org.mozilla.gecko.animation.PropertyAnimator;
michael@0 10 import org.mozilla.gecko.animation.ViewHelper;
michael@0 11 import org.mozilla.gecko.BrowserApp;
michael@0 12 import org.mozilla.gecko.R;
michael@0 13 import org.mozilla.gecko.SiteIdentity;
michael@0 14 import org.mozilla.gecko.SiteIdentity.SecurityMode;
michael@0 15 import org.mozilla.gecko.Tab;
michael@0 16 import org.mozilla.gecko.Tabs;
michael@0 17 import org.mozilla.gecko.toolbar.BrowserToolbar.ForwardButtonAnimation;
michael@0 18 import org.mozilla.gecko.util.StringUtils;
michael@0 19 import org.mozilla.gecko.widget.ThemedLinearLayout;
michael@0 20 import org.mozilla.gecko.widget.ThemedTextView;
michael@0 21
michael@0 22 import org.json.JSONObject;
michael@0 23
michael@0 24 import android.content.Context;
michael@0 25 import android.content.res.Resources;
michael@0 26 import android.graphics.Bitmap;
michael@0 27 import android.os.Build;
michael@0 28 import android.os.SystemClock;
michael@0 29 import android.text.style.ForegroundColorSpan;
michael@0 30 import android.text.Spannable;
michael@0 31 import android.text.SpannableStringBuilder;
michael@0 32 import android.text.Spanned;
michael@0 33 import android.text.TextUtils;
michael@0 34 import android.util.AttributeSet;
michael@0 35 import android.util.Log;
michael@0 36 import android.view.LayoutInflater;
michael@0 37 import android.view.View;
michael@0 38 import android.view.animation.Animation;
michael@0 39 import android.view.animation.AnimationUtils;
michael@0 40 import android.view.animation.AlphaAnimation;
michael@0 41 import android.view.animation.TranslateAnimation;
michael@0 42 import android.widget.Button;
michael@0 43 import android.widget.ImageButton;
michael@0 44 import android.widget.LinearLayout.LayoutParams;
michael@0 45
michael@0 46 import java.util.Arrays;
michael@0 47 import java.util.EnumSet;
michael@0 48 import java.util.List;
michael@0 49
michael@0 50 /**
michael@0 51 * {@code ToolbarDisplayLayout} is the UI for when the toolbar is in
michael@0 52 * display state. It's used to display the state of the currently selected
michael@0 53 * tab. It should always be updated through a single entry point
michael@0 54 * (updateFromTab) and should never track any tab events or gecko messages
michael@0 55 * on its own to keep it as dumb as possible.
michael@0 56 *
michael@0 57 * The UI has two possible modes: progress and display which are triggered
michael@0 58 * when UpdateFlags.PROGRESS is used depending on the current tab state.
michael@0 59 * The progress mode is triggered when the tab is loading a page. Display mode
michael@0 60 * is used otherwise.
michael@0 61 *
michael@0 62 * {@code ToolbarDisplayLayout} is meant to be owned by {@code BrowserToolbar}
michael@0 63 * which is the main event bus for the toolbar subsystem.
michael@0 64 */
michael@0 65 public class ToolbarDisplayLayout extends ThemedLinearLayout
michael@0 66 implements Animation.AnimationListener {
michael@0 67
michael@0 68 private static final String LOGTAG = "GeckoToolbarDisplayLayout";
michael@0 69
michael@0 70 // To be used with updateFromTab() to allow the caller
michael@0 71 // to give enough context for the requested state change.
michael@0 72 enum UpdateFlags {
michael@0 73 TITLE,
michael@0 74 FAVICON,
michael@0 75 PROGRESS,
michael@0 76 SITE_IDENTITY,
michael@0 77 PRIVATE_MODE,
michael@0 78
michael@0 79 // Disable any animation that might be
michael@0 80 // triggered from this state change. Mostly
michael@0 81 // used on tab switches, see BrowserToolbar.
michael@0 82 DISABLE_ANIMATIONS
michael@0 83 }
michael@0 84
michael@0 85 private enum UIMode {
michael@0 86 PROGRESS,
michael@0 87 DISPLAY
michael@0 88 }
michael@0 89
michael@0 90 interface OnStopListener {
michael@0 91 public Tab onStop();
michael@0 92 }
michael@0 93
michael@0 94 interface OnTitleChangeListener {
michael@0 95 public void onTitleChange(CharSequence title);
michael@0 96 }
michael@0 97
michael@0 98 private final BrowserApp mActivity;
michael@0 99
michael@0 100 private UIMode mUiMode;
michael@0 101
michael@0 102 private ThemedTextView mTitle;
michael@0 103 private int mTitlePadding;
michael@0 104 private ToolbarTitlePrefs mTitlePrefs;
michael@0 105 private OnTitleChangeListener mTitleChangeListener;
michael@0 106
michael@0 107 private ImageButton mSiteSecurity;
michael@0 108 private boolean mSiteSecurityVisible;
michael@0 109
michael@0 110 // To de-bounce sets.
michael@0 111 private Bitmap mLastFavicon;
michael@0 112 private ImageButton mFavicon;
michael@0 113 private int mFaviconSize;
michael@0 114
michael@0 115 private ImageButton mStop;
michael@0 116 private OnStopListener mStopListener;
michael@0 117
michael@0 118 private PageActionLayout mPageActionLayout;
michael@0 119
michael@0 120 private AlphaAnimation mLockFadeIn;
michael@0 121 private TranslateAnimation mTitleSlideLeft;
michael@0 122 private TranslateAnimation mTitleSlideRight;
michael@0 123
michael@0 124 private SiteIdentityPopup mSiteIdentityPopup;
michael@0 125 private SecurityMode mSecurityMode;
michael@0 126
michael@0 127 private PropertyAnimator mForwardAnim;
michael@0 128
michael@0 129 private final ForegroundColorSpan mUrlColor;
michael@0 130 private final ForegroundColorSpan mBlockedColor;
michael@0 131 private final ForegroundColorSpan mDomainColor;
michael@0 132 private final ForegroundColorSpan mPrivateDomainColor;
michael@0 133
michael@0 134 public ToolbarDisplayLayout(Context context, AttributeSet attrs) {
michael@0 135 super(context, attrs);
michael@0 136 setOrientation(HORIZONTAL);
michael@0 137
michael@0 138 mActivity = (BrowserApp) context;
michael@0 139
michael@0 140 LayoutInflater.from(context).inflate(R.layout.toolbar_display_layout, this);
michael@0 141
michael@0 142 mTitle = (ThemedTextView) findViewById(R.id.url_bar_title);
michael@0 143 mTitlePadding = mTitle.getPaddingRight();
michael@0 144
michael@0 145 final Resources res = getResources();
michael@0 146
michael@0 147 mUrlColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_urltext));
michael@0 148 mBlockedColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_blockedtext));
michael@0 149 mDomainColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_domaintext));
michael@0 150 mPrivateDomainColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_domaintext_private));
michael@0 151
michael@0 152 mFavicon = (ImageButton) findViewById(R.id.favicon);
michael@0 153 if (Build.VERSION.SDK_INT >= 16) {
michael@0 154 mFavicon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
michael@0 155 }
michael@0 156 mFaviconSize = Math.round(res.getDimension(R.dimen.browser_toolbar_favicon_size));
michael@0 157
michael@0 158 mSiteSecurity = (ImageButton) findViewById(R.id.site_security);
michael@0 159 mSiteSecurityVisible = (mSiteSecurity.getVisibility() == View.VISIBLE);
michael@0 160
michael@0 161 mSiteIdentityPopup = new SiteIdentityPopup(mActivity);
michael@0 162 mSiteIdentityPopup.setAnchor(mSiteSecurity);
michael@0 163
michael@0 164 mStop = (ImageButton) findViewById(R.id.stop);
michael@0 165 mPageActionLayout = (PageActionLayout) findViewById(R.id.page_action_layout);
michael@0 166 }
michael@0 167
michael@0 168 @Override
michael@0 169 public void onAttachedToWindow() {
michael@0 170 mTitlePrefs = new ToolbarTitlePrefs();
michael@0 171
michael@0 172 Button.OnClickListener faviconListener = new Button.OnClickListener() {
michael@0 173 @Override
michael@0 174 public void onClick(View view) {
michael@0 175 if (mSiteSecurity.getVisibility() != View.VISIBLE) {
michael@0 176 return;
michael@0 177 }
michael@0 178
michael@0 179 mSiteIdentityPopup.show();
michael@0 180 }
michael@0 181 };
michael@0 182
michael@0 183 mFavicon.setOnClickListener(faviconListener);
michael@0 184 mSiteSecurity.setOnClickListener(faviconListener);
michael@0 185
michael@0 186 mStop.setOnClickListener(new Button.OnClickListener() {
michael@0 187 @Override
michael@0 188 public void onClick(View v) {
michael@0 189 if (mStopListener != null) {
michael@0 190 // Force toolbar to switch to Display mode
michael@0 191 // immediately based on the stopped tab.
michael@0 192 final Tab tab = mStopListener.onStop();
michael@0 193 if (tab != null) {
michael@0 194 updateUiMode(tab, UIMode.DISPLAY, EnumSet.noneOf(UpdateFlags.class));
michael@0 195 }
michael@0 196 }
michael@0 197 }
michael@0 198 });
michael@0 199
michael@0 200 float slideWidth = getResources().getDimension(R.dimen.browser_toolbar_lock_width);
michael@0 201
michael@0 202 LayoutParams siteSecParams = (LayoutParams) mSiteSecurity.getLayoutParams();
michael@0 203 final float scale = getResources().getDisplayMetrics().density;
michael@0 204 slideWidth += (siteSecParams.leftMargin + siteSecParams.rightMargin) * scale + 0.5f;
michael@0 205
michael@0 206 mLockFadeIn = new AlphaAnimation(0.0f, 1.0f);
michael@0 207 mLockFadeIn.setAnimationListener(this);
michael@0 208
michael@0 209 mTitleSlideLeft = new TranslateAnimation(slideWidth, 0, 0, 0);
michael@0 210 mTitleSlideLeft.setAnimationListener(this);
michael@0 211
michael@0 212 mTitleSlideRight = new TranslateAnimation(-slideWidth, 0, 0, 0);
michael@0 213 mTitleSlideRight.setAnimationListener(this);
michael@0 214
michael@0 215 final int lockAnimDuration = 300;
michael@0 216 mLockFadeIn.setDuration(lockAnimDuration);
michael@0 217 mTitleSlideLeft.setDuration(lockAnimDuration);
michael@0 218 mTitleSlideRight.setDuration(lockAnimDuration);
michael@0 219 }
michael@0 220
michael@0 221 @Override
michael@0 222 public void onDetachedFromWindow() {
michael@0 223 mTitlePrefs.close();
michael@0 224 }
michael@0 225
michael@0 226 @Override
michael@0 227 public void onAnimationStart(Animation animation) {
michael@0 228 if (animation.equals(mLockFadeIn)) {
michael@0 229 if (mSiteSecurityVisible)
michael@0 230 mSiteSecurity.setVisibility(View.VISIBLE);
michael@0 231 } else if (animation.equals(mTitleSlideLeft)) {
michael@0 232 // These two animations may be scheduled to start while the forward
michael@0 233 // animation is occurring. If we're showing the site security icon, make
michael@0 234 // sure it doesn't take any space during the forward transition.
michael@0 235 mSiteSecurity.setVisibility(View.GONE);
michael@0 236 } else if (animation.equals(mTitleSlideRight)) {
michael@0 237 // If we're hiding the icon, make sure that we keep its padding
michael@0 238 // in place during the forward transition
michael@0 239 mSiteSecurity.setVisibility(View.INVISIBLE);
michael@0 240 }
michael@0 241 }
michael@0 242
michael@0 243 @Override
michael@0 244 public void onAnimationRepeat(Animation animation) {
michael@0 245 }
michael@0 246
michael@0 247 @Override
michael@0 248 public void onAnimationEnd(Animation animation) {
michael@0 249 if (animation.equals(mTitleSlideRight)) {
michael@0 250 mSiteSecurity.startAnimation(mLockFadeIn);
michael@0 251 }
michael@0 252 }
michael@0 253
michael@0 254 @Override
michael@0 255 public void setNextFocusDownId(int nextId) {
michael@0 256 mFavicon.setNextFocusDownId(nextId);
michael@0 257 mStop.setNextFocusDownId(nextId);
michael@0 258 mSiteSecurity.setNextFocusDownId(nextId);
michael@0 259 mPageActionLayout.setNextFocusDownId(nextId);
michael@0 260 }
michael@0 261
michael@0 262 void updateFromTab(Tab tab, EnumSet<UpdateFlags> flags) {
michael@0 263 if (flags.contains(UpdateFlags.TITLE)) {
michael@0 264 updateTitle(tab);
michael@0 265 }
michael@0 266
michael@0 267 if (flags.contains(UpdateFlags.FAVICON)) {
michael@0 268 updateFavicon(tab);
michael@0 269 }
michael@0 270
michael@0 271 if (flags.contains(UpdateFlags.SITE_IDENTITY)) {
michael@0 272 updateSiteIdentity(tab, flags);
michael@0 273 }
michael@0 274
michael@0 275 if (flags.contains(UpdateFlags.PROGRESS)) {
michael@0 276 updateProgress(tab, flags);
michael@0 277 }
michael@0 278
michael@0 279 if (flags.contains(UpdateFlags.PRIVATE_MODE)) {
michael@0 280 mTitle.setPrivateMode(tab != null && tab.isPrivate());
michael@0 281 }
michael@0 282 }
michael@0 283
michael@0 284 void setTitle(CharSequence title) {
michael@0 285 mTitle.setText(title);
michael@0 286
michael@0 287 if (mTitleChangeListener != null) {
michael@0 288 mTitleChangeListener.onTitleChange(title);
michael@0 289 }
michael@0 290 }
michael@0 291
michael@0 292 private void updateTitle(Tab tab) {
michael@0 293 // Keep the title unchanged if there's no selected tab,
michael@0 294 // or if the tab is entering reader mode.
michael@0 295 if (tab == null || tab.isEnteringReaderMode()) {
michael@0 296 return;
michael@0 297 }
michael@0 298
michael@0 299 final String url = tab.getURL();
michael@0 300
michael@0 301 // Setting a null title will ensure we just see the
michael@0 302 // "Enter Search or Address" placeholder text.
michael@0 303 if (AboutPages.isTitlelessAboutPage(url)) {
michael@0 304 setTitle(null);
michael@0 305 return;
michael@0 306 }
michael@0 307
michael@0 308 // Show the about:blocked page title in red, regardless of prefs
michael@0 309 if (tab.getErrorType() == Tab.ErrorType.BLOCKED) {
michael@0 310 final String title = tab.getDisplayTitle();
michael@0 311
michael@0 312 final SpannableStringBuilder builder = new SpannableStringBuilder(title);
michael@0 313 builder.setSpan(mBlockedColor, 0, title.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
michael@0 314
michael@0 315 setTitle(builder);
michael@0 316 return;
michael@0 317 }
michael@0 318
michael@0 319 // If the pref to show the URL isn't set, just use the tab's display title.
michael@0 320 if (!mTitlePrefs.shouldShowUrl() || url == null) {
michael@0 321 setTitle(tab.getDisplayTitle());
michael@0 322 return;
michael@0 323 }
michael@0 324
michael@0 325 CharSequence title = url;
michael@0 326 if (mTitlePrefs.shouldTrimUrls()) {
michael@0 327 title = StringUtils.stripCommonSubdomains(StringUtils.stripScheme(url));
michael@0 328 }
michael@0 329
michael@0 330 final String baseDomain = tab.getBaseDomain();
michael@0 331 if (!TextUtils.isEmpty(baseDomain)) {
michael@0 332 final SpannableStringBuilder builder = new SpannableStringBuilder(title);
michael@0 333
michael@0 334 int index = title.toString().indexOf(baseDomain);
michael@0 335 if (index > -1) {
michael@0 336 builder.setSpan(mUrlColor, 0, title.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
michael@0 337 builder.setSpan(tab.isPrivate() ? mPrivateDomainColor : mDomainColor,
michael@0 338 index, index + baseDomain.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
michael@0 339
michael@0 340 title = builder;
michael@0 341 }
michael@0 342 }
michael@0 343
michael@0 344 setTitle(title);
michael@0 345 }
michael@0 346
michael@0 347 private void updateFavicon(Tab tab) {
michael@0 348 if (tab == null) {
michael@0 349 mFavicon.setImageDrawable(null);
michael@0 350 return;
michael@0 351 }
michael@0 352
michael@0 353 Bitmap image = tab.getFavicon();
michael@0 354
michael@0 355 if (image != null && image == mLastFavicon) {
michael@0 356 Log.d(LOGTAG, "Ignoring favicon: new image is identical to previous one.");
michael@0 357 return;
michael@0 358 }
michael@0 359
michael@0 360 // Cache the original so we can debounce without scaling
michael@0 361 mLastFavicon = image;
michael@0 362
michael@0 363 Log.d(LOGTAG, "updateFavicon(" + image + ")");
michael@0 364
michael@0 365 if (image != null) {
michael@0 366 image = Bitmap.createScaledBitmap(image, mFaviconSize, mFaviconSize, false);
michael@0 367 mFavicon.setImageBitmap(image);
michael@0 368 } else {
michael@0 369 mFavicon.setImageResource(R.drawable.favicon);
michael@0 370 }
michael@0 371 }
michael@0 372
michael@0 373 private void updateSiteIdentity(Tab tab, EnumSet<UpdateFlags> flags) {
michael@0 374 final SiteIdentity siteIdentity;
michael@0 375 if (tab == null) {
michael@0 376 siteIdentity = null;
michael@0 377 } else {
michael@0 378 siteIdentity = tab.getSiteIdentity();
michael@0 379 }
michael@0 380
michael@0 381 mSiteIdentityPopup.setSiteIdentity(siteIdentity);
michael@0 382
michael@0 383 final SecurityMode securityMode;
michael@0 384 if (siteIdentity == null) {
michael@0 385 securityMode = SecurityMode.UNKNOWN;
michael@0 386 } else {
michael@0 387 securityMode = siteIdentity.getSecurityMode();
michael@0 388 }
michael@0 389
michael@0 390 if (mSecurityMode != securityMode) {
michael@0 391 mSecurityMode = securityMode;
michael@0 392 mSiteSecurity.setImageLevel(mSecurityMode.ordinal());
michael@0 393 updatePageActions(flags);
michael@0 394 }
michael@0 395 }
michael@0 396
michael@0 397 private void updateProgress(Tab tab, EnumSet<UpdateFlags> flags) {
michael@0 398 final boolean shouldShowThrobber = (tab != null &&
michael@0 399 tab.getState() == Tab.STATE_LOADING);
michael@0 400
michael@0 401 updateUiMode(tab, shouldShowThrobber ? UIMode.PROGRESS : UIMode.DISPLAY, flags);
michael@0 402 }
michael@0 403
michael@0 404 private void updateUiMode(Tab tab, UIMode uiMode, EnumSet<UpdateFlags> flags) {
michael@0 405 if (mUiMode == uiMode) {
michael@0 406 return;
michael@0 407 }
michael@0 408
michael@0 409 mUiMode = uiMode;
michael@0 410
michael@0 411 // The "Throbber start" and "Throbber stop" log messages in this method
michael@0 412 // are needed by S1/S2 tests (http://mrcote.info/phonedash/#).
michael@0 413 // See discussion in Bug 804457. Bug 805124 tracks paring these down.
michael@0 414 if (mUiMode == UIMode.PROGRESS) {
michael@0 415 Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - Throbber start");
michael@0 416 } else {
michael@0 417 Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - Throbber stop");
michael@0 418 }
michael@0 419
michael@0 420 updatePageActions(flags);
michael@0 421 }
michael@0 422
michael@0 423 private void updatePageActions(EnumSet<UpdateFlags> flags) {
michael@0 424 final boolean isShowingProgress = (mUiMode == UIMode.PROGRESS);
michael@0 425
michael@0 426 mStop.setVisibility(isShowingProgress ? View.VISIBLE : View.GONE);
michael@0 427 mPageActionLayout.setVisibility(!isShowingProgress ? View.VISIBLE : View.GONE);
michael@0 428
michael@0 429 boolean shouldShowSiteSecurity = (!isShowingProgress &&
michael@0 430 mSecurityMode != SecurityMode.UNKNOWN);
michael@0 431
michael@0 432 setSiteSecurityVisibility(shouldShowSiteSecurity, flags);
michael@0 433
michael@0 434 // We want title to fill the whole space available for it when there are icons
michael@0 435 // being shown on the right side of the toolbar as the icons already have some
michael@0 436 // padding in them. This is just to avoid wasting space when icons are shown.
michael@0 437 mTitle.setPadding(0, 0, (!isShowingProgress ? mTitlePadding : 0), 0);
michael@0 438 }
michael@0 439
michael@0 440 private void setSiteSecurityVisibility(boolean visible, EnumSet<UpdateFlags> flags) {
michael@0 441 if (visible == mSiteSecurityVisible) {
michael@0 442 return;
michael@0 443 }
michael@0 444
michael@0 445 mSiteSecurityVisible = visible;
michael@0 446
michael@0 447 mTitle.clearAnimation();
michael@0 448 mSiteSecurity.clearAnimation();
michael@0 449
michael@0 450 if (flags.contains(UpdateFlags.DISABLE_ANIMATIONS)) {
michael@0 451 mSiteSecurity.setVisibility(visible ? View.VISIBLE : View.GONE);
michael@0 452 return;
michael@0 453 }
michael@0 454
michael@0 455 // If any of these animations were cancelled as a result of the
michael@0 456 // clearAnimation() calls above, we need to reset them.
michael@0 457 mLockFadeIn.reset();
michael@0 458 mTitleSlideLeft.reset();
michael@0 459 mTitleSlideRight.reset();
michael@0 460
michael@0 461 if (mForwardAnim != null) {
michael@0 462 long delay = mForwardAnim.getRemainingTime();
michael@0 463 mTitleSlideRight.setStartOffset(delay);
michael@0 464 mTitleSlideLeft.setStartOffset(delay);
michael@0 465 } else {
michael@0 466 mTitleSlideRight.setStartOffset(0);
michael@0 467 mTitleSlideLeft.setStartOffset(0);
michael@0 468 }
michael@0 469
michael@0 470 mTitle.startAnimation(visible ? mTitleSlideRight : mTitleSlideLeft);
michael@0 471 }
michael@0 472
michael@0 473 List<View> getFocusOrder() {
michael@0 474 return Arrays.asList(mSiteSecurity, mPageActionLayout, mStop);
michael@0 475 }
michael@0 476
michael@0 477 void setOnStopListener(OnStopListener listener) {
michael@0 478 mStopListener = listener;
michael@0 479 }
michael@0 480
michael@0 481 void setOnTitleChangeListener(OnTitleChangeListener listener) {
michael@0 482 mTitleChangeListener = listener;
michael@0 483 }
michael@0 484
michael@0 485 View getDoorHangerAnchor() {
michael@0 486 return mFavicon;
michael@0 487 }
michael@0 488
michael@0 489 void prepareForwardAnimation(PropertyAnimator anim, ForwardButtonAnimation animation, int width) {
michael@0 490 mForwardAnim = anim;
michael@0 491
michael@0 492 if (animation == ForwardButtonAnimation.HIDE) {
michael@0 493 anim.attach(mTitle,
michael@0 494 PropertyAnimator.Property.TRANSLATION_X,
michael@0 495 0);
michael@0 496 anim.attach(mFavicon,
michael@0 497 PropertyAnimator.Property.TRANSLATION_X,
michael@0 498 0);
michael@0 499 anim.attach(mSiteSecurity,
michael@0 500 PropertyAnimator.Property.TRANSLATION_X,
michael@0 501 0);
michael@0 502
michael@0 503 // We're hiding the forward button. We're going to reset the margin before
michael@0 504 // the animation starts, so we shift these items to the right so that they don't
michael@0 505 // appear to move initially.
michael@0 506 ViewHelper.setTranslationX(mTitle, width);
michael@0 507 ViewHelper.setTranslationX(mFavicon, width);
michael@0 508 ViewHelper.setTranslationX(mSiteSecurity, width);
michael@0 509 } else {
michael@0 510 anim.attach(mTitle,
michael@0 511 PropertyAnimator.Property.TRANSLATION_X,
michael@0 512 width);
michael@0 513 anim.attach(mFavicon,
michael@0 514 PropertyAnimator.Property.TRANSLATION_X,
michael@0 515 width);
michael@0 516 anim.attach(mSiteSecurity,
michael@0 517 PropertyAnimator.Property.TRANSLATION_X,
michael@0 518 width);
michael@0 519 }
michael@0 520 }
michael@0 521
michael@0 522 void finishForwardAnimation() {
michael@0 523 ViewHelper.setTranslationX(mTitle, 0);
michael@0 524 ViewHelper.setTranslationX(mFavicon, 0);
michael@0 525 ViewHelper.setTranslationX(mSiteSecurity, 0);
michael@0 526
michael@0 527 mForwardAnim = null;
michael@0 528 }
michael@0 529
michael@0 530 void prepareStartEditingAnimation() {
michael@0 531 // Hide page actions/stop buttons immediately
michael@0 532 ViewHelper.setAlpha(mPageActionLayout, 0);
michael@0 533 ViewHelper.setAlpha(mStop, 0);
michael@0 534 }
michael@0 535
michael@0 536 void prepareStopEditingAnimation(PropertyAnimator anim) {
michael@0 537 // Fade toolbar buttons (page actions, stop) after the entry
michael@0 538 // is schrunk back to its original size.
michael@0 539 anim.attach(mPageActionLayout,
michael@0 540 PropertyAnimator.Property.ALPHA,
michael@0 541 1);
michael@0 542
michael@0 543 anim.attach(mStop,
michael@0 544 PropertyAnimator.Property.ALPHA,
michael@0 545 1);
michael@0 546 }
michael@0 547
michael@0 548 boolean dismissSiteIdentityPopup() {
michael@0 549 if (mSiteIdentityPopup != null && mSiteIdentityPopup.isShowing()) {
michael@0 550 mSiteIdentityPopup.dismiss();
michael@0 551 return true;
michael@0 552 }
michael@0 553
michael@0 554 return false;
michael@0 555 }
michael@0 556 }

mercurial