// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.compositor.bottombar.contextualsearch; import android.content.Context; import android.support.v4.view.animation.PathInterpolatorCompat; import android.text.TextUtils; import android.view.animation.Interpolator; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelAnimation; import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation; /** * Controls the image shown in the Bar. Owns the {@link ContextualSearchIconSpriteControl} and * details about the thumbnail, and handles animating between the two. */ public class ContextualSearchImageControl implements ChromeAnimation.Animatable<ContextualSearchImageControl.AnimationType> { /** * Animation properties. */ protected enum AnimationType { THUMBNAIL_VISIBILITY } /** The current context. */ private final Context mContext; /** The OverlayPanelAnimation used to add animations. */ private final OverlayPanelAnimation mOverlayPanelAnimation; public ContextualSearchImageControl(OverlayPanelAnimation overlayPanelAnimation, Context context) { mContext = context; mOverlayPanelAnimation = overlayPanelAnimation; } // ============================================================================================ // Search Provider Icon Sprite // ============================================================================================ private ContextualSearchIconSpriteControl mIconSpriteControl; /** * @return The {@link ContextualSearchIconSpriteControl} for the panel. */ public ContextualSearchIconSpriteControl getIconSpriteControl() { if (mIconSpriteControl == null) { mIconSpriteControl = new ContextualSearchIconSpriteControl(mOverlayPanelAnimation, mContext); } return mIconSpriteControl; } /** * @param shouldAnimateIconSprite Whether the search provider icon sprite should be animated. */ public void setShouldAnimateIconSprite(boolean shouldAnimateIconSprite) { getIconSpriteControl().setShouldAnimateAppearance(shouldAnimateIconSprite); } // ============================================================================================ // Thumbnail // ============================================================================================ /** * The URL of the thumbnail to display. */ private String mThumbnailUrl; /** * The height and width of the thumbnail. */ private int mThumbnailSize; /** * Whether the thumbnail is visible. */ private boolean mThumbnailVisible; /** * The thumbnail visibility percentage, which dictates how and where to draw the thumbnail. * The thumbnail is not visible at all at 0.f and completely visible at 1.f. */ private float mThumbnailVisibilityPercentage = 0.f; /** * @param thumbnailUrl The URL of the thumbnail to display */ public void setThumbnailUrl(String thumbnailUrl) { mThumbnailUrl = thumbnailUrl; } /** * @return The URL used to fetch a thumbnail to display in the Bar. Will return an empty string * if no thumbnail is available. */ public String getThumbnailUrl() { return mThumbnailUrl != null ? mThumbnailUrl : ""; } /** * Hides the thumbnail if it is visible and makes the icon sprite visible. Also resets the * thumbnail URL. * @param animate Whether hiding the thumbnail should be animated. */ public void hideThumbnail(boolean animate) { getIconSpriteControl().setIsVisible(true); if (mThumbnailVisible && animate) { animateThumbnailVisibility(false); } else { mOverlayPanelAnimation.cancelAnimation(this, AnimationType.THUMBNAIL_VISIBILITY); onThumbnailHidden(); } } /** * @return The height and width of the thumbnail in px. */ public int getThumbnailSize() { if (mThumbnailSize == 0) { mThumbnailSize = mContext.getResources().getDimensionPixelSize( R.dimen.contextual_search_thumbnail_size); } return mThumbnailSize; } /** * @return Whether the thumbnail is visible. */ public boolean getThumbnailVisible() { return mThumbnailVisible; } /** * @return The thumbnail visibility percentage, which dictates how and where to draw the * thumbnail. The thumbnail is not visible at all at 0.f and completely visible at 1.f. */ public float getThumbnailVisibilityPercentage() { return mThumbnailVisibilityPercentage; } /** * Called when the thumbnail has finished being fetched. * @param success Whether fetching the thumbnail was successful. */ public void onThumbnailFetched(boolean success) { // Check if the thumbnail URL was cleared before the thumbnail fetch completed. This may // occur if the user taps to refine the search. mThumbnailVisible = success && !TextUtils.isEmpty(mThumbnailUrl); if (!mThumbnailVisible) return; // TODO(twellington): if the icon sprite is animating wait to start the thumbnail visibility // animation. animateThumbnailVisibility(true); } private void onThumbnailHidden() { mThumbnailUrl = ""; mThumbnailVisible = false; getIconSpriteControl().setIsVisible(true); mThumbnailVisibilityPercentage = 0.f; } // ============================================================================================ // Thumbnail Animation // ============================================================================================ private Interpolator mThumbnailVisibilityInterpolator; private void animateThumbnailVisibility(boolean visible) { if (mThumbnailVisibilityInterpolator == null) { mThumbnailVisibilityInterpolator = PathInterpolatorCompat.create(0.4f, 0.f, 0.6f, 1.f); } mOverlayPanelAnimation.cancelAnimation(this, AnimationType.THUMBNAIL_VISIBILITY); float endValue = visible ? 1.f : 0.f; mOverlayPanelAnimation.addToAnimation(this, AnimationType.THUMBNAIL_VISIBILITY, mThumbnailVisibilityPercentage, endValue, OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, 0, false, mThumbnailVisibilityInterpolator); } @Override public void setProperty(AnimationType prop, float val) { if (prop == AnimationType.THUMBNAIL_VISIBILITY) { mThumbnailVisibilityPercentage = val; } } @Override public void onPropertyAnimationFinished(AnimationType prop) { if (prop == AnimationType.THUMBNAIL_VISIBILITY) { if (mThumbnailVisibilityPercentage == 0.f) { onThumbnailHidden(); } else { getIconSpriteControl().setIsVisible(false); } } } }