Commit d8434146 authored by Donn Denman's avatar Donn Denman Committed by Commit Bot

[TTS] Use an X in the Bar when EoC is enabled.

Checks if Contextual Suggestions is enabled and applies the
generic sheet UX, which for now just always displays a close
box in the Bar instead of an Arrow that transitions to a close
when expanded.

Since the close box has a different behavior from clicking on the bulk
of the Bar, there's always a divider line in the Bar when the X is
enabled.

BUG=831783

Change-Id: I016073a36e633458ae8df8e99f9e13d940fc91d7
Reviewed-on: https://chromium-review.googlesource.com/1022982
Commit-Queue: Donn Denman <donnd@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554848}
parent 53744640
......@@ -14,7 +14,6 @@ import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.compositor.animation.CompositorAnimator;
import org.chromium.chrome.browser.compositor.animation.CompositorAnimator.AnimatorUpdateListener;
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelAnimation;
import org.chromium.ui.base.LocalizationUtils;
import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
......@@ -23,10 +22,19 @@ import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
* Controls the Search Bar in the Contextual Search Panel.
*/
public class ContextualSearchBarControl {
/** Full opacity -- fully visible. */
private static final float FULL_OPACITY = 1.0f;
/** Transparent opacity -- completely transparent (not visible). */
private static final float TRANSPARENT_OPACITY = 0.0f;
/** The opacity of the divider line when using the generic UX. */
private static final float DIVIDER_LINE_OPACITY_GENERIC = FULL_OPACITY;
/**
* The panel used to get information about the panel layout.
*/
protected OverlayPanel mOverlayPanel;
protected ContextualSearchPanel mContextualSearchPanel;
/**
* The {@link ContextualSearchContextControl} used to control the Search Context View.
......@@ -129,7 +137,7 @@ public class ContextualSearchBarControl {
Context context,
ViewGroup container,
DynamicResourceLoader loader) {
mOverlayPanel = panel;
mContextualSearchPanel = panel;
mCanPromoteToNewTab = panel.canPromoteToNewTab();
mImageControl = new ContextualSearchImageControl(panel);
mContextControl = new ContextualSearchContextControl(panel, context, container, loader);
......@@ -194,10 +202,10 @@ public class ContextualSearchBarControl {
public void onUpdateFromCloseToPeek(float percentage) {
// #onUpdateFromPeekToExpanded() never reaches the 0.f value because this method is called
// instead. If the panel is fully peeked, call #onUpdateFromPeekToExpanded().
if (percentage == 1.f) onUpdateFromPeekToExpand(0.f);
if (percentage == FULL_OPACITY) onUpdateFromPeekToExpand(TRANSPARENT_OPACITY);
// When the panel is completely closed the caption and custom image should be hidden.
if (percentage == 0.f) {
if (percentage == TRANSPARENT_OPACITY) {
mQuickActionControl.reset();
mCaptionControl.hide();
getImageControl().hideCustomImage(false);
......@@ -247,7 +255,7 @@ public class ContextualSearchBarControl {
// If the panel is expanded, the divider line should not be hidden. This may happen if the
// panel is opened before the search term is resolved.
if (mExpandedPercent == 0.f) animateDividerLine(false);
if (mExpandedPercent == TRANSPARENT_OPACITY) animateDividerLine(false);
}
/**
......@@ -350,8 +358,8 @@ public class ContextualSearchBarControl {
* context is made visible and the search term invisible.
*/
private void resetSearchBarContextOpacity() {
mSearchBarContextOpacity = 1.f;
mSearchBarTermOpacity = 0.f;
mSearchBarContextOpacity = FULL_OPACITY;
mSearchBarTermOpacity = TRANSPARENT_OPACITY;
}
/**
......@@ -359,8 +367,8 @@ public class ContextualSearchBarControl {
* term is made visible and the search context invisible.
*/
private void resetSearchBarTermOpacity() {
mSearchBarContextOpacity = 0.f;
mSearchBarTermOpacity = 1.f;
mSearchBarContextOpacity = TRANSPARENT_OPACITY;
mSearchBarTermOpacity = FULL_OPACITY;
}
/**
......@@ -377,8 +385,12 @@ public class ContextualSearchBarControl {
* @return The visibility percentage for the divider line ranging from 0.f to 1.f.
*/
public float getDividerLineVisibilityPercentage() {
if (mContextualSearchPanel.useGenericSheetUx()) {
return DIVIDER_LINE_OPACITY_GENERIC;
} else {
return mDividerLineVisibilityPercentage;
}
}
/**
* @return The width of the divider line in px.
......@@ -408,7 +420,8 @@ public class ContextualSearchBarControl {
if (LocalizationUtils.isLayoutRtl()) {
return mEndButtonWidth;
} else {
return mOverlayPanel.getContentViewWidthPx() - mEndButtonWidth - getDividerLineWidth();
return mContextualSearchPanel.getContentViewWidthPx() - mEndButtonWidth
- getDividerLineWidth();
}
}
......@@ -417,7 +430,7 @@ public class ContextualSearchBarControl {
* @param visible Whether the divider line should be made visible.
*/
private void animateDividerLine(boolean visible) {
float endValue = visible ? 1.f : 0.f;
float endValue = visible ? FULL_OPACITY : TRANSPARENT_OPACITY;
if (mDividerLineVisibilityPercentage == endValue) return;
if (mDividerLineVisibilityAnimation != null) mDividerLineVisibilityAnimation.cancel();
AnimatorUpdateListener listener = new AnimatorUpdateListener() {
......@@ -427,8 +440,8 @@ public class ContextualSearchBarControl {
}
};
mDividerLineVisibilityAnimation = CompositorAnimator.ofFloat(
mOverlayPanel.getAnimationHandler(), mDividerLineVisibilityPercentage, endValue,
OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, listener);
mContextualSearchPanel.getAnimationHandler(), mDividerLineVisibilityPercentage,
endValue, OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, listener);
mDividerLineVisibilityAnimation.start();
}
......@@ -485,12 +498,13 @@ public class ContextualSearchBarControl {
// The touch was not on the end button so the touch highlight should cover everything
// except the end button.
return mOverlayPanel.getContentViewWidthPx() - mEndButtonWidth - getDividerLineWidth();
return mContextualSearchPanel.getContentViewWidthPx() - mEndButtonWidth
- getDividerLineWidth();
}
// If the divider line wasn't visible when the Bar was touched, the touch highlight covers
// the entire Bar.
return mOverlayPanel.getContentViewWidthPx();
return mContextualSearchPanel.getContentViewWidthPx();
}
/**
......@@ -522,16 +536,18 @@ public class ContextualSearchBarControl {
// If the panel is expanded or maximized and the panel content cannot be promoted to a new
// tab, then tapping anywhere besides the end button does nothing. In this case, the touch
// highlight should not be shown.
if (!mWasTouchOnEndButton && !mOverlayPanel.isPeeking() && !mCanPromoteToNewTab) return;
if (!mWasTouchOnEndButton && !mContextualSearchPanel.isPeeking() && !mCanPromoteToNewTab)
return;
mWasDividerVisibleOnTouch = getDividerLineVisibilityPercentage() > 0.f;
mWasDividerVisibleOnTouch = getDividerLineVisibilityPercentage() > TRANSPARENT_OPACITY;
mTouchHighlightVisible = true;
// The touch highlight animation is used to ensure the touch highlight is visible for at
// least OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS.
// TODO(twellington): Add a material ripple to this animation.
if (mTouchHighlightAnimation == null) {
mTouchHighlightAnimation = new CompositorAnimator(mOverlayPanel.getAnimationHandler());
mTouchHighlightAnimation =
new CompositorAnimator(mContextualSearchPanel.getAnimationHandler());
mTouchHighlightAnimation.setDuration(OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS);
mTouchHighlightAnimation.addListener(new AnimatorListenerAdapter() {
@Override
......@@ -549,7 +565,7 @@ public class ContextualSearchBarControl {
* @return Whether the touch occurred on the search Bar's end button.
*/
private boolean isTouchOnEndButton(float x) {
if (getDividerLineVisibilityPercentage() == 0.f) return false;
if (getDividerLineVisibilityPercentage() == TRANSPARENT_OPACITY) return false;
float xPx = x * mDpToPx;
if (LocalizationUtils.isLayoutRtl()) return xPx <= getDividerLineXOffset();
......@@ -565,8 +581,9 @@ public class ContextualSearchBarControl {
*/
public void animateSearchTermResolution() {
if (mTextOpacityAnimation == null) {
mTextOpacityAnimation = CompositorAnimator.ofFloat(mOverlayPanel.getAnimationHandler(),
0.f, 1.f, OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, null);
mTextOpacityAnimation = CompositorAnimator.ofFloat(
mContextualSearchPanel.getAnimationHandler(), TRANSPARENT_OPACITY, FULL_OPACITY,
OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, null);
mTextOpacityAnimation.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(CompositorAnimator animator) {
......@@ -595,9 +612,11 @@ public class ContextualSearchBarControl {
// The search context will start fading out before the search term starts fading in.
// They will both be partially visible for overlapPercentage of the animation duration.
float overlapPercentage = .75f;
float fadingOutPercentage = Math.max(1 - (percentage / overlapPercentage), 0.f);
float fadingOutPercentage =
Math.max(1 - (percentage / overlapPercentage), TRANSPARENT_OPACITY);
float fadingInPercentage =
Math.max(percentage - (1 - overlapPercentage), 0.f) / overlapPercentage;
Math.max(percentage - (1 - overlapPercentage), TRANSPARENT_OPACITY)
/ overlapPercentage;
mSearchBarContextOpacity = fadingOutPercentage;
mSearchBarTermOpacity = fadingInPercentage;
......
......@@ -26,7 +26,9 @@ import org.chromium.chrome.browser.compositor.scene_layer.ContextualSearchSceneL
import org.chromium.chrome.browser.compositor.scene_layer.SceneOverlayLayer;
import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.chrome.browser.util.MathUtils;
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.base.LocalizationUtils;
import org.chromium.ui.resources.ResourceManager;
......@@ -40,40 +42,39 @@ public class ContextualSearchPanel extends OverlayPanel {
*/
private static final long HIDE_PROGRESS_BAR_DELAY = 1000 / 60 * 4;
/**
* Used for logging state changes.
*/
/** When using the Generic UX we never show the Arrow Icon */
private static final float ARROW_ICON_OPACITY_GENERIC_UX = 0.f;
/** When using the Generic UX we always show the Close Icon */
private static final float CLOSE_ICON_OPACITY_GENERIC_UX = 1.f;
/** Used for logging state changes. */
private final ContextualSearchPanelMetrics mPanelMetrics;
/**
* The height of the bar shadow, in pixels.
*/
/** The height of the bar shadow, in pixels. */
private final float mBarShadowHeightPx;
/**
* The distance of the divider from the end of the bar, in dp.
*/
/** The distance of the divider from the end of the bar, in dp. */
private final float mEndButtonWidthDp;
/**
* Whether the Panel should be promoted to a new tab after being maximized.
*/
/** Whether the Panel should be promoted to a new tab after being maximized. */
private boolean mShouldPromoteToTabAfterMaximizing;
/**
* The object for handling global Contextual Search management duties
*/
/** The object for handling global Contextual Search management duties */
private ContextualSearchManagementDelegate mManagementDelegate;
/**
* Whether the content view has been touched.
*/
/** Whether the content view has been touched. */
private boolean mHasContentBeenTouched;
/** The compositor layer used for drawing the panel. */
private ContextualSearchSceneLayer mSceneLayer;
/**
* The compositor layer used for drawing the panel.
* Whether to use the Generic Sheet UX.
* This activates the closebox in the peeking Bar, and may someday do more,
* e.g. swipe-closed behavior. See crbug.com/831783 for details.
*/
private ContextualSearchSceneLayer mSceneLayer;
private boolean mUseGenericSheetUx;
// ============================================================================================
// Constructor
......@@ -99,6 +100,13 @@ public class ContextualSearchPanel extends OverlayPanel {
R.dimen.contextual_search_end_button_width);
}
@Override
protected void initializeUiState() {
mUseGenericSheetUx = mActivity.supportsContextualSuggestionsBottomSheet()
&& FeatureUtilities.isContextualSuggestionsBottomSheetEnabled(
DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity));
}
@Override
public OverlayPanelContent createNewOverlayPanelContent() {
return new OverlayPanelContent(mManagementDelegate.getOverlayContentDelegate(),
......@@ -288,7 +296,9 @@ public class ContextualSearchPanel extends OverlayPanel {
getSearchBarControl().onSearchBarClick(x);
if (isPeeking()) {
if (getSearchBarControl().getQuickActionControl().hasQuickAction()
if (useGenericSheetUx() && isCoordinateInsideCloseButton(x)) {
closePanel(StateChangeReason.CLOSE_BUTTON, true);
} else if (getSearchBarControl().getQuickActionControl().hasQuickAction()
&& isCoordinateInsideActionTarget(x)) {
mPanelMetrics.setWasQuickActionClicked();
getSearchBarControl().getQuickActionControl().sendIntent(
......@@ -689,6 +699,33 @@ public class ContextualSearchPanel extends OverlayPanel {
mManagementDelegate.onPanelResized();
}
@Override
public float getArrowIconOpacity() {
if (useGenericSheetUx()) {
return ARROW_ICON_OPACITY_GENERIC_UX;
} else {
return super.getArrowIconOpacity();
}
}
@Override
public float getCloseIconOpacity() {
if (useGenericSheetUx()) {
return CLOSE_ICON_OPACITY_GENERIC_UX;
} else {
return super.getCloseIconOpacity();
}
}
/**
* Whether the UX should match the generic sheet UX used by the generic assistive surface.
* TODO(crbug.com/831783) remove when the generic sheet UX is the default.
* @return Whether to apply the generic UX, rather than the legacy Contextual Search UX.
*/
boolean useGenericSheetUx() {
return mUseGenericSheetUx;
}
// ============================================================================================
// Selection position
// ============================================================================================
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment