michael@0: /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.preferences; michael@0: michael@0: import org.mozilla.gecko.R; michael@0: michael@0: import android.app.AlertDialog; michael@0: import android.content.Context; michael@0: import android.content.res.Resources; michael@0: import android.graphics.Color; michael@0: import android.preference.DialogPreference; michael@0: import android.util.AttributeSet; michael@0: import android.util.Log; michael@0: import android.util.TypedValue; michael@0: import android.view.LayoutInflater; michael@0: import android.view.View; michael@0: import android.view.ViewGroup; michael@0: import android.widget.Button; michael@0: import android.widget.ScrollView; michael@0: import android.widget.TextView; michael@0: michael@0: import java.util.HashMap; michael@0: michael@0: class FontSizePreference extends DialogPreference { michael@0: private static final String LOGTAG = "FontSizePreference"; michael@0: private static final int TWIP_TO_PT_RATIO = 20; // 20 twip = 1 point. michael@0: private static final int PREVIEW_FONT_SIZE_UNIT = TypedValue.COMPLEX_UNIT_PT; michael@0: private static final int DEFAULT_FONT_INDEX = 2; michael@0: michael@0: private final Context mContext; michael@0: /** Container for mPreviewFontView to allow for scrollable padding at the top of the view. */ michael@0: private ScrollView mScrollingContainer; michael@0: private TextView mPreviewFontView; michael@0: private Button mIncreaseFontButton; michael@0: private Button mDecreaseFontButton; michael@0: michael@0: private final String[] mFontTwipValues; michael@0: private final String[] mFontSizeNames; // Ex: "Small". michael@0: /** Index into the above arrays for the saved preference value (from Gecko). */ michael@0: private int mSavedFontIndex = DEFAULT_FONT_INDEX; michael@0: /** Index into the above arrays for the currently displayed font size (the preview). */ michael@0: private int mPreviewFontIndex = mSavedFontIndex; michael@0: private final HashMap mFontTwipToIndexMap; michael@0: michael@0: public FontSizePreference(Context context, AttributeSet attrs) { michael@0: super(context, attrs); michael@0: mContext = context; michael@0: michael@0: final Resources res = mContext.getResources(); michael@0: mFontTwipValues = res.getStringArray(R.array.pref_font_size_values); michael@0: mFontSizeNames = res.getStringArray(R.array.pref_font_size_entries); michael@0: mFontTwipToIndexMap = new HashMap(); michael@0: for (int i = 0; i < mFontTwipValues.length; ++i) { michael@0: mFontTwipToIndexMap.put(mFontTwipValues[i], i); michael@0: } michael@0: } michael@0: michael@0: @Override michael@0: protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { michael@0: final LayoutInflater inflater = michael@0: (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); michael@0: View dialogView = inflater.inflate(R.layout.font_size_preference, null); michael@0: initInternalViews(dialogView); michael@0: updatePreviewFontSize(mFontTwipValues[mPreviewFontIndex]); michael@0: michael@0: builder.setTitle(null); michael@0: builder.setView(dialogView); michael@0: } michael@0: michael@0: /** Saves relevant views to instance variables and initializes their settings. */ michael@0: private void initInternalViews(View dialogView) { michael@0: mScrollingContainer = (ScrollView) dialogView.findViewById(R.id.scrolling_container); michael@0: // Background cannot be set in XML (see bug 783597 - TODO: Change this to XML when bug is fixed). michael@0: mScrollingContainer.setBackgroundColor(Color.WHITE); michael@0: mPreviewFontView = (TextView) dialogView.findViewById(R.id.preview); michael@0: michael@0: mDecreaseFontButton = (Button) dialogView.findViewById(R.id.decrease_preview_font_button); michael@0: mIncreaseFontButton = (Button) dialogView.findViewById(R.id.increase_preview_font_button); michael@0: setButtonState(mPreviewFontIndex); michael@0: mDecreaseFontButton.setOnClickListener(new View.OnClickListener() { michael@0: @Override michael@0: public void onClick(View v) { michael@0: mPreviewFontIndex = Math.max(mPreviewFontIndex - 1, 0); michael@0: updatePreviewFontSize(mFontTwipValues[mPreviewFontIndex]); michael@0: mIncreaseFontButton.setEnabled(true); michael@0: // If we reached the minimum index, disable the button. michael@0: if (mPreviewFontIndex == 0) { michael@0: mDecreaseFontButton.setEnabled(false); michael@0: } michael@0: } michael@0: }); michael@0: mIncreaseFontButton.setOnClickListener(new View.OnClickListener() { michael@0: @Override michael@0: public void onClick(View v) { michael@0: mPreviewFontIndex = Math.min(mPreviewFontIndex + 1, mFontTwipValues.length - 1); michael@0: updatePreviewFontSize(mFontTwipValues[mPreviewFontIndex]); michael@0: michael@0: mDecreaseFontButton.setEnabled(true); michael@0: // If we reached the maximum index, disable the button. michael@0: if (mPreviewFontIndex == mFontTwipValues.length - 1) { michael@0: mIncreaseFontButton.setEnabled(false); michael@0: } michael@0: } michael@0: }); michael@0: } michael@0: michael@0: @Override michael@0: protected void onDialogClosed(boolean positiveResult) { michael@0: super.onDialogClosed(positiveResult); michael@0: if (!positiveResult) { michael@0: mPreviewFontIndex = mSavedFontIndex; michael@0: return; michael@0: } michael@0: mSavedFontIndex = mPreviewFontIndex; michael@0: final String twipVal = mFontTwipValues[mSavedFontIndex]; michael@0: final OnPreferenceChangeListener prefChangeListener = getOnPreferenceChangeListener(); michael@0: if (prefChangeListener == null) { michael@0: Log.e(LOGTAG, "PreferenceChangeListener is null. FontSizePreference will not be saved to Gecko."); michael@0: return; michael@0: } michael@0: prefChangeListener.onPreferenceChange(this, twipVal); michael@0: } michael@0: michael@0: /** michael@0: * Finds the index of the given twip value and sets it as the saved preference value. Also the michael@0: * current preview text size to the given value. Does not update the mPreviewFontView text size. michael@0: */ michael@0: protected void setSavedFontSize(String twip) { michael@0: final Integer index = mFontTwipToIndexMap.get(twip); michael@0: if (index != null) { michael@0: mSavedFontIndex = index; michael@0: mPreviewFontIndex = mSavedFontIndex; michael@0: return; michael@0: } michael@0: resetSavedFontSizeToDefault(); michael@0: Log.e(LOGTAG, "setSavedFontSize: Given font size does not exist in twip values map. Reverted to default font size."); michael@0: } michael@0: michael@0: /** michael@0: * Updates the mPreviewFontView to the given text size, resets the container's scroll to the top michael@0: * left, and invalidates the view. Does not update the font indices. michael@0: */ michael@0: private void updatePreviewFontSize(String twip) { michael@0: float pt = convertTwipStrToPT(twip); michael@0: // Android will not render a font size of 0 pt but for Gecko, 0 twip turns off font michael@0: // inflation. Thus we special case 0 twip to display a renderable font size. michael@0: if (pt == 0) { michael@0: // Android adds an inexplicable extra margin on the smallest font size so to get around michael@0: // this, we reinflate the view. michael@0: ViewGroup parentView = (ViewGroup) mScrollingContainer.getParent(); michael@0: parentView.removeAllViews(); michael@0: final LayoutInflater inflater = michael@0: (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); michael@0: View dialogView = inflater.inflate(R.layout.font_size_preference, parentView); michael@0: initInternalViews(dialogView); michael@0: mPreviewFontView.setTextSize(PREVIEW_FONT_SIZE_UNIT, 1); michael@0: } else { michael@0: mPreviewFontView.setTextSize(PREVIEW_FONT_SIZE_UNIT, pt); michael@0: } michael@0: mScrollingContainer.scrollTo(0, 0); michael@0: } michael@0: michael@0: /** michael@0: * Resets the font indices to the default value. Does not update the mPreviewFontView text size. michael@0: */ michael@0: private void resetSavedFontSizeToDefault() { michael@0: mSavedFontIndex = DEFAULT_FONT_INDEX; michael@0: mPreviewFontIndex = mSavedFontIndex; michael@0: } michael@0: michael@0: private void setButtonState(int index) { michael@0: if (index == 0) { michael@0: mDecreaseFontButton.setEnabled(false); michael@0: } else if (index == mFontTwipValues.length - 1) { michael@0: mIncreaseFontButton.setEnabled(false); michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Returns the name of the font size (ex: "Small") at the currently saved preference value. michael@0: */ michael@0: protected String getSavedFontSizeName() { michael@0: return mFontSizeNames[mSavedFontIndex]; michael@0: } michael@0: michael@0: private float convertTwipStrToPT(String twip) { michael@0: return Float.parseFloat(twip) / TWIP_TO_PT_RATIO; michael@0: } michael@0: }