Clock widget scaling and dimensions.

BUG: 9519509
BUG: 9533414

Increased complexity of scaling calculation to improve result.
Check vertical scaling when height is small (as in landscape.)

Change-Id: Ieb9944b338574830ef1fba6bfe802086148f5751
diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml
index 311d495..0acf502 100644
--- a/res/values-sw600dp-land/dimens.xml
+++ b/res/values-sw600dp-land/dimens.xml
@@ -54,8 +54,4 @@
     <dimen name="timer_button_extra_offset">0dip</dimen>
 
     <dimen name="glowpadview_margin_right">-64dip</dimen>
-
-    <dimen name="min_digital_widget_resize_width">370dip</dimen>
-    <dimen name="min_digital_widget_height">200dip</dimen>
-    <dimen name="digital_widget_list_min_height">200dip</dimen>
 </resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index a986c41..7534a33 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -36,9 +36,7 @@
     <dimen name="alarm_label_padding">64dip</dimen>
 
     <dimen name="big_font_size">220dp</dimen>
-    <dimen name="widget_big_font_size">130dp</dimen>
     <dimen name="medium_font_size">100dp</dimen>
-    <dimen name="widget_medium_font_size">70dp</dimen>
     <dimen name="label_font_size">18sp</dimen>
     <dimen name="body_font_size">24sp</dimen>
 
@@ -84,11 +82,17 @@
 
     <dimen name="glowpadview_margin_bottom">0dip</dimen>
 
-    <dimen name="min_digital_widget_width">450dip</dimen>
-    <dimen name="min_digital_widget_height">120dip</dimen>
-    <dimen name="min_digital_widget_resize_width">450dip</dimen>
-    <dimen name="min_digital_widget_resize_height">120dip</dimen>
-    <dimen name="def_digital_widget_width">200dip</dimen>
-    <dimen name="digital_widget_list_min_height">190dip</dimen>
+    <!-- Digital Widget settings (keyguard|home_screen) -->
+    <!-- Use larger fonts -->
+    <dimen name="widget_big_font_size">130dp</dimen>
+    <dimen name="widget_medium_font_size">52dp</dimen>
+    <dimen name="widget_24_medium_font_size">65dp</dimen>
+    <dimen name="min_digital_widget_width">335dp</dimen>
+    <dimen name="min_digital_widget_height">207dp</dimen>
+    <dimen name="min_digital_widget_resize_width">335dp</dimen>
+    <dimen name="min_digital_widget_resize_height">207dp</dimen>
+    <dimen name="digital_widget_list_min_scaled_height">263dp</dimen>
+    <dimen name="digital_widget_list_min_fixed_height">15dp</dimen>
+    <dimen name="digital_widget_list_margin_top">15dp</dimen>
 
 </resources>
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
index bee4607..76bf866 100644
--- a/res/values-sw720dp-land/dimens.xml
+++ b/res/values-sw720dp-land/dimens.xml
@@ -22,7 +22,5 @@
     <dimen name="glowpadview_margin_right">48dip</dimen>
 
     <dimen name="alarm_alert_clock_padding_left">128dp</dimen>
-    <dimen name="digital_widget_list_min_height">150dip</dimen>
-    <dimen name="min_digital_widget_resize_width">370dip</dimen>
 
 </resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
deleted file mode 100644
index 142ff79..0000000
--- a/res/values-sw720dp/dimens.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2012 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<!-- These resources are around just to allow their values to be customized
-     for different hardware and product builds. -->
-<resources>
-    <dimen name="digital_widget_list_min_height">100dip</dimen>
-</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3c9ffe5..ac11ec9 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -50,10 +50,8 @@
     <dimen name="circletimer_marker_size">16dip</dimen>
 
     <dimen name="big_font_size">120dp</dimen>
-    <dimen name="widget_big_font_size">80dp</dimen>
     <dimen name="small_font_size">48sp</dimen>
     <dimen name="medium_font_size">60dp</dimen>
-    <dimen name="widget_medium_font_size">48dp</dimen>
     <dimen name="label_font_size">14sp</dimen>
     <dimen name="header_font_size">24sp</dimen>
     <dimen name="body_font_size">18sp</dimen>
@@ -150,13 +148,23 @@
     <dimen name="glowpadview_margin_bottom">-64dip</dimen>
     <dimen name="glowpadview_margin_right">0dip</dimen>
 
-    <dimen name="min_digital_widget_width">160dip</dimen>
-    <dimen name="min_digital_widget_height">70dip</dimen>
-    <dimen name="min_digital_widget_resize_width">160dip</dimen>
-    <dimen name="min_digital_widget_resize_height">70dip</dimen>
-    <dimen name="def_digital_widget_width">160dip</dimen>
-    <dimen name="def_digital_widget_height">130dip</dimen>
-    <dimen name="digital_widget_list_min_height">70dip</dimen>
-    <dimen name="digital_widget_list_margin_top">12dip</dimen>
+    <!-- Digital Widget settings (keyguard|home_screen) -->
+    <!-- Clock and world clock sizes -->
+    <dimen name="widget_big_font_size">80dp</dimen>
+    <dimen name="widget_medium_font_size">32dp</dimen>
+    <dimen name="widget_24_medium_font_size">40dp</dimen>
+    <!-- width/height of layout/digital_widget_time -->
+    <!-- height is sum of widget_big_font_size + label_font_size + margins -->
+    <dimen name="min_digital_widget_width">206dp</dimen>
+    <dimen name="min_digital_widget_height">129dp</dimen>
+    <!-- same as min_digital_widget_{width,height} -->
+    <dimen name="min_digital_widget_resize_width">206dp</dimen>
+    <dimen name="min_digital_widget_resize_height">129dp</dimen>
+    <!-- sum of scaled heights -->
+    <dimen name="digital_widget_list_min_scaled_height">162dp</dimen>
+    <!-- sum of fixed heights -->
+    <dimen name="digital_widget_list_min_fixed_height">12dp</dimen>
+    <!-- top margin for digital_appwidget_listview -->
+    <dimen name="digital_widget_list_margin_top">12dp</dimen>
 
 </resources>
diff --git a/src/com/android/alarmclock/DigitalWidgetViewsFactory.java b/src/com/android/alarmclock/DigitalWidgetViewsFactory.java
index b4d5027..b92fc0d 100644
--- a/src/com/android/alarmclock/DigitalWidgetViewsFactory.java
+++ b/src/com/android/alarmclock/DigitalWidgetViewsFactory.java
@@ -50,7 +50,6 @@
     private boolean mReloadCitiesList = true;
     private boolean mReloadCitiesDb = true;
     private float mFontScale = 1;
-    private float mListScale = 1;
     private PendingIntent mQuarterlyIntent;
     private String mLastTimeZone;
 
@@ -58,10 +57,12 @@
     // An adapter to provide the view for the list of cities in the world clock.
     private class RemoteWorldClockAdapter extends WorldClockAdapter {
         private final float mFontSize;
+        private final float mFont24Size;
 
         public RemoteWorldClockAdapter(Context context) {
             super(context);
             mFontSize = context.getResources().getDimension(R.dimen.widget_medium_font_size);
+            mFont24Size = context.getResources().getDimension(R.dimen.widget_24_medium_font_size);
         }
 
         public RemoteViews getViewAt(int position) {
@@ -100,9 +101,10 @@
             now.setTimeZone(TimeZone.getTimeZone(cityTZ));
             int cityDayOfWeek = now.get(Calendar.DAY_OF_WEEK);
 
-            float scale = Math.min(mFontScale, mListScale);
-            clock.setTextViewTextSize(clockId1, TypedValue.COMPLEX_UNIT_PX, mFontSize * scale);
-            clock.setTextViewTextSize(clockId2, TypedValue.COMPLEX_UNIT_PX, mFontSize * scale);
+            float fontSize = mFontScale * (DateFormat.is24HourFormat(mContext)
+                    ? mFont24Size : mFontSize);
+            clock.setTextViewTextSize(clockId1, TypedValue.COMPLEX_UNIT_PX, fontSize * mFontScale);
+            clock.setTextViewTextSize(clockId2, TypedValue.COMPLEX_UNIT_PX, fontSize * mFontScale);
             clock.setString(clockId1, "setTimeZone", cityObj.mTimeZone);
             clock.setString(clockId2, "setTimeZone", cityObj.mTimeZone);
 
@@ -211,8 +213,6 @@
         }
 
         mFontScale = WidgetUtils.getScaleRatio(mContext, null, mId);
-        mListScale = WidgetUtils.getHeightScaleRatio(mContext, null, mId);
-
     }
 
     @Override
diff --git a/src/com/android/alarmclock/WidgetUtils.java b/src/com/android/alarmclock/WidgetUtils.java
index ad1bd63..3dc5835 100644
--- a/src/com/android/alarmclock/WidgetUtils.java
+++ b/src/com/android/alarmclock/WidgetUtils.java
@@ -18,6 +18,7 @@
 
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.util.Log;
@@ -39,29 +40,42 @@
 
     // Calculate the scale factor of the fonts in the widget
     public static float getScaleRatio(Context context, Bundle options, int id) {
-        AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
         if (options == null) {
+            AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
+            if (widgetManager == null) {
+                // no manager , do no scaling
+                return 1f;
+            }
             options = widgetManager.getAppWidgetOptions(id);
         }
         if (options != null) {
-            float minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
+            int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
             if (minWidth == 0) {
                 // No data , do no scaling
                 return 1f;
             }
             Resources res = context.getResources();
             float density = res.getDisplayMetrics().density;
-            minWidth *= density;
-            float ratio = minWidth / res.getDimension(R.dimen.def_digital_widget_width);
+            float ratio = (density * minWidth) / res.getDimension(R.dimen.min_digital_widget_width);
+            // Check if the height could introduce a font size constraint
+            int minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
+            if (minHeight > 0 && (density * minHeight)
+                    < res.getDimension(R.dimen.min_digital_widget_height)) {
+                ratio = Math.min(ratio, getHeightScaleRatio(context, options, id));
+            }
             return (ratio > 1) ? 1 : ratio;
         }
         return 1;
     }
 
     // Calculate the scale factor of the fonts in the list of  the widget using the widget height
-    public static float getHeightScaleRatio(Context context, Bundle options, int id) {
-        AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
+    private static float getHeightScaleRatio(Context context, Bundle options, int id) {
         if (options == null) {
+            AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
+            if (widgetManager == null) {
+                // no manager , do no scaling
+                return 1f;
+            }
             options = widgetManager.getAppWidgetOptions(id);
         }
         if (options != null) {
@@ -71,8 +85,15 @@
                 return 1f;
             }
             Resources res = context.getResources();
-            float ratio = minHeight / res.getDimension(R.dimen.def_digital_widget_height);
-            return (ratio > 1) ? 1 : ratio;
+            float density = res.getDisplayMetrics().density;
+            // Estimate height of date text box - 1.35 roughly approximates the text box padding
+            float lblBox = 1.35f * res.getDimension(R.dimen.label_font_size);
+            // Ensure divisor for ratio is positive number
+            if (res.getDimension(R.dimen.min_digital_widget_height) - lblBox > 0) {
+                float ratio = ((density * minHeight) - lblBox)
+                        / (res.getDimension(R.dimen.min_digital_widget_height) - lblBox);
+                return (ratio > 1) ? 1 : ratio;
+            }
         }
         return 1;
     }
@@ -81,17 +102,33 @@
     // Decide if to show the list of world clock.
     // Check to see if the widget size is big enough, if it is return true.
     public static boolean showList(Context context, int id, float scale) {
-        Bundle options = AppWidgetManager.getInstance(context).getAppWidgetOptions(id);
+        AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
+        if (widgetManager == null) {
+            // no manager to make the calculation, show the list anyway
+            return true;
+        }
+        Bundle options = widgetManager.getAppWidgetOptions(id);
         if (options == null) {
             // no data to make the calculation, show the list anyway
             return true;
         }
-        float minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
         Resources res = context.getResources();
+        String whichHeight = res.getConfiguration().orientation ==
+                Configuration.ORIENTATION_PORTRAIT
+                ? AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT
+                : AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
+        int height = options.getInt(whichHeight);
+        if (height == 0) {
+            // no data to make the calculation, show the list anyway
+            return true;
+        }
         float density = res.getDisplayMetrics().density;
-        minHeight *= density;
-        int neededSize = (int) res.getDimension(R.dimen.digital_widget_list_min_height);
-        return (minHeight > neededSize);
+        // Estimate height of date text box
+        float lblBox = 1.35f * res.getDimension(R.dimen.label_font_size);
+        float neededSize = res.getDimension(R.dimen.digital_widget_list_min_fixed_height) +
+                2 * lblBox +
+                scale * res.getDimension(R.dimen.digital_widget_list_min_scaled_height);
+        return ((density * height) > neededSize);
     }
 }