1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.alarmclock;
18 
19 import android.appwidget.AppWidgetManager;
20 import android.content.Context;
21 import android.content.res.Configuration;
22 import android.content.res.Resources;
23 import android.os.Bundle;
24 import android.util.TypedValue;
25 import android.widget.RemoteViews;
26 
27 import com.android.deskclock.R;
28 import com.android.deskclock.Utils;
29 import com.android.deskclock.data.DataModel;
30 
31 public class WidgetUtils {
32     static final String TAG = "WidgetUtils";
33 
setClockSize(Context context, RemoteViews clock, float scale)34     public static void setClockSize(Context context, RemoteViews clock, float scale) {
35         float fontSize = context.getResources().getDimension(R.dimen.widget_big_font_size);
36         clock.setTextViewTextSize(
37                 R.id.the_clock, TypedValue.COMPLEX_UNIT_PX, fontSize * scale);
38     }
39 
40     // Calculate the scale factor of the fonts in the widget
getScaleRatio(Context context, Bundle options, int id)41     public static float getScaleRatio(Context context, Bundle options, int id) {
42         if (options == null) {
43             AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
44             if (widgetManager == null) {
45                 // no manager , do no scaling
46                 return 1f;
47             }
48             options = widgetManager.getAppWidgetOptions(id);
49         }
50         if (options != null) {
51             int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
52             if (minWidth == 0) {
53                 // No data , do no scaling
54                 return 1f;
55             }
56             Resources res = context.getResources();
57             float density = res.getDisplayMetrics().density;
58             float ratio = (density * minWidth) / res.getDimension(R.dimen.min_digital_widget_width);
59             ratio = Math.min(ratio, getHeightScaleRatio(context, options, id));
60             ratio *= .83f;
61 
62             final SelectedCitiesRunnable selectedCitiesRunnable = new SelectedCitiesRunnable();
63             DataModel.getDataModel().run(selectedCitiesRunnable);
64             if (selectedCitiesRunnable.mAnyCitiesSelected) {
65                 return (ratio > 1f) ? 1f : ratio;
66             }
67 
68             ratio = Math.min(ratio, 1.6f);
69             if (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
70                 ratio = Math.max(ratio, .71f);
71             }
72             else {
73                 ratio = Math.max(ratio, .45f);
74             }
75             return ratio;
76         }
77         return 1f;
78     }
79 
80     // Calculate the scale factor of the fonts in the list of  the widget using the widget height
getHeightScaleRatio(Context context, Bundle options, int id)81     private static float getHeightScaleRatio(Context context, Bundle options, int id) {
82         if (options == null) {
83             AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
84             if (widgetManager == null) {
85                 // no manager , do no scaling
86                 return 1f;
87             }
88             options = widgetManager.getAppWidgetOptions(id);
89         }
90         if (options != null) {
91             int minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
92             if (minHeight == 0) {
93                 // No data , do no scaling
94                 return 1f;
95             }
96             Resources res = context.getResources();
97             float density = res.getDisplayMetrics().density;
98             float ratio = density * minHeight / res.getDimension(R.dimen.min_digital_widget_height);
99             if (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
100                 return ratio * 1.75f;
101             }
102             return ratio;
103         }
104         return 1;
105     }
106 
107 
108     // Decide if to show the list of world clock.
109     // Check to see if the widget size is big enough, if it is return true.
showList(Context context, int id, float scale)110     public static boolean showList(Context context, int id, float scale) {
111         AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
112         if (widgetManager == null) {
113             // no manager to make the calculation, show the list anyway
114             return true;
115         }
116         Bundle options = widgetManager.getAppWidgetOptions(id);
117         if (options == null) {
118             // no data to make the calculation, show the list anyway
119             return true;
120         }
121         Resources res = context.getResources();
122         String whichHeight = res.getConfiguration().orientation ==
123                 Configuration.ORIENTATION_PORTRAIT
124                 ? AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT
125                 : AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
126         int height = options.getInt(whichHeight);
127         if (height == 0) {
128             // no data to make the calculation, show the list anyway
129             return true;
130         }
131         float density = res.getDisplayMetrics().density;
132         // Estimate height of date text box
133         float lblBox = 1.35f * res.getDimension(R.dimen.label_font_size);
134         float neededSize = res.getDimension(R.dimen.digital_widget_list_min_fixed_height) +
135                 2 * lblBox +
136                 scale * res.getDimension(R.dimen.digital_widget_list_min_scaled_height);
137         return ((density * height) > neededSize);
138     }
139 
140     /***
141      * Set the format of the time on the clock according to the locale
142      * @param context - Context used to get user's locale and time preferences
143      * @param clock - view to format
144      * @param showAmPm - show am/pm label if true
145      * @param clockId - id of TextClock view as defined in the clock's layout.
146      */
setTimeFormat(Context context, RemoteViews clock, boolean showAmPm, int clockId)147     public static void setTimeFormat(Context context, RemoteViews clock, boolean showAmPm,
148             int clockId) {
149         if (clock != null) {
150             // Set the best format for 12 hours mode according to the locale
151             clock.setCharSequence(clockId, "setFormat12Hour",
152                     Utils.get12ModeFormat(context, showAmPm));
153             // Set the best format for 24 hours mode according to the locale
154             clock.setCharSequence(clockId, "setFormat24Hour", Utils.get24ModeFormat());
155         }
156     }
157 
158     private static class SelectedCitiesRunnable implements Runnable {
159 
160         private boolean mAnyCitiesSelected;
161 
162         @Override
run()163         public void run() {
164             mAnyCitiesSelected = !DataModel.getDataModel().getSelectedCities().isEmpty();
165         }
166     }
167 }
168 
169