/* * Copyright (C) 2011 Chris Gao <chris@exina.net> * * 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. */ package com.emobc.android.views; import java.util.Calendar; import java.util.Map; import java.util.TreeSet; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.MonthDisplayHelper; import android.view.MotionEvent; import android.widget.ImageView; import com.emobc.android.activities.R; import com.emobc.android.levels.impl.EventDataItem; public class CalendarView extends ImageView { private static int WEEK_TOP_MARGIN = 74; private static int WEEK_LEFT_MARGIN = 40; private static int CELL_WIDTH = 58; private static int CELL_HEIGH = 53; private static int CELL_MARGIN_TOP = 92; private static int CELL_MARGIN_LEFT = 39; private static float CELL_TEXT_SIZE; private Calendar mRightNow = null; //private Drawable mWeekTitle = null; private Cell mToday = null; private Cell[][] mCells = new Cell[6][7]; private OnCellTouchListener mOnCellTouchListener = null; MonthDisplayHelper mHelper; Drawable mDecoration = null; //Collection of events private Map<String,TreeSet<EventDataItem>> events; public Map<String, TreeSet<EventDataItem>> getEvents() { return events; } public interface OnCellTouchListener { public void onTouch(Cell cell); } public CalendarView(Context context) { this(context, null); } public CalendarView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CalendarView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mDecoration = context.getResources().getDrawable(R.drawable.typeb_calendar_today); initCalendarView(); } private void initCalendarView() { mRightNow = Calendar.getInstance(); // prepare static vars Resources res = getResources(); WEEK_TOP_MARGIN = (int) res.getDimension(R.dimen.week_top_margin); WEEK_LEFT_MARGIN = (int) res.getDimension(R.dimen.week_left_margin); CELL_WIDTH = (int) res.getDimension(R.dimen.cell_width); CELL_HEIGH = (int) res.getDimension(R.dimen.cell_heigh); CELL_MARGIN_TOP = (int) res.getDimension(R.dimen.cell_margin_top); CELL_MARGIN_LEFT = (int) res.getDimension(R.dimen.cell_margin_left); CELL_TEXT_SIZE = res.getDimension(R.dimen.cell_text_size); // set background setImageResource(R.drawable.background); // mWeekTitle = res.getDrawable(R.drawable.calendar_week_es); mHelper = new MonthDisplayHelper(mRightNow.get(Calendar.YEAR), mRightNow.get(Calendar.MONTH), Calendar.MONDAY); } private void initCells() { class _calendar { public int day; public boolean thisMonth; public _calendar(int d, boolean b) { day = d; thisMonth = b; } public _calendar(int d) { this(d, false); } }; _calendar tmp[][] = new _calendar[6][7]; for(int i=0; i<tmp.length; i++) { int n[] = mHelper.getDigitsForRow(i); for(int d=0; d<n.length; d++) { if(mHelper.isWithinCurrentMonth(i,d)) tmp[i][d] = new _calendar(n[d], true); else tmp[i][d] = new _calendar(n[d]); } } Calendar today = Calendar.getInstance(); int thisDay = 0; mToday = null; if(mHelper.getYear()==today.get(Calendar.YEAR) && mHelper.getMonth()==today.get(Calendar.MONTH)) { thisDay = today.get(Calendar.DAY_OF_MONTH); } // build cells Rect Bound = new Rect(CELL_MARGIN_LEFT, CELL_MARGIN_TOP, CELL_WIDTH+CELL_MARGIN_LEFT, CELL_HEIGH+CELL_MARGIN_TOP); for(int week=0; week<mCells.length; week++) { for(int day=0; day<mCells[week].length; day++) { if(tmp[week][day].thisMonth) { if(day==5 || day==6 ) mCells[week][day] = new RedCell(tmp[week][day].day, new Rect(Bound), CELL_TEXT_SIZE); else mCells[week][day] = new Cell(tmp[week][day].day, new Rect(Bound), CELL_TEXT_SIZE); } else { mCells[week][day] = new GrayCell(tmp[week][day].day, new Rect(Bound), CELL_TEXT_SIZE); } // paint days with events // Searching events with this day if (events!=null){ String dateKey; int dayNumber = tmp[week][day].day; if (dayNumber<10){ dateKey = "0"+dayNumber; }else{ dateKey = ""+dayNumber; } int monthNumber = mHelper.getMonth()+1; if (monthNumber <10){ dateKey = dateKey+"/0"+monthNumber ; }else{ dateKey = dateKey+"/"+monthNumber; } int yearNumber = mHelper.getYear(); dateKey = dateKey+"/"+yearNumber; if(events.get(dateKey)!=null) { if (tmp[week][day].thisMonth) mCells[week][day] = new EventCell(tmp[week][day].day, new Rect(Bound), CELL_TEXT_SIZE); } } Bound.offset(CELL_WIDTH, 0); // move to next column // get today if(tmp[week][day].day==thisDay && tmp[week][day].thisMonth) { mToday = mCells[week][day]; mDecoration.setBounds(mToday.getBound()); } } Bound.offset(0, CELL_HEIGH); // move to next row and first column Bound.left = CELL_MARGIN_LEFT; Bound.right = CELL_MARGIN_LEFT+CELL_WIDTH; } } @Override public void onLayout(boolean changed, int left, int top, int right, int bottom) { Rect re = getDrawable().getBounds(); WEEK_LEFT_MARGIN = CELL_MARGIN_LEFT = (right-left - re.width()) / 2; // mWeekTitle.setBounds(WEEK_LEFT_MARGIN, WEEK_TOP_MARGIN, WEEK_LEFT_MARGIN+mWeekTitle.getMinimumWidth(), WEEK_TOP_MARGIN+mWeekTitle.getMinimumHeight()); initCells(); super.onLayout(changed, left, top, right, bottom); } public void setTimeInMillis(long milliseconds) { mRightNow.setTimeInMillis(milliseconds); initCells(); this.invalidate(); } public int getYear() { return mHelper.getYear(); } public int getMonth() { return mHelper.getMonth(); } public void nextMonth() { mHelper.nextMonth(); initCells(); invalidate(); } public void previousMonth() { mHelper.previousMonth(); initCells(); invalidate(); } public boolean firstDay(int day) { return day==1; } public boolean lastDay(int day) { return mHelper.getNumberOfDaysInMonth()==day; } public void goToday() { Calendar cal = Calendar.getInstance(); mHelper = new MonthDisplayHelper(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)); initCells(); invalidate(); } public Calendar getDate() { return mRightNow; } @Override public boolean onTouchEvent(MotionEvent event) { if(mOnCellTouchListener!=null){ for(Cell[] week : mCells) { for(Cell day : week) { if(day.hitTest((int)event.getX(), (int)event.getY())) { mOnCellTouchListener.onTouch(day); } } } } return super.onTouchEvent(event); } public void setOnCellTouchListener(OnCellTouchListener p) { mOnCellTouchListener = p; } @Override protected void onDraw(Canvas canvas) { // draw background super.onDraw(canvas); //mWeekTitle.draw(canvas); // draw cells for(Cell[] week : mCells) { for(Cell day : week) { day.draw(canvas); } } // draw today if(mDecoration!=null && mToday!=null) { mDecoration.draw(canvas); } } public class GrayCell extends Cell { public GrayCell(int dayOfMon, Rect rect, float s) { super(dayOfMon, rect, s); mPaint.setColor(Color.LTGRAY); } } private class RedCell extends Cell { public RedCell(int dayOfMon, Rect rect, float s) { super(dayOfMon, rect, s); mPaint.setColor(0xdddd0000); } } private class EventCell extends Cell{ public EventCell(int dayOfMon, Rect rect, float s) { super(dayOfMon, rect, s); mPaint.setColor(Color.BLUE); } } public class PushCell extends Cell{ public PushCell(int dayOfMon, Rect rect, float s) { super(dayOfMon, rect, s); mPaint.setColor(Color.GREEN); } } /** * Paint a collections of events in the calendar * @param events Map with key that is a String of date with format like dd/mm/yy */ public void setEvents(Map<String,TreeSet<EventDataItem>> events){ this.events = events; initCells(); } }