SimpleWeeksAdapter.java revision 91b01ed605e36fc5a7a924c226597a62c789b50d
1b025734047dd8b630c34cea53b371361adb2a65aEric Christopher/*
2b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * Copyright (C) 2010 The Android Open Source Project
3b025734047dd8b630c34cea53b371361adb2a65aEric Christopher *
4b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * Licensed under the Apache License, Version 2.0 (the "License");
5b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * you may not use this file except in compliance with the License.
6b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * You may obtain a copy of the License at
7b025734047dd8b630c34cea53b371361adb2a65aEric Christopher *
8b025734047dd8b630c34cea53b371361adb2a65aEric Christopher *      http://www.apache.org/licenses/LICENSE-2.0
9b025734047dd8b630c34cea53b371361adb2a65aEric Christopher *
10b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * Unless required by applicable law or agreed to in writing, software
11b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * distributed under the License is distributed on an "AS IS" BASIS,
12b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * See the License for the specific language governing permissions and
14b025734047dd8b630c34cea53b371361adb2a65aEric Christopher * limitations under the License.
15b025734047dd8b630c34cea53b371361adb2a65aEric Christopher */
16b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
17b025734047dd8b630c34cea53b371361adb2a65aEric Christopherpackage com.android.calendar.month;
18b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
19b025734047dd8b630c34cea53b371361adb2a65aEric Christopher// TODO Remove calendar imports when the required methods have been
20b025734047dd8b630c34cea53b371361adb2a65aEric Christopher// refactored into the public api
21b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport com.android.calendar.CalendarController;
22b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport com.android.calendar.Utils;
23b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
24b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.content.Context;
25b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.text.format.Time;
26b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.util.Log;
27b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.view.GestureDetector;
28b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.view.MotionEvent;
29b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.view.View;
30b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.view.View.OnTouchListener;
31b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.view.ViewGroup;
32b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.widget.AbsListView.LayoutParams;
33b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport android.widget.BaseAdapter;
34b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
35b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport java.util.Calendar;
36b025734047dd8b630c34cea53b371361adb2a65aEric Christopherimport java.util.HashMap;
37b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
38b025734047dd8b630c34cea53b371361adb2a65aEric Christopherpublic class MonthByWeekSimpleAdapter extends BaseAdapter implements OnTouchListener {
39b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
40b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    private static final String TAG = "MonthByWeek";
41b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
42b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public static final String WEEK_PARAMS_NUM_WEEKS = "num_weeks";
43b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public static final String WEEK_PARAMS_FOCUS_MONTH = "focus_month";
44b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public static final String WEEK_PARAMS_SHOW_WEEK = "week_numbers";
45b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public static final String WEEK_PARAMS_WEEK_START = "week_start";
46b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public static final String WEEK_PARAMS_JULIAN_DAY = "start_day";
47b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public static final String WEEK_PARAMS_DAYS_PER_WEEK = "days_per_week";
48b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
49b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected static final int WEEK_COUNT = CalendarController.MAX_CALENDAR_WEEK
50b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            - CalendarController.MIN_CALENDAR_WEEK;
51b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected static int DEFAULT_NUM_WEEKS = 6;
52b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected static int DEFAULT_MONTH_FOCUS = 0;
53b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected static int DEFAULT_DAYS_PER_WEEK = 7;
54b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected static int DEFAULT_WEEK_HEIGHT = 32;
55b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected static int WEEK_7_OVERHANG_HEIGHT = 7;
56b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected static float mScale = 0;
57b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected Context mContext;
58b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected Time mSelectedDay;
59b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected int mSelectedWeek;
60b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected int mFirstDayOfWeek = Calendar.getInstance().getFirstDayOfWeek();
61b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected boolean mShowWeekNumber = false;
62b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected GestureDetector mGestureDetector;
63b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected int mNumWeeks = DEFAULT_NUM_WEEKS;
64b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected int mDaysPerWeek = DEFAULT_DAYS_PER_WEEK;
65b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected int mFocusMonth = DEFAULT_MONTH_FOCUS;
66b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
67b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public MonthByWeekSimpleAdapter(Context context, HashMap<String, Integer> params) {
68b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        mContext = context;
69b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
70b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
71b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (mScale == 0) {
72b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            mScale = context.getResources().getDisplayMetrics().density;
73b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            if (mScale != 1) {
74b025734047dd8b630c34cea53b371361adb2a65aEric Christopher                WEEK_7_OVERHANG_HEIGHT *= mScale;
75b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            }
76b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
77b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        init();
78b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        updateParams(params);
79b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
80b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
81b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected void init() {
82b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
83b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        mSelectedDay = new Time();
84b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        mSelectedDay.setToNow();
85b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
86b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
87b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public void updateParams(HashMap<String, Integer> params) {
88b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (params == null) {
89b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            Log.e(TAG, "WeekParameters are null! Cannot update adapter.");
90b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            return;
91b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
92b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (params.containsKey(WEEK_PARAMS_FOCUS_MONTH)) {
93b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            mFocusMonth = params.get(WEEK_PARAMS_FOCUS_MONTH);
94b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
95b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (params.containsKey(WEEK_PARAMS_FOCUS_MONTH)) {
96b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            mNumWeeks = params.get(WEEK_PARAMS_NUM_WEEKS);
97b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
98b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (params.containsKey(WEEK_PARAMS_SHOW_WEEK)) {
99b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            mShowWeekNumber = params.get(WEEK_PARAMS_SHOW_WEEK) != 0;
100b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
101b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (params.containsKey(WEEK_PARAMS_WEEK_START)) {
102b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            mFirstDayOfWeek = params.get(WEEK_PARAMS_WEEK_START);
103b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
104b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (params.containsKey(WEEK_PARAMS_JULIAN_DAY)) {
105b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            mSelectedDay.setJulianDay(params.get(WEEK_PARAMS_JULIAN_DAY));
106b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
107b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (params.containsKey(WEEK_PARAMS_DAYS_PER_WEEK)) {
108b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            mDaysPerWeek = params.get(WEEK_PARAMS_DAYS_PER_WEEK);
109b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
110b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        refresh();
111b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
112b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
113b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public void setSelectedDay(Time selectedTime) {
114b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        mSelectedDay.set(selectedTime);
115b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        long millis = mSelectedDay.normalize(true);
116b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        mSelectedWeek = Utils.getWeeksSinceEpochFromJulianDay(
117b025734047dd8b630c34cea53b371361adb2a65aEric Christopher                Time.getJulianDay(millis, mSelectedDay.gmtoff), mFirstDayOfWeek);
118b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        notifyDataSetChanged();
119b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
120b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
121b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public Time getSelectedDay() {
122b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        return mSelectedDay;
123b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
124b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
125b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    protected void refresh() {
126b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        // TODO Add system support for first day of week and week numbers
127b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        // mFirstDayOfWeek = Utils.getFirstDayOfWeek(mContext);
128b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        // mShowWeekNumber = Utils.getShowWeekNumber(mContext);
129b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        notifyDataSetChanged();
130b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
131b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
132b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    @Override
133b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public int getCount() {
134b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        return WEEK_COUNT;
135b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
136b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
137b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    @Override
138b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public Object getItem(int position) {
139b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        return null;
140b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
141b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
142b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    @Override
143b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public long getItemId(int position) {
144b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        return position;
145b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    }
146b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
147b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    @SuppressWarnings("unchecked")
148b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    @Override
149b025734047dd8b630c34cea53b371361adb2a65aEric Christopher    public View getView(int position, View convertView, ViewGroup parent) {
150b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        MonthWeekSimpleView v;
151b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        LayoutParams params = new LayoutParams(
152b025734047dd8b630c34cea53b371361adb2a65aEric Christopher                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
153b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        HashMap<String, Integer> drawingParams = null;
154b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (convertView != null) {
155b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            v = (MonthWeekSimpleView) convertView;
156b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            // TODO Store drawing params in the view's Tag instead of having a
157b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            // new getter method
158b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            drawingParams = (HashMap<String, Integer>) v.getTag();
159b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        } else {
160b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            v = new MonthWeekSimpleView(mContext);
161b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
162b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (drawingParams == null) {
163b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            drawingParams = new HashMap<String, Integer>();
164b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
165b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        drawingParams.clear();
166b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
167b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        v.setLayoutParams(params);
168b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        v.setClickable(true);
169b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        v.setOnTouchListener(this);
170b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
171b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        int selectedDay = -1;
172b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        if (mSelectedWeek == position) {
173b025734047dd8b630c34cea53b371361adb2a65aEric Christopher            selectedDay = mSelectedDay.weekDay;
174b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        }
175b025734047dd8b630c34cea53b371361adb2a65aEric Christopher
176b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        drawingParams.put(MonthWeekSimpleView.VIEW_PARAMS_HEIGHT,
177b025734047dd8b630c34cea53b371361adb2a65aEric Christopher                (parent.getHeight() - WEEK_7_OVERHANG_HEIGHT) / mNumWeeks);
178b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        drawingParams.put(MonthWeekSimpleView.VIEW_PARAMS_SELECTED_DAY, selectedDay);
179b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        drawingParams.put(MonthWeekSimpleView.VIEW_PARAMS_SHOW_WK_NUM, mShowWeekNumber ? 1 : 0);
180b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        drawingParams.put(MonthWeekSimpleView.VIEW_PARAMS_WEEK_START, mFirstDayOfWeek);
181b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        drawingParams.put(MonthWeekSimpleView.VIEW_PARAMS_NUM_DAYS, mDaysPerWeek);
182b025734047dd8b630c34cea53b371361adb2a65aEric Christopher        drawingParams.put(MonthWeekSimpleView.VIEW_PARAMS_WEEK, position);
183        drawingParams.put(MonthWeekSimpleView.VIEW_PARAMS_FOCUS_MONTH, mFocusMonth);
184        v.setWeekParams(drawingParams, mSelectedDay.timezone);
185
186        return v;
187    }
188
189    public void updateFocusMonth(int month) {
190        mFocusMonth = month;
191        notifyDataSetChanged();
192    }
193
194    @Override
195    public boolean onTouch(View v, MotionEvent event) {
196        if (mGestureDetector.onTouchEvent(event)) {
197            MonthWeekSimpleView view = (MonthWeekSimpleView) v;
198            Time day = ((MonthWeekSimpleView)v).getDayFromLocation(event.getX());
199            if (Log.isLoggable(TAG, Log.DEBUG)) {
200                Log.d(TAG, "Touched day at Row=" + view.mWeek + " day=" + day.toString());
201            }
202            if (day != null) {
203                onDayTapped(day);
204            }
205            return true;
206        }
207        return false;
208    }
209
210    /**
211     * @param day The day that was tapped
212     */
213    protected void onDayTapped(Time day) {
214        day.hour = mSelectedDay.hour;
215        day.minute = mSelectedDay.minute;
216        day.second = mSelectedDay.second;
217        setSelectedDay(day);
218    }
219
220
221    // This is here so we can identify single tap events and set the selected
222    // day correctly
223    protected class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
224        @Override
225        public boolean onSingleTapUp(MotionEvent e) {
226            return true;
227        }
228    }
229}
230