mobile/android/base/preferences/FontSizePreference.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/preferences/FontSizePreference.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,192 @@
     1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +package org.mozilla.gecko.preferences;
    1.10 +
    1.11 +import org.mozilla.gecko.R;
    1.12 +
    1.13 +import android.app.AlertDialog;
    1.14 +import android.content.Context;
    1.15 +import android.content.res.Resources;
    1.16 +import android.graphics.Color;
    1.17 +import android.preference.DialogPreference;
    1.18 +import android.util.AttributeSet;
    1.19 +import android.util.Log;
    1.20 +import android.util.TypedValue;
    1.21 +import android.view.LayoutInflater;
    1.22 +import android.view.View;
    1.23 +import android.view.ViewGroup;
    1.24 +import android.widget.Button;
    1.25 +import android.widget.ScrollView;
    1.26 +import android.widget.TextView;
    1.27 +
    1.28 +import java.util.HashMap;
    1.29 +
    1.30 +class FontSizePreference extends DialogPreference {
    1.31 +    private static final String LOGTAG = "FontSizePreference";
    1.32 +    private static final int TWIP_TO_PT_RATIO = 20; // 20 twip = 1 point.
    1.33 +    private static final int PREVIEW_FONT_SIZE_UNIT = TypedValue.COMPLEX_UNIT_PT;
    1.34 +    private static final int DEFAULT_FONT_INDEX = 2;
    1.35 +
    1.36 +    private final Context mContext;
    1.37 +    /** Container for mPreviewFontView to allow for scrollable padding at the top of the view. */
    1.38 +    private ScrollView mScrollingContainer;
    1.39 +    private TextView mPreviewFontView;
    1.40 +    private Button mIncreaseFontButton;
    1.41 +    private Button mDecreaseFontButton;
    1.42 +
    1.43 +    private final String[] mFontTwipValues;
    1.44 +    private final String[] mFontSizeNames; // Ex: "Small".
    1.45 +    /** Index into the above arrays for the saved preference value (from Gecko). */
    1.46 +    private int mSavedFontIndex = DEFAULT_FONT_INDEX;
    1.47 +    /** Index into the above arrays for the currently displayed font size (the preview). */
    1.48 +    private int mPreviewFontIndex = mSavedFontIndex;
    1.49 +    private final HashMap<String, Integer> mFontTwipToIndexMap;
    1.50 +
    1.51 +    public FontSizePreference(Context context, AttributeSet attrs) {
    1.52 +        super(context, attrs);
    1.53 +        mContext = context;
    1.54 +
    1.55 +        final Resources res = mContext.getResources();
    1.56 +        mFontTwipValues = res.getStringArray(R.array.pref_font_size_values);
    1.57 +        mFontSizeNames = res.getStringArray(R.array.pref_font_size_entries);
    1.58 +        mFontTwipToIndexMap = new HashMap<String, Integer>();
    1.59 +        for (int i = 0; i < mFontTwipValues.length; ++i) {
    1.60 +            mFontTwipToIndexMap.put(mFontTwipValues[i], i);
    1.61 +        }
    1.62 +    }
    1.63 +
    1.64 +    @Override
    1.65 +    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
    1.66 +        final LayoutInflater inflater =
    1.67 +            (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    1.68 +        View dialogView = inflater.inflate(R.layout.font_size_preference, null);
    1.69 +        initInternalViews(dialogView);
    1.70 +        updatePreviewFontSize(mFontTwipValues[mPreviewFontIndex]);
    1.71 +
    1.72 +        builder.setTitle(null);
    1.73 +        builder.setView(dialogView);
    1.74 +    }
    1.75 +
    1.76 +    /** Saves relevant views to instance variables and initializes their settings. */
    1.77 +    private void initInternalViews(View dialogView) {
    1.78 +        mScrollingContainer = (ScrollView) dialogView.findViewById(R.id.scrolling_container);
    1.79 +        // Background cannot be set in XML (see bug 783597 - TODO: Change this to XML when bug is fixed).
    1.80 +        mScrollingContainer.setBackgroundColor(Color.WHITE);
    1.81 +        mPreviewFontView = (TextView) dialogView.findViewById(R.id.preview);
    1.82 +
    1.83 +        mDecreaseFontButton = (Button) dialogView.findViewById(R.id.decrease_preview_font_button);
    1.84 +        mIncreaseFontButton = (Button) dialogView.findViewById(R.id.increase_preview_font_button);
    1.85 +        setButtonState(mPreviewFontIndex);
    1.86 +        mDecreaseFontButton.setOnClickListener(new View.OnClickListener() {
    1.87 +            @Override
    1.88 +            public void onClick(View v) {
    1.89 +                mPreviewFontIndex = Math.max(mPreviewFontIndex - 1, 0);
    1.90 +                updatePreviewFontSize(mFontTwipValues[mPreviewFontIndex]);
    1.91 +                mIncreaseFontButton.setEnabled(true);
    1.92 +                // If we reached the minimum index, disable the button.
    1.93 +                if (mPreviewFontIndex == 0) {
    1.94 +                    mDecreaseFontButton.setEnabled(false);
    1.95 +                }
    1.96 +            }
    1.97 +        });
    1.98 +        mIncreaseFontButton.setOnClickListener(new View.OnClickListener() {
    1.99 +            @Override
   1.100 +            public void onClick(View v) {
   1.101 +                mPreviewFontIndex = Math.min(mPreviewFontIndex + 1, mFontTwipValues.length - 1);
   1.102 +                updatePreviewFontSize(mFontTwipValues[mPreviewFontIndex]);
   1.103 +
   1.104 +                mDecreaseFontButton.setEnabled(true);
   1.105 +                // If we reached the maximum index, disable the button.
   1.106 +                if (mPreviewFontIndex == mFontTwipValues.length - 1) {
   1.107 +                    mIncreaseFontButton.setEnabled(false);
   1.108 +                }
   1.109 +            }
   1.110 +        });
   1.111 +    }
   1.112 +
   1.113 +    @Override
   1.114 +    protected void onDialogClosed(boolean positiveResult) {
   1.115 +        super.onDialogClosed(positiveResult);
   1.116 +        if (!positiveResult) {
   1.117 +            mPreviewFontIndex = mSavedFontIndex;
   1.118 +            return;
   1.119 +        }
   1.120 +        mSavedFontIndex = mPreviewFontIndex;
   1.121 +        final String twipVal = mFontTwipValues[mSavedFontIndex];
   1.122 +        final OnPreferenceChangeListener prefChangeListener = getOnPreferenceChangeListener();
   1.123 +        if (prefChangeListener == null) {
   1.124 +            Log.e(LOGTAG, "PreferenceChangeListener is null. FontSizePreference will not be saved to Gecko.");
   1.125 +            return;
   1.126 +        }
   1.127 +        prefChangeListener.onPreferenceChange(this, twipVal);
   1.128 +    }
   1.129 +
   1.130 +    /**
   1.131 +     * Finds the index of the given twip value and sets it as the saved preference value. Also the
   1.132 +     * current preview text size to the given value. Does not update the mPreviewFontView text size.
   1.133 +     */
   1.134 +    protected void setSavedFontSize(String twip) {
   1.135 +        final Integer index = mFontTwipToIndexMap.get(twip);
   1.136 +        if (index != null) {
   1.137 +            mSavedFontIndex = index;
   1.138 +            mPreviewFontIndex = mSavedFontIndex;
   1.139 +            return;
   1.140 +        }
   1.141 +        resetSavedFontSizeToDefault();
   1.142 +        Log.e(LOGTAG, "setSavedFontSize: Given font size does not exist in twip values map. Reverted to default font size.");
   1.143 +    }
   1.144 +
   1.145 +    /**
   1.146 +     * Updates the mPreviewFontView to the given text size, resets the container's scroll to the top
   1.147 +     * left, and invalidates the view. Does not update the font indices.
   1.148 +     */
   1.149 +    private void updatePreviewFontSize(String twip) {
   1.150 +        float pt = convertTwipStrToPT(twip);
   1.151 +        // Android will not render a font size of 0 pt but for Gecko, 0 twip turns off font
   1.152 +        // inflation. Thus we special case 0 twip to display a renderable font size.
   1.153 +        if (pt == 0) {
   1.154 +            // Android adds an inexplicable extra margin on the smallest font size so to get around
   1.155 +            // this, we reinflate the view.
   1.156 +            ViewGroup parentView = (ViewGroup) mScrollingContainer.getParent();
   1.157 +            parentView.removeAllViews();
   1.158 +            final LayoutInflater inflater =
   1.159 +                (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   1.160 +            View dialogView = inflater.inflate(R.layout.font_size_preference, parentView);
   1.161 +            initInternalViews(dialogView);
   1.162 +            mPreviewFontView.setTextSize(PREVIEW_FONT_SIZE_UNIT, 1);
   1.163 +        } else {
   1.164 +            mPreviewFontView.setTextSize(PREVIEW_FONT_SIZE_UNIT, pt);
   1.165 +        }
   1.166 +        mScrollingContainer.scrollTo(0, 0);
   1.167 +    }
   1.168 +
   1.169 +    /**
   1.170 +     * Resets the font indices to the default value. Does not update the mPreviewFontView text size.
   1.171 +     */
   1.172 +    private void resetSavedFontSizeToDefault() {
   1.173 +        mSavedFontIndex = DEFAULT_FONT_INDEX;
   1.174 +        mPreviewFontIndex = mSavedFontIndex;
   1.175 +    }
   1.176 +
   1.177 +    private void setButtonState(int index) {
   1.178 +        if (index == 0) {
   1.179 +            mDecreaseFontButton.setEnabled(false);
   1.180 +        } else if (index == mFontTwipValues.length - 1) {
   1.181 +            mIncreaseFontButton.setEnabled(false);
   1.182 +        }
   1.183 +    }
   1.184 +
   1.185 +    /**
   1.186 +     * Returns the name of the font size (ex: "Small") at the currently saved preference value.
   1.187 +     */
   1.188 +    protected String getSavedFontSizeName() {
   1.189 +        return mFontSizeNames[mSavedFontIndex];
   1.190 +    }
   1.191 +
   1.192 +    private float convertTwipStrToPT(String twip) {
   1.193 +        return Float.parseFloat(twip) / TWIP_TO_PT_RATIO;
   1.194 +    }
   1.195 +}

mercurial