Bug 779861: Fixing styling on Font Inflation dialog. r=bnicholson
authorMichael Comella <michael.l.comella@gmail.com>
Mon, 20 Aug 2012 15:09:00 +1200
changeset 102907 26d631be3337cd394ee1fdf6ff5aa49be9875f0c
parent 102906 1f256d6070ac93baafd76373afc09774e63d5477
child 102908 e262e9e1a0b1eac63be08d3dfd90f616e7169c7a
push id23313
push usergsharp@mozilla.com
push dateTue, 21 Aug 2012 18:08:14 +0000
treeherderautoland@688a80cdf39f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbnicholson
bugs779861
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 779861: Fixing styling on Font Inflation dialog. r=bnicholson
mobile/android/base/FontSizePreference.java
mobile/android/base/GeckoPreferences.java
mobile/android/base/Makefile.in
mobile/android/base/resources/layout-xlarge-v11/font_size_preference.xml
mobile/android/base/resources/layout/font_size_preference.xml
--- a/mobile/android/base/FontSizePreference.java
+++ b/mobile/android/base/FontSizePreference.java
@@ -2,92 +2,88 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import android.app.AlertDialog;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.preference.DialogPreference;
 import android.preference.Preference.OnPreferenceChangeListener;
-import android.text.method.ScrollingMovementMethod;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.ScrollView;
 import android.widget.TextView;
 
 import java.util.HashMap;
 
 class FontSizePreference extends DialogPreference {
     private static final String LOGTAG = "FontSizePreference";
     private static final int TWIP_TO_PT_RATIO = 20; // 20 twip = 1 point.
     private static final int PREVIEW_FONT_SIZE_UNIT = TypedValue.COMPLEX_UNIT_PT;
     private static final int DEFAULT_FONT_INDEX = 2;
 
-    // Final line height = line height * line_mult + line_mult;
-    private static final float LINE_SPACING_ADD = 0f; // Units unknown.
-    private static final float LINE_SPACING_MULT = 1.0f;
-
-    private static final float MIN_TEXTVIEW_WIDTH_DIP = 360; // Width of the Galaxy Nexus (portrait).
-    /** The dialog will encompass the minimum width + (1 / scaleFactor) of the remaining space. */
-    private static final float TEXTVIEW_WIDTH_SCALE_FACTOR = 3;
-
     private final Context mContext;
-    private int mCurrentOrientation;
+    /** Container for mPreviewFontView to allow for scrollable padding at the top of the view. */
+    private ScrollView mScrollingContainer;
     private TextView mPreviewFontView;
     private Button mIncreaseFontButton;
     private Button mDecreaseFontButton;
 
     private final String[] mFontTwipValues;
     private final String[] mFontSizeNames; // Ex: "Small".
     /** Index into the above arrays for the saved preference value (from Gecko). */
     private int mSavedFontIndex = DEFAULT_FONT_INDEX;
     /** Index into the above arrays for the currently displayed font size (the preview). */
     private int mPreviewFontIndex = mSavedFontIndex;
     private final HashMap<String, Integer> mFontTwipToIndexMap;
 
-    private boolean mPreviewFontViewHeightSet;
-
     public FontSizePreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
 
         final Resources res = mContext.getResources();
         mFontTwipValues = res.getStringArray(R.array.pref_font_size_values);
         mFontSizeNames = res.getStringArray(R.array.pref_font_size_entries);
         mFontTwipToIndexMap = new HashMap<String, Integer>();
         for (int i = 0; i < mFontTwipValues.length; ++i) {
             mFontTwipToIndexMap.put(mFontTwipValues[i], i);
         }
-        mCurrentOrientation = res.getConfiguration().orientation;
     }
 
     @Override
     protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
         final LayoutInflater inflater =
             (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View dialogView = inflater.inflate(R.layout.font_size_preference, null);
+        initInternalViews(dialogView);
+        updatePreviewFontSize(mFontTwipValues[mPreviewFontIndex]);
+
+        builder.setTitle(null);
+        builder.setView(dialogView);
+    }
+
+    /** Saves relevant views to instance variables and initializes their settings. */
+    private void initInternalViews(View dialogView) {
+        mScrollingContainer = (ScrollView) dialogView.findViewById(R.id.scrolling_container);
+        // Background cannot be set in XML (see bug 783597 - TODO: Change this to XML when bug is fixed).
+        mScrollingContainer.setBackgroundColor(Color.WHITE);
         mPreviewFontView = (TextView) dialogView.findViewById(R.id.preview);
-        mPreviewFontView.setMovementMethod(new ScrollingMovementMethod());
-        // There is no way to get the value for this padding so we turn it off.
-        mPreviewFontView.setIncludeFontPadding(false);
-        // Retrieving line spacing is not available until API 16 so we override the values instead.
-        mPreviewFontView.setLineSpacing(LINE_SPACING_ADD, LINE_SPACING_MULT);
 
         mDecreaseFontButton = (Button) dialogView.findViewById(R.id.decrease_preview_font_button);
         mIncreaseFontButton = (Button) dialogView.findViewById(R.id.increase_preview_font_button);
+        setButtonState(mPreviewFontIndex);
         mDecreaseFontButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 updatePreviewFontSize(mFontTwipValues[--mPreviewFontIndex]);
                 mIncreaseFontButton.setEnabled(true);
                 // If we reached the minimum index, disable the button.
                 if (mPreviewFontIndex == 0) {
                     mDecreaseFontButton.setEnabled(false);
                 }
@@ -99,23 +95,16 @@ class FontSizePreference extends DialogP
         
                 mDecreaseFontButton.setEnabled(true);
                 // If we reached the maximum index, disable the button.
                 if (mPreviewFontIndex == mFontTwipValues.length - 1) {
                     mIncreaseFontButton.setEnabled(false);
                 }
             }
         });
-
-        // Set mPreviewFontView dimensions.
-        setPreviewFontViewWidth();
-        setPreviewFontViewHeightListener();
-        setFontSizeToMaximum(); // Expects onGlobalLayout() to be called.
-
-        builder.setView(dialogView);
     }
 
     @Override
     protected void onDialogClosed(boolean positiveResult) {
         super.onDialogClosed(positiveResult);
         if (!positiveResult) {
             mPreviewFontIndex = mSavedFontIndex;
             return;
@@ -125,116 +114,53 @@ class FontSizePreference extends DialogP
         final OnPreferenceChangeListener prefChangeListener = getOnPreferenceChangeListener();
         if (prefChangeListener == null) {
             Log.e(LOGTAG, "PreferenceChangeListener is null. FontSizePreference will not be saved to Gecko.");
             return;
         }
         prefChangeListener.onPreferenceChange(this, twipVal);
     }
 
-    protected void onConfigurationChanged(Configuration newConfig) {
-        if (mCurrentOrientation != newConfig.orientation) {
-            mCurrentOrientation = newConfig.orientation;
-
-            // mPreviewFontView will be null if the dialog has not yet been shown.
-            if (mPreviewFontView != null) {
-                // Recalculate the mPreviewFontView dimensions since we have new screen dimensions.
-                setPreviewFontViewWidth();
-                mPreviewFontViewHeightSet = false;
-                setFontSizeToMaximum(); // Expects onGlobalLayout() to be called.
-            }
-        }
-    }
-
-    /**
-     * Sets the preview font size to the maximum given size.
-     */
-    private void setFontSizeToMaximum() {
-        updatePreviewFontSize(mFontTwipValues[mFontTwipValues.length - 1]);
-        // NOTE: If this method is being used with onGlobalLayout() to set mFontPreviewView height,
-        // the font size cannot be changed past this point or the dialog height will not calculate
-        // correctly. We must wait for the global layout state to change, calculate the height in
-        // onGlobalLayout(), and only then can changes be made.
-    }
-
-    /**
-     * Sets a global layout listener that will calculate the maximum required height of
-     * mPreviewFontView based upon the current font values and then reset the TextView to the saved
-     * preference values. This listener will only run once. mPreviewFontViewHeightSet must be set to
-     * false before being used again.
-     */
-    private void setPreviewFontViewHeightListener() {
-        mPreviewFontViewHeightSet = false;
-        final ViewTreeObserver vto = mPreviewFontView.getViewTreeObserver(); 
-        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
-            @Override 
-            public void onGlobalLayout() { 
-                if (!mPreviewFontViewHeightSet) {
-                    mPreviewFontViewHeightSet = true;
-                    final int desiredHeight = (int) (mPreviewFontView.getLineCount() *
-                            mPreviewFontView.getLineHeight() * LINE_SPACING_MULT + LINE_SPACING_ADD +
-                            mPreviewFontView.getPaddingTop() + mPreviewFontView.getPaddingBottom());
-                    mPreviewFontView.setHeight(desiredHeight);
-
-                    // Set the dialog state to the saved preference values.
-                    setButtonState(mPreviewFontIndex);
-                    updatePreviewFontSize(mFontTwipValues[mPreviewFontIndex]);
-                }
-            } 
-        }); 
-    }
-
-    /**
-     * Sets the width of the mPreviewFontView TextView. The width is calculated by adding a constant
-     * minimum width to a fraction of the remaining space on screen (if any), which is determined by
-     * the given scale factor. Note that in ICS, it appears that the dialog will not wrap content
-     * and will set the view size itself. In Gingerbread, this code executes and sets the dialog
-     * width dynamically.
-     */
-    private void setPreviewFontViewWidth() {
-        final DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
-        final float density = metrics.density;
-
-        final float actualWidthDip = metrics.widthPixels / density;
-        float scaleExtraDip = (actualWidthDip - MIN_TEXTVIEW_WIDTH_DIP) / TEXTVIEW_WIDTH_SCALE_FACTOR;
-        scaleExtraDip = scaleExtraDip >= 0 ? scaleExtraDip : 0;
-        final float desiredWidthDip = MIN_TEXTVIEW_WIDTH_DIP + scaleExtraDip;
-        final int desiredWidthPx = Math.round(desiredWidthDip * density);
-        mPreviewFontView.setWidth(desiredWidthPx);
-    }
-
     /**
      * Finds the index of the given twip value and sets it as the saved preference value. Also the
      * current preview text size to the given value. Does not update the mPreviewFontView text size.
      */
     protected void setSavedFontSize(String twip) {
         final Integer index = mFontTwipToIndexMap.get(twip);
         if (index != null) {
             mSavedFontIndex = index;
             mPreviewFontIndex = mSavedFontIndex;
             return;
         }
         resetSavedFontSizeToDefault();
         Log.e(LOGTAG, "setSavedFontSize: Given font size does not exist in twip values map. Reverted to default font size.");
     }
 
     /**
-     * Updates the mPreviewFontView to the given text size, resets the scroll to the top left, and
-     * invalidates the view. Does not update the font indices.
+     * Updates the mPreviewFontView to the given text size, resets the container's scroll to the top
+     * left, and invalidates the view. Does not update the font indices.
      */
     private void updatePreviewFontSize(String twip) {
         float pt = convertTwipStrToPT(twip);
         // Android will not render a font size of 0 pt but for Gecko, 0 twip turns off font
         // inflation. Thus we special case 0 twip to display a renderable font size.
         if (pt == 0) {
+            // Android adds an inexplicable extra margin on the smallest font size so to get around
+            // this, we reinflate the view.
+            ViewGroup parentView = (ViewGroup) mScrollingContainer.getParent();
+            parentView.removeAllViews();
+            final LayoutInflater inflater =
+                (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            View dialogView = inflater.inflate(R.layout.font_size_preference, parentView);
+            initInternalViews(dialogView);
             mPreviewFontView.setTextSize(PREVIEW_FONT_SIZE_UNIT, 1);
         } else {
             mPreviewFontView.setTextSize(PREVIEW_FONT_SIZE_UNIT, pt);
         }
-        mPreviewFontView.scrollTo(0, 0);
+        mScrollingContainer.scrollTo(0, 0);
     }
 
     /**
      * Resets the font indices to the default value. Does not update the mPreviewFontView text size.
      */
     private void resetSavedFontSizeToDefault() {
         mSavedFontIndex = DEFAULT_FONT_INDEX;
         mPreviewFontIndex = mSavedFontIndex;
--- a/mobile/android/base/GeckoPreferences.java
+++ b/mobile/android/base/GeckoPreferences.java
@@ -43,17 +43,16 @@ public class GeckoPreferences
     implements OnPreferenceChangeListener, GeckoEventListener
 {
     private static final String LOGTAG = "GeckoPreferences";
 
     private ArrayList<String> mPreferencesList;
     private PreferenceScreen mPreferenceScreen;
     private static boolean sIsCharEncodingEnabled = false;
     private static final String NON_PREF_PREFIX = "android.not_a_preference.";
-    private static final String FONT_SIZE_PREF_KEY = "font.size.inflation.minTwips";
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.preferences);
         registerEventListener("Preferences:Data");
         registerEventListener("Sanitize:Finished");
    }
@@ -65,25 +64,16 @@ public class GeckoPreferences
 
         mPreferencesList = new ArrayList<String>();
         mPreferenceScreen = getPreferenceScreen();
         initGroups(mPreferenceScreen);
         initValues();
     }
 
     @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        final FontSizePreference fontSizePref =
-                (FontSizePreference) mPreferenceScreen.findPreference(FONT_SIZE_PREF_KEY);
-        fontSizePref.onConfigurationChanged(newConfig);
-    }
-
-    @Override
     protected void onDestroy() {
         super.onDestroy();
         unregisterEventListener("Preferences:Data");
         unregisterEventListener("Sanitize:Finished");
     }
 
     public void handleMessage(String event, JSONObject message) {
         try {
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -352,16 +352,17 @@ RES_LAYOUT_LARGE_V11 = \
   res/layout-large-v11/doorhangerpopup.xml \
   res/layout-large-v11/site_identity_popup.xml \
   res/layout-large-v11/tabs_panel_toolbar_menu.xml \
   $(NULL)
 
 RES_LAYOUT_XLARGE_V11 = \
   res/layout-xlarge-v11/awesomebar_search.xml \
   res/layout-xlarge-v11/browser_toolbar_menu.xml \
+  res/layout-xlarge-v11/font_size_preference.xml \
   res/layout-xlarge-v11/remote_tabs_child.xml \
   res/layout-xlarge-v11/remote_tabs_group.xml \
   res/layout-xlarge-v11/tabs_panel_toolbar_menu.xml \
   res/layout-xlarge-v11/tabs_row.xml \
   $(NULL)
 
 RES_VALUES = \
   $(SYNC_RES_VALUES) \
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/layout-xlarge-v11/font_size_preference.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this file,
+   - You can obtain one at http://mozilla.org/MPL/2.0/.  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:orientation="vertical"> 
+
+    <ScrollView android:id="@+id/scrolling_container"
+                android:layout_width="fill_parent"
+                android:layout_height="350dp"
+                android:layout_margin="8dp"
+                android:padding="8dp"
+                android:scrollbars="vertical"
+                android:scrollbarStyle="outsideOverlay"
+                android:fadeScrollbars="true"
+                android:requiresFadingEdge="vertical">
+
+            <TextView android:id="@+id/preview"
+                      android:layout_width="fill_parent"
+                      android:layout_height="wrap_content"
+                      android:text="@string/pref_font_size_preview_text"
+                      android:textColor="#ff000000"/>
+
+    </ScrollView>
+
+    <LinearLayout android:id="@+id/button_container"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:layout_marginLeft="4dp"
+                  android:layout_marginRight="4dp"
+                  android:orientation="horizontal">
+
+        <Button android:id="@+id/decrease_preview_font_button"
+                android:layout_width="0dp"
+                android:layout_height="fill_parent"
+                android:layout_weight="1"
+                android:text="@string/pref_font_size_adjust_char"
+                android:textSize="8sp"/>
+
+        <Button android:id="@+id/increase_preview_font_button"
+                android:layout_width="0dp"
+                android:layout_height="fill_parent"
+                android:layout_weight="1"
+                android:text="@string/pref_font_size_adjust_char"
+                android:textSize="16sp"/>
+
+    </LinearLayout>
+
+</LinearLayout>
--- a/mobile/android/base/resources/layout/font_size_preference.xml
+++ b/mobile/android/base/resources/layout/font_size_preference.xml
@@ -1,35 +1,24 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this file,
    - You can obtain one at http://mozilla.org/MPL/2.0/.  -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent"
-              android:orientation="vertical"> 
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent">
 
-    <TextView android:id="@+id/preview"
-              android:layout_width="fill_parent"
-              android:layout_height="wrap_content"
-              android:layout_weight="1"
-              android:background="#ffffffff"
-              android:paddingTop="2dp"
-              android:paddingBottom="2dp"
-              android:paddingLeft="3dp"
-              android:paddingRight="3dp"
-              android:text="@string/pref_font_size_preview_text"
-              android:textColor="#ff000000"
-              android:scrollbars="vertical"
-              android:fadeScrollbars="true"/>
-
-    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    <LinearLayout android:id="@+id/button_container"
                   android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
+                  android:layout_marginLeft="4dp"
+                  android:layout_marginRight="4dp"
+                  android:layout_alignParentBottom="true"
+                  android:layout_alignParentLeft="true"
                   android:orientation="horizontal">
 
         <Button android:id="@+id/decrease_preview_font_button"
                 android:layout_width="0dp"
                 android:layout_height="fill_parent"
                 android:layout_weight="1"
                 android:text="@string/pref_font_size_adjust_char"
                 android:textSize="8sp"/>
@@ -38,9 +27,28 @@
                 android:layout_width="0dp"
                 android:layout_height="fill_parent"
                 android:layout_weight="1"
                 android:text="@string/pref_font_size_adjust_char"
                 android:textSize="16sp"/>
 
     </LinearLayout>
 
-</LinearLayout>
+    <ScrollView android:id="@+id/scrolling_container"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:layout_above="@id/button_container"
+                android:layout_margin="8dp"
+                android:padding="8dp"
+                android:scrollbars="vertical"
+                android:scrollbarStyle="outsideOverlay"
+                android:fadeScrollbars="true"
+                android:requiresFadingEdge="vertical">
+
+            <TextView android:id="@+id/preview"
+                      android:layout_width="fill_parent"
+                      android:layout_height="wrap_content"
+                      android:text="@string/pref_font_size_preview_text"
+                      android:textColor="#ff000000"/>
+
+    </ScrollView>
+
+</RelativeLayout>