Home | History | Annotate | Download | only in alarmclock
      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.Intent;
     22 import android.content.res.Resources;
     23 import android.text.format.DateFormat;
     24 import android.util.Log;
     25 import android.util.TypedValue;
     26 import android.view.View;
     27 import android.widget.RemoteViews;
     28 import android.widget.RemoteViewsService.RemoteViewsFactory;
     29 
     30 import com.android.deskclock.R;
     31 import com.android.deskclock.Utils;
     32 import com.android.deskclock.worldclock.CityObj;
     33 import com.android.deskclock.worldclock.WorldClockAdapter;
     34 
     35 import java.util.Calendar;
     36 import java.util.Locale;
     37 import java.util.TimeZone;
     38 
     39 public class DigitalWidgetViewsFactory implements RemoteViewsFactory {
     40     private static final String TAG = "DigitalWidgetViewsFactory";
     41 
     42     private Context mContext;
     43     private Resources mResources;
     44     private int mId = AppWidgetManager.INVALID_APPWIDGET_ID;
     45     private RemoteWorldClockAdapter mAdapter;
     46     private float mFontScale = 1;
     47 
     48     // An adapter to provide the view for the list of cities in the world clock.
     49     private class RemoteWorldClockAdapter extends WorldClockAdapter {
     50         private final float mFontSize;
     51         private final float mFont24Size;
     52 
     53         public RemoteWorldClockAdapter(Context context) {
     54             super(context);
     55             mClocksPerRow = context.getResources().getInteger(
     56                     R.integer.appwidget_world_clocks_per_row);
     57             mFontSize = context.getResources().getDimension(R.dimen.widget_medium_font_size);
     58             mFont24Size = context.getResources().getDimension(R.dimen.widget_24_medium_font_size);
     59         }
     60 
     61         public RemoteViews getViewAt(int position) {
     62             // There are 2 cities per item
     63             int index = position * 2;
     64             if (index < 0 || index >= mCitiesList.length) {
     65                 return null;
     66             }
     67 
     68             RemoteViews views = new RemoteViews(
     69                     mContext.getPackageName(), R.layout.world_clock_remote_list_item);
     70 
     71             // Always how the left clock
     72             updateView(views, (CityObj) mCitiesList[index], R.id.left_clock,
     73                     R.id.city_name_left, R.id.city_day_left);
     74             // Show the right clock if any, make it invisible if there is no
     75             // clock on the right
     76             // to keep the left view on the left.
     77             if (index + 1 < mCitiesList.length) {
     78                 updateView(views, (CityObj) mCitiesList[index + 1], R.id.right_clock,
     79                         R.id.city_name_right, R.id.city_day_right);
     80             } else {
     81                 hideView(views, R.id.right_clock, R.id.city_name_right,
     82                         R.id.city_day_right);
     83             }
     84 
     85             // Hide last spacer if last row
     86             int lastRow = ((mCitiesList.length + 1) / 2) - 1;
     87             if (position == lastRow) {
     88                 views.setViewVisibility(R.id.city_spacer, View.GONE);
     89             } else {
     90                 views.setViewVisibility(R.id.city_spacer, View.VISIBLE);
     91             }
     92 
     93             return views;
     94         }
     95 
     96         private void updateView(RemoteViews clock, CityObj cityObj, int clockId,
     97                 int labelId, int dayId) {
     98             final Calendar now = Calendar.getInstance();
     99             now.setTimeInMillis(System.currentTimeMillis());
    100             int myDayOfWeek = now.get(Calendar.DAY_OF_WEEK);
    101             CityObj cityInDb = mCitiesDb.get(cityObj.mCityId);
    102             String cityTZ = (cityInDb != null) ? cityInDb.mTimeZone : cityObj.mTimeZone;
    103             now.setTimeZone(TimeZone.getTimeZone(cityTZ));
    104             int cityDayOfWeek = now.get(Calendar.DAY_OF_WEEK);
    105 
    106             WidgetUtils.setTimeFormat(clock,
    107                     (int)mResources.getDimension(R.dimen.widget_label_font_size), clockId);
    108             float fontSize = mFontScale * (DateFormat.is24HourFormat(mContext)
    109                     ? mFont24Size : mFontSize);
    110             clock.setTextViewTextSize(clockId, TypedValue.COMPLEX_UNIT_PX, fontSize * mFontScale);
    111             clock.setString(clockId, "setTimeZone", cityObj.mTimeZone);
    112 
    113             // Home city or city not in DB , use data from the save selected cities list
    114             clock.setTextViewText(labelId, Utils.getCityName(cityObj, cityInDb));
    115 
    116             if (myDayOfWeek != cityDayOfWeek) {
    117                 clock.setTextViewText(dayId, mContext.getString(
    118                         R.string.world_day_of_week_label, now.getDisplayName(
    119                                 Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault())));
    120                 clock.setViewVisibility(dayId, View.VISIBLE);
    121             } else {
    122                 clock.setViewVisibility(dayId, View.GONE);
    123             }
    124 
    125             clock.setViewVisibility(clockId, View.VISIBLE);
    126             clock.setViewVisibility(labelId, View.VISIBLE);
    127         }
    128 
    129         private void hideView(
    130                 RemoteViews clock, int clockId, int labelId, int dayId) {
    131             clock.setViewVisibility(clockId, View.INVISIBLE);
    132             clock.setViewVisibility(labelId, View.INVISIBLE);
    133             clock.setViewVisibility(dayId, View.INVISIBLE);
    134         }
    135     }
    136 
    137     public DigitalWidgetViewsFactory(Context context, Intent intent) {
    138         mContext = context;
    139         mResources = mContext.getResources();
    140         mId = intent.getIntExtra(
    141                 AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
    142         mAdapter = new RemoteWorldClockAdapter(context);
    143     }
    144 
    145     @SuppressWarnings("unused")
    146     public DigitalWidgetViewsFactory() {
    147     }
    148 
    149     @Override
    150     public int getCount() {
    151         if (WidgetUtils.showList(mContext, mId, mFontScale)) {
    152             return mAdapter.getCount();
    153         }
    154         return 0;
    155     }
    156 
    157     @Override
    158     public long getItemId(int position) {
    159         return position;
    160     }
    161 
    162     @Override
    163     public RemoteViews getLoadingView() {
    164         return null;
    165     }
    166 
    167     @Override
    168     public RemoteViews getViewAt(int position) {
    169         RemoteViews v = mAdapter.getViewAt(position);
    170         if (v != null) {
    171             Intent fillInIntent = new Intent();
    172             v.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
    173         }
    174         return v;
    175     }
    176 
    177     @Override
    178     public int getViewTypeCount() {
    179         return 1;
    180     }
    181 
    182     @Override
    183     public boolean hasStableIds() {
    184         return true;
    185     }
    186 
    187     @Override
    188     public void onCreate() {
    189         if (DigitalAppWidgetService.LOGGING) {
    190             Log.i(TAG, "DigitalWidget onCreate " + mId);
    191         }
    192     }
    193 
    194     @Override
    195     public void onDataSetChanged() {
    196         mAdapter.loadData(mContext);
    197         mAdapter.loadCitiesDb(mContext);
    198         mAdapter.updateHomeLabel(mContext);
    199 
    200         mFontScale = WidgetUtils.getScaleRatio(mContext, null, mId);
    201     }
    202 
    203     @Override
    204     public void onDestroy() {
    205         if (DigitalAppWidgetService.LOGGING) {
    206             Log.i(TAG, "DigitalWidget onDestroy " + mId);
    207         }
    208     }
    209 }
    210 
    211