Commit c623550d authored by Tibor Goldschwendt's avatar Tibor Goldschwendt Committed by Commit Bot

Move dialog logic from PageInfoPopup to PageInfoDialog

Change-Id: I2333926b6d37544a535c6683078fd4f22f75aad9
Reviewed-on: https://chromium-review.googlesource.com/1017008
Commit-Queue: Tibor Goldschwendt <tiborg@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Reviewed-by: default avatarBecky Zhou <huayinz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553594}
parent ad2b0436
......@@ -12,7 +12,6 @@
<item name="foreground_drawable" type="id"/>
<item name="fre_pager" type="id"/>
<item name="page_info_click_callback" type="id" />
<item name="permission_type" type="id"/>
<item name="refine_view_id" type="id"/>
<item name="tabswitcher_multiple_drawable" type="id"/>
<item name="tabswitcher_single_drawable" type="id"/>
......
// Copyright 2018 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.page_info;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.NonNull;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import org.chromium.chrome.browser.modaldialog.ModalDialogManager;
import org.chromium.chrome.browser.modaldialog.ModalDialogView;
import org.chromium.ui.interpolators.BakedBezierInterpolator;
/**
* Represents the dialog containing the page info view.
*/
class PageInfoDialog {
private static final int ENTER_START_DELAY_MS = 100;
private static final int ENTER_EXIT_DURATION_MS = 200;
private static final int CLOSE_CLEANUP_DELAY_MS = 10;
private static final int MAX_MODAL_DIALOG_WIDTH_DP = 400;
@NonNull
private final PageInfoView mView;
private final boolean mIsSheet;
// The dialog implementation.
// mSheetDialog is set if the dialog appears as a sheet. Otherwise, mModalDialog is set.
private final Dialog mSheetDialog;
private final ModalDialogView mModalDialog;
@NonNull
private final ModalDialogManager mManager;
@NonNull
private final ModalDialogView.Controller mController;
// Animation which is currently running, if there is one.
private Animator mCurrentAnimation;
private boolean mDismissWithoutAnimation;
/**
* Creates a new page info dialog. The dialog can appear as a sheet (using Android dialogs) or a
* standard dialog (using modal dialogs).
*
* @param context The context used for creating the dialog.
* @param view The view shown inside the dialog.
* @param tabView The view if the tab the dialog is shown in.
* @param isSheet Whether the dialog should appear as a sheet.
* @param manager The dialog's manager used for modal dialogs.
* @param controller The dialog's controller.
*
*/
public PageInfoDialog(Context context, @NonNull PageInfoView view, View tabView,
boolean isSheet, @NonNull ModalDialogManager manager,
@NonNull ModalDialogView.Controller controller) {
mView = view;
mIsSheet = isSheet;
mManager = manager;
mController = controller;
mView.setVisibility(View.INVISIBLE);
mView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(
View v, int l, int t, int r, int b, int ol, int ot, int or, int ob) {
// Trigger the entrance animations once the main container has been laid out and has
// a height.
mView.removeOnLayoutChangeListener(this);
mView.setVisibility(View.VISIBLE);
createAllAnimations(true, null).start();
}
});
ViewGroup container;
if (isSheet) {
// On smaller screens, make the dialog fill the width of the screen.
container = createSheetContainer(context, tabView);
} else {
// On larger screens, make the dialog centered in the screen and have a maximum width.
container = createModalContainer(context);
}
container.addView(mView);
if (isSheet) {
mSheetDialog = createSheetDialog(context, container);
mModalDialog = null;
} else {
mModalDialog = createModalDialog(container);
mSheetDialog = null;
}
}
/** Shows the dialogs. */
public void show() {
if (mIsSheet) {
mSheetDialog.show();
} else {
mManager.showDialog(mModalDialog, ModalDialogManager.APP_MODAL);
}
}
/**
* Hides the dialog.
*
* @param animated Whether to animate the transition to hidden.
*/
public void dismiss(boolean animated) {
mDismissWithoutAnimation = !animated;
if (mIsSheet) {
mSheetDialog.dismiss();
} else {
mManager.dismissDialog(mModalDialog);
}
}
private Dialog createSheetDialog(Context context, View container) {
Dialog sheetDialog = new Dialog(context) {
private void superDismiss() {
super.dismiss();
}
@Override
public void dismiss() {
if (mDismissWithoutAnimation) {
// Dismiss the modal dialogs without any custom animations.
super.dismiss();
} else {
createAllAnimations(false, () -> {
// onAnimationEnd is called during the final frame of the animation.
// Delay the cleanup by a tiny amount to give this frame a chance to
// be displayed before we destroy the dialog.
mView.postDelayed(this ::superDismiss, CLOSE_CLEANUP_DELAY_MS);
}).start();
}
}
};
sheetDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
sheetDialog.setCanceledOnTouchOutside(true);
Window window = sheetDialog.getWindow();
window.setGravity(Gravity.TOP);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
sheetDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
mController.onDismiss();
}
});
sheetDialog.addContentView(container,
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
// This must be called after addContentView, or it won't fully fill to the edge.
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
return sheetDialog;
}
private ModalDialogView createModalDialog(View container) {
ModalDialogView.Params params = new ModalDialogView.Params();
params.customView = container;
params.cancelOnTouchOutside = true;
return new ModalDialogView(mController, params);
}
private ViewGroup createSheetContainer(Context context, View tabView) {
return new ScrollView(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(
tabView != null ? tabView.getHeight() : 0, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
}
private ViewGroup createModalContainer(Context context) {
return new ScrollView(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int maxDialogWidthInPx = (int) (MAX_MODAL_DIALOG_WIDTH_DP
* context.getResources().getDisplayMetrics().density);
if (MeasureSpec.getSize(widthMeasureSpec) > maxDialogWidthInPx) {
widthMeasureSpec =
MeasureSpec.makeMeasureSpec(maxDialogWidthInPx, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
}
/**
* Create an animator to slide in the entire dialog from the top of the screen.
*/
private Animator createDialogSlideAnimaton(boolean isEnter) {
final float animHeight = -mView.getHeight();
ObjectAnimator translateAnim;
if (isEnter) {
mView.setTranslationY(animHeight);
translateAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y, 0f);
translateAnim.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE);
} else {
translateAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y, animHeight);
translateAnim.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE);
}
translateAnim.setDuration(ENTER_EXIT_DURATION_MS);
return translateAnim;
}
/**
* Create an animator to show/hide the entire dialog. On phones the dialog is slid in as a
* sheet. Otherwise, the default fade-in is used.
*/
private Animator createAllAnimations(boolean isEnter, Runnable onAnimationEnd) {
Animator dialogAnimation =
mIsSheet ? createDialogSlideAnimaton(isEnter) : new AnimatorSet();
Animator viewAnimation = mView.createEnterExitAnimation(isEnter);
AnimatorSet allAnimations = new AnimatorSet();
if (isEnter) allAnimations.setStartDelay(ENTER_START_DELAY_MS);
allAnimations.playTogether(dialogAnimation, viewAnimation);
allAnimations.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimation = null;
if (onAnimationEnd == null) return;
onAnimationEnd.run();
}
});
if (mCurrentAnimation != null) mCurrentAnimation.cancel();
mCurrentAnimation = allAnimations;
return allAnimations;
}
}
\ No newline at end of file
......@@ -251,12 +251,8 @@ public class PageInfoView extends FrameLayout implements OnClickListener, OnLong
}
}
public Animator createEnterAnimation() {
return createFadeAnimations(true);
}
public Animator createExitAnimation() {
return createFadeAnimations(false);
public Animator createEnterExitAnimation(boolean isEnter) {
return createFadeAnimations(isEnter);
}
public void toggleUrlTruncation() {
......
......@@ -855,6 +855,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/page_info/CertificateChainHelper.java",
"java/src/org/chromium/chrome/browser/page_info/CertificateViewer.java",
"java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java",
"java/src/org/chromium/chrome/browser/page_info/PageInfoDialog.java",
"java/src/org/chromium/chrome/browser/page_info/PageInfoPopup.java",
"java/src/org/chromium/chrome/browser/page_info/PageInfoView.java",
"java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmark.java",
......
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