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 +}