diff options
Diffstat (limited to 'src/com/android/calendar/month/MonthWeekEventsView.java')
-rw-r--r-- | src/com/android/calendar/month/MonthWeekEventsView.java | 1110 |
1 files changed, 0 insertions, 1110 deletions
diff --git a/src/com/android/calendar/month/MonthWeekEventsView.java b/src/com/android/calendar/month/MonthWeekEventsView.java deleted file mode 100644 index e1c78c67..00000000 --- a/src/com/android/calendar/month/MonthWeekEventsView.java +++ /dev/null @@ -1,1110 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * 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.android.calendar.month; - -import com.android.calendar.Event; -import com.android.calendar.R; -import com.android.calendar.Utils; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.app.Service; -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Paint.Align; -import android.graphics.Paint.Style; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.provider.CalendarContract.Attendees; -import android.text.TextPaint; -import android.text.TextUtils; -import android.text.format.DateFormat; -import android.text.format.DateUtils; -import android.text.format.Time; -import android.util.Log; -import android.view.MotionEvent; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Formatter; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -public class MonthWeekEventsView extends SimpleWeekView { - - private static final String TAG = "MonthView"; - - private static final boolean DEBUG_LAYOUT = false; - - public static final String VIEW_PARAMS_ORIENTATION = "orientation"; - public static final String VIEW_PARAMS_ANIMATE_TODAY = "animate_today"; - - /* NOTE: these are not constants, and may be multiplied by a scale factor */ - private static int TEXT_SIZE_MONTH_NUMBER = 32; - private static int TEXT_SIZE_EVENT = 12; - private static int TEXT_SIZE_EVENT_TITLE = 14; - private static int TEXT_SIZE_MORE_EVENTS = 12; - private static int TEXT_SIZE_MONTH_NAME = 14; - private static int TEXT_SIZE_WEEK_NUM = 12; - - private static int DNA_MARGIN = 4; - private static int DNA_ALL_DAY_HEIGHT = 4; - private static int DNA_MIN_SEGMENT_HEIGHT = 4; - private static int DNA_WIDTH = 8; - private static int DNA_ALL_DAY_WIDTH = 32; - private static int DNA_SIDE_PADDING = 6; - private static int CONFLICT_COLOR = Color.BLACK; - private static int EVENT_TEXT_COLOR = Color.WHITE; - - private static int DEFAULT_EDGE_SPACING = 0; - private static int SIDE_PADDING_MONTH_NUMBER = 4; - private static int TOP_PADDING_MONTH_NUMBER = 4; - private static int TOP_PADDING_WEEK_NUMBER = 4; - private static int SIDE_PADDING_WEEK_NUMBER = 20; - private static int DAY_SEPARATOR_OUTER_WIDTH = 0; - private static int DAY_SEPARATOR_INNER_WIDTH = 1; - private static int DAY_SEPARATOR_VERTICAL_LENGTH = 53; - private static int DAY_SEPARATOR_VERTICAL_LENGHT_PORTRAIT = 64; - private static int MIN_WEEK_WIDTH = 50; - - private static int EVENT_X_OFFSET_LANDSCAPE = 38; - private static int EVENT_Y_OFFSET_LANDSCAPE = 8; - private static int EVENT_Y_OFFSET_PORTRAIT = 7; - private static int EVENT_SQUARE_WIDTH = 10; - private static int EVENT_SQUARE_BORDER = 2; - private static int EVENT_LINE_PADDING = 2; - private static int EVENT_RIGHT_PADDING = 4; - private static int EVENT_BOTTOM_PADDING = 3; - - private static int TODAY_HIGHLIGHT_WIDTH = 2; - - private static int SPACING_WEEK_NUMBER = 24; - private static boolean mInitialized = false; - private static boolean mShowDetailsInMonth; - - protected Time mToday = new Time(); - protected boolean mHasToday = false; - protected int mTodayIndex = -1; - protected int mOrientation = Configuration.ORIENTATION_LANDSCAPE; - protected List<ArrayList<Event>> mEvents = null; - protected ArrayList<Event> mUnsortedEvents = null; - HashMap<Integer, Utils.DNAStrand> mDna = null; - // This is for drawing the outlines around event chips and supports up to 10 - // events being drawn on each day. The code will expand this if necessary. - protected FloatRef mEventOutlines = new FloatRef(10 * 4 * 4 * 7); - - - - protected static StringBuilder mStringBuilder = new StringBuilder(50); - // TODO recreate formatter when locale changes - protected static Formatter mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); - - protected Paint mMonthNamePaint; - protected TextPaint mEventPaint; - protected TextPaint mSolidBackgroundEventPaint; - protected TextPaint mFramedEventPaint; - protected TextPaint mDeclinedEventPaint; - protected TextPaint mEventExtrasPaint; - protected TextPaint mEventDeclinedExtrasPaint; - protected Paint mWeekNumPaint; - protected Paint mDNAAllDayPaint; - protected Paint mDNATimePaint; - protected Paint mEventSquarePaint; - - - protected Drawable mTodayDrawable; - - protected int mMonthNumHeight; - protected int mMonthNumAscentHeight; - protected int mEventHeight; - protected int mEventAscentHeight; - protected int mExtrasHeight; - protected int mExtrasAscentHeight; - protected int mExtrasDescent; - protected int mWeekNumAscentHeight; - - protected int mMonthBGColor; - protected int mMonthBGOtherColor; - protected int mMonthBGTodayColor; - protected int mMonthNumColor; - protected int mMonthNumOtherColor; - protected int mMonthNumTodayColor; - protected int mMonthNameColor; - protected int mMonthNameOtherColor; - protected int mMonthEventColor; - protected int mMonthDeclinedEventColor; - protected int mMonthDeclinedExtrasColor; - protected int mMonthEventExtraColor; - protected int mMonthEventOtherColor; - protected int mMonthEventExtraOtherColor; - protected int mMonthWeekNumColor; - protected int mMonthBusyBitsBgColor; - protected int mMonthBusyBitsBusyTimeColor; - protected int mMonthBusyBitsConflictTimeColor; - private int mClickedDayIndex = -1; - private int mClickedDayColor; - private static final int mClickedAlpha = 128; - - protected int mEventChipOutlineColor = 0xFFFFFFFF; - protected int mDaySeparatorInnerColor; - protected int mTodayAnimateColor; - - private boolean mAnimateToday; - private int mAnimateTodayAlpha = 0; - private ObjectAnimator mTodayAnimator = null; - - private final TodayAnimatorListener mAnimatorListener = new TodayAnimatorListener(); - - class TodayAnimatorListener extends AnimatorListenerAdapter { - private volatile Animator mAnimator = null; - private volatile boolean mFadingIn = false; - - @Override - public void onAnimationEnd(Animator animation) { - synchronized (this) { - if (mAnimator != animation) { - animation.removeAllListeners(); - animation.cancel(); - return; - } - if (mFadingIn) { - if (mTodayAnimator != null) { - mTodayAnimator.removeAllListeners(); - mTodayAnimator.cancel(); - } - mTodayAnimator = ObjectAnimator.ofInt(MonthWeekEventsView.this, - "animateTodayAlpha", 255, 0); - mAnimator = mTodayAnimator; - mFadingIn = false; - mTodayAnimator.addListener(this); - mTodayAnimator.setDuration(600); - mTodayAnimator.start(); - } else { - mAnimateToday = false; - mAnimateTodayAlpha = 0; - mAnimator.removeAllListeners(); - mAnimator = null; - mTodayAnimator = null; - invalidate(); - } - } - } - - public void setAnimator(Animator animation) { - mAnimator = animation; - } - - public void setFadingIn(boolean fadingIn) { - mFadingIn = fadingIn; - } - - } - - private int[] mDayXs; - - /** - * This provides a reference to a float array which allows for easy size - * checking and reallocation. Used for drawing lines. - */ - private class FloatRef { - float[] array; - - public FloatRef(int size) { - array = new float[size]; - } - - public void ensureSize(int newSize) { - if (newSize >= array.length) { - // Add enough space for 7 more boxes to be drawn - array = Arrays.copyOf(array, newSize + 16 * 7); - } - } - } - - /** - * Shows up as an error if we don't include this. - */ - public MonthWeekEventsView(Context context) { - super(context); - } - - // Sets the list of events for this week. Takes a sorted list of arrays - // divided up by day for generating the large month version and the full - // arraylist sorted by start time to generate the dna version. - public void setEvents(List<ArrayList<Event>> sortedEvents, ArrayList<Event> unsortedEvents) { - setEvents(sortedEvents); - // The MIN_WEEK_WIDTH is a hack to prevent the view from trying to - // generate dna bits before its width has been fixed. - createDna(unsortedEvents); - } - - /** - * Sets up the dna bits for the view. This will return early if the view - * isn't in a state that will create a valid set of dna yet (such as the - * views width not being set correctly yet). - */ - public void createDna(ArrayList<Event> unsortedEvents) { - if (unsortedEvents == null || mWidth <= MIN_WEEK_WIDTH || getContext() == null) { - // Stash the list of events for use when this view is ready, or - // just clear it if a null set has been passed to this view - mUnsortedEvents = unsortedEvents; - mDna = null; - return; - } else { - // clear the cached set of events since we're ready to build it now - mUnsortedEvents = null; - } - // Create the drawing coordinates for dna - if (!mShowDetailsInMonth) { - int numDays = mEvents.size(); - int effectiveWidth = mWidth - mPadding * 2; - if (mShowWeekNum) { - effectiveWidth -= SPACING_WEEK_NUMBER; - } - DNA_ALL_DAY_WIDTH = effectiveWidth / numDays - 2 * DNA_SIDE_PADDING; - mDNAAllDayPaint.setStrokeWidth(DNA_ALL_DAY_WIDTH); - mDayXs = new int[numDays]; - for (int day = 0; day < numDays; day++) { - mDayXs[day] = computeDayLeftPosition(day) + DNA_WIDTH / 2 + DNA_SIDE_PADDING; - - } - - int top = DAY_SEPARATOR_INNER_WIDTH + DNA_MARGIN + DNA_ALL_DAY_HEIGHT + 1; - int bottom = mHeight - DNA_MARGIN; - mDna = Utils.createDNAStrands(mFirstJulianDay, unsortedEvents, top, bottom, - DNA_MIN_SEGMENT_HEIGHT, mDayXs, getContext()); - } - } - - public void setEvents(List<ArrayList<Event>> sortedEvents) { - mEvents = sortedEvents; - if (sortedEvents == null) { - return; - } - if (sortedEvents.size() != mNumDays) { - if (Log.isLoggable(TAG, Log.ERROR)) { - Log.wtf(TAG, "Events size must be same as days displayed: size=" - + sortedEvents.size() + " days=" + mNumDays); - } - mEvents = null; - return; - } - } - - protected void loadColors(Context context) { - Resources res = context.getResources(); - mMonthWeekNumColor = res.getColor(R.color.month_week_num_color); - mMonthNumColor = res.getColor(R.color.month_day_number); - mMonthNumOtherColor = res.getColor(R.color.month_day_number_other); - mMonthNumTodayColor = res.getColor(R.color.month_today_number); - mMonthNameColor = mMonthNumColor; - mMonthNameOtherColor = mMonthNumOtherColor; - mMonthEventColor = res.getColor(R.color.month_event_color); - mMonthDeclinedEventColor = res.getColor(R.color.agenda_item_declined_color); - mMonthDeclinedExtrasColor = res.getColor(R.color.agenda_item_where_declined_text_color); - mMonthEventExtraColor = res.getColor(R.color.month_event_extra_color); - mMonthEventOtherColor = res.getColor(R.color.month_event_other_color); - mMonthEventExtraOtherColor = res.getColor(R.color.month_event_extra_other_color); - mMonthBGTodayColor = res.getColor(R.color.month_today_bgcolor); - mMonthBGOtherColor = res.getColor(R.color.month_other_bgcolor); - mMonthBGColor = res.getColor(R.color.month_bgcolor); - mDaySeparatorInnerColor = res.getColor(R.color.month_grid_lines); - mTodayAnimateColor = res.getColor(R.color.today_highlight_color); - mClickedDayColor = res.getColor(R.color.day_clicked_background_color); - mTodayDrawable = res.getDrawable(R.drawable.today_blue_week_holo_light); - } - - /** - * Sets up the text and style properties for painting. Override this if you - * want to use a different paint. - */ - @Override - protected void initView() { - super.initView(); - - if (!mInitialized) { - Resources resources = getContext().getResources(); - mShowDetailsInMonth = Utils.getConfigBool(getContext(), R.bool.show_details_in_month); - TEXT_SIZE_EVENT_TITLE = resources.getInteger(R.integer.text_size_event_title); - TEXT_SIZE_MONTH_NUMBER = resources.getInteger(R.integer.text_size_month_number); - SIDE_PADDING_MONTH_NUMBER = resources.getInteger(R.integer.month_day_number_margin); - CONFLICT_COLOR = resources.getColor(R.color.month_dna_conflict_time_color); - EVENT_TEXT_COLOR = resources.getColor(R.color.calendar_event_text_color); - if (mScale != 1) { - TOP_PADDING_MONTH_NUMBER *= mScale; - TOP_PADDING_WEEK_NUMBER *= mScale; - SIDE_PADDING_MONTH_NUMBER *= mScale; - SIDE_PADDING_WEEK_NUMBER *= mScale; - SPACING_WEEK_NUMBER *= mScale; - TEXT_SIZE_MONTH_NUMBER *= mScale; - TEXT_SIZE_EVENT *= mScale; - TEXT_SIZE_EVENT_TITLE *= mScale; - TEXT_SIZE_MORE_EVENTS *= mScale; - TEXT_SIZE_MONTH_NAME *= mScale; - TEXT_SIZE_WEEK_NUM *= mScale; - DAY_SEPARATOR_OUTER_WIDTH *= mScale; - DAY_SEPARATOR_INNER_WIDTH *= mScale; - DAY_SEPARATOR_VERTICAL_LENGTH *= mScale; - DAY_SEPARATOR_VERTICAL_LENGHT_PORTRAIT *= mScale; - EVENT_X_OFFSET_LANDSCAPE *= mScale; - EVENT_Y_OFFSET_LANDSCAPE *= mScale; - EVENT_Y_OFFSET_PORTRAIT *= mScale; - EVENT_SQUARE_WIDTH *= mScale; - EVENT_SQUARE_BORDER *= mScale; - EVENT_LINE_PADDING *= mScale; - EVENT_BOTTOM_PADDING *= mScale; - EVENT_RIGHT_PADDING *= mScale; - DNA_MARGIN *= mScale; - DNA_WIDTH *= mScale; - DNA_ALL_DAY_HEIGHT *= mScale; - DNA_MIN_SEGMENT_HEIGHT *= mScale; - DNA_SIDE_PADDING *= mScale; - DEFAULT_EDGE_SPACING *= mScale; - DNA_ALL_DAY_WIDTH *= mScale; - TODAY_HIGHLIGHT_WIDTH *= mScale; - } - if (!mShowDetailsInMonth) { - TOP_PADDING_MONTH_NUMBER += DNA_ALL_DAY_HEIGHT + DNA_MARGIN; - } - mInitialized = true; - } - mPadding = DEFAULT_EDGE_SPACING; - loadColors(getContext()); - // TODO modify paint properties depending on isMini - - mMonthNumPaint = new Paint(); - mMonthNumPaint.setFakeBoldText(false); - mMonthNumPaint.setAntiAlias(true); - mMonthNumPaint.setTextSize(TEXT_SIZE_MONTH_NUMBER); - mMonthNumPaint.setColor(mMonthNumColor); - mMonthNumPaint.setStyle(Style.FILL); - mMonthNumPaint.setTextAlign(Align.RIGHT); - mMonthNumPaint.setTypeface(Typeface.DEFAULT); - - mMonthNumAscentHeight = (int) (-mMonthNumPaint.ascent() + 0.5f); - mMonthNumHeight = (int) (mMonthNumPaint.descent() - mMonthNumPaint.ascent() + 0.5f); - - mEventPaint = new TextPaint(); - mEventPaint.setFakeBoldText(true); - mEventPaint.setAntiAlias(true); - mEventPaint.setTextSize(TEXT_SIZE_EVENT_TITLE); - mEventPaint.setColor(mMonthEventColor); - - mSolidBackgroundEventPaint = new TextPaint(mEventPaint); - mSolidBackgroundEventPaint.setColor(EVENT_TEXT_COLOR); - mFramedEventPaint = new TextPaint(mSolidBackgroundEventPaint); - - mDeclinedEventPaint = new TextPaint(); - mDeclinedEventPaint.setFakeBoldText(true); - mDeclinedEventPaint.setAntiAlias(true); - mDeclinedEventPaint.setTextSize(TEXT_SIZE_EVENT_TITLE); - mDeclinedEventPaint.setColor(mMonthDeclinedEventColor); - - mEventAscentHeight = (int) (-mEventPaint.ascent() + 0.5f); - mEventHeight = (int) (mEventPaint.descent() - mEventPaint.ascent() + 0.5f); - - mEventExtrasPaint = new TextPaint(); - mEventExtrasPaint.setFakeBoldText(false); - mEventExtrasPaint.setAntiAlias(true); - mEventExtrasPaint.setStrokeWidth(EVENT_SQUARE_BORDER); - mEventExtrasPaint.setTextSize(TEXT_SIZE_EVENT); - mEventExtrasPaint.setColor(mMonthEventExtraColor); - mEventExtrasPaint.setStyle(Style.FILL); - mEventExtrasPaint.setTextAlign(Align.LEFT); - mExtrasHeight = (int)(mEventExtrasPaint.descent() - mEventExtrasPaint.ascent() + 0.5f); - mExtrasAscentHeight = (int)(-mEventExtrasPaint.ascent() + 0.5f); - mExtrasDescent = (int)(mEventExtrasPaint.descent() + 0.5f); - - mEventDeclinedExtrasPaint = new TextPaint(); - mEventDeclinedExtrasPaint.setFakeBoldText(false); - mEventDeclinedExtrasPaint.setAntiAlias(true); - mEventDeclinedExtrasPaint.setStrokeWidth(EVENT_SQUARE_BORDER); - mEventDeclinedExtrasPaint.setTextSize(TEXT_SIZE_EVENT); - mEventDeclinedExtrasPaint.setColor(mMonthDeclinedExtrasColor); - mEventDeclinedExtrasPaint.setStyle(Style.FILL); - mEventDeclinedExtrasPaint.setTextAlign(Align.LEFT); - - mWeekNumPaint = new Paint(); - mWeekNumPaint.setFakeBoldText(false); - mWeekNumPaint.setAntiAlias(true); - mWeekNumPaint.setTextSize(TEXT_SIZE_WEEK_NUM); - mWeekNumPaint.setColor(mWeekNumColor); - mWeekNumPaint.setStyle(Style.FILL); - mWeekNumPaint.setTextAlign(Align.RIGHT); - - mWeekNumAscentHeight = (int) (-mWeekNumPaint.ascent() + 0.5f); - - mDNAAllDayPaint = new Paint(); - mDNATimePaint = new Paint(); - mDNATimePaint.setColor(mMonthBusyBitsBusyTimeColor); - mDNATimePaint.setStyle(Style.FILL_AND_STROKE); - mDNATimePaint.setStrokeWidth(DNA_WIDTH); - mDNATimePaint.setAntiAlias(false); - mDNAAllDayPaint.setColor(mMonthBusyBitsConflictTimeColor); - mDNAAllDayPaint.setStyle(Style.FILL_AND_STROKE); - mDNAAllDayPaint.setStrokeWidth(DNA_ALL_DAY_WIDTH); - mDNAAllDayPaint.setAntiAlias(false); - - mEventSquarePaint = new Paint(); - mEventSquarePaint.setStrokeWidth(EVENT_SQUARE_BORDER); - mEventSquarePaint.setAntiAlias(false); - - if (DEBUG_LAYOUT) { - Log.d("EXTRA", "mScale=" + mScale); - Log.d("EXTRA", "mMonthNumPaint ascent=" + mMonthNumPaint.ascent() - + " descent=" + mMonthNumPaint.descent() + " int height=" + mMonthNumHeight); - Log.d("EXTRA", "mEventPaint ascent=" + mEventPaint.ascent() - + " descent=" + mEventPaint.descent() + " int height=" + mEventHeight - + " int ascent=" + mEventAscentHeight); - Log.d("EXTRA", "mEventExtrasPaint ascent=" + mEventExtrasPaint.ascent() - + " descent=" + mEventExtrasPaint.descent() + " int height=" + mExtrasHeight); - Log.d("EXTRA", "mWeekNumPaint ascent=" + mWeekNumPaint.ascent() - + " descent=" + mWeekNumPaint.descent()); - } - } - - @Override - public void setWeekParams(HashMap<String, Integer> params, String tz) { - super.setWeekParams(params, tz); - - if (params.containsKey(VIEW_PARAMS_ORIENTATION)) { - mOrientation = params.get(VIEW_PARAMS_ORIENTATION); - } - - updateToday(tz); - mNumCells = mNumDays + 1; - - if (params.containsKey(VIEW_PARAMS_ANIMATE_TODAY) && mHasToday) { - synchronized (mAnimatorListener) { - if (mTodayAnimator != null) { - mTodayAnimator.removeAllListeners(); - mTodayAnimator.cancel(); - } - mTodayAnimator = ObjectAnimator.ofInt(this, "animateTodayAlpha", - Math.max(mAnimateTodayAlpha, 80), 255); - mTodayAnimator.setDuration(150); - mAnimatorListener.setAnimator(mTodayAnimator); - mAnimatorListener.setFadingIn(true); - mTodayAnimator.addListener(mAnimatorListener); - mAnimateToday = true; - mTodayAnimator.start(); - } - } - } - - /** - * @param tz - */ - public boolean updateToday(String tz) { - mToday.timezone = tz; - mToday.setToNow(); - mToday.normalize(true); - int julianToday = Time.getJulianDay(mToday.toMillis(false), mToday.gmtoff); - if (julianToday >= mFirstJulianDay && julianToday < mFirstJulianDay + mNumDays) { - mHasToday = true; - mTodayIndex = julianToday - mFirstJulianDay; - } else { - mHasToday = false; - mTodayIndex = -1; - } - return mHasToday; - } - - public void setAnimateTodayAlpha(int alpha) { - mAnimateTodayAlpha = alpha; - invalidate(); - } - - @Override - protected void onDraw(Canvas canvas) { - drawBackground(canvas); - drawWeekNums(canvas); - drawDaySeparators(canvas); - if (mHasToday && mAnimateToday) { - drawToday(canvas); - } - if (mShowDetailsInMonth) { - drawEvents(canvas); - } else { - if (mDna == null && mUnsortedEvents != null) { - createDna(mUnsortedEvents); - } - drawDNA(canvas); - } - drawClick(canvas); - } - - protected void drawToday(Canvas canvas) { - r.top = DAY_SEPARATOR_INNER_WIDTH + (TODAY_HIGHLIGHT_WIDTH / 2); - r.bottom = mHeight - (int) Math.ceil(TODAY_HIGHLIGHT_WIDTH / 2.0f); - p.setStyle(Style.STROKE); - p.setStrokeWidth(TODAY_HIGHLIGHT_WIDTH); - r.left = computeDayLeftPosition(mTodayIndex) + (TODAY_HIGHLIGHT_WIDTH / 2); - r.right = computeDayLeftPosition(mTodayIndex + 1) - - (int) Math.ceil(TODAY_HIGHLIGHT_WIDTH / 2.0f); - p.setColor(mTodayAnimateColor | (mAnimateTodayAlpha << 24)); - canvas.drawRect(r, p); - p.setStyle(Style.FILL); - } - - // TODO move into SimpleWeekView - // Computes the x position for the left side of the given day - private int computeDayLeftPosition(int day) { - int effectiveWidth = mWidth; - int x = 0; - int xOffset = 0; - if (mShowWeekNum) { - xOffset = SPACING_WEEK_NUMBER + mPadding; - effectiveWidth -= xOffset; - } - x = day * effectiveWidth / mNumDays + xOffset; - return x; - } - - @Override - protected void drawDaySeparators(Canvas canvas) { - float lines[] = new float[8 * 4]; - int count = 6 * 4; - int wkNumOffset = 0; - int i = 0; - if (mShowWeekNum) { - // This adds the first line separating the week number - int xOffset = SPACING_WEEK_NUMBER + mPadding; - count += 4; - lines[i++] = xOffset; - lines[i++] = 0; - lines[i++] = xOffset; - lines[i++] = mHeight; - wkNumOffset++; - } - count += 4; - lines[i++] = 0; - lines[i++] = 0; - lines[i++] = mWidth; - lines[i++] = 0; - int y0 = 0; - int y1 = mHeight; - - while (i < count) { - int x = computeDayLeftPosition(i / 4 - wkNumOffset); - lines[i++] = x; - lines[i++] = y0; - lines[i++] = x; - lines[i++] = y1; - } - p.setColor(mDaySeparatorInnerColor); - p.setStrokeWidth(DAY_SEPARATOR_INNER_WIDTH); - canvas.drawLines(lines, 0, count, p); - } - - @Override - protected void drawBackground(Canvas canvas) { - int i = 0; - int offset = 0; - r.top = DAY_SEPARATOR_INNER_WIDTH; - r.bottom = mHeight; - if (mShowWeekNum) { - i++; - offset++; - } - if (!mOddMonth[i]) { - while (++i < mOddMonth.length && !mOddMonth[i]) - ; - r.right = computeDayLeftPosition(i - offset); - r.left = 0; - p.setColor(mMonthBGOtherColor); - canvas.drawRect(r, p); - // compute left edge for i, set up r, draw - } else if (!mOddMonth[(i = mOddMonth.length - 1)]) { - while (--i >= offset && !mOddMonth[i]) - ; - i++; - // compute left edge for i, set up r, draw - r.right = mWidth; - r.left = computeDayLeftPosition(i - offset); - p.setColor(mMonthBGOtherColor); - canvas.drawRect(r, p); - } - if (mHasToday) { - p.setColor(mMonthBGTodayColor); - r.left = computeDayLeftPosition(mTodayIndex); - r.right = computeDayLeftPosition(mTodayIndex + 1); - canvas.drawRect(r, p); - } - } - - // Draw the "clicked" color on the tapped day - private void drawClick(Canvas canvas) { - if (mClickedDayIndex != -1) { - int alpha = p.getAlpha(); - p.setColor(mClickedDayColor); - p.setAlpha(mClickedAlpha); - r.left = computeDayLeftPosition(mClickedDayIndex); - r.right = computeDayLeftPosition(mClickedDayIndex + 1); - r.top = DAY_SEPARATOR_INNER_WIDTH; - r.bottom = mHeight; - canvas.drawRect(r, p); - p.setAlpha(alpha); - } - } - - @Override - protected void drawWeekNums(Canvas canvas) { - int y; - - int i = 0; - int offset = -1; - int todayIndex = mTodayIndex; - int x = 0; - int numCount = mNumDays; - if (mShowWeekNum) { - x = SIDE_PADDING_WEEK_NUMBER + mPadding; - y = mWeekNumAscentHeight + TOP_PADDING_WEEK_NUMBER; - canvas.drawText(mDayNumbers[0], x, y, mWeekNumPaint); - numCount++; - i++; - todayIndex++; - offset++; - - } - - y = mMonthNumAscentHeight + TOP_PADDING_MONTH_NUMBER; - - boolean isFocusMonth = mFocusDay[i]; - boolean isBold = false; - mMonthNumPaint.setColor(isFocusMonth ? mMonthNumColor : mMonthNumOtherColor); - for (; i < numCount; i++) { - if (mHasToday && todayIndex == i) { - mMonthNumPaint.setColor(mMonthNumTodayColor); - mMonthNumPaint.setFakeBoldText(isBold = true); - if (i + 1 < numCount) { - // Make sure the color will be set back on the next - // iteration - isFocusMonth = !mFocusDay[i + 1]; - } - } else if (mFocusDay[i] != isFocusMonth) { - isFocusMonth = mFocusDay[i]; - mMonthNumPaint.setColor(isFocusMonth ? mMonthNumColor : mMonthNumOtherColor); - } - x = computeDayLeftPosition(i - offset) - (SIDE_PADDING_MONTH_NUMBER); - canvas.drawText(mDayNumbers[i], x, y, mMonthNumPaint); - if (isBold) { - mMonthNumPaint.setFakeBoldText(isBold = false); - } - } - } - - protected void drawEvents(Canvas canvas) { - if (mEvents == null) { - return; - } - - int day = -1; - for (ArrayList<Event> eventDay : mEvents) { - day++; - if (eventDay == null || eventDay.size() == 0) { - continue; - } - int ySquare; - int xSquare = computeDayLeftPosition(day) + SIDE_PADDING_MONTH_NUMBER + 1; - int rightEdge = computeDayLeftPosition(day + 1); - - if (mOrientation == Configuration.ORIENTATION_PORTRAIT) { - ySquare = EVENT_Y_OFFSET_PORTRAIT + mMonthNumHeight + TOP_PADDING_MONTH_NUMBER; - rightEdge -= SIDE_PADDING_MONTH_NUMBER + 1; - } else { - ySquare = EVENT_Y_OFFSET_LANDSCAPE; - rightEdge -= EVENT_X_OFFSET_LANDSCAPE; - } - - // Determine if everything will fit when time ranges are shown. - boolean showTimes = true; - Iterator<Event> iter = eventDay.iterator(); - int yTest = ySquare; - while (iter.hasNext()) { - Event event = iter.next(); - int newY = drawEvent(canvas, event, xSquare, yTest, rightEdge, iter.hasNext(), - showTimes, /*doDraw*/ false); - if (newY == yTest) { - showTimes = false; - break; - } - yTest = newY; - } - - int eventCount = 0; - iter = eventDay.iterator(); - while (iter.hasNext()) { - Event event = iter.next(); - int newY = drawEvent(canvas, event, xSquare, ySquare, rightEdge, iter.hasNext(), - showTimes, /*doDraw*/ true); - if (newY == ySquare) { - break; - } - eventCount++; - ySquare = newY; - } - - int remaining = eventDay.size() - eventCount; - if (remaining > 0) { - drawMoreEvents(canvas, remaining, xSquare); - } - } - } - - protected int addChipOutline(FloatRef lines, int count, int x, int y) { - lines.ensureSize(count + 16); - // top of box - lines.array[count++] = x; - lines.array[count++] = y; - lines.array[count++] = x + EVENT_SQUARE_WIDTH; - lines.array[count++] = y; - // right side of box - lines.array[count++] = x + EVENT_SQUARE_WIDTH; - lines.array[count++] = y; - lines.array[count++] = x + EVENT_SQUARE_WIDTH; - lines.array[count++] = y + EVENT_SQUARE_WIDTH; - // left side of box - lines.array[count++] = x; - lines.array[count++] = y; - lines.array[count++] = x; - lines.array[count++] = y + EVENT_SQUARE_WIDTH + 1; - // bottom of box - lines.array[count++] = x; - lines.array[count++] = y + EVENT_SQUARE_WIDTH; - lines.array[count++] = x + EVENT_SQUARE_WIDTH + 1; - lines.array[count++] = y + EVENT_SQUARE_WIDTH; - - return count; - } - - /** - * Attempts to draw the given event. Returns the y for the next event or the - * original y if the event will not fit. An event is considered to not fit - * if the event and its extras won't fit or if there are more events and the - * more events line would not fit after drawing this event. - * - * @param canvas the canvas to draw on - * @param event the event to draw - * @param x the top left corner for this event's color chip - * @param y the top left corner for this event's color chip - * @param rightEdge the rightmost point we're allowed to draw on (exclusive) - * @param moreEvents indicates whether additional events will follow this one - * @param showTimes if set, a second line with a time range will be displayed for non-all-day - * events - * @param doDraw if set, do the actual drawing; otherwise this just computes the height - * and returns - * @return the y for the next event or the original y if it won't fit - */ - protected int drawEvent(Canvas canvas, Event event, int x, int y, int rightEdge, - boolean moreEvents, boolean showTimes, boolean doDraw) { - /* - * Vertical layout: - * (top of box) - * a. EVENT_Y_OFFSET_LANDSCAPE or portrait equivalent - * b. Event title: mEventHeight for a normal event, + 2xBORDER_SPACE for all-day event - * c. [optional] Time range (mExtrasHeight) - * d. EVENT_LINE_PADDING - * - * Repeat (b,c,d) as needed and space allows. If we have more events than fit, we need - * to leave room for something like "+2" at the bottom: - * - * e. "+ more" line (mExtrasHeight) - * - * f. EVENT_BOTTOM_PADDING (overlaps EVENT_LINE_PADDING) - * (bottom of box) - */ - final int BORDER_SPACE = EVENT_SQUARE_BORDER + 1; // want a 1-pixel gap inside border - final int STROKE_WIDTH_ADJ = EVENT_SQUARE_BORDER / 2; // adjust bounds for stroke width - boolean allDay = event.allDay; - int eventRequiredSpace = mEventHeight; - if (allDay) { - // Add a few pixels for the box we draw around all-day events. - eventRequiredSpace += BORDER_SPACE * 2; - } else if (showTimes) { - // Need room for the "1pm - 2pm" line. - eventRequiredSpace += mExtrasHeight; - } - int reservedSpace = EVENT_BOTTOM_PADDING; // leave a bit of room at the bottom - if (moreEvents) { - // More events follow. Leave a bit of space between events. - eventRequiredSpace += EVENT_LINE_PADDING; - - // Make sure we have room for the "+ more" line. (The "+ more" line is expected - // to be <= the height of an event line, so we won't show "+1" when we could be - // showing the event.) - reservedSpace += mExtrasHeight; - } - - if (y + eventRequiredSpace + reservedSpace > mHeight) { - // Not enough space, return original y - return y; - } else if (!doDraw) { - return y + eventRequiredSpace; - } - - boolean isDeclined = event.selfAttendeeStatus == Attendees.ATTENDEE_STATUS_DECLINED; - int color = event.color; - if (isDeclined) { - color = Utils.getDeclinedColorFromColor(color); - } - - int textX, textY, textRightEdge; - - if (allDay) { - // We shift the render offset "inward", because drawRect with a stroke width greater - // than 1 draws outside the specified bounds. (We don't adjust the left edge, since - // we want to match the existing appearance of the "event square".) - r.left = x; - r.right = rightEdge - STROKE_WIDTH_ADJ; - r.top = y + STROKE_WIDTH_ADJ; - r.bottom = y + mEventHeight + BORDER_SPACE * 2 - STROKE_WIDTH_ADJ; - textX = x + BORDER_SPACE; - textY = y + mEventAscentHeight + BORDER_SPACE; - textRightEdge = rightEdge - BORDER_SPACE; - } else { - r.left = x; - r.right = x + EVENT_SQUARE_WIDTH; - r.bottom = y + mEventAscentHeight; - r.top = r.bottom - EVENT_SQUARE_WIDTH; - textX = x + EVENT_SQUARE_WIDTH + EVENT_RIGHT_PADDING; - textY = y + mEventAscentHeight; - textRightEdge = rightEdge; - } - - Style boxStyle = Style.STROKE; - boolean solidBackground = false; - if (event.selfAttendeeStatus != Attendees.ATTENDEE_STATUS_INVITED) { - boxStyle = Style.FILL_AND_STROKE; - if (allDay) { - solidBackground = true; - } - } - mEventSquarePaint.setStyle(boxStyle); - mEventSquarePaint.setColor(color); - canvas.drawRect(r, mEventSquarePaint); - - float avail = textRightEdge - textX; - CharSequence text = TextUtils.ellipsize( - event.title, mEventPaint, avail, TextUtils.TruncateAt.END); - Paint textPaint; - if (solidBackground) { - // Text color needs to contrast with solid background. - textPaint = mSolidBackgroundEventPaint; - } else if (isDeclined) { - // Use "declined event" color. - textPaint = mDeclinedEventPaint; - } else if (allDay) { - // Text inside frame is same color as frame. - mFramedEventPaint.setColor(color); - textPaint = mFramedEventPaint; - } else { - // Use generic event text color. - textPaint = mEventPaint; - } - canvas.drawText(text.toString(), textX, textY, textPaint); - y += mEventHeight; - if (allDay) { - y += BORDER_SPACE * 2; - } - - if (showTimes && !allDay) { - // show start/end time, e.g. "1pm - 2pm" - textY = y + mExtrasAscentHeight; - mStringBuilder.setLength(0); - text = DateUtils.formatDateRange(getContext(), mFormatter, event.startMillis, - event.endMillis, DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, - Utils.getTimeZone(getContext(), null)).toString(); - text = TextUtils.ellipsize(text, mEventExtrasPaint, avail, TextUtils.TruncateAt.END); - canvas.drawText(text.toString(), textX, textY, isDeclined ? mEventDeclinedExtrasPaint - : mEventExtrasPaint); - y += mExtrasHeight; - } - - y += EVENT_LINE_PADDING; - - return y; - } - - protected void drawMoreEvents(Canvas canvas, int remainingEvents, int x) { - int y = mHeight - (mExtrasDescent + EVENT_BOTTOM_PADDING); - String text = getContext().getResources().getQuantityString( - R.plurals.month_more_events, remainingEvents); - mEventExtrasPaint.setAntiAlias(true); - mEventExtrasPaint.setFakeBoldText(true); - canvas.drawText(String.format(text, remainingEvents), x, y, mEventExtrasPaint); - mEventExtrasPaint.setFakeBoldText(false); - } - - /** - * Draws a line showing busy times in each day of week The method draws - * non-conflicting times in the event color and times with conflicting - * events in the dna conflict color defined in colors. - * - * @param canvas - */ - protected void drawDNA(Canvas canvas) { - // Draw event and conflict times - if (mDna != null) { - for (Utils.DNAStrand strand : mDna.values()) { - if (strand.color == CONFLICT_COLOR || strand.points == null - || strand.points.length == 0) { - continue; - } - mDNATimePaint.setColor(strand.color); - canvas.drawLines(strand.points, mDNATimePaint); - } - // Draw black last to make sure it's on top - Utils.DNAStrand strand = mDna.get(CONFLICT_COLOR); - if (strand != null && strand.points != null && strand.points.length != 0) { - mDNATimePaint.setColor(strand.color); - canvas.drawLines(strand.points, mDNATimePaint); - } - if (mDayXs == null) { - return; - } - int numDays = mDayXs.length; - int xOffset = (DNA_ALL_DAY_WIDTH - DNA_WIDTH) / 2; - if (strand != null && strand.allDays != null && strand.allDays.length == numDays) { - for (int i = 0; i < numDays; i++) { - // this adds at most 7 draws. We could sort it by color and - // build an array instead but this is easier. - if (strand.allDays[i] != 0) { - mDNAAllDayPaint.setColor(strand.allDays[i]); - canvas.drawLine(mDayXs[i] + xOffset, DNA_MARGIN, mDayXs[i] + xOffset, - DNA_MARGIN + DNA_ALL_DAY_HEIGHT, mDNAAllDayPaint); - } - } - } - } - } - - @Override - protected void updateSelectionPositions() { - if (mHasSelectedDay) { - int selectedPosition = mSelectedDay - mWeekStart; - if (selectedPosition < 0) { - selectedPosition += 7; - } - int effectiveWidth = mWidth - mPadding * 2; - effectiveWidth -= SPACING_WEEK_NUMBER; - mSelectedLeft = selectedPosition * effectiveWidth / mNumDays + mPadding; - mSelectedRight = (selectedPosition + 1) * effectiveWidth / mNumDays + mPadding; - mSelectedLeft += SPACING_WEEK_NUMBER; - mSelectedRight += SPACING_WEEK_NUMBER; - } - } - - public int getDayIndexFromLocation(float x) { - int dayStart = mShowWeekNum ? SPACING_WEEK_NUMBER + mPadding : mPadding; - if (x < dayStart || x > mWidth - mPadding) { - return -1; - } - // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels - return ((int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding))); - } - - @Override - public Time getDayFromLocation(float x) { - int dayPosition = getDayIndexFromLocation(x); - if (dayPosition == -1) { - return null; - } - int day = mFirstJulianDay + dayPosition; - - Time time = new Time(mTimeZone); - if (mWeek == 0) { - // This week is weird... - if (day < Time.EPOCH_JULIAN_DAY) { - day++; - } else if (day == Time.EPOCH_JULIAN_DAY) { - time.set(1, 0, 1970); - time.normalize(true); - return time; - } - } - - time.setJulianDay(day); - return time; - } - - @Override - public boolean onHoverEvent(MotionEvent event) { - Context context = getContext(); - // only send accessibility events if accessibility and exploration are - // on. - AccessibilityManager am = (AccessibilityManager) context - .getSystemService(Service.ACCESSIBILITY_SERVICE); - if (!am.isEnabled() || !am.isTouchExplorationEnabled()) { - return super.onHoverEvent(event); - } - if (event.getAction() != MotionEvent.ACTION_HOVER_EXIT) { - Time hover = getDayFromLocation(event.getX()); - if (hover != null - && (mLastHoverTime == null || Time.compare(hover, mLastHoverTime) != 0)) { - Long millis = hover.toMillis(true); - String date = Utils.formatDateRange(context, millis, millis, - DateUtils.FORMAT_SHOW_DATE); - AccessibilityEvent accessEvent = AccessibilityEvent - .obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); - accessEvent.getText().add(date); - if (mShowDetailsInMonth && mEvents != null) { - int dayStart = SPACING_WEEK_NUMBER + mPadding; - int dayPosition = (int) ((event.getX() - dayStart) * mNumDays / (mWidth - - dayStart - mPadding)); - ArrayList<Event> events = mEvents.get(dayPosition); - List<CharSequence> text = accessEvent.getText(); - for (Event e : events) { - text.add(e.getTitleAndLocation() + ". "); - int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR; - if (!e.allDay) { - flags |= DateUtils.FORMAT_SHOW_TIME; - if (DateFormat.is24HourFormat(context)) { - flags |= DateUtils.FORMAT_24HOUR; - } - } else { - flags |= DateUtils.FORMAT_UTC; - } - text.add(Utils.formatDateRange(context, e.startMillis, e.endMillis, - flags) + ". "); - } - } - sendAccessibilityEventUnchecked(accessEvent); - mLastHoverTime = hover; - } - } - return true; - } - - public void setClickedDay(float xLocation) { - mClickedDayIndex = getDayIndexFromLocation(xLocation); - invalidate(); - } - public void clearClickedDay() { - mClickedDayIndex = -1; - invalidate(); - } -} |