Home | History | Annotate | Download | only in selectcalendars
      1 /*
      2  * Copyright (C) 2010 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.calendar.selectcalendars;
     18 
     19 import com.android.calendar.R;
     20 import com.android.calendar.Utils;
     21 
     22 import android.content.Context;
     23 import android.content.res.Configuration;
     24 import android.content.res.Resources;
     25 import android.database.Cursor;
     26 import android.graphics.drawable.Drawable;
     27 import android.provider.CalendarContract.Calendars;
     28 import android.text.TextUtils;
     29 import android.view.LayoutInflater;
     30 import android.view.View;
     31 import android.view.ViewGroup;
     32 import android.view.ViewGroup.LayoutParams;
     33 import android.widget.BaseAdapter;
     34 import android.widget.CheckBox;
     35 import android.widget.ListAdapter;
     36 import android.widget.RelativeLayout;
     37 import android.widget.TextView;
     38 
     39 public class SelectCalendarsSimpleAdapter extends BaseAdapter implements ListAdapter {
     40     private static final String TAG = "SelectCalendarsAdapter";
     41     private static int SELECTED_COLOR_CHIP_SIZE = 16;
     42     private static int UNSELECTED_COLOR_CHIP_SIZE = 10;
     43     private static int COLOR_CHIP_LEFT_MARGIN = 20;
     44     private static int COLOR_CHIP_RIGHT_MARGIN = 8;
     45     private static int COLOR_CHIP_TOP_OFFSET = 5;
     46     private static int BOTTOM_ITEM_HEIGHT = 64;
     47     private static int NORMAL_ITEM_HEIGHT = 48;
     48 
     49     private static final int IS_SELECTED = 1 << 0;
     50     private static final int IS_TOP = 1 << 1;
     51     private static final int IS_BOTTOM = 1 << 2;
     52     private static final int IS_BELOW_SELECTED = 1 << 3;
     53 
     54 
     55     private LayoutInflater mInflater;
     56     Resources mRes;
     57     private int mLayout;
     58     private int mOrientation;
     59     private CalendarRow[] mData;
     60     private Cursor mCursor;
     61     private int mRowCount = 0;
     62 
     63     private int mIdColumn;
     64     private int mNameColumn;
     65     private int mColorColumn;
     66     private int mVisibleColumn;
     67     private int mOwnerAccountColumn;
     68     private float mScale = 0;
     69     private int mColorCalendarVisible;
     70     private int mColorCalendarHidden;
     71     private int mColorCalendarSecondaryVisible;
     72     private int mColorCalendarSecondaryHidden;
     73 
     74     private class CalendarRow {
     75         long id;
     76         String displayName;
     77         String ownerAccount;
     78         int color;
     79         boolean selected;
     80     }
     81 
     82     public SelectCalendarsSimpleAdapter(Context context, int layout, Cursor c) {
     83         super();
     84         mLayout = layout;
     85         mOrientation = context.getResources().getConfiguration().orientation;
     86         initData(c);
     87         mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     88         mRes = context.getResources();
     89         mColorCalendarVisible = mRes.getColor(R.color.calendar_visible);
     90         mColorCalendarHidden = mRes.getColor(R.color.calendar_hidden);
     91         mColorCalendarSecondaryVisible = mRes.getColor(R.color.calendar_secondary_visible);
     92         mColorCalendarSecondaryHidden = mRes.getColor(R.color.calendar_secondary_hidden);
     93 
     94         if (mScale == 0) {
     95             mScale = mRes.getDisplayMetrics().density;
     96             SELECTED_COLOR_CHIP_SIZE *= mScale;
     97             UNSELECTED_COLOR_CHIP_SIZE *= mScale;
     98             COLOR_CHIP_LEFT_MARGIN *= mScale;
     99             COLOR_CHIP_RIGHT_MARGIN *= mScale;
    100             COLOR_CHIP_TOP_OFFSET *= mScale;
    101             BOTTOM_ITEM_HEIGHT *= mScale;
    102             NORMAL_ITEM_HEIGHT *= mScale;
    103         }
    104     }
    105 
    106     private static class TabletCalendarItemBackgrounds {
    107         static private int[] mBackgrounds = null;
    108 
    109         /**
    110          * Sets up the background drawables for the calendars list
    111          *
    112          * @param res The context's resources
    113          */
    114         static int[] getBackgrounds() {
    115             // Not thread safe. Ok if called only from main thread
    116             if (mBackgrounds != null) {
    117                 return mBackgrounds;
    118             }
    119 
    120             mBackgrounds = new int[16];
    121 
    122             mBackgrounds[0] = R.drawable.calname_unselected;
    123 
    124             mBackgrounds[IS_SELECTED] = R.drawable.calname_select_underunselected;
    125 
    126             mBackgrounds[IS_SELECTED | IS_BOTTOM] =
    127                     R.drawable.calname_bottom_select_underunselected;
    128 
    129             mBackgrounds[IS_SELECTED | IS_BOTTOM | IS_BELOW_SELECTED] =
    130                     R.drawable.calname_bottom_select_underselect;
    131             mBackgrounds[IS_SELECTED | IS_TOP | IS_BOTTOM | IS_BELOW_SELECTED] = mBackgrounds[
    132                     IS_SELECTED | IS_BOTTOM | IS_BELOW_SELECTED];
    133             mBackgrounds[IS_SELECTED | IS_TOP | IS_BOTTOM] = mBackgrounds[IS_SELECTED | IS_BOTTOM
    134                     | IS_BELOW_SELECTED];
    135 
    136             mBackgrounds[IS_SELECTED | IS_BELOW_SELECTED] = R.drawable.calname_select_underselect;
    137             mBackgrounds[IS_SELECTED | IS_TOP | IS_BELOW_SELECTED] = mBackgrounds[IS_SELECTED
    138                     | IS_BELOW_SELECTED];
    139             mBackgrounds[IS_SELECTED | IS_TOP] = mBackgrounds[IS_SELECTED | IS_BELOW_SELECTED];
    140 
    141             mBackgrounds[IS_BOTTOM] = R.drawable.calname_bottom_unselected;
    142 
    143             mBackgrounds[IS_BOTTOM | IS_BELOW_SELECTED] =
    144                     R.drawable.calname_bottom_unselected_underselect;
    145             mBackgrounds[IS_TOP | IS_BOTTOM | IS_BELOW_SELECTED] = mBackgrounds[IS_BOTTOM
    146                     | IS_BELOW_SELECTED];
    147             mBackgrounds[IS_TOP | IS_BOTTOM] = mBackgrounds[IS_BOTTOM | IS_BELOW_SELECTED];
    148 
    149             mBackgrounds[IS_BELOW_SELECTED] = R.drawable.calname_unselected_underselect;
    150             mBackgrounds[IS_TOP | IS_BELOW_SELECTED] = mBackgrounds[IS_BELOW_SELECTED];
    151             mBackgrounds[IS_TOP] = mBackgrounds[IS_BELOW_SELECTED];
    152             return mBackgrounds;
    153         }
    154     }
    155 
    156     private void initData(Cursor c) {
    157         if (mCursor != null && c != mCursor) {
    158             mCursor.close();
    159         }
    160         if (c == null) {
    161             mCursor = c;
    162             mRowCount = 0;
    163             mData = null;
    164             return;
    165         }
    166         // TODO create a broadcast listener for ACTION_PROVIDER_CHANGED to update the cursor
    167         mCursor = c;
    168         mIdColumn = c.getColumnIndexOrThrow(Calendars._ID);
    169         mNameColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME);
    170         mColorColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR);
    171         mVisibleColumn = c.getColumnIndexOrThrow(Calendars.VISIBLE);
    172         mOwnerAccountColumn = c.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT);
    173 
    174         mRowCount = c.getCount();
    175         mData = new CalendarRow[(c.getCount())];
    176         c.moveToPosition(-1);
    177         int p = 0;
    178         while (c.moveToNext()) {
    179             mData[p] = new CalendarRow();
    180             mData[p].id = c.getLong(mIdColumn);
    181             mData[p].displayName = c.getString(mNameColumn);
    182             mData[p].color = c.getInt(mColorColumn);
    183             mData[p].selected = c.getInt(mVisibleColumn) != 0;
    184             mData[p].ownerAccount = c.getString(mOwnerAccountColumn);
    185             p++;
    186         }
    187     }
    188 
    189     public void changeCursor(Cursor c) {
    190         initData(c);
    191         notifyDataSetChanged();
    192     }
    193 
    194     public View getView(int position, View convertView, ViewGroup parent) {
    195         if (position >= mRowCount) {
    196             return null;
    197         }
    198         String name = mData[position].displayName;
    199         boolean selected = mData[position].selected;
    200 
    201         int color = Utils.getDisplayColorFromColor(mData[position].color);
    202         View view;
    203         if (convertView == null) {
    204             view = mInflater.inflate(mLayout, parent, false);
    205         } else {
    206             view = convertView;
    207         }
    208 
    209         TextView calendarName = (TextView) view.findViewById(R.id.calendar);
    210         calendarName.setText(name);
    211 
    212         View colorView = view.findViewById(R.id.color);
    213         colorView.setBackgroundColor(color);
    214 
    215         CheckBox syncCheckBox = (CheckBox) view.findViewById(R.id.sync);
    216         if (syncCheckBox != null) {
    217             // Full screen layout
    218             syncCheckBox.setChecked(selected);
    219 
    220             int textColor;
    221             if (selected) {
    222                 textColor = mColorCalendarVisible;
    223             } else {
    224                 textColor = mColorCalendarHidden;
    225             }
    226             calendarName.setTextColor(textColor);
    227             LayoutParams layoutParam = calendarName.getLayoutParams();
    228 
    229             TextView secondaryText = (TextView) view.findViewById(R.id.status);
    230             if (!TextUtils.isEmpty(mData[position].ownerAccount)
    231                     && !mData[position].ownerAccount.equals(name)
    232                     && !mData[position].ownerAccount.endsWith("calendar.google.com")) {
    233                 int secondaryColor;
    234                 if (selected) {
    235                     secondaryColor = mColorCalendarSecondaryVisible;
    236                 } else {
    237                     secondaryColor = mColorCalendarSecondaryHidden;
    238                 }
    239                 secondaryText.setText(mData[position].ownerAccount);
    240                 secondaryText.setTextColor(secondaryColor);
    241                 secondaryText.setVisibility(View.VISIBLE);
    242                 layoutParam.height = LayoutParams.WRAP_CONTENT;
    243             } else {
    244                 secondaryText.setVisibility(View.GONE);
    245                 layoutParam.height = LayoutParams.MATCH_PARENT;
    246             }
    247 
    248             calendarName.setLayoutParams(layoutParam);
    249 
    250         } else {
    251             // Tablet layout
    252             RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
    253                     SELECTED_COLOR_CHIP_SIZE, SELECTED_COLOR_CHIP_SIZE);
    254             params.leftMargin = COLOR_CHIP_LEFT_MARGIN;
    255             params.rightMargin = COLOR_CHIP_RIGHT_MARGIN;
    256             // This offset is needed because the assets include the bottom of the
    257             // previous item
    258             params.topMargin = COLOR_CHIP_TOP_OFFSET;
    259             if (!selected) {
    260                 params.height = UNSELECTED_COLOR_CHIP_SIZE;
    261                 params.width = UNSELECTED_COLOR_CHIP_SIZE;
    262                 params.leftMargin += (SELECTED_COLOR_CHIP_SIZE - UNSELECTED_COLOR_CHIP_SIZE) / 2;
    263                 params.topMargin += (SELECTED_COLOR_CHIP_SIZE - UNSELECTED_COLOR_CHIP_SIZE) / 2;
    264             }
    265             colorView.setLayoutParams(params);
    266 
    267             Drawable bg = getBackground(position, selected);
    268             view.setBackgroundDrawable(bg);
    269             ViewGroup.LayoutParams newParams = view.getLayoutParams();
    270             if (position == mData.length - 1) {
    271                 newParams.height = BOTTOM_ITEM_HEIGHT;
    272             } else {
    273                 newParams.height = NORMAL_ITEM_HEIGHT;
    274             }
    275             view.setLayoutParams(newParams);
    276             CheckBox visibleCheckBox = (CheckBox) view.findViewById(R.id.visible_check_box);
    277             if (visibleCheckBox != null) {
    278                 visibleCheckBox.setChecked(selected);
    279             }
    280         }
    281         view.invalidate();
    282         return view;
    283     }
    284 
    285     /**
    286      * @param position position of the calendar item
    287      * @param selected whether it is selected or not
    288      * @return the drawable to use for this view
    289      */
    290     protected Drawable getBackground(int position, boolean selected) {
    291         int bg;
    292         bg = selected ? IS_SELECTED : 0;
    293         bg |= (position == 0 && mOrientation == Configuration.ORIENTATION_LANDSCAPE) ? IS_TOP : 0;
    294         bg |= position == mData.length - 1 ? IS_BOTTOM : 0;
    295         bg |= (position > 0 && mData[position - 1].selected) ? IS_BELOW_SELECTED : 0;
    296         return mRes.getDrawable(TabletCalendarItemBackgrounds.getBackgrounds()[bg]);
    297     }
    298 
    299     public int getCount() {
    300         return mRowCount;
    301     }
    302 
    303     public Object getItem(int position) {
    304         if (position >= mRowCount) {
    305             return null;
    306         }
    307         CalendarRow item = mData[position];
    308         return item;
    309     }
    310 
    311     public long getItemId(int position) {
    312         if (position >= mRowCount) {
    313             return 0;
    314         }
    315         return mData[position].id;
    316     }
    317 
    318     public void setVisible(int position, int visible) {
    319         mData[position].selected = visible != 0;
    320         notifyDataSetChanged();
    321     }
    322 
    323     public int getVisible(int position) {
    324         return mData[position].selected ? 1 : 0;
    325     }
    326 
    327     @Override
    328     public boolean hasStableIds() {
    329         return true;
    330     }
    331 }
    332