182b318634af1b6594e60cfd1f2df4d3845f80587Erik/* 282b318634af1b6594e60cfd1f2df4d3845f80587Erik * Copyright (C) 2010 The Android Open Source Project 382b318634af1b6594e60cfd1f2df4d3845f80587Erik * 482b318634af1b6594e60cfd1f2df4d3845f80587Erik * Licensed under the Apache License, Version 2.0 (the "License"); 582b318634af1b6594e60cfd1f2df4d3845f80587Erik * you may not use this file except in compliance with the License. 682b318634af1b6594e60cfd1f2df4d3845f80587Erik * You may obtain a copy of the License at 782b318634af1b6594e60cfd1f2df4d3845f80587Erik * 882b318634af1b6594e60cfd1f2df4d3845f80587Erik * http://www.apache.org/licenses/LICENSE-2.0 982b318634af1b6594e60cfd1f2df4d3845f80587Erik * 1082b318634af1b6594e60cfd1f2df4d3845f80587Erik * Unless required by applicable law or agreed to in writing, software 1182b318634af1b6594e60cfd1f2df4d3845f80587Erik * distributed under the License is distributed on an "AS IS" BASIS, 1282b318634af1b6594e60cfd1f2df4d3845f80587Erik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382b318634af1b6594e60cfd1f2df4d3845f80587Erik * See the License for the specific language governing permissions and 1482b318634af1b6594e60cfd1f2df4d3845f80587Erik * limitations under the License. 1582b318634af1b6594e60cfd1f2df4d3845f80587Erik */ 1682b318634af1b6594e60cfd1f2df4d3845f80587Erik 1782b318634af1b6594e60cfd1f2df4d3845f80587Erikpackage com.android.calendar.month; 1882b318634af1b6594e60cfd1f2df4d3845f80587Erik 193553621c824afe1f3eacbe8555678005ca1264a1Erikimport com.android.calendar.Event; 203553621c824afe1f3eacbe8555678005ca1264a1Erikimport com.android.calendar.R; 2140bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport com.android.calendar.Utils; 22f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik 235b872523e28fc778a3fc34e7e9096ca1197c6509RoboErikimport android.animation.Animator; 245b872523e28fc778a3fc34e7e9096ca1197c6509RoboErikimport android.animation.AnimatorListenerAdapter; 255b872523e28fc778a3fc34e7e9096ca1197c6509RoboErikimport android.animation.ObjectAnimator; 26f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErikimport android.app.Service; 2782b318634af1b6594e60cfd1f2df4d3845f80587Erikimport android.content.Context; 283553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.content.res.Configuration; 293553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.content.res.Resources; 303553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.graphics.Canvas; 31092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErikimport android.graphics.Color; 323553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.graphics.Paint; 333553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.graphics.Paint.Align; 343553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.graphics.Paint.Style; 3540bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.graphics.Typeface; 3640bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.graphics.drawable.Drawable; 37a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErikimport android.provider.CalendarContract.Attendees; 3840bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.text.TextPaint; 3940bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.text.TextUtils; 4067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErikimport android.text.format.DateFormat; 4140bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.text.format.DateUtils; 423553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.text.format.Time; 433553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.util.Log; 4467f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErikimport android.view.MotionEvent; 4567f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErikimport android.view.accessibility.AccessibilityEvent; 46f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErikimport android.view.accessibility.AccessibilityManager; 473553621c824afe1f3eacbe8555678005ca1264a1Erik 483553621c824afe1f3eacbe8555678005ca1264a1Erikimport java.util.ArrayList; 49f445411ff661014c4b5a37e2f97552989e9278ecRoboErikimport java.util.Arrays; 5040bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport java.util.Formatter; 513553621c824afe1f3eacbe8555678005ca1264a1Erikimport java.util.HashMap; 5240bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport java.util.Iterator; 5340bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport java.util.List; 5440bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport java.util.Locale; 5582b318634af1b6594e60cfd1f2df4d3845f80587Erik 56e21674aefc9755ba519dfc5b3ff4348be4814903Erikpublic class MonthWeekEventsView extends SimpleWeekView { 57092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 583553621c824afe1f3eacbe8555678005ca1264a1Erik private static final String TAG = "MonthView"; 593553621c824afe1f3eacbe8555678005ca1264a1Erik 6069f9b450fc255203b758f445163f371c22c816c0Andy McFadden private static final boolean DEBUG_LAYOUT = false; 6169f9b450fc255203b758f445163f371c22c816c0Andy McFadden 623553621c824afe1f3eacbe8555678005ca1264a1Erik public static final String VIEW_PARAMS_ORIENTATION = "orientation"; 635b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik public static final String VIEW_PARAMS_ANIMATE_TODAY = "animate_today"; 643553621c824afe1f3eacbe8555678005ca1264a1Erik 6569f9b450fc255203b758f445163f371c22c816c0Andy McFadden /* NOTE: these are not constants, and may be multiplied by a scale factor */ 663553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_MONTH_NUMBER = 32; 67c76ed496f5aa09ec85cc304b70c527c73cf8243eRoboErik private static int TEXT_SIZE_EVENT = 12; 68c76ed496f5aa09ec85cc304b70c527c73cf8243eRoboErik private static int TEXT_SIZE_EVENT_TITLE = 14; 693553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_MORE_EVENTS = 12; 703553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_MONTH_NAME = 14; 713553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_WEEK_NUM = 12; 723553621c824afe1f3eacbe8555678005ca1264a1Erik 73092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_MARGIN = 4; 74092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_ALL_DAY_HEIGHT = 4; 75092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_MIN_SEGMENT_HEIGHT = 4; 76092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_WIDTH = 8; 77092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_ALL_DAY_WIDTH = 32; 78092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_SIDE_PADDING = 6; 79092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int CONFLICT_COLOR = Color.BLACK; 80458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden private static int EVENT_TEXT_COLOR = Color.WHITE; 81092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 823bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static int DEFAULT_EDGE_SPACING = 0; 833bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static int SIDE_PADDING_MONTH_NUMBER = 4; 84763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik private static int TOP_PADDING_MONTH_NUMBER = 4; 85092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int TOP_PADDING_WEEK_NUMBER = 4; 86092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int SIDE_PADDING_WEEK_NUMBER = 20; 873bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static int DAY_SEPARATOR_OUTER_WIDTH = 0; 8840bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int DAY_SEPARATOR_INNER_WIDTH = 1; 8940bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int DAY_SEPARATOR_VERTICAL_LENGTH = 53; 9040bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int DAY_SEPARATOR_VERTICAL_LENGHT_PORTRAIT = 64; 91092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int MIN_WEEK_WIDTH = 50; 9240bcd101b212c9863c3110c05a487a7ae6ebc3caErik 93f658df6b9c285f24c45cdca3ab90f2ca65e5b7cfRoboErik private static int EVENT_X_OFFSET_LANDSCAPE = 38; 9469f9b450fc255203b758f445163f371c22c816c0Andy McFadden private static int EVENT_Y_OFFSET_LANDSCAPE = 8; 9569f9b450fc255203b758f445163f371c22c816c0Andy McFadden private static int EVENT_Y_OFFSET_PORTRAIT = 7; 9640bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int EVENT_SQUARE_WIDTH = 10; 97a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik private static int EVENT_SQUARE_BORDER = 2; 9869f9b450fc255203b758f445163f371c22c816c0Andy McFadden private static int EVENT_LINE_PADDING = 2; 9940bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int EVENT_RIGHT_PADDING = 4; 10069f9b450fc255203b758f445163f371c22c816c0Andy McFadden private static int EVENT_BOTTOM_PADDING = 3; 1013553621c824afe1f3eacbe8555678005ca1264a1Erik 1025b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik private static int TODAY_HIGHLIGHT_WIDTH = 2; 10382400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson 104092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int SPACING_WEEK_NUMBER = 24; 105458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden private static boolean mInitialized = false; 1063bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static boolean mShowDetailsInMonth; 1073553621c824afe1f3eacbe8555678005ca1264a1Erik 1083553621c824afe1f3eacbe8555678005ca1264a1Erik protected Time mToday = new Time(); 1093553621c824afe1f3eacbe8555678005ca1264a1Erik protected boolean mHasToday = false; 1103553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mTodayIndex = -1; 1113553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mOrientation = Configuration.ORIENTATION_LANDSCAPE; 11240bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected List<ArrayList<Event>> mEvents = null; 1135b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik protected ArrayList<Event> mUnsortedEvents = null; 114092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik HashMap<Integer, Utils.DNAStrand> mDna = null; 115f445411ff661014c4b5a37e2f97552989e9278ecRoboErik // This is for drawing the outlines around event chips and supports up to 10 116f445411ff661014c4b5a37e2f97552989e9278ecRoboErik // events being drawn on each day. The code will expand this if necessary. 117f445411ff661014c4b5a37e2f97552989e9278ecRoboErik protected FloatRef mEventOutlines = new FloatRef(10 * 4 * 4 * 7); 11840bcd101b212c9863c3110c05a487a7ae6ebc3caErik 11971b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson 12071b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson 12140bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected static StringBuilder mStringBuilder = new StringBuilder(50); 12240bcd101b212c9863c3110c05a487a7ae6ebc3caErik // TODO recreate formatter when locale changes 12340bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected static Formatter mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); 1243553621c824afe1f3eacbe8555678005ca1264a1Erik 1253553621c824afe1f3eacbe8555678005ca1264a1Erik protected Paint mMonthNamePaint; 12640bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected TextPaint mEventPaint; 127458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden protected TextPaint mSolidBackgroundEventPaint; 128458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden protected TextPaint mFramedEventPaint; 129210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik protected TextPaint mDeclinedEventPaint; 13040bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected TextPaint mEventExtrasPaint; 131210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik protected TextPaint mEventDeclinedExtrasPaint; 1323553621c824afe1f3eacbe8555678005ca1264a1Erik protected Paint mWeekNumPaint; 133092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik protected Paint mDNAAllDayPaint; 134092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik protected Paint mDNATimePaint; 135a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik protected Paint mEventSquarePaint; 13671b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson 1373553621c824afe1f3eacbe8555678005ca1264a1Erik 13840bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected Drawable mTodayDrawable; 13940bcd101b212c9863c3110c05a487a7ae6ebc3caErik 1403553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNumHeight; 14169f9b450fc255203b758f445163f371c22c816c0Andy McFadden protected int mMonthNumAscentHeight; 1423553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mEventHeight; 14369f9b450fc255203b758f445163f371c22c816c0Andy McFadden protected int mEventAscentHeight; 1443553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mExtrasHeight; 14569f9b450fc255203b758f445163f371c22c816c0Andy McFadden protected int mExtrasAscentHeight; 14669f9b450fc255203b758f445163f371c22c816c0Andy McFadden protected int mExtrasDescent; 14769f9b450fc255203b758f445163f371c22c816c0Andy McFadden protected int mWeekNumAscentHeight; 1483553621c824afe1f3eacbe8555678005ca1264a1Erik 14967d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik protected int mMonthBGColor; 15067d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik protected int mMonthBGOtherColor; 15167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik protected int mMonthBGTodayColor; 1523553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNumColor; 1533553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNumOtherColor; 1543553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNumTodayColor; 1553553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNameColor; 1563553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNameOtherColor; 1573553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthEventColor; 158210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik protected int mMonthDeclinedEventColor; 159210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik protected int mMonthDeclinedExtrasColor; 1603553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthEventExtraColor; 1613553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthEventOtherColor; 1623553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthEventExtraOtherColor; 1633553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthWeekNumColor; 16482400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson protected int mMonthBusyBitsBgColor; 16571b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson protected int mMonthBusyBitsBusyTimeColor; 16671b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson protected int mMonthBusyBitsConflictTimeColor; 16759a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson private int mClickedDayIndex = -1; 16859a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson private int mClickedDayColor; 16959a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson private static final int mClickedAlpha = 128; 17082b318634af1b6594e60cfd1f2df4d3845f80587Erik 17140bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected int mEventChipOutlineColor = 0xFFFFFFFF; 172e9baa2499d9592343e30c983116e3f8dc921d3b0RoboErik protected int mDaySeparatorInnerColor; 1735b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik protected int mTodayAnimateColor; 1745b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 1755b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik private boolean mAnimateToday; 1765b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik private int mAnimateTodayAlpha = 0; 1775b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik private ObjectAnimator mTodayAnimator = null; 1785b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 17959a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson private final TodayAnimatorListener mAnimatorListener = new TodayAnimatorListener(); 1805b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 1815b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik class TodayAnimatorListener extends AnimatorListenerAdapter { 1825b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik private volatile Animator mAnimator = null; 1835b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik private volatile boolean mFadingIn = false; 1845b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 1855b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik @Override 1865b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik public void onAnimationEnd(Animator animation) { 1875b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik synchronized (this) { 1885b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik if (mAnimator != animation) { 1895b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik animation.removeAllListeners(); 1905b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik animation.cancel(); 1915b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik return; 1925b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 1935b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik if (mFadingIn) { 1945b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik if (mTodayAnimator != null) { 1955b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.removeAllListeners(); 1965b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.cancel(); 1975b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 1985b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator = ObjectAnimator.ofInt(MonthWeekEventsView.this, 1995b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik "animateTodayAlpha", 255, 0); 2005b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimator = mTodayAnimator; 2015b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mFadingIn = false; 2025b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.addListener(this); 2035b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.setDuration(600); 2045b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.start(); 2055b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } else { 2065b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimateToday = false; 2075b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimateTodayAlpha = 0; 2085b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimator.removeAllListeners(); 2095b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimator = null; 2105b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator = null; 2115b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik invalidate(); 2125b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 2135b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 2145b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 2155b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 2165b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik public void setAnimator(Animator animation) { 2175b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimator = animation; 2185b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 2195b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 2205b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik public void setFadingIn(boolean fadingIn) { 2215b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mFadingIn = fadingIn; 2225b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 2235b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 2245b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 22540bcd101b212c9863c3110c05a487a7ae6ebc3caErik 226092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private int[] mDayXs; 22782400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson 22882b318634af1b6594e60cfd1f2df4d3845f80587Erik /** 229f445411ff661014c4b5a37e2f97552989e9278ecRoboErik * This provides a reference to a float array which allows for easy size 230f445411ff661014c4b5a37e2f97552989e9278ecRoboErik * checking and reallocation. Used for drawing lines. 231f445411ff661014c4b5a37e2f97552989e9278ecRoboErik */ 232f445411ff661014c4b5a37e2f97552989e9278ecRoboErik private class FloatRef { 233f445411ff661014c4b5a37e2f97552989e9278ecRoboErik float[] array; 234f445411ff661014c4b5a37e2f97552989e9278ecRoboErik 235f445411ff661014c4b5a37e2f97552989e9278ecRoboErik public FloatRef(int size) { 236f445411ff661014c4b5a37e2f97552989e9278ecRoboErik array = new float[size]; 237f445411ff661014c4b5a37e2f97552989e9278ecRoboErik } 238f445411ff661014c4b5a37e2f97552989e9278ecRoboErik 239f445411ff661014c4b5a37e2f97552989e9278ecRoboErik public void ensureSize(int newSize) { 240f445411ff661014c4b5a37e2f97552989e9278ecRoboErik if (newSize >= array.length) { 241f445411ff661014c4b5a37e2f97552989e9278ecRoboErik // Add enough space for 7 more boxes to be drawn 242f445411ff661014c4b5a37e2f97552989e9278ecRoboErik array = Arrays.copyOf(array, newSize + 16 * 7); 243f445411ff661014c4b5a37e2f97552989e9278ecRoboErik } 244f445411ff661014c4b5a37e2f97552989e9278ecRoboErik } 245f445411ff661014c4b5a37e2f97552989e9278ecRoboErik } 246f445411ff661014c4b5a37e2f97552989e9278ecRoboErik 247f445411ff661014c4b5a37e2f97552989e9278ecRoboErik /** 2485b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik * Shows up as an error if we don't include this. 24982b318634af1b6594e60cfd1f2df4d3845f80587Erik */ 25082b318634af1b6594e60cfd1f2df4d3845f80587Erik public MonthWeekEventsView(Context context) { 25182b318634af1b6594e60cfd1f2df4d3845f80587Erik super(context); 252092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 253092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 254092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Sets the list of events for this week. Takes a sorted list of arrays 255092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // divided up by day for generating the large month version and the full 256092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // arraylist sorted by start time to generate the dna version. 257092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik public void setEvents(List<ArrayList<Event>> sortedEvents, ArrayList<Event> unsortedEvents) { 258092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik setEvents(sortedEvents); 259092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // The MIN_WEEK_WIDTH is a hack to prevent the view from trying to 260092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // generate dna bits before its width has been fixed. 2615b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik createDna(unsortedEvents); 2625b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 2635b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 2645b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik /** 2655b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik * Sets up the dna bits for the view. This will return early if the view 2665b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik * isn't in a state that will create a valid set of dna yet (such as the 2675b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik * views width not being set correctly yet). 2685b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik */ 2695b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik public void createDna(ArrayList<Event> unsortedEvents) { 2707d66103066f04ba2b7c4ddfcfdafd0368ad9d9cbAndy McFadden if (unsortedEvents == null || mWidth <= MIN_WEEK_WIDTH || getContext() == null) { 2715b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik // Stash the list of events for use when this view is ready, or 2725b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik // just clear it if a null set has been passed to this view 2735b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mUnsortedEvents = unsortedEvents; 274092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDna = null; 275092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik return; 2765b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } else { 2775b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik // clear the cached set of events since we're ready to build it now 2785b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mUnsortedEvents = null; 279092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 280092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Create the drawing coordinates for dna 281092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (!mShowDetailsInMonth) { 282092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int numDays = mEvents.size(); 283763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik int effectiveWidth = mWidth - mPadding * 2; 284763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik if (mShowWeekNum) { 285763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik effectiveWidth -= SPACING_WEEK_NUMBER; 286763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik } 287092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_ALL_DAY_WIDTH = effectiveWidth / numDays - 2 * DNA_SIDE_PADDING; 288092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setStrokeWidth(DNA_ALL_DAY_WIDTH); 289092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDayXs = new int[numDays]; 290092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik for (int day = 0; day < numDays; day++) { 291092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDayXs[day] = computeDayLeftPosition(day) + DNA_WIDTH / 2 + DNA_SIDE_PADDING; 292092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 293092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 294092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 295092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int top = DAY_SEPARATOR_INNER_WIDTH + DNA_MARGIN + DNA_ALL_DAY_HEIGHT + 1; 296092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int bottom = mHeight - DNA_MARGIN; 297092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDna = Utils.createDNAStrands(mFirstJulianDay, unsortedEvents, top, bottom, 2987d66103066f04ba2b7c4ddfcfdafd0368ad9d9cbAndy McFadden DNA_MIN_SEGMENT_HEIGHT, mDayXs, getContext()); 299092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 3003553621c824afe1f3eacbe8555678005ca1264a1Erik } 3013553621c824afe1f3eacbe8555678005ca1264a1Erik 30240bcd101b212c9863c3110c05a487a7ae6ebc3caErik public void setEvents(List<ArrayList<Event>> sortedEvents) { 3033553621c824afe1f3eacbe8555678005ca1264a1Erik mEvents = sortedEvents; 3043553621c824afe1f3eacbe8555678005ca1264a1Erik if (sortedEvents == null) { 3053553621c824afe1f3eacbe8555678005ca1264a1Erik return; 3063553621c824afe1f3eacbe8555678005ca1264a1Erik } 3073553621c824afe1f3eacbe8555678005ca1264a1Erik if (sortedEvents.size() != mNumDays) { 3083553621c824afe1f3eacbe8555678005ca1264a1Erik if (Log.isLoggable(TAG, Log.ERROR)) { 3093553621c824afe1f3eacbe8555678005ca1264a1Erik Log.wtf(TAG, "Events size must be same as days displayed: size=" 3103553621c824afe1f3eacbe8555678005ca1264a1Erik + sortedEvents.size() + " days=" + mNumDays); 3113553621c824afe1f3eacbe8555678005ca1264a1Erik } 3123553621c824afe1f3eacbe8555678005ca1264a1Erik mEvents = null; 3133553621c824afe1f3eacbe8555678005ca1264a1Erik return; 3143553621c824afe1f3eacbe8555678005ca1264a1Erik } 3153553621c824afe1f3eacbe8555678005ca1264a1Erik } 3163553621c824afe1f3eacbe8555678005ca1264a1Erik 3173553621c824afe1f3eacbe8555678005ca1264a1Erik protected void loadColors(Context context) { 3183553621c824afe1f3eacbe8555678005ca1264a1Erik Resources res = context.getResources(); 3193553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthWeekNumColor = res.getColor(R.color.month_week_num_color); 3203553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumColor = res.getColor(R.color.month_day_number); 3213553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumOtherColor = res.getColor(R.color.month_day_number_other); 3223553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumTodayColor = res.getColor(R.color.month_today_number); 3233553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNameColor = mMonthNumColor; 3243553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNameOtherColor = mMonthNumOtherColor; 3253553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthEventColor = res.getColor(R.color.month_event_color); 326210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mMonthDeclinedEventColor = res.getColor(R.color.agenda_item_declined_color); 327210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mMonthDeclinedExtrasColor = res.getColor(R.color.agenda_item_where_declined_text_color); 3283553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthEventExtraColor = res.getColor(R.color.month_event_extra_color); 3293553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthEventOtherColor = res.getColor(R.color.month_event_other_color); 3303553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthEventExtraOtherColor = res.getColor(R.color.month_event_extra_other_color); 33167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthBGTodayColor = res.getColor(R.color.month_today_bgcolor); 33267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthBGOtherColor = res.getColor(R.color.month_other_bgcolor); 33367d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthBGColor = res.getColor(R.color.month_bgcolor); 334e9baa2499d9592343e30c983116e3f8dc921d3b0RoboErik mDaySeparatorInnerColor = res.getColor(R.color.month_grid_lines); 3355b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimateColor = res.getColor(R.color.today_highlight_color); 33659a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson mClickedDayColor = res.getColor(R.color.day_clicked_background_color); 33740bcd101b212c9863c3110c05a487a7ae6ebc3caErik mTodayDrawable = res.getDrawable(R.drawable.today_blue_week_holo_light); 3383553621c824afe1f3eacbe8555678005ca1264a1Erik } 3393553621c824afe1f3eacbe8555678005ca1264a1Erik 3403553621c824afe1f3eacbe8555678005ca1264a1Erik /** 3413553621c824afe1f3eacbe8555678005ca1264a1Erik * Sets up the text and style properties for painting. Override this if you 3423553621c824afe1f3eacbe8555678005ca1264a1Erik * want to use a different paint. 3433553621c824afe1f3eacbe8555678005ca1264a1Erik */ 3443553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 3457203d809b39fb07caab177d8e8bd9428097b73b6Erik protected void initView() { 3467203d809b39fb07caab177d8e8bd9428097b73b6Erik super.initView(); 3477203d809b39fb07caab177d8e8bd9428097b73b6Erik 348458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (!mInitialized) { 3493bff945d29d6ef277391745cd160f3bf16b98905RoboErik Resources resources = getContext().getResources(); 3507d66103066f04ba2b7c4ddfcfdafd0368ad9d9cbAndy McFadden mShowDetailsInMonth = Utils.getConfigBool(getContext(), R.bool.show_details_in_month); 351e0942157628776cff5573da8ce85fb3f3c3cfc35Mindy Pereira TEXT_SIZE_EVENT_TITLE = resources.getInteger(R.integer.text_size_event_title); 3523bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_MONTH_NUMBER = resources.getInteger(R.integer.text_size_month_number); 3533bff945d29d6ef277391745cd160f3bf16b98905RoboErik SIDE_PADDING_MONTH_NUMBER = resources.getInteger(R.integer.month_day_number_margin); 354092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik CONFLICT_COLOR = resources.getColor(R.color.month_dna_conflict_time_color); 355458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden EVENT_TEXT_COLOR = resources.getColor(R.color.calendar_event_text_color); 3563bff945d29d6ef277391745cd160f3bf16b98905RoboErik if (mScale != 1) { 3573bff945d29d6ef277391745cd160f3bf16b98905RoboErik TOP_PADDING_MONTH_NUMBER *= mScale; 358092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik TOP_PADDING_WEEK_NUMBER *= mScale; 3593bff945d29d6ef277391745cd160f3bf16b98905RoboErik SIDE_PADDING_MONTH_NUMBER *= mScale; 3603bff945d29d6ef277391745cd160f3bf16b98905RoboErik SIDE_PADDING_WEEK_NUMBER *= mScale; 3613bff945d29d6ef277391745cd160f3bf16b98905RoboErik SPACING_WEEK_NUMBER *= mScale; 3623bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_MONTH_NUMBER *= mScale; 3633bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_EVENT *= mScale; 364c76ed496f5aa09ec85cc304b70c527c73cf8243eRoboErik TEXT_SIZE_EVENT_TITLE *= mScale; 3653bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_MORE_EVENTS *= mScale; 3663bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_MONTH_NAME *= mScale; 3673bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_WEEK_NUM *= mScale; 3683bff945d29d6ef277391745cd160f3bf16b98905RoboErik DAY_SEPARATOR_OUTER_WIDTH *= mScale; 3693bff945d29d6ef277391745cd160f3bf16b98905RoboErik DAY_SEPARATOR_INNER_WIDTH *= mScale; 3703bff945d29d6ef277391745cd160f3bf16b98905RoboErik DAY_SEPARATOR_VERTICAL_LENGTH *= mScale; 3713bff945d29d6ef277391745cd160f3bf16b98905RoboErik DAY_SEPARATOR_VERTICAL_LENGHT_PORTRAIT *= mScale; 3723bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_X_OFFSET_LANDSCAPE *= mScale; 3733bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_Y_OFFSET_LANDSCAPE *= mScale; 3743bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_Y_OFFSET_PORTRAIT *= mScale; 3753bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_SQUARE_WIDTH *= mScale; 376a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik EVENT_SQUARE_BORDER *= mScale; 3773bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_LINE_PADDING *= mScale; 3783bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_BOTTOM_PADDING *= mScale; 3793bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_RIGHT_PADDING *= mScale; 380092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_MARGIN *= mScale; 381092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_WIDTH *= mScale; 382092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_ALL_DAY_HEIGHT *= mScale; 383092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_MIN_SEGMENT_HEIGHT *= mScale; 384092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_SIDE_PADDING *= mScale; 3853bff945d29d6ef277391745cd160f3bf16b98905RoboErik DEFAULT_EDGE_SPACING *= mScale; 386092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_ALL_DAY_WIDTH *= mScale; 3875b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik TODAY_HIGHLIGHT_WIDTH *= mScale; 388092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 389092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (!mShowDetailsInMonth) { 390092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik TOP_PADDING_MONTH_NUMBER += DNA_ALL_DAY_HEIGHT + DNA_MARGIN; 3913bff945d29d6ef277391745cd160f3bf16b98905RoboErik } 392458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden mInitialized = true; 3937203d809b39fb07caab177d8e8bd9428097b73b6Erik } 3943bff945d29d6ef277391745cd160f3bf16b98905RoboErik mPadding = DEFAULT_EDGE_SPACING; 3953f888688c0f2644ad3de032d5d1cf623a7b092fdAndy McFadden loadColors(getContext()); 3963553621c824afe1f3eacbe8555678005ca1264a1Erik // TODO modify paint properties depending on isMini 3973553621c824afe1f3eacbe8555678005ca1264a1Erik 3983553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint = new Paint(); 39940bcd101b212c9863c3110c05a487a7ae6ebc3caErik mMonthNumPaint.setFakeBoldText(false); 4003553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setAntiAlias(true); 4013553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setTextSize(TEXT_SIZE_MONTH_NUMBER); 4023553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setColor(mMonthNumColor); 4033553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setStyle(Style.FILL); 404a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mMonthNumPaint.setTextAlign(Align.RIGHT); 40564d67bea6bdb8516c1685b0bb19bc217c3cbe14eRoboErik mMonthNumPaint.setTypeface(Typeface.DEFAULT); 4063553621c824afe1f3eacbe8555678005ca1264a1Erik 40769f9b450fc255203b758f445163f371c22c816c0Andy McFadden mMonthNumAscentHeight = (int) (-mMonthNumPaint.ascent() + 0.5f); 40869f9b450fc255203b758f445163f371c22c816c0Andy McFadden mMonthNumHeight = (int) (mMonthNumPaint.descent() - mMonthNumPaint.ascent() + 0.5f); 4093553621c824afe1f3eacbe8555678005ca1264a1Erik 41040bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventPaint = new TextPaint(); 411f658df6b9c285f24c45cdca3ab90f2ca65e5b7cfRoboErik mEventPaint.setFakeBoldText(true); 4123553621c824afe1f3eacbe8555678005ca1264a1Erik mEventPaint.setAntiAlias(true); 413c76ed496f5aa09ec85cc304b70c527c73cf8243eRoboErik mEventPaint.setTextSize(TEXT_SIZE_EVENT_TITLE); 4143553621c824afe1f3eacbe8555678005ca1264a1Erik mEventPaint.setColor(mMonthEventColor); 4153553621c824afe1f3eacbe8555678005ca1264a1Erik 416458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden mSolidBackgroundEventPaint = new TextPaint(mEventPaint); 417458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden mSolidBackgroundEventPaint.setColor(EVENT_TEXT_COLOR); 418458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden mFramedEventPaint = new TextPaint(mSolidBackgroundEventPaint); 419458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden 420210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mDeclinedEventPaint = new TextPaint(); 421210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mDeclinedEventPaint.setFakeBoldText(true); 422210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mDeclinedEventPaint.setAntiAlias(true); 423c76ed496f5aa09ec85cc304b70c527c73cf8243eRoboErik mDeclinedEventPaint.setTextSize(TEXT_SIZE_EVENT_TITLE); 424210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mDeclinedEventPaint.setColor(mMonthDeclinedEventColor); 425210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik 42669f9b450fc255203b758f445163f371c22c816c0Andy McFadden mEventAscentHeight = (int) (-mEventPaint.ascent() + 0.5f); 42769f9b450fc255203b758f445163f371c22c816c0Andy McFadden mEventHeight = (int) (mEventPaint.descent() - mEventPaint.ascent() + 0.5f); 4283553621c824afe1f3eacbe8555678005ca1264a1Erik 42940bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventExtrasPaint = new TextPaint(); 4303553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setFakeBoldText(false); 4313553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setAntiAlias(true); 43240bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventExtrasPaint.setStrokeWidth(EVENT_SQUARE_BORDER); 4333553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setTextSize(TEXT_SIZE_EVENT); 4343553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setColor(mMonthEventExtraColor); 4353553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setStyle(Style.FILL); 4363553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setTextAlign(Align.LEFT); 43769f9b450fc255203b758f445163f371c22c816c0Andy McFadden mExtrasHeight = (int)(mEventExtrasPaint.descent() - mEventExtrasPaint.ascent() + 0.5f); 43869f9b450fc255203b758f445163f371c22c816c0Andy McFadden mExtrasAscentHeight = (int)(-mEventExtrasPaint.ascent() + 0.5f); 43969f9b450fc255203b758f445163f371c22c816c0Andy McFadden mExtrasDescent = (int)(mEventExtrasPaint.descent() + 0.5f); 4403553621c824afe1f3eacbe8555678005ca1264a1Erik 441210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventDeclinedExtrasPaint = new TextPaint(); 442210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventDeclinedExtrasPaint.setFakeBoldText(false); 443210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventDeclinedExtrasPaint.setAntiAlias(true); 444210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventDeclinedExtrasPaint.setStrokeWidth(EVENT_SQUARE_BORDER); 445210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventDeclinedExtrasPaint.setTextSize(TEXT_SIZE_EVENT); 446210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventDeclinedExtrasPaint.setColor(mMonthDeclinedExtrasColor); 447210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventDeclinedExtrasPaint.setStyle(Style.FILL); 448210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventDeclinedExtrasPaint.setTextAlign(Align.LEFT); 449210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik 4503553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint = new Paint(); 4513553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setFakeBoldText(false); 4523553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setAntiAlias(true); 4533553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setTextSize(TEXT_SIZE_WEEK_NUM); 4543553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setColor(mWeekNumColor); 4553553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setStyle(Style.FILL); 4563553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setTextAlign(Align.RIGHT); 4573553621c824afe1f3eacbe8555678005ca1264a1Erik 45869f9b450fc255203b758f445163f371c22c816c0Andy McFadden mWeekNumAscentHeight = (int) (-mWeekNumPaint.ascent() + 0.5f); 45971b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson 460092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint = new Paint(); 461092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint = new Paint(); 462092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setColor(mMonthBusyBitsBusyTimeColor); 463092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setStyle(Style.FILL_AND_STROKE); 464092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setStrokeWidth(DNA_WIDTH); 465092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setAntiAlias(false); 466092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setColor(mMonthBusyBitsConflictTimeColor); 467092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setStyle(Style.FILL_AND_STROKE); 468092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setStrokeWidth(DNA_ALL_DAY_WIDTH); 469092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setAntiAlias(false); 470a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik 471a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint = new Paint(); 472a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint.setStrokeWidth(EVENT_SQUARE_BORDER); 473a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint.setAntiAlias(false); 47469f9b450fc255203b758f445163f371c22c816c0Andy McFadden 47569f9b450fc255203b758f445163f371c22c816c0Andy McFadden if (DEBUG_LAYOUT) { 47669f9b450fc255203b758f445163f371c22c816c0Andy McFadden Log.d("EXTRA", "mScale=" + mScale); 47769f9b450fc255203b758f445163f371c22c816c0Andy McFadden Log.d("EXTRA", "mMonthNumPaint ascent=" + mMonthNumPaint.ascent() 47869f9b450fc255203b758f445163f371c22c816c0Andy McFadden + " descent=" + mMonthNumPaint.descent() + " int height=" + mMonthNumHeight); 47969f9b450fc255203b758f445163f371c22c816c0Andy McFadden Log.d("EXTRA", "mEventPaint ascent=" + mEventPaint.ascent() 48069f9b450fc255203b758f445163f371c22c816c0Andy McFadden + " descent=" + mEventPaint.descent() + " int height=" + mEventHeight 48169f9b450fc255203b758f445163f371c22c816c0Andy McFadden + " int ascent=" + mEventAscentHeight); 48269f9b450fc255203b758f445163f371c22c816c0Andy McFadden Log.d("EXTRA", "mEventExtrasPaint ascent=" + mEventExtrasPaint.ascent() 48369f9b450fc255203b758f445163f371c22c816c0Andy McFadden + " descent=" + mEventExtrasPaint.descent() + " int height=" + mExtrasHeight); 48469f9b450fc255203b758f445163f371c22c816c0Andy McFadden Log.d("EXTRA", "mWeekNumPaint ascent=" + mWeekNumPaint.ascent() 48569f9b450fc255203b758f445163f371c22c816c0Andy McFadden + " descent=" + mWeekNumPaint.descent()); 48669f9b450fc255203b758f445163f371c22c816c0Andy McFadden } 4873553621c824afe1f3eacbe8555678005ca1264a1Erik } 4883553621c824afe1f3eacbe8555678005ca1264a1Erik 4893553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 4903553621c824afe1f3eacbe8555678005ca1264a1Erik public void setWeekParams(HashMap<String, Integer> params, String tz) { 4913553621c824afe1f3eacbe8555678005ca1264a1Erik super.setWeekParams(params, tz); 4923553621c824afe1f3eacbe8555678005ca1264a1Erik 49340bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (params.containsKey(VIEW_PARAMS_ORIENTATION)) { 49440bcd101b212c9863c3110c05a487a7ae6ebc3caErik mOrientation = params.get(VIEW_PARAMS_ORIENTATION); 49540bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 49640bcd101b212c9863c3110c05a487a7ae6ebc3caErik 4975b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik updateToday(tz); 4985b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mNumCells = mNumDays + 1; 4995b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 5005b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik if (params.containsKey(VIEW_PARAMS_ANIMATE_TODAY) && mHasToday) { 5015b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik synchronized (mAnimatorListener) { 5025b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik if (mTodayAnimator != null) { 5035b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.removeAllListeners(); 5045b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.cancel(); 5055b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 5065b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator = ObjectAnimator.ofInt(this, "animateTodayAlpha", 5075b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik Math.max(mAnimateTodayAlpha, 80), 255); 5085b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.setDuration(150); 5095b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimatorListener.setAnimator(mTodayAnimator); 5105b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimatorListener.setFadingIn(true); 5115b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.addListener(mAnimatorListener); 5125b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimateToday = true; 5135b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mTodayAnimator.start(); 5145b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 5155b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 5165b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 5175b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 5185b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik /** 5195b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik * @param tz 5205b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik */ 5215b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik public boolean updateToday(String tz) { 5223553621c824afe1f3eacbe8555678005ca1264a1Erik mToday.timezone = tz; 5233553621c824afe1f3eacbe8555678005ca1264a1Erik mToday.setToNow(); 5243553621c824afe1f3eacbe8555678005ca1264a1Erik mToday.normalize(true); 5253553621c824afe1f3eacbe8555678005ca1264a1Erik int julianToday = Time.getJulianDay(mToday.toMillis(false), mToday.gmtoff); 5263553621c824afe1f3eacbe8555678005ca1264a1Erik if (julianToday >= mFirstJulianDay && julianToday < mFirstJulianDay + mNumDays) { 5273553621c824afe1f3eacbe8555678005ca1264a1Erik mHasToday = true; 5283553621c824afe1f3eacbe8555678005ca1264a1Erik mTodayIndex = julianToday - mFirstJulianDay; 5293553621c824afe1f3eacbe8555678005ca1264a1Erik } else { 5303553621c824afe1f3eacbe8555678005ca1264a1Erik mHasToday = false; 5313553621c824afe1f3eacbe8555678005ca1264a1Erik mTodayIndex = -1; 5323553621c824afe1f3eacbe8555678005ca1264a1Erik } 5335b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik return mHasToday; 5345b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 5355b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 5365b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik public void setAnimateTodayAlpha(int alpha) { 5375b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik mAnimateTodayAlpha = alpha; 5385b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik invalidate(); 5393553621c824afe1f3eacbe8555678005ca1264a1Erik } 5403553621c824afe1f3eacbe8555678005ca1264a1Erik 5413553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 54240bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected void onDraw(Canvas canvas) { 54340bcd101b212c9863c3110c05a487a7ae6ebc3caErik drawBackground(canvas); 54440bcd101b212c9863c3110c05a487a7ae6ebc3caErik drawWeekNums(canvas); 54540bcd101b212c9863c3110c05a487a7ae6ebc3caErik drawDaySeparators(canvas); 5465b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik if (mHasToday && mAnimateToday) { 5475b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik drawToday(canvas); 5485b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 549ff5c4345f794ec12b0a92f284434ddc1c88ff3a8Isaac Katzenelson if (mShowDetailsInMonth) { 55096a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson drawEvents(canvas); 55182400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson } else { 5525b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik if (mDna == null && mUnsortedEvents != null) { 5535b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik createDna(mUnsortedEvents); 5545b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 555092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik drawDNA(canvas); 556092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 55759a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson drawClick(canvas); 558092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 559092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 5605b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik protected void drawToday(Canvas canvas) { 5615b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik r.top = DAY_SEPARATOR_INNER_WIDTH + (TODAY_HIGHLIGHT_WIDTH / 2); 5625b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik r.bottom = mHeight - (int) Math.ceil(TODAY_HIGHLIGHT_WIDTH / 2.0f); 5635b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik p.setStyle(Style.STROKE); 5645b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik p.setStrokeWidth(TODAY_HIGHLIGHT_WIDTH); 5655b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik r.left = computeDayLeftPosition(mTodayIndex) + (TODAY_HIGHLIGHT_WIDTH / 2); 5665b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik r.right = computeDayLeftPosition(mTodayIndex + 1) 5675b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik - (int) Math.ceil(TODAY_HIGHLIGHT_WIDTH / 2.0f); 5685b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik p.setColor(mTodayAnimateColor | (mAnimateTodayAlpha << 24)); 5695b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik canvas.drawRect(r, p); 5705b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik p.setStyle(Style.FILL); 5715b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik } 5725b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik 573092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // TODO move into SimpleWeekView 574092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Computes the x position for the left side of the given day 575092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private int computeDayLeftPosition(int day) { 576092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int effectiveWidth = mWidth; 577092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int x = 0; 578092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int xOffset = 0; 579092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (mShowWeekNum) { 580092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik xOffset = SPACING_WEEK_NUMBER + mPadding; 581092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik effectiveWidth -= xOffset; 58296a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson } 583092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik x = day * effectiveWidth / mNumDays + xOffset; 584092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik return x; 58540bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 58640bcd101b212c9863c3110c05a487a7ae6ebc3caErik 58740bcd101b212c9863c3110c05a487a7ae6ebc3caErik @Override 58840bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected void drawDaySeparators(Canvas canvas) { 58940bcd101b212c9863c3110c05a487a7ae6ebc3caErik float lines[] = new float[8 * 4]; 590092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int count = 6 * 4; 59140bcd101b212c9863c3110c05a487a7ae6ebc3caErik int wkNumOffset = 0; 592092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int i = 0; 593092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (mShowWeekNum) { 594092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // This adds the first line separating the week number 595092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int xOffset = SPACING_WEEK_NUMBER + mPadding; 596092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik count += 4; 597092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = xOffset; 598092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = 0; 599092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = xOffset; 600092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = mHeight; 601092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik wkNumOffset++; 602092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 603bf4aa400663a072813c87cf9c8aaee2d07abc945Erik count += 4; 604092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = 0; 605092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = 0; 606092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = mWidth; 607092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = 0; 6083bff945d29d6ef277391745cd160f3bf16b98905RoboErik int y0 = 0; 6093bff945d29d6ef277391745cd160f3bf16b98905RoboErik int y1 = mHeight; 61040bcd101b212c9863c3110c05a487a7ae6ebc3caErik 611092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik while (i < count) { 612092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int x = computeDayLeftPosition(i / 4 - wkNumOffset); 61340bcd101b212c9863c3110c05a487a7ae6ebc3caErik lines[i++] = x; 61440bcd101b212c9863c3110c05a487a7ae6ebc3caErik lines[i++] = y0; 61540bcd101b212c9863c3110c05a487a7ae6ebc3caErik lines[i++] = x; 61640bcd101b212c9863c3110c05a487a7ae6ebc3caErik lines[i++] = y1; 61740bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 61840bcd101b212c9863c3110c05a487a7ae6ebc3caErik p.setColor(mDaySeparatorInnerColor); 61940bcd101b212c9863c3110c05a487a7ae6ebc3caErik p.setStrokeWidth(DAY_SEPARATOR_INNER_WIDTH); 62040bcd101b212c9863c3110c05a487a7ae6ebc3caErik canvas.drawLines(lines, 0, count, p); 62140bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 62240bcd101b212c9863c3110c05a487a7ae6ebc3caErik 62340bcd101b212c9863c3110c05a487a7ae6ebc3caErik @Override 6243553621c824afe1f3eacbe8555678005ca1264a1Erik protected void drawBackground(Canvas canvas) { 62567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik int i = 0; 62667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik int offset = 0; 627092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik r.top = DAY_SEPARATOR_INNER_WIDTH; 6283553621c824afe1f3eacbe8555678005ca1264a1Erik r.bottom = mHeight; 62967d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik if (mShowWeekNum) { 63067d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik i++; 63167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik offset++; 63267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik } 63341cdd1a43d80054c6a336585c40169e1c5538fdaIsaac Katzenelson if (!mOddMonth[i]) { 63441cdd1a43d80054c6a336585c40169e1c5538fdaIsaac Katzenelson while (++i < mOddMonth.length && !mOddMonth[i]) 63567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik ; 63667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.right = computeDayLeftPosition(i - offset); 63767d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.left = 0; 638e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik p.setColor(mMonthBGOtherColor); 63967d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik canvas.drawRect(r, p); 64067d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik // compute left edge for i, set up r, draw 64141cdd1a43d80054c6a336585c40169e1c5538fdaIsaac Katzenelson } else if (!mOddMonth[(i = mOddMonth.length - 1)]) { 64241cdd1a43d80054c6a336585c40169e1c5538fdaIsaac Katzenelson while (--i >= offset && !mOddMonth[i]) 64367d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik ; 64467d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik i++; 64567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik // compute left edge for i, set up r, draw 64667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.right = mWidth; 64767d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.left = computeDayLeftPosition(i - offset); 648e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik p.setColor(mMonthBGOtherColor); 64967d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik canvas.drawRect(r, p); 65067d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik } 65167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik if (mHasToday) { 65267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik p.setColor(mMonthBGTodayColor); 65367d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.left = computeDayLeftPosition(mTodayIndex); 65467d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.right = computeDayLeftPosition(mTodayIndex + 1); 65567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik canvas.drawRect(r, p); 65667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik } 6573553621c824afe1f3eacbe8555678005ca1264a1Erik } 6583553621c824afe1f3eacbe8555678005ca1264a1Erik 65959a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson // Draw the "clicked" color on the tapped day 66059a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson private void drawClick(Canvas canvas) { 66159a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson if (mClickedDayIndex != -1) { 66259a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson int alpha = p.getAlpha(); 66359a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson p.setColor(mClickedDayColor); 66459a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson p.setAlpha(mClickedAlpha); 66559a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson r.left = computeDayLeftPosition(mClickedDayIndex); 66659a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson r.right = computeDayLeftPosition(mClickedDayIndex + 1); 66759a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson r.top = DAY_SEPARATOR_INNER_WIDTH; 66859a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson r.bottom = mHeight; 66959a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson canvas.drawRect(r, p); 67059a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson p.setAlpha(alpha); 67159a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson } 67259a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson } 67359a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson 6743553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 6753553621c824afe1f3eacbe8555678005ca1264a1Erik protected void drawWeekNums(Canvas canvas) { 676bf4aa400663a072813c87cf9c8aaee2d07abc945Erik int y; 6773553621c824afe1f3eacbe8555678005ca1264a1Erik 6783553621c824afe1f3eacbe8555678005ca1264a1Erik int i = 0; 679a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik int offset = -1; 6803553621c824afe1f3eacbe8555678005ca1264a1Erik int todayIndex = mTodayIndex; 681092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int x = 0; 682ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik int numCount = mNumDays; 6833553621c824afe1f3eacbe8555678005ca1264a1Erik if (mShowWeekNum) { 684092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik x = SIDE_PADDING_WEEK_NUMBER + mPadding; 68569f9b450fc255203b758f445163f371c22c816c0Andy McFadden y = mWeekNumAscentHeight + TOP_PADDING_WEEK_NUMBER; 6863553621c824afe1f3eacbe8555678005ca1264a1Erik canvas.drawText(mDayNumbers[0], x, y, mWeekNumPaint); 687ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik numCount++; 688ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik i++; 689ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik todayIndex++; 690ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik offset++; 691092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 6923553621c824afe1f3eacbe8555678005ca1264a1Erik } 6933553621c824afe1f3eacbe8555678005ca1264a1Erik 69469f9b450fc255203b758f445163f371c22c816c0Andy McFadden y = mMonthNumAscentHeight + TOP_PADDING_MONTH_NUMBER; 6953553621c824afe1f3eacbe8555678005ca1264a1Erik 6963553621c824afe1f3eacbe8555678005ca1264a1Erik boolean isFocusMonth = mFocusDay[i]; 69767d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik boolean isBold = false; 6983553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setColor(isFocusMonth ? mMonthNumColor : mMonthNumOtherColor); 699ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik for (; i < numCount; i++) { 7003553621c824afe1f3eacbe8555678005ca1264a1Erik if (mHasToday && todayIndex == i) { 7013553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setColor(mMonthNumTodayColor); 70267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthNumPaint.setFakeBoldText(isBold = true); 703259b8f9a21fffd3858218581e9daaf689b6b888fErik if (i + 1 < numCount) { 7043553621c824afe1f3eacbe8555678005ca1264a1Erik // Make sure the color will be set back on the next 7053553621c824afe1f3eacbe8555678005ca1264a1Erik // iteration 7063553621c824afe1f3eacbe8555678005ca1264a1Erik isFocusMonth = !mFocusDay[i + 1]; 7073553621c824afe1f3eacbe8555678005ca1264a1Erik } 7083553621c824afe1f3eacbe8555678005ca1264a1Erik } else if (mFocusDay[i] != isFocusMonth) { 7093553621c824afe1f3eacbe8555678005ca1264a1Erik isFocusMonth = mFocusDay[i]; 7103553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setColor(isFocusMonth ? mMonthNumColor : mMonthNumOtherColor); 7113553621c824afe1f3eacbe8555678005ca1264a1Erik } 712a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik x = computeDayLeftPosition(i - offset) - (SIDE_PADDING_MONTH_NUMBER); 7133553621c824afe1f3eacbe8555678005ca1264a1Erik canvas.drawText(mDayNumbers[i], x, y, mMonthNumPaint); 71467d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik if (isBold) { 71567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthNumPaint.setFakeBoldText(isBold = false); 71667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik } 7173553621c824afe1f3eacbe8555678005ca1264a1Erik } 7183553621c824afe1f3eacbe8555678005ca1264a1Erik } 7193553621c824afe1f3eacbe8555678005ca1264a1Erik 72040bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected void drawEvents(Canvas canvas) { 72140bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (mEvents == null) { 72240bcd101b212c9863c3110c05a487a7ae6ebc3caErik return; 72340bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 72440bcd101b212c9863c3110c05a487a7ae6ebc3caErik 72540bcd101b212c9863c3110c05a487a7ae6ebc3caErik int day = -1; 72640bcd101b212c9863c3110c05a487a7ae6ebc3caErik for (ArrayList<Event> eventDay : mEvents) { 72740bcd101b212c9863c3110c05a487a7ae6ebc3caErik day++; 72840bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (eventDay == null || eventDay.size() == 0) { 72940bcd101b212c9863c3110c05a487a7ae6ebc3caErik continue; 73040bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 73140bcd101b212c9863c3110c05a487a7ae6ebc3caErik int ySquare; 732a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik int xSquare = computeDayLeftPosition(day) + SIDE_PADDING_MONTH_NUMBER + 1; 733a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik int rightEdge = computeDayLeftPosition(day + 1); 734a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik 73540bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (mOrientation == Configuration.ORIENTATION_PORTRAIT) { 7363bff945d29d6ef277391745cd160f3bf16b98905RoboErik ySquare = EVENT_Y_OFFSET_PORTRAIT + mMonthNumHeight + TOP_PADDING_MONTH_NUMBER; 737a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik rightEdge -= SIDE_PADDING_MONTH_NUMBER + 1; 73840bcd101b212c9863c3110c05a487a7ae6ebc3caErik } else { 73940bcd101b212c9863c3110c05a487a7ae6ebc3caErik ySquare = EVENT_Y_OFFSET_LANDSCAPE; 740a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik rightEdge -= EVENT_X_OFFSET_LANDSCAPE; 74140bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 742458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden 743458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // Determine if everything will fit when time ranges are shown. 744458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden boolean showTimes = true; 74540bcd101b212c9863c3110c05a487a7ae6ebc3caErik Iterator<Event> iter = eventDay.iterator(); 746458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden int yTest = ySquare; 74740bcd101b212c9863c3110c05a487a7ae6ebc3caErik while (iter.hasNext()) { 74840bcd101b212c9863c3110c05a487a7ae6ebc3caErik Event event = iter.next(); 749458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden int newY = drawEvent(canvas, event, xSquare, yTest, rightEdge, iter.hasNext(), 750458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden showTimes, /*doDraw*/ false); 751458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (newY == yTest) { 752458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden showTimes = false; 753458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden break; 754458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } 755458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden yTest = newY; 756458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } 757458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden 758458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden int eventCount = 0; 759458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden iter = eventDay.iterator(); 760458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden while (iter.hasNext()) { 761458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden Event event = iter.next(); 762458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden int newY = drawEvent(canvas, event, xSquare, ySquare, rightEdge, iter.hasNext(), 763458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden showTimes, /*doDraw*/ true); 76440bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (newY == ySquare) { 76540bcd101b212c9863c3110c05a487a7ae6ebc3caErik break; 76640bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 76740bcd101b212c9863c3110c05a487a7ae6ebc3caErik eventCount++; 76840bcd101b212c9863c3110c05a487a7ae6ebc3caErik ySquare = newY; 76940bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 77040bcd101b212c9863c3110c05a487a7ae6ebc3caErik 77140bcd101b212c9863c3110c05a487a7ae6ebc3caErik int remaining = eventDay.size() - eventCount; 77240bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (remaining > 0) { 77340bcd101b212c9863c3110c05a487a7ae6ebc3caErik drawMoreEvents(canvas, remaining, xSquare); 77440bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 77540bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 77640bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 77740bcd101b212c9863c3110c05a487a7ae6ebc3caErik 778f445411ff661014c4b5a37e2f97552989e9278ecRoboErik protected int addChipOutline(FloatRef lines, int count, int x, int y) { 779f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.ensureSize(count + 16); 78040bcd101b212c9863c3110c05a487a7ae6ebc3caErik // top of box 781f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x; 782f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y; 783f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x + EVENT_SQUARE_WIDTH; 784f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y; 78540bcd101b212c9863c3110c05a487a7ae6ebc3caErik // right side of box 786f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x + EVENT_SQUARE_WIDTH; 787f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y; 788f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x + EVENT_SQUARE_WIDTH; 789f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y + EVENT_SQUARE_WIDTH; 79040bcd101b212c9863c3110c05a487a7ae6ebc3caErik // left side of box 791f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x; 792f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y; 793f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x; 794f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y + EVENT_SQUARE_WIDTH + 1; 79540bcd101b212c9863c3110c05a487a7ae6ebc3caErik // bottom of box 796f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x; 797f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y + EVENT_SQUARE_WIDTH; 7982fda24534978f55711526dbde747aa50d68dec40RoboErik lines.array[count++] = x + EVENT_SQUARE_WIDTH + 1; 799f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y + EVENT_SQUARE_WIDTH; 80040bcd101b212c9863c3110c05a487a7ae6ebc3caErik 80140bcd101b212c9863c3110c05a487a7ae6ebc3caErik return count; 80240bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 80340bcd101b212c9863c3110c05a487a7ae6ebc3caErik 80440bcd101b212c9863c3110c05a487a7ae6ebc3caErik /** 80540bcd101b212c9863c3110c05a487a7ae6ebc3caErik * Attempts to draw the given event. Returns the y for the next event or the 80640bcd101b212c9863c3110c05a487a7ae6ebc3caErik * original y if the event will not fit. An event is considered to not fit 80740bcd101b212c9863c3110c05a487a7ae6ebc3caErik * if the event and its extras won't fit or if there are more events and the 80840bcd101b212c9863c3110c05a487a7ae6ebc3caErik * more events line would not fit after drawing this event. 80940bcd101b212c9863c3110c05a487a7ae6ebc3caErik * 810458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * @param canvas the canvas to draw on 81140bcd101b212c9863c3110c05a487a7ae6ebc3caErik * @param event the event to draw 81240bcd101b212c9863c3110c05a487a7ae6ebc3caErik * @param x the top left corner for this event's color chip 81340bcd101b212c9863c3110c05a487a7ae6ebc3caErik * @param y the top left corner for this event's color chip 814458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * @param rightEdge the rightmost point we're allowed to draw on (exclusive) 815458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * @param moreEvents indicates whether additional events will follow this one 816458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * @param showTimes if set, a second line with a time range will be displayed for non-all-day 817458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * events 818458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * @param doDraw if set, do the actual drawing; otherwise this just computes the height 819458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * and returns 82040bcd101b212c9863c3110c05a487a7ae6ebc3caErik * @return the y for the next event or the original y if it won't fit 82140bcd101b212c9863c3110c05a487a7ae6ebc3caErik */ 822458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden protected int drawEvent(Canvas canvas, Event event, int x, int y, int rightEdge, 823458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden boolean moreEvents, boolean showTimes, boolean doDraw) { 82469f9b450fc255203b758f445163f371c22c816c0Andy McFadden /* 82569f9b450fc255203b758f445163f371c22c816c0Andy McFadden * Vertical layout: 82669f9b450fc255203b758f445163f371c22c816c0Andy McFadden * (top of box) 82769f9b450fc255203b758f445163f371c22c816c0Andy McFadden * a. EVENT_Y_OFFSET_LANDSCAPE or portrait equivalent 828458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * b. Event title: mEventHeight for a normal event, + 2xBORDER_SPACE for all-day event 82969f9b450fc255203b758f445163f371c22c816c0Andy McFadden * c. [optional] Time range (mExtrasHeight) 83069f9b450fc255203b758f445163f371c22c816c0Andy McFadden * d. EVENT_LINE_PADDING 83169f9b450fc255203b758f445163f371c22c816c0Andy McFadden * 83269f9b450fc255203b758f445163f371c22c816c0Andy McFadden * Repeat (b,c,d) as needed and space allows. If we have more events than fit, we need 83369f9b450fc255203b758f445163f371c22c816c0Andy McFadden * to leave room for something like "+2" at the bottom: 83469f9b450fc255203b758f445163f371c22c816c0Andy McFadden * 835458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden * e. "+ more" line (mExtrasHeight) 83669f9b450fc255203b758f445163f371c22c816c0Andy McFadden * 83769f9b450fc255203b758f445163f371c22c816c0Andy McFadden * f. EVENT_BOTTOM_PADDING (overlaps EVENT_LINE_PADDING) 83869f9b450fc255203b758f445163f371c22c816c0Andy McFadden * (bottom of box) 83969f9b450fc255203b758f445163f371c22c816c0Andy McFadden */ 840458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden final int BORDER_SPACE = EVENT_SQUARE_BORDER + 1; // want a 1-pixel gap inside border 841458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden final int STROKE_WIDTH_ADJ = EVENT_SQUARE_BORDER / 2; // adjust bounds for stroke width 842458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden boolean allDay = event.allDay; 843458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden int eventRequiredSpace = mEventHeight; 844458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (allDay) { 845458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // Add a few pixels for the box we draw around all-day events. 846458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden eventRequiredSpace += BORDER_SPACE * 2; 847458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } else if (showTimes) { 84869f9b450fc255203b758f445163f371c22c816c0Andy McFadden // Need room for the "1pm - 2pm" line. 849458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden eventRequiredSpace += mExtrasHeight; 85040bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 851458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden int reservedSpace = EVENT_BOTTOM_PADDING; // leave a bit of room at the bottom 85269f9b450fc255203b758f445163f371c22c816c0Andy McFadden if (moreEvents) { 853458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // More events follow. Leave a bit of space between events. 854458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden eventRequiredSpace += EVENT_LINE_PADDING; 855458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden 856458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // Make sure we have room for the "+ more" line. (The "+ more" line is expected 857458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // to be <= the height of an event line, so we won't show "+1" when we could be 858458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // showing the event.) 859458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden reservedSpace += mExtrasHeight; 86069f9b450fc255203b758f445163f371c22c816c0Andy McFadden } 86169f9b450fc255203b758f445163f371c22c816c0Andy McFadden 862458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (y + eventRequiredSpace + reservedSpace > mHeight) { 863458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // Not enough space, return original y 86440bcd101b212c9863c3110c05a487a7ae6ebc3caErik return y; 865458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } else if (!doDraw) { 866458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden return y + eventRequiredSpace; 86740bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 868458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden 869210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik boolean isDeclined = event.selfAttendeeStatus == Attendees.ATTENDEE_STATUS_DECLINED; 870210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik int color = event.color; 871210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik if (isDeclined) { 872210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik color = Utils.getDeclinedColorFromColor(color); 873210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik } 874458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden 875458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden int textX, textY, textRightEdge; 876458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden 877458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (allDay) { 878458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // We shift the render offset "inward", because drawRect with a stroke width greater 879458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // than 1 draws outside the specified bounds. (We don't adjust the left edge, since 880458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // we want to match the existing appearance of the "event square".) 881458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden r.left = x; 882458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden r.right = rightEdge - STROKE_WIDTH_ADJ; 883458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden r.top = y + STROKE_WIDTH_ADJ; 884458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden r.bottom = y + mEventHeight + BORDER_SPACE * 2 - STROKE_WIDTH_ADJ; 885458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textX = x + BORDER_SPACE; 886458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textY = y + mEventAscentHeight + BORDER_SPACE; 887458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textRightEdge = rightEdge - BORDER_SPACE; 888458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } else { 889458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden r.left = x; 890458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden r.right = x + EVENT_SQUARE_WIDTH; 891458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden r.bottom = y + mEventAscentHeight; 892458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden r.top = r.bottom - EVENT_SQUARE_WIDTH; 893458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textX = x + EVENT_SQUARE_WIDTH + EVENT_RIGHT_PADDING; 894458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textY = y + mEventAscentHeight; 895458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textRightEdge = rightEdge; 896458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } 897458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden 898458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden Style boxStyle = Style.STROKE; 899458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden boolean solidBackground = false; 900458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (event.selfAttendeeStatus != Attendees.ATTENDEE_STATUS_INVITED) { 901458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden boxStyle = Style.FILL_AND_STROKE; 902458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (allDay) { 903458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden solidBackground = true; 904458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } 905458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } 906458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden mEventSquarePaint.setStyle(boxStyle); 907210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik mEventSquarePaint.setColor(color); 908a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik canvas.drawRect(r, mEventSquarePaint); 90940bcd101b212c9863c3110c05a487a7ae6ebc3caErik 910458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden float avail = textRightEdge - textX; 91140bcd101b212c9863c3110c05a487a7ae6ebc3caErik CharSequence text = TextUtils.ellipsize( 91240bcd101b212c9863c3110c05a487a7ae6ebc3caErik event.title, mEventPaint, avail, TextUtils.TruncateAt.END); 913458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden Paint textPaint; 914458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (solidBackground) { 915458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // Text color needs to contrast with solid background. 916458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textPaint = mSolidBackgroundEventPaint; 917458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } else if (isDeclined) { 918458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // Use "declined event" color. 919458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textPaint = mDeclinedEventPaint; 920458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } else if (allDay) { 921458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // Text inside frame is same color as frame. 922458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden mFramedEventPaint.setColor(color); 923458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textPaint = mFramedEventPaint; 924458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } else { 925458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden // Use generic event text color. 926458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden textPaint = mEventPaint; 927458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } 928458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden canvas.drawText(text.toString(), textX, textY, textPaint); 92969f9b450fc255203b758f445163f371c22c816c0Andy McFadden y += mEventHeight; 930458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (allDay) { 931458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden y += BORDER_SPACE * 2; 932458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden } 93369f9b450fc255203b758f445163f371c22c816c0Andy McFadden 934458a67d9a63836b4b08b24d58f4a91514de97268Andy McFadden if (showTimes && !allDay) { 93569f9b450fc255203b758f445163f371c22c816c0Andy McFadden // show start/end time, e.g. "1pm - 2pm" 93669f9b450fc255203b758f445163f371c22c816c0Andy McFadden textY = y + mExtrasAscentHeight; 93740bcd101b212c9863c3110c05a487a7ae6ebc3caErik mStringBuilder.setLength(0); 9383f888688c0f2644ad3de032d5d1cf623a7b092fdAndy McFadden text = DateUtils.formatDateRange(getContext(), mFormatter, event.startMillis, 93940bcd101b212c9863c3110c05a487a7ae6ebc3caErik event.endMillis, DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, 9403f888688c0f2644ad3de032d5d1cf623a7b092fdAndy McFadden Utils.getTimeZone(getContext(), null)).toString(); 94140bcd101b212c9863c3110c05a487a7ae6ebc3caErik text = TextUtils.ellipsize(text, mEventExtrasPaint, avail, TextUtils.TruncateAt.END); 942210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik canvas.drawText(text.toString(), textX, textY, isDeclined ? mEventDeclinedExtrasPaint 943210642aa1f8bec18f7275cddb9a3b50fad3f4218RoboErik : mEventExtrasPaint); 94469f9b450fc255203b758f445163f371c22c816c0Andy McFadden y += mExtrasHeight; 94540bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 94640bcd101b212c9863c3110c05a487a7ae6ebc3caErik 94769f9b450fc255203b758f445163f371c22c816c0Andy McFadden y += EVENT_LINE_PADDING; 94869f9b450fc255203b758f445163f371c22c816c0Andy McFadden 94969f9b450fc255203b758f445163f371c22c816c0Andy McFadden return y; 95040bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 95140bcd101b212c9863c3110c05a487a7ae6ebc3caErik 95240bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected void drawMoreEvents(Canvas canvas, int remainingEvents, int x) { 95369f9b450fc255203b758f445163f371c22c816c0Andy McFadden int y = mHeight - (mExtrasDescent + EVENT_BOTTOM_PADDING); 9543f888688c0f2644ad3de032d5d1cf623a7b092fdAndy McFadden String text = getContext().getResources().getQuantityString( 95540bcd101b212c9863c3110c05a487a7ae6ebc3caErik R.plurals.month_more_events, remainingEvents); 956a74b9e2e0c7dce78cf7e343a30d34accea0891ccRoboErik mEventExtrasPaint.setAntiAlias(true); 95740bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventExtrasPaint.setFakeBoldText(true); 95840bcd101b212c9863c3110c05a487a7ae6ebc3caErik canvas.drawText(String.format(text, remainingEvents), x, y, mEventExtrasPaint); 95940bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventExtrasPaint.setFakeBoldText(false); 96040bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 96140bcd101b212c9863c3110c05a487a7ae6ebc3caErik 96271b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson /** 963092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik * Draws a line showing busy times in each day of week The method draws 964092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik * non-conflicting times in the event color and times with conflicting 965092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik * events in the dna conflict color defined in colors. 96671b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson * 96771b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson * @param canvas 96871b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson */ 969092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik protected void drawDNA(Canvas canvas) { 970092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Draw event and conflict times 971092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (mDna != null) { 972092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik for (Utils.DNAStrand strand : mDna.values()) { 973092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (strand.color == CONFLICT_COLOR || strand.points == null 974092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik || strand.points.length == 0) { 975092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik continue; 976092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 977092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setColor(strand.color); 978092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik canvas.drawLines(strand.points, mDNATimePaint); 979092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 980092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Draw black last to make sure it's on top 981092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik Utils.DNAStrand strand = mDna.get(CONFLICT_COLOR); 982092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (strand != null && strand.points != null && strand.points.length != 0) { 983092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setColor(strand.color); 984092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik canvas.drawLines(strand.points, mDNATimePaint); 98571b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson } 986092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (mDayXs == null) { 987092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik return; 988092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 989092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int numDays = mDayXs.length; 990092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int xOffset = (DNA_ALL_DAY_WIDTH - DNA_WIDTH) / 2; 991092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (strand != null && strand.allDays != null && strand.allDays.length == numDays) { 992092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik for (int i = 0; i < numDays; i++) { 993092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // this adds at most 7 draws. We could sort it by color and 994092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // build an array instead but this is easier. 995092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (strand.allDays[i] != 0) { 996092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setColor(strand.allDays[i]); 997092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik canvas.drawLine(mDayXs[i] + xOffset, DNA_MARGIN, mDayXs[i] + xOffset, 998092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_MARGIN + DNA_ALL_DAY_HEIGHT, mDNAAllDayPaint); 999092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 1000092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 100182400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson } 100282400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson } 100382400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson } 100482400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson 10053553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 10063553621c824afe1f3eacbe8555678005ca1264a1Erik protected void updateSelectionPositions() { 10073553621c824afe1f3eacbe8555678005ca1264a1Erik if (mHasSelectedDay) { 10083553621c824afe1f3eacbe8555678005ca1264a1Erik int selectedPosition = mSelectedDay - mWeekStart; 10093553621c824afe1f3eacbe8555678005ca1264a1Erik if (selectedPosition < 0) { 10103553621c824afe1f3eacbe8555678005ca1264a1Erik selectedPosition += 7; 10113553621c824afe1f3eacbe8555678005ca1264a1Erik } 10123553621c824afe1f3eacbe8555678005ca1264a1Erik int effectiveWidth = mWidth - mPadding * 2; 1013bf4aa400663a072813c87cf9c8aaee2d07abc945Erik effectiveWidth -= SPACING_WEEK_NUMBER; 10143553621c824afe1f3eacbe8555678005ca1264a1Erik mSelectedLeft = selectedPosition * effectiveWidth / mNumDays + mPadding; 10153553621c824afe1f3eacbe8555678005ca1264a1Erik mSelectedRight = (selectedPosition + 1) * effectiveWidth / mNumDays + mPadding; 1016bf4aa400663a072813c87cf9c8aaee2d07abc945Erik mSelectedLeft += SPACING_WEEK_NUMBER; 1017bf4aa400663a072813c87cf9c8aaee2d07abc945Erik mSelectedRight += SPACING_WEEK_NUMBER; 10183553621c824afe1f3eacbe8555678005ca1264a1Erik } 10193553621c824afe1f3eacbe8555678005ca1264a1Erik } 10203553621c824afe1f3eacbe8555678005ca1264a1Erik 102159a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson public int getDayIndexFromLocation(float x) { 1022da532a723613001f1175c067aece5f859d079bfcRoboErik int dayStart = mShowWeekNum ? SPACING_WEEK_NUMBER + mPadding : mPadding; 10233553621c824afe1f3eacbe8555678005ca1264a1Erik if (x < dayStart || x > mWidth - mPadding) { 102459a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson return -1; 10253553621c824afe1f3eacbe8555678005ca1264a1Erik } 10263553621c824afe1f3eacbe8555678005ca1264a1Erik // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels 102759a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson return ((int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding))); 102859a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson } 102959a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson 103059a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson @Override 103159a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson public Time getDayFromLocation(float x) { 103259a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson int dayPosition = getDayIndexFromLocation(x); 103359a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson if (dayPosition == -1) { 103459a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson return null; 103559a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson } 10363553621c824afe1f3eacbe8555678005ca1264a1Erik int day = mFirstJulianDay + dayPosition; 10373553621c824afe1f3eacbe8555678005ca1264a1Erik 10383553621c824afe1f3eacbe8555678005ca1264a1Erik Time time = new Time(mTimeZone); 10393553621c824afe1f3eacbe8555678005ca1264a1Erik if (mWeek == 0) { 10403553621c824afe1f3eacbe8555678005ca1264a1Erik // This week is weird... 10413553621c824afe1f3eacbe8555678005ca1264a1Erik if (day < Time.EPOCH_JULIAN_DAY) { 10423553621c824afe1f3eacbe8555678005ca1264a1Erik day++; 10433553621c824afe1f3eacbe8555678005ca1264a1Erik } else if (day == Time.EPOCH_JULIAN_DAY) { 10443553621c824afe1f3eacbe8555678005ca1264a1Erik time.set(1, 0, 1970); 10453553621c824afe1f3eacbe8555678005ca1264a1Erik time.normalize(true); 10463553621c824afe1f3eacbe8555678005ca1264a1Erik return time; 10473553621c824afe1f3eacbe8555678005ca1264a1Erik } 10483553621c824afe1f3eacbe8555678005ca1264a1Erik } 10493553621c824afe1f3eacbe8555678005ca1264a1Erik 10503553621c824afe1f3eacbe8555678005ca1264a1Erik time.setJulianDay(day); 10513553621c824afe1f3eacbe8555678005ca1264a1Erik return time; 105282b318634af1b6594e60cfd1f2df4d3845f80587Erik } 105382b318634af1b6594e60cfd1f2df4d3845f80587Erik 105467f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik @Override 105567f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik public boolean onHoverEvent(MotionEvent event) { 1056f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik Context context = getContext(); 1057f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik // only send accessibility events if accessibility and exploration are 1058f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik // on. 105993c08b7693d8246305c75dc2416f70321ce9c1a2RoboErik AccessibilityManager am = (AccessibilityManager) context 106093c08b7693d8246305c75dc2416f70321ce9c1a2RoboErik .getSystemService(Service.ACCESSIBILITY_SERVICE); 1061f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik if (!am.isEnabled() || !am.isTouchExplorationEnabled()) { 1062f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik return super.onHoverEvent(event); 1063f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik } 106467f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik if (event.getAction() != MotionEvent.ACTION_HOVER_EXIT) { 106567f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik Time hover = getDayFromLocation(event.getX()); 106667f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik if (hover != null 106767f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik && (mLastHoverTime == null || Time.compare(hover, mLastHoverTime) != 0)) { 106867f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik Long millis = hover.toMillis(true); 1069f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik String date = Utils.formatDateRange(context, millis, millis, 107067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik DateUtils.FORMAT_SHOW_DATE); 107167f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik AccessibilityEvent accessEvent = AccessibilityEvent 107267f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik .obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); 107367f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik accessEvent.getText().add(date); 1074044a43c3c1789ba93d83ae68d799d94dc4e4ecf2Michael Chan if (mShowDetailsInMonth && mEvents != null) { 107567f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik int dayStart = SPACING_WEEK_NUMBER + mPadding; 107667f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik int dayPosition = (int) ((event.getX() - dayStart) * mNumDays / (mWidth 107767f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik - dayStart - mPadding)); 107867f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik ArrayList<Event> events = mEvents.get(dayPosition); 107967f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik List<CharSequence> text = accessEvent.getText(); 108067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik for (Event e : events) { 108167f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik text.add(e.getTitleAndLocation() + ". "); 108267f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR; 108367f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik if (!e.allDay) { 108467f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik flags |= DateUtils.FORMAT_SHOW_TIME; 1085f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik if (DateFormat.is24HourFormat(context)) { 108667f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik flags |= DateUtils.FORMAT_24HOUR; 108767f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 1088aeebdbcf782a531bc972078cf05e70f21112ecafRoboErik } else { 1089aeebdbcf782a531bc972078cf05e70f21112ecafRoboErik flags |= DateUtils.FORMAT_UTC; 109067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 1091f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik text.add(Utils.formatDateRange(context, e.startMillis, e.endMillis, 109267f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik flags) + ". "); 109367f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 109467f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 109567f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik sendAccessibilityEventUnchecked(accessEvent); 109667f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik mLastHoverTime = hover; 109767f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 109867f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 109967f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik return true; 110067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 110159a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson 110259a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson public void setClickedDay(float xLocation) { 110359a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson mClickedDayIndex = getDayIndexFromLocation(xLocation); 110459a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson invalidate(); 110559a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson } 110659a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson public void clearClickedDay() { 110759a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson mClickedDayIndex = -1; 110859a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson invalidate(); 110959a44aa4bb3fac90f7ceab65da191e7fd81905f2Isaac Katzenelson } 111082b318634af1b6594e60cfd1f2df4d3845f80587Erik} 1111