| Index: chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java
|
| index 356c10f72c73476a259f2d2b503a065c7973c01b..b350e84822f43827eba686779e079eb0b8915951 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarLayout.java
|
| @@ -23,6 +23,9 @@ import android.widget.TextView;
|
|
|
| import org.chromium.base.ApiCompatibilityUtils;
|
| import org.chromium.chrome.R;
|
| +import org.chromium.chrome.browser.widget.ButtonCompat;
|
| +
|
| +import java.util.ArrayList;
|
|
|
| /**
|
| * Layout that arranges an InfoBar's views. An InfoBarLayout consists of:
|
| @@ -76,6 +79,18 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| /** Whether the views are vertically stacked. */
|
| public boolean isStacked;
|
|
|
| + Group(View... views) {
|
| + this.views = views;
|
| + }
|
| +
|
| + static View[] filterNullViews(View... views) {
|
| + ArrayList<View> viewsList = new ArrayList<View>();
|
| + for (View v : views) {
|
| + if (v != null) viewsList.add(v);
|
| + }
|
| + return viewsList.toArray(new View[viewsList.size()]);
|
| + }
|
| +
|
| void setHorizontalMode(int horizontalSpacing, int startMargin, int endMargin) {
|
| isStacked = false;
|
| for (int i = 0; i < views.length; i++) {
|
| @@ -85,7 +100,6 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| lp.endMargin = i == views.length - 1 ? endMargin : 0;
|
| lp.bottomMargin = 0;
|
| }
|
| -
|
| }
|
|
|
| void setVerticalMode(int verticalSpacing, int bottomMargin) {
|
| @@ -109,9 +123,14 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| private final int mAccentColor;
|
|
|
| private final InfoBarView mInfoBarView;
|
| - private final TextView mMessageView;
|
| private final ImageButton mCloseButton;
|
| + private TextView mMessageTextView;
|
| + private View mMessageView;
|
| private ImageView mIconView;
|
| + private ButtonCompat mPrimaryButton;
|
| + private Button mSecondaryButton;
|
| + private Button mTertiaryButton;
|
| + private View mCustomButton;
|
|
|
| private Group mMainGroup;
|
| private Group mCustomGroup;
|
| @@ -169,7 +188,6 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| mCloseButton.setOnClickListener(this);
|
| mCloseButton.setContentDescription(res.getString(R.string.infobar_close));
|
| mCloseButton.setLayoutParams(new LayoutParams(0, -mMargin, -mMargin, -mMargin));
|
| - addView(mCloseButton);
|
|
|
| // Set up the icon.
|
| if (iconResourceId != 0 || iconBitmap != null) {
|
| @@ -186,24 +204,27 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| }
|
|
|
| // Set up the message view.
|
| - mMessageView = (TextView) LayoutInflater.from(context).inflate(R.layout.infobar_text, null);
|
| - mMessageView.setText(message, TextView.BufferType.SPANNABLE);
|
| - mMessageView.setMovementMethod(LinkMovementMethod.getInstance());
|
| - mMessageView.setLinkTextColor(mAccentColor);
|
| - mMessageView.setLayoutParams(new LayoutParams(0, mMargin / 4, 0, 0));
|
| -
|
| - if (mIconView == null) {
|
| - mMainGroup = addGroup(mMessageView);
|
| - } else {
|
| - mMainGroup = addGroup(mIconView, mMessageView);
|
| - }
|
| + mMessageTextView = (TextView) LayoutInflater.from(context).inflate(R.layout.infobar_text,
|
| + null);
|
| + mMessageTextView.setText(message, TextView.BufferType.SPANNABLE);
|
| + mMessageTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
| + mMessageTextView.setLinkTextColor(mAccentColor);
|
| + mMessageView = mMessageTextView;
|
| }
|
|
|
| /**
|
| * Sets the message to show on the infobar.
|
| */
|
| public void setMessage(CharSequence message) {
|
| - mMessageView.setText(message, TextView.BufferType.SPANNABLE);
|
| + mMessageTextView.setText(message, TextView.BufferType.SPANNABLE);
|
| + }
|
| +
|
| + /**
|
| + * Sets a custom view to show in place of the message.
|
| + */
|
| + public void setMessageView(View view) {
|
| + mMessageView = view;
|
| + mMessageTextView = null;
|
| }
|
|
|
| /**
|
| @@ -215,7 +236,7 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| * - Stacked above each other on two separate rows, taking up the full width of the infobar.
|
| */
|
| public void setCustomContent(View view1, View view2) {
|
| - mCustomGroup = addGroup(view1, view2);
|
| + mCustomGroup = new Group(view1, view2);
|
| }
|
|
|
| /**
|
| @@ -227,7 +248,7 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| * - On a separate row, start-aligned
|
| */
|
| public void setCustomContent(View view) {
|
| - mCustomGroup = addGroup(view);
|
| + mCustomGroup = new Group(view);
|
| }
|
|
|
| /**
|
| @@ -247,53 +268,85 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| public void setButtons(String primaryText, String secondaryText, String tertiaryText) {
|
| if (TextUtils.isEmpty(primaryText)) return;
|
|
|
| - LayoutInflater inflater = LayoutInflater.from(getContext());
|
| - Button primaryButton = (Button) inflater.inflate(R.layout.infobar_button, null);
|
| - primaryButton.setId(R.id.button_primary);
|
| - primaryButton.setOnClickListener(this);
|
| - primaryButton.setText(primaryText);
|
| - primaryButton.setBackgroundResource(R.drawable.btn_infobar_blue);
|
| - primaryButton.setTextColor(Color.WHITE);
|
| -
|
| - if (TextUtils.isEmpty(secondaryText)) {
|
| - mButtonGroup = addGroup(primaryButton);
|
| - return;
|
| - }
|
| + mPrimaryButton = new ButtonCompat(getContext(), mAccentColor);
|
| + mPrimaryButton.setId(R.id.button_primary);
|
| + mPrimaryButton.setOnClickListener(this);
|
| + mPrimaryButton.setText(primaryText);
|
| + mPrimaryButton.setTextColor(Color.WHITE);
|
| +
|
| + if (TextUtils.isEmpty(secondaryText)) return;
|
| +
|
| + mSecondaryButton = ButtonCompat.createBorderlessButton(getContext());
|
| + mSecondaryButton.setId(R.id.button_secondary);
|
| + mSecondaryButton.setOnClickListener(this);
|
| + mSecondaryButton.setText(secondaryText);
|
| + mSecondaryButton.setTextColor(mAccentColor);
|
| +
|
| + if (TextUtils.isEmpty(tertiaryText)) return;
|
| +
|
| + mTertiaryButton = ButtonCompat.createBorderlessButton(getContext());
|
| + mTertiaryButton.setId(R.id.button_tertiary);
|
| + mTertiaryButton.setOnClickListener(this);
|
| + mTertiaryButton.setText(tertiaryText);
|
| + mTertiaryButton.setPadding(mMargin / 2, mTertiaryButton.getPaddingTop(), mMargin / 2,
|
| + mTertiaryButton.getPaddingBottom());
|
| + mTertiaryButton.setTextColor(
|
| + getContext().getResources().getColor(R.color.infobar_tertiary_button_text));
|
| + }
|
|
|
| - Button secondaryButton = (Button) inflater.inflate(R.layout.infobar_button, null);
|
| - secondaryButton.setId(R.id.button_secondary);
|
| - secondaryButton.setOnClickListener(this);
|
| - secondaryButton.setText(secondaryText);
|
| - secondaryButton.setTextColor(mAccentColor);
|
| + /**
|
| + * Adds a custom view to show in the button row in place of the tertiary button.
|
| + */
|
| + public void setCustomViewInButtonRow(View view) {
|
| + mCustomButton = view;
|
| + }
|
|
|
| - if (TextUtils.isEmpty(tertiaryText)) {
|
| - mButtonGroup = addGroup(secondaryButton, primaryButton);
|
| - return;
|
| - }
|
| + /**
|
| + * Sets the size of the icon and the spacing between it and the message.
|
| + */
|
| + public void setIconSizeAndSpacing(int width, int height, int iconMessageSpacing) {
|
| + LayoutParams lp = (LayoutParams) mIconView.getLayoutParams();
|
| + lp.width = width;
|
| + lp.height = height;
|
| + lp.endMargin = iconMessageSpacing;
|
| + }
|
|
|
| - Button tertiaryButton = (Button) inflater.inflate(R.layout.infobar_button, null);
|
| - tertiaryButton.setId(R.id.button_tertiary);
|
| - tertiaryButton.setOnClickListener(this);
|
| - tertiaryButton.setText(tertiaryText);
|
| - tertiaryButton.setPadding(mMargin / 2, tertiaryButton.getPaddingTop(), mMargin / 2,
|
| - tertiaryButton.getPaddingBottom());
|
| - tertiaryButton.setTextColor(
|
| - getContext().getResources().getColor(R.color.infobar_tertiary_button_text));
|
|
|
| - mButtonGroup = addGroup(tertiaryButton, secondaryButton, primaryButton);
|
| + /**
|
| + * Returns the primary button, or null if it doesn't exist.
|
| + */
|
| + public ButtonCompat getPrimaryButton() {
|
| + return mPrimaryButton;
|
| }
|
|
|
| /**
|
| - * Adds a group of Views that are measured and laid out together.
|
| + * Returns the icon, or null if it doesn't exist.
|
| */
|
| - private Group addGroup(View... views) {
|
| - Group group = new Group();
|
| - group.views = views;
|
| + public ImageView getIcon() {
|
| + return mIconView;
|
| + }
|
| +
|
| + /**
|
| + * Must be called after the message, buttons, and custom content have been set, and before the
|
| + * first call to onMeasure().
|
| + */
|
| + void onContentCreated() {
|
| + mMessageView.setLayoutParams(new LayoutParams(0, mMargin / 4, 0, 0));
|
| + mMainGroup = new Group(Group.filterNullViews(mIconView, mMessageView));
|
|
|
| - for (View v : views) {
|
| - addView(v);
|
| + View[] buttons = Group.filterNullViews(mCustomButton, mTertiaryButton,
|
| + mSecondaryButton, mPrimaryButton);
|
| + if (buttons.length != 0) mButtonGroup = new Group(buttons);
|
| +
|
| + // Add the child views in the desired focus order.
|
| + for (View v : mMainGroup.views) addView(v);
|
| + if (mCustomGroup != null) {
|
| + for (View v : mCustomGroup.views) addView(v);
|
| }
|
| - return group;
|
| + if (mButtonGroup != null) {
|
| + for (View v : mButtonGroup.views) addView(v);
|
| + }
|
| + addView(mCloseButton);
|
| }
|
|
|
| @Override
|
| @@ -393,13 +446,32 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
|
|
| // If the infobar consists of just a main row and a buttons row, the buttons must be
|
| // at least 32dp below the bottom of the message text.
|
| - if (mCustomGroup == null) {
|
| - LayoutParams lp = (LayoutParams) mMessageView.getLayoutParams();
|
| - int messageBottom = lp.top + mMessageView.getMeasuredHeight();
|
| + if (mCustomGroup == null && mMessageTextView != null) {
|
| + LayoutParams lp = (LayoutParams) mMessageTextView.getLayoutParams();
|
| + int messageBottom = lp.top + mMessageTextView.getMeasuredHeight();
|
| mTop = Math.max(mTop, messageBottom + 2 * mMargin);
|
| }
|
| }
|
| placeGroup(mButtonGroup);
|
| +
|
| + if (mCustomButton != null && !buttonGroupOnMainRow) {
|
| + // The custom button is start-aligned with the message view (unless that causes it
|
| + // to overlap the primary button).
|
| + LayoutParams primaryButtonLP = (LayoutParams) mPrimaryButton.getLayoutParams();
|
| + LayoutParams customButtonLP = (LayoutParams) mCustomButton.getLayoutParams();
|
| + LayoutParams messageLP = (LayoutParams) mMessageView.getLayoutParams();
|
| + if (customButtonLP.start >= messageLP.start) {
|
| + customButtonLP.start = messageLP.start;
|
| + } else {
|
| + customButtonLP.start = mMargin;
|
| + }
|
| + if (!mButtonGroup.isStacked) {
|
| + // Center the custom button vertically relative to the primary button.
|
| + customButtonLP.top = primaryButtonLP.top
|
| + + (mPrimaryButton.getMeasuredHeight()
|
| + - mCustomButton.getMeasuredHeight()) / 2;
|
| + }
|
| + }
|
| }
|
|
|
| startRow();
|
| @@ -516,11 +588,15 @@ public class InfoBarLayout extends ViewGroup implements View.OnClickListener {
|
| // Group is too wide to fit on a single row, so stack the group items vertically.
|
| mButtonGroup.setVerticalMode(mMargin / 2, 0);
|
| mButtonGroup.gravity = Gravity.FILL_HORIZONTAL;
|
| - } else if (mButtonGroup.views.length == 3) {
|
| - // Align tertiary button at the start and the other two buttons at the end.
|
| - ((LayoutParams) mButtonGroup.views[0].getLayoutParams()).endMargin += extraWidth;
|
| + } else if (mTertiaryButton != null) {
|
| + // Align tertiary or custom button at the start and the other buttons at the end.
|
| + ((LayoutParams) mTertiaryButton.getLayoutParams()).endMargin += extraWidth;
|
| }
|
| }
|
| + if (row == ROW_MAIN && mCustomButton != null) {
|
| + // Increase spacing between custom button and primary button.
|
| + ((LayoutParams) mCustomButton.getLayoutParams()).endMargin = mMargin;
|
| + }
|
| }
|
|
|
| /**
|
|
|