DistilledPagePrefsView.java revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1// Copyright 2014 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
5package org.chromium.chrome.browser.dom_distiller;
6
7import android.app.AlertDialog;
8import android.content.Context;
9import android.util.AttributeSet;
10import android.view.LayoutInflater;
11import android.view.View;
12import android.view.ViewGroup;
13import android.widget.LinearLayout;
14import android.widget.RadioButton;
15import android.widget.RadioGroup;
16import android.widget.SeekBar;
17import android.widget.TextView;
18
19import org.chromium.chrome.R;
20import org.chromium.chrome.browser.accessibility.FontSizePrefs;
21import org.chromium.chrome.browser.profiles.Profile;
22import org.chromium.components.dom_distiller.core.DistilledPagePrefs;
23import org.chromium.components.dom_distiller.core.FontFamily;
24import org.chromium.components.dom_distiller.core.Theme;
25
26import java.text.NumberFormat;
27import java.util.EnumMap;
28import java.util.Locale;
29import java.util.Map;
30
31/**
32 * A view which displays preferences for distilled pages.  This allows users
33 * to change the theme, font size, etc. of distilled pages.
34 */
35public class DistilledPagePrefsView extends LinearLayout
36        implements DistilledPagePrefs.Observer, SeekBar.OnSeekBarChangeListener,
37        FontSizePrefs.Observer {
38    // XML layout for View.
39    private static final int VIEW_LAYOUT = R.layout.distilled_page_prefs_view;
40
41    // RadioGroup for color mode buttons.
42    private RadioGroup mRadioGroup;
43
44    // Buttons for color mode.
45    private final Map<Theme, RadioButton> mColorModeButtons;
46
47    private final DistilledPagePrefs mDistilledPagePrefs;
48    private final FontSizePrefs mFontSizePrefs;
49
50    // Text field showing font scale percentage.
51    private TextView mFontScaleTextView;
52
53    // SeekBar for font scale. Has range of [0, 30].
54    private SeekBar mFontScaleSeekBar;
55
56    private NumberFormat mPercentageFormatter;
57
58    /**
59     * Creates a DistilledPagePrefsView.
60     *
61     * @param context Context for acquiring resources.
62     * @param attrs Attributes from the XML layout inflation.
63     */
64    public DistilledPagePrefsView(Context context, AttributeSet attrs) {
65        super(context, attrs);
66        mDistilledPagePrefs = DomDistillerServiceFactory.getForProfile(
67                Profile.getLastUsedProfile()).getDistilledPagePrefs();
68        mFontSizePrefs = FontSizePrefs.getInstance(getContext());
69        mColorModeButtons = new EnumMap<Theme, RadioButton>(Theme.class);
70        mPercentageFormatter = NumberFormat.getPercentInstance(Locale.getDefault());
71    }
72
73    public static DistilledPagePrefsView create(Context context) {
74        return (DistilledPagePrefsView) LayoutInflater.from(context)
75                .inflate(VIEW_LAYOUT, null);
76    }
77
78    public static void showDialog(Context context) {
79        AlertDialog.Builder builder = new AlertDialog.Builder(context);
80        builder.setView(DistilledPagePrefsView.create(context));
81        builder.show();
82    }
83
84    @Override
85    public void onFinishInflate() {
86        super.onFinishInflate();
87        mRadioGroup = (RadioGroup) findViewById(R.id.radio_button_group);
88        mColorModeButtons.put(Theme.LIGHT,
89                initializeAndGetButton(R.id.light_mode, Theme.LIGHT));
90        mColorModeButtons.put(Theme.DARK,
91                initializeAndGetButton(R.id.dark_mode, Theme.DARK));
92        mColorModeButtons.put(Theme.SEPIA,
93                initializeAndGetButton(R.id.sepia_mode, Theme.SEPIA));
94        mColorModeButtons.get(mDistilledPagePrefs.getTheme()).setChecked(true);
95
96        mFontScaleSeekBar = (SeekBar) findViewById(R.id.font_size);
97        mFontScaleTextView = (TextView) findViewById(R.id.font_size_percentage);
98
99        // Setting initial progress on font scale seekbar.
100        onChangeFontSize(mFontSizePrefs.getFontScaleFactor());
101        mFontScaleSeekBar.setOnSeekBarChangeListener(this);
102    }
103
104    @Override
105    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
106        mRadioGroup.setOrientation(HORIZONTAL);
107
108        for (RadioButton button : mColorModeButtons.values()) {
109            ViewGroup.LayoutParams layoutParams =
110                    (ViewGroup.LayoutParams) button.getLayoutParams();
111            layoutParams.width = 0;
112        }
113
114        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
115
116        // If text is wider than button, change layout so that buttons are stacked on
117        // top of each other.
118        for (RadioButton button : mColorModeButtons.values()) {
119            if (button.getLineCount() > 1) {
120                mRadioGroup.setOrientation(VERTICAL);
121                for (RadioButton innerLoopButton : mColorModeButtons.values()) {
122                    ViewGroup.LayoutParams layoutParams =
123                            (ViewGroup.LayoutParams) innerLoopButton.getLayoutParams();
124                    layoutParams.width = LayoutParams.MATCH_PARENT;
125                }
126                break;
127            }
128        }
129
130        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
131    }
132
133    @Override
134    public void onAttachedToWindow() {
135        super.onAttachedToWindow();
136        mDistilledPagePrefs.addObserver(this);
137    }
138
139    @Override
140    public void onDetachedFromWindow() {
141        super.onDetachedFromWindow();
142        mDistilledPagePrefs.removeObserver(this);
143    }
144
145    // DistilledPagePrefs.Observer
146
147    @Override
148    public void onChangeFontFamily(FontFamily fontFamily) {
149         // TODO(smaslo): add GUI and front end implementation for FontFamily.
150    }
151
152    /**
153     * Changes which button is selected if the theme is changed in another tab.
154     */
155    @Override
156    public void onChangeTheme(Theme theme) {
157        mColorModeButtons.get(theme).setChecked(true);
158    }
159
160    // SeekBar.OnSeekBarChangeListener
161
162    @Override
163    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
164        // progress = [0, 30]
165        // newValue = .50, .55, .60, ..., 1.95, 2.00 (supported font scales)
166        float newValue = (progress / 20f + .5f);
167        setFontScaleTextView(newValue);
168        mFontSizePrefs.setFontScaleFactor((float) newValue);
169    }
170
171    @Override
172    public void onStartTrackingTouch(SeekBar seekBar) {}
173
174    @Override
175    public void onStopTrackingTouch(SeekBar seekBar) {}
176
177    // FontSizePrefs.Observer
178
179    @Override
180    public void onChangeFontSize(float newFontSize) {
181        setFontScaleTextView(newFontSize);
182        setFontScaleProgress(newFontSize);
183    }
184
185    @Override
186    public void onChangeForceEnableZoom(boolean enabled) {}
187
188    @Override
189    public void onChangeUserSetForceEnableZoom(boolean enabled) {}
190
191    /**
192     * Initiatializes a Button and selects it if it corresponds to the current
193     * theme.
194     */
195    private RadioButton initializeAndGetButton(int id, final Theme theme) {
196        final RadioButton button = (RadioButton) findViewById(id);
197        button.setOnClickListener(new View.OnClickListener() {
198            @Override
199            public void onClick(View v) {
200                mDistilledPagePrefs.setTheme(theme);
201            }
202        });
203        return button;
204    }
205
206    /**
207     * Sets the progress of mFontScaleSeekBar.
208     */
209    private void setFontScaleProgress(float newValue) {
210        // newValue = .50, .55, .60, ..., 1.95, 2.00 (supported font scales)
211        // progress = [0, 30]
212        int progress = (int) ((newValue - .5) * 20);
213        mFontScaleSeekBar.setProgress(progress);
214    }
215
216    /**
217     * Sets the text for the font scale text view.
218     */
219    private void setFontScaleTextView(float newValue) {
220        mFontScaleTextView.setText(mPercentageFormatter.format(newValue));
221    }
222}
223