1 // Copyright 2020 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.components.page_info; 6 7 import android.content.Context; 8 import android.graphics.drawable.Drawable; 9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.view.animation.AccelerateInterpolator; 13 import android.view.animation.DecelerateInterpolator; 14 import android.widget.FrameLayout; 15 import android.widget.TextView; 16 17 import org.chromium.ui.widget.ChromeImageButton; 18 19 /** 20 * Represents the url, a sub page header and container for page info content. 21 */ 22 public class PageInfoContainer extends FrameLayout { 23 public static final float sScale = 0.92f; 24 public static final int sOutDuration = 90; 25 public static final int sInDuration = 210; 26 27 /** Parameters to configure the view of page info subpage. */ 28 public static class Params { 29 // Whether the URL title should be shown. 30 public boolean urlTitleShown; 31 // The URL to be shown at the top of the page. 32 public CharSequence url; 33 // The length of the URL's origin in number of characters. 34 public int urlOriginLength; 35 // The URL to show in truncated state. 36 public String truncatedUrl; 37 // If the page has preview UI shown. 38 public boolean previewUIShown; 39 // The icon used for preview UI. 40 public Drawable previewUIIcon; 41 42 public Runnable urlTitleClickCallback; 43 public Runnable urlTitleLongClickCallback; 44 public Runnable backButtonClickCallback; 45 } 46 private PageInfoView.ElidedUrlTextView mExpandedUrlTitle; 47 private TextView mTruncatedUrlTitle; 48 private TextView mPreviewMessage; 49 50 private final ViewGroup mWrapper; 51 private final ViewGroup mContent; 52 private View mCurrentView; 53 54 private final View mSubpageHeader; 55 private final TextView mSubpageTitle; 56 PageInfoContainer(Context context)57 public PageInfoContainer(Context context) { 58 super(context); 59 LayoutInflater.from(context).inflate(R.layout.page_info_container, this, true); 60 mWrapper = findViewById(R.id.page_info_wrapper); 61 mContent = findViewById(R.id.page_info_content); 62 mSubpageHeader = findViewById(R.id.page_info_subpage_header); 63 mSubpageTitle = findViewById(R.id.page_info_subpage_title); 64 } 65 setParams(Params params)66 public void setParams(Params params) { 67 mExpandedUrlTitle = findViewById(R.id.page_info_url); 68 initializeUrlView(mExpandedUrlTitle, params); 69 mExpandedUrlTitle.setUrl(params.url, params.urlOriginLength); 70 // Adjust the mUrlTitle for displaying the non-truncated URL. 71 mExpandedUrlTitle.toggleTruncation(); 72 73 mTruncatedUrlTitle = findViewById(R.id.page_info_truncated_url); 74 // Use a separate view for truncated URL display. 75 initializeUrlView(mTruncatedUrlTitle, params); 76 mTruncatedUrlTitle = findViewById(R.id.page_info_truncated_url); 77 mTruncatedUrlTitle.setText(params.truncatedUrl); 78 79 View urlWrapper = findViewById(R.id.page_info_url_wrapper); 80 urlWrapper.setVisibility(params.urlTitleShown ? VISIBLE : GONE); 81 82 mPreviewMessage = findViewById(R.id.page_info_preview_message); 83 mPreviewMessage.setText(R.string.page_info_preview_message); 84 mPreviewMessage.setCompoundDrawablesRelative(params.previewUIIcon, null, null, null); 85 86 View previewWrapper = findViewById(R.id.page_info_preview_message_wrapper); 87 previewWrapper.setVisibility(params.previewUIShown ? VISIBLE : GONE); 88 89 ChromeImageButton backButton = findViewById(R.id.subpage_back_button); 90 backButton.setOnClickListener(v -> params.backButtonClickCallback.run()); 91 } 92 initializeUrlView(View view, Params params)93 private void initializeUrlView(View view, Params params) { 94 if (params.urlTitleClickCallback != null) { 95 view.setOnClickListener(v -> { params.urlTitleClickCallback.run(); }); 96 } 97 if (params.urlTitleLongClickCallback != null) { 98 view.setOnLongClickListener(v -> { 99 params.urlTitleLongClickCallback.run(); 100 return true; 101 }); 102 } 103 } 104 toggleUrlTruncation()105 public void toggleUrlTruncation() { 106 boolean showExpanded = mExpandedUrlTitle.getVisibility() != VISIBLE; 107 mExpandedUrlTitle.setVisibility(showExpanded ? VISIBLE : GONE); 108 mTruncatedUrlTitle.setVisibility(showExpanded ? GONE : VISIBLE); 109 announceForAccessibility(getResources().getString( 110 showExpanded ? R.string.page_info_url_expanded : R.string.page_info_url_truncated)); 111 } 112 setFavicon(Drawable favicon)113 public void setFavicon(Drawable favicon) { 114 mTruncatedUrlTitle.setCompoundDrawablesRelative(favicon, null, null, null); 115 } 116 showPage(View view, CharSequence subPageTitle, Runnable onPreviousPageRemoved)117 public void showPage(View view, CharSequence subPageTitle, Runnable onPreviousPageRemoved) { 118 if (mCurrentView == null) { 119 // Don't animate if there is no current view. 120 assert onPreviousPageRemoved == null; 121 replaceContentView(view, subPageTitle); 122 return; 123 } 124 // Create "fade-through" animation. 125 // TODO(crbug.com/1077766): Animate height change and set correct interpolator. 126 mWrapper.animate() 127 .setDuration(sOutDuration) 128 .alpha(0) 129 .setInterpolator(new AccelerateInterpolator()) 130 .withEndAction(() -> { 131 replaceContentView(view, subPageTitle); 132 mWrapper.setScaleX(sScale); 133 mWrapper.setScaleY(sScale); 134 mWrapper.setAlpha(0); 135 mWrapper.animate() 136 .setDuration(sInDuration) 137 .scaleX(1) 138 .scaleY(1) 139 .alpha(1) 140 .setInterpolator(new DecelerateInterpolator()) 141 .withEndAction(onPreviousPageRemoved); 142 }); 143 } 144 145 /** 146 * Replaces the current view with |view| and configures the subpage header. 147 */ replaceContentView(View view, CharSequence subPageTitle)148 private void replaceContentView(View view, CharSequence subPageTitle) { 149 mContent.removeAllViews(); 150 mCurrentView = view; 151 mSubpageHeader.setVisibility(subPageTitle != null ? VISIBLE : GONE); 152 mSubpageTitle.setText(subPageTitle); 153 mContent.addView(view); 154 announceForAccessibility(subPageTitle != null 155 ? subPageTitle 156 : getResources().getString(R.string.accessibility_toolbar_btn_site_info)); 157 } 158 } 159