OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.infobar; | 5 package org.chromium.chrome.browser.infobar; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.content.res.Resources; | 8 import android.content.res.Resources; |
9 import android.graphics.Paint; | 9 import android.graphics.Paint; |
10 import android.support.annotation.Nullable; | 10 import android.support.annotation.Nullable; |
11 import android.support.v7.widget.SwitchCompat; | 11 import android.support.v7.widget.SwitchCompat; |
12 import android.text.method.LinkMovementMethod; | 12 import android.text.method.LinkMovementMethod; |
| 13 import android.util.AttributeSet; |
13 import android.view.LayoutInflater; | 14 import android.view.LayoutInflater; |
14 import android.view.View; | 15 import android.view.View; |
15 import android.view.ViewGroup; | 16 import android.view.ViewGroup; |
16 import android.widget.ArrayAdapter; | 17 import android.widget.ArrayAdapter; |
17 import android.widget.ImageView; | 18 import android.widget.ImageView; |
18 import android.widget.LinearLayout; | 19 import android.widget.LinearLayout; |
19 import android.widget.RadioButton; | |
20 import android.widget.RadioGroup; | |
21 import android.widget.RatingBar; | 20 import android.widget.RatingBar; |
22 import android.widget.Spinner; | 21 import android.widget.Spinner; |
23 import android.widget.TextView; | 22 import android.widget.TextView; |
24 | 23 |
25 import org.chromium.base.ApiCompatibilityUtils; | 24 import org.chromium.base.ApiCompatibilityUtils; |
26 import org.chromium.base.VisibleForTesting; | 25 import org.chromium.base.VisibleForTesting; |
27 import org.chromium.chrome.R; | 26 import org.chromium.chrome.R; |
28 import org.chromium.chrome.browser.widget.DualControlLayout; | 27 import org.chromium.chrome.browser.widget.DualControlLayout; |
| 28 import org.chromium.chrome.browser.widget.RadioButtonLayout; |
29 | 29 |
30 import java.util.List; | 30 import java.util.List; |
31 | 31 |
32 /** | 32 /** |
33 * Lays out a group of controls (e.g. switches, spinners, or additional text) fo
r InfoBars that need | 33 * Lays out a group of controls (e.g. switches, spinners, or additional text) fo
r InfoBars that need |
34 * more than the normal pair of buttons. | 34 * more than the normal pair of buttons. |
35 * | 35 * |
36 * This class works with the {@link InfoBarLayout} to define a standard set of c
ontrols with | 36 * This class works with the {@link InfoBarLayout} to define a standard set of c
ontrols with |
37 * standardized spacings and text styling that gets laid out in grid form: https
://crbug.com/543205 | 37 * standardized spacings and text styling that gets laid out in grid form: https
://crbug.com/543205 |
38 * | 38 * |
39 * Manually specified margins on the children managed by this layout are EXPLICI
TLY ignored to | 39 * Manually specified margins on the children managed by this layout are EXPLICI
TLY ignored to |
40 * enforce a uniform margin between controls across all InfoBar types. Do NOT c
ircumvent this | 40 * enforce a uniform margin between controls across all InfoBar types. Do NOT c
ircumvent this |
41 * restriction with creative layout definitions. If the layout algorithm doesn'
t work for your new | 41 * restriction with creative layout definitions. If the layout algorithm doesn'
t work for your new |
42 * InfoBar, convince Chrome for Android's UX team to amend the master spec and t
hen change the | 42 * InfoBar, convince Chrome for Android's UX team to amend the master spec and t
hen change the |
43 * layout algorithm to match. | 43 * layout algorithm to match. |
44 * | 44 * |
45 * TODO(dfalcantara): The line spacing multiplier is applied to all lines in JB
& KK, even if the | 45 * TODO(dfalcantara): The line spacing multiplier is applied to all lines in JB
& KK, even if the |
46 * TextView has only one line. This throws off vertical alig
nment. Find a | 46 * TextView has only one line. This throws off vertical alig
nment. Find a |
47 * solution that hopefully doesn't involve subclassing the Te
xtView. | 47 * solution that hopefully doesn't involve subclassing the Te
xtView. |
48 * | |
49 * TODO(dfalcantara): Move this to a more general location. | |
50 */ | 48 */ |
51 public final class InfoBarControlLayout extends ViewGroup { | 49 public final class InfoBarControlLayout extends ViewGroup { |
52 public static final int INVALID_INDEX = -1; | |
53 | |
54 /** | 50 /** |
55 * ArrayAdapter that automatically determines what size make its Views to ac
commodate all of | 51 * ArrayAdapter that automatically determines what size make its Views to ac
commodate all of |
56 * its potential values. | 52 * its potential values. |
57 * @param <T> Type of object that the ArrayAdapter stores. | 53 * @param <T> Type of object that the ArrayAdapter stores. |
58 */ | 54 */ |
59 public static final class InfoBarArrayAdapter<T> extends ArrayAdapter<T> { | 55 public static final class InfoBarArrayAdapter<T> extends ArrayAdapter<T> { |
60 private final String mLabel; | 56 private final String mLabel; |
61 private int mMinWidthRequiredForValues; | 57 private int mMinWidthRequiredForValues; |
62 | 58 |
63 public InfoBarArrayAdapter(Context context, String label) { | 59 public InfoBarArrayAdapter(Context context, String label) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 } | 152 } |
157 } | 153 } |
158 | 154 |
159 private final int mMarginBetweenRows; | 155 private final int mMarginBetweenRows; |
160 private final int mMarginBetweenColumns; | 156 private final int mMarginBetweenColumns; |
161 | 157 |
162 /** | 158 /** |
163 * Do not call this method directly; use {@link InfoBarLayout#addControlLayo
ut()}. | 159 * Do not call this method directly; use {@link InfoBarLayout#addControlLayo
ut()}. |
164 */ | 160 */ |
165 public InfoBarControlLayout(Context context) { | 161 public InfoBarControlLayout(Context context) { |
166 super(context); | 162 this(context, null); |
| 163 } |
| 164 |
| 165 public InfoBarControlLayout(Context context, AttributeSet attrs) { |
| 166 super(context, attrs); |
167 | 167 |
168 Resources resources = context.getResources(); | 168 Resources resources = context.getResources(); |
169 mMarginBetweenRows = | 169 mMarginBetweenRows = |
170 resources.getDimensionPixelSize(R.dimen.infobar_control_margin_b
etween_rows); | 170 resources.getDimensionPixelSize(R.dimen.infobar_control_margin_b
etween_rows); |
171 mMarginBetweenColumns = | 171 mMarginBetweenColumns = |
172 resources.getDimensionPixelSize(R.dimen.infobar_control_margin_b
etween_columns); | 172 resources.getDimensionPixelSize(R.dimen.infobar_control_margin_b
etween_columns); |
173 } | 173 } |
174 | 174 |
175 @Override | 175 @Override |
176 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | 176 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 (SwitchCompat) switchLayout.findViewById(R.id.control_toggle_swi
tch); | 354 (SwitchCompat) switchLayout.findViewById(R.id.control_toggle_swi
tch); |
355 switchView.setId(toggleId); | 355 switchView.setId(toggleId); |
356 switchView.setChecked(isChecked); | 356 switchView.setChecked(isChecked); |
357 | 357 |
358 return switchLayout; | 358 return switchLayout; |
359 } | 359 } |
360 | 360 |
361 /** | 361 /** |
362 * Creates a set of standard radio buttons and adds it to the layout. | 362 * Creates a set of standard radio buttons and adds it to the layout. |
363 * | 363 * |
364 * ------------------------------------------------- | |
365 * | O | MESSAGE #1 | | |
366 * | O | MESSAGE #N | | |
367 * ------------------------------------------------- | |
368 * | |
369 * @param messages Messages to display for the options. | 364 * @param messages Messages to display for the options. |
370 * @param tags Optional list of tags to attach to the buttons. | 365 * @param tags Optional list of tags to attach to the buttons. |
371 * @param selectedIndex Which index to mark as being selected. | |
372 */ | 366 */ |
373 public RadioGroup addRadioButtons( | 367 public RadioButtonLayout addRadioButtons(List<CharSequence> messages, @Nulla
ble List<?> tags) { |
374 List<CharSequence> messages, @Nullable List<?> tags, int selectedInd
ex) { | |
375 if (tags != null) assert tags.size() == messages.size(); | |
376 | |
377 ControlLayoutParams params = new ControlLayoutParams(); | 368 ControlLayoutParams params = new ControlLayoutParams(); |
378 params.mMustBeFullWidth = true; | 369 params.mMustBeFullWidth = true; |
379 | 370 |
380 RadioGroup radioLayout = new RadioGroup(getContext()); | 371 RadioButtonLayout radioLayout = new RadioButtonLayout(getContext()); |
| 372 radioLayout.addOptions(messages, tags); |
| 373 |
381 addView(radioLayout, params); | 374 addView(radioLayout, params); |
382 | |
383 for (int i = 0; i < messages.size(); i++) { | |
384 RadioButton button = | |
385 (RadioButton) LayoutInflater.from(getContext()) | |
386 .inflate(R.layout.infobar_control_radio, radioLayout
, false); | |
387 button.setText(messages.get(i)); | |
388 if (tags != null) button.setTag(tags.get(i)); | |
389 button.setChecked(i == selectedIndex); | |
390 radioLayout.addView(button); | |
391 | |
392 // Add margins between each of the radio buttons. | |
393 if (i < messages.size() - 1) { | |
394 ((MarginLayoutParams) button.getLayoutParams()).bottomMargin = m
MarginBetweenRows; | |
395 } | |
396 } | |
397 | |
398 return radioLayout; | 375 return radioLayout; |
399 } | 376 } |
400 | 377 |
401 /** | 378 /** |
402 * Creates a standard spinner and adds it to the layout. | 379 * Creates a standard spinner and adds it to the layout. |
403 */ | 380 */ |
404 public <T> Spinner addSpinner(int spinnerId, ArrayAdapter<T> arrayAdapter) { | 381 public <T> Spinner addSpinner(int spinnerId, ArrayAdapter<T> arrayAdapter) { |
405 Spinner spinner = (Spinner) LayoutInflater.from(getContext()).inflate( | 382 Spinner spinner = (Spinner) LayoutInflater.from(getContext()).inflate( |
406 R.layout.infobar_control_spinner, this, false); | 383 R.layout.infobar_control_spinner, this, false); |
407 spinner.setAdapter(arrayAdapter); | 384 spinner.setAdapter(arrayAdapter); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 | 439 |
463 /** | 440 /** |
464 * @return The {@link ControlLayoutParams} for the given child. | 441 * @return The {@link ControlLayoutParams} for the given child. |
465 */ | 442 */ |
466 @VisibleForTesting | 443 @VisibleForTesting |
467 static ControlLayoutParams getControlLayoutParams(View child) { | 444 static ControlLayoutParams getControlLayoutParams(View child) { |
468 return (ControlLayoutParams) child.getLayoutParams(); | 445 return (ControlLayoutParams) child.getLayoutParams(); |
469 } | 446 } |
470 | 447 |
471 } | 448 } |
OLD | NEW |