MonthWeekEventsView.java revision da532a723613001f1175c067aece5f859d079bfc
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 23f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErikimport android.app.Service; 2482b318634af1b6594e60cfd1f2df4d3845f80587Erikimport android.content.Context; 253553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.content.res.Configuration; 263553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.content.res.Resources; 273553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.graphics.Canvas; 28092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErikimport android.graphics.Color; 293553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.graphics.Paint; 303553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.graphics.Paint.Align; 313553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.graphics.Paint.Style; 3240bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.graphics.Typeface; 3340bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.graphics.drawable.Drawable; 34a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErikimport android.provider.CalendarContract.Attendees; 3540bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.text.TextPaint; 3640bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.text.TextUtils; 3767f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErikimport android.text.format.DateFormat; 3840bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport android.text.format.DateUtils; 393553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.text.format.Time; 403553621c824afe1f3eacbe8555678005ca1264a1Erikimport android.util.Log; 4167f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErikimport android.view.MotionEvent; 4267f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErikimport android.view.accessibility.AccessibilityEvent; 43f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErikimport android.view.accessibility.AccessibilityManager; 443553621c824afe1f3eacbe8555678005ca1264a1Erik 453553621c824afe1f3eacbe8555678005ca1264a1Erikimport java.util.ArrayList; 46f445411ff661014c4b5a37e2f97552989e9278ecRoboErikimport java.util.Arrays; 4740bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport java.util.Formatter; 483553621c824afe1f3eacbe8555678005ca1264a1Erikimport java.util.HashMap; 4940bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport java.util.Iterator; 5040bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport java.util.List; 5140bcd101b212c9863c3110c05a487a7ae6ebc3caErikimport java.util.Locale; 5282b318634af1b6594e60cfd1f2df4d3845f80587Erik 53e21674aefc9755ba519dfc5b3ff4348be4814903Erikpublic class MonthWeekEventsView extends SimpleWeekView { 54092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 553553621c824afe1f3eacbe8555678005ca1264a1Erik private static final String TAG = "MonthView"; 563553621c824afe1f3eacbe8555678005ca1264a1Erik 573553621c824afe1f3eacbe8555678005ca1264a1Erik public static final String VIEW_PARAMS_ORIENTATION = "orientation"; 583553621c824afe1f3eacbe8555678005ca1264a1Erik 593553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_MONTH_NUMBER = 32; 603553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_EVENT = 14; 613553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_MORE_EVENTS = 12; 623553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_MONTH_NAME = 14; 633553621c824afe1f3eacbe8555678005ca1264a1Erik private static int TEXT_SIZE_WEEK_NUM = 12; 643553621c824afe1f3eacbe8555678005ca1264a1Erik 65092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_MARGIN = 4; 66092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_ALL_DAY_HEIGHT = 4; 67092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_MIN_SEGMENT_HEIGHT = 4; 68092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_WIDTH = 8; 69092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_ALL_DAY_WIDTH = 32; 70092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int DNA_SIDE_PADDING = 6; 71092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int CONFLICT_COLOR = Color.BLACK; 72092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 733bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static int DEFAULT_EDGE_SPACING = 0; 743bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static int SIDE_PADDING_MONTH_NUMBER = 4; 75763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik private static int TOP_PADDING_MONTH_NUMBER = 4; 76092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int TOP_PADDING_WEEK_NUMBER = 4; 77092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int SIDE_PADDING_WEEK_NUMBER = 20; 783bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static int DAY_SEPARATOR_OUTER_WIDTH = 0; 7940bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int DAY_SEPARATOR_INNER_WIDTH = 1; 8040bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int DAY_SEPARATOR_VERTICAL_LENGTH = 53; 8140bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int DAY_SEPARATOR_VERTICAL_LENGHT_PORTRAIT = 64; 82092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int MIN_WEEK_WIDTH = 50; 8340bcd101b212c9863c3110c05a487a7ae6ebc3caErik 84f658df6b9c285f24c45cdca3ab90f2ca65e5b7cfRoboErik private static int EVENT_X_OFFSET_LANDSCAPE = 38; 8540bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int EVENT_Y_OFFSET_LANDSCAPE = 11; 863bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static int EVENT_Y_OFFSET_PORTRAIT = 16; 8740bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int EVENT_SQUARE_WIDTH = 10; 88a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik private static int EVENT_SQUARE_BORDER = 2; 8940bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int EVENT_LINE_PADDING = 4; 9040bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static int EVENT_RIGHT_PADDING = 4; 91f658df6b9c285f24c45cdca3ab90f2ca65e5b7cfRoboErik private static int EVENT_BOTTOM_PADDING = 8; 923553621c824afe1f3eacbe8555678005ca1264a1Erik 9382400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson 94092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private static int SPACING_WEEK_NUMBER = 24; 9540bcd101b212c9863c3110c05a487a7ae6ebc3caErik private static boolean mScaled = false; 963bff945d29d6ef277391745cd160f3bf16b98905RoboErik private static boolean mShowDetailsInMonth; 973553621c824afe1f3eacbe8555678005ca1264a1Erik 983553621c824afe1f3eacbe8555678005ca1264a1Erik protected Time mToday = new Time(); 993553621c824afe1f3eacbe8555678005ca1264a1Erik protected boolean mHasToday = false; 1003553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mTodayIndex = -1; 1013553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mOrientation = Configuration.ORIENTATION_LANDSCAPE; 10240bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected List<ArrayList<Event>> mEvents = null; 103092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik HashMap<Integer, Utils.DNAStrand> mDna = null; 104f445411ff661014c4b5a37e2f97552989e9278ecRoboErik // This is for drawing the outlines around event chips and supports up to 10 105f445411ff661014c4b5a37e2f97552989e9278ecRoboErik // events being drawn on each day. The code will expand this if necessary. 106f445411ff661014c4b5a37e2f97552989e9278ecRoboErik protected FloatRef mEventOutlines = new FloatRef(10 * 4 * 4 * 7); 10740bcd101b212c9863c3110c05a487a7ae6ebc3caErik 10871b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson 10971b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson 11040bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected static StringBuilder mStringBuilder = new StringBuilder(50); 11140bcd101b212c9863c3110c05a487a7ae6ebc3caErik // TODO recreate formatter when locale changes 11240bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected static Formatter mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); 1133553621c824afe1f3eacbe8555678005ca1264a1Erik 1143553621c824afe1f3eacbe8555678005ca1264a1Erik protected Paint mMonthNamePaint; 11540bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected TextPaint mEventPaint; 11640bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected TextPaint mEventExtrasPaint; 1173553621c824afe1f3eacbe8555678005ca1264a1Erik protected Paint mWeekNumPaint; 118092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik protected Paint mDNAAllDayPaint; 119092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik protected Paint mDNATimePaint; 120a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik protected Paint mEventSquarePaint; 12171b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson 1223553621c824afe1f3eacbe8555678005ca1264a1Erik 12340bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected Drawable mTodayDrawable; 12440bcd101b212c9863c3110c05a487a7ae6ebc3caErik 1253553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNumHeight; 1263553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mEventHeight; 1273553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mExtrasHeight; 1283553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mWeekNumHeight; 1293553621c824afe1f3eacbe8555678005ca1264a1Erik 13067d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik protected int mMonthBGColor; 13167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik protected int mMonthBGOtherColor; 13267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik protected int mMonthBGTodayColor; 1333553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNumColor; 1343553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNumOtherColor; 1353553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNumTodayColor; 1363553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNameColor; 1373553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthNameOtherColor; 1383553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthEventColor; 1393553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthEventExtraColor; 1403553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthEventOtherColor; 1413553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthEventExtraOtherColor; 1423553621c824afe1f3eacbe8555678005ca1264a1Erik protected int mMonthWeekNumColor; 14382400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson protected int mMonthBusyBitsBgColor; 14471b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson protected int mMonthBusyBitsBusyTimeColor; 14571b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson protected int mMonthBusyBitsConflictTimeColor; 14682b318634af1b6594e60cfd1f2df4d3845f80587Erik 14740bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected int mEventChipOutlineColor = 0xFFFFFFFF; 148e9baa2499d9592343e30c983116e3f8dc921d3b0RoboErik protected int mDaySeparatorInnerColor; 14940bcd101b212c9863c3110c05a487a7ae6ebc3caErik 150092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private int[] mDayXs; 15182400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson 15282b318634af1b6594e60cfd1f2df4d3845f80587Erik /** 153f445411ff661014c4b5a37e2f97552989e9278ecRoboErik * This provides a reference to a float array which allows for easy size 154f445411ff661014c4b5a37e2f97552989e9278ecRoboErik * checking and reallocation. Used for drawing lines. 155f445411ff661014c4b5a37e2f97552989e9278ecRoboErik */ 156f445411ff661014c4b5a37e2f97552989e9278ecRoboErik private class FloatRef { 157f445411ff661014c4b5a37e2f97552989e9278ecRoboErik float[] array; 158f445411ff661014c4b5a37e2f97552989e9278ecRoboErik 159f445411ff661014c4b5a37e2f97552989e9278ecRoboErik public FloatRef(int size) { 160f445411ff661014c4b5a37e2f97552989e9278ecRoboErik array = new float[size]; 161f445411ff661014c4b5a37e2f97552989e9278ecRoboErik } 162f445411ff661014c4b5a37e2f97552989e9278ecRoboErik 163f445411ff661014c4b5a37e2f97552989e9278ecRoboErik public void ensureSize(int newSize) { 164f445411ff661014c4b5a37e2f97552989e9278ecRoboErik if (newSize >= array.length) { 165f445411ff661014c4b5a37e2f97552989e9278ecRoboErik // Add enough space for 7 more boxes to be drawn 166f445411ff661014c4b5a37e2f97552989e9278ecRoboErik array = Arrays.copyOf(array, newSize + 16 * 7); 167f445411ff661014c4b5a37e2f97552989e9278ecRoboErik } 168f445411ff661014c4b5a37e2f97552989e9278ecRoboErik } 169f445411ff661014c4b5a37e2f97552989e9278ecRoboErik } 170f445411ff661014c4b5a37e2f97552989e9278ecRoboErik 17182400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson 172f445411ff661014c4b5a37e2f97552989e9278ecRoboErik /** 17382b318634af1b6594e60cfd1f2df4d3845f80587Erik * @param context 17482b318634af1b6594e60cfd1f2df4d3845f80587Erik */ 17582b318634af1b6594e60cfd1f2df4d3845f80587Erik public MonthWeekEventsView(Context context) { 17682b318634af1b6594e60cfd1f2df4d3845f80587Erik super(context); 177092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 178092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 179092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Sets the list of events for this week. Takes a sorted list of arrays 180092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // divided up by day for generating the large month version and the full 181092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // arraylist sorted by start time to generate the dna version. 182092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik public void setEvents(List<ArrayList<Event>> sortedEvents, ArrayList<Event> unsortedEvents) { 183092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik setEvents(sortedEvents); 184092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // The MIN_WEEK_WIDTH is a hack to prevent the view from trying to 185092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // generate dna bits before its width has been fixed. 1867d66103066f04ba2b7c4ddfcfdafd0368ad9d9cbAndy McFadden if (unsortedEvents == null || mWidth <= MIN_WEEK_WIDTH || getContext() == null) { 187092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDna = null; 188092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik return; 189092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 190092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Create the drawing coordinates for dna 191092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (!mShowDetailsInMonth) { 192092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int numDays = mEvents.size(); 193763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik int effectiveWidth = mWidth - mPadding * 2; 194763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik if (mShowWeekNum) { 195763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik effectiveWidth -= SPACING_WEEK_NUMBER; 196763b9308fa13c8c9c3b9a715f4daf8eba497b935RoboErik } 197092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_ALL_DAY_WIDTH = effectiveWidth / numDays - 2 * DNA_SIDE_PADDING; 198092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setStrokeWidth(DNA_ALL_DAY_WIDTH); 199092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDayXs = new int[numDays]; 200092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik for (int day = 0; day < numDays; day++) { 201092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDayXs[day] = computeDayLeftPosition(day) + DNA_WIDTH / 2 + DNA_SIDE_PADDING; 202092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 203092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 204092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 205092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int top = DAY_SEPARATOR_INNER_WIDTH + DNA_MARGIN + DNA_ALL_DAY_HEIGHT + 1; 206092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int bottom = mHeight - DNA_MARGIN; 207092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDna = Utils.createDNAStrands(mFirstJulianDay, unsortedEvents, top, bottom, 2087d66103066f04ba2b7c4ddfcfdafd0368ad9d9cbAndy McFadden DNA_MIN_SEGMENT_HEIGHT, mDayXs, getContext()); 209092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 2103553621c824afe1f3eacbe8555678005ca1264a1Erik } 2113553621c824afe1f3eacbe8555678005ca1264a1Erik 21240bcd101b212c9863c3110c05a487a7ae6ebc3caErik public void setEvents(List<ArrayList<Event>> sortedEvents) { 2133553621c824afe1f3eacbe8555678005ca1264a1Erik mEvents = sortedEvents; 2143553621c824afe1f3eacbe8555678005ca1264a1Erik if (sortedEvents == null) { 2153553621c824afe1f3eacbe8555678005ca1264a1Erik return; 2163553621c824afe1f3eacbe8555678005ca1264a1Erik } 2173553621c824afe1f3eacbe8555678005ca1264a1Erik if (sortedEvents.size() != mNumDays) { 2183553621c824afe1f3eacbe8555678005ca1264a1Erik if (Log.isLoggable(TAG, Log.ERROR)) { 2193553621c824afe1f3eacbe8555678005ca1264a1Erik Log.wtf(TAG, "Events size must be same as days displayed: size=" 2203553621c824afe1f3eacbe8555678005ca1264a1Erik + sortedEvents.size() + " days=" + mNumDays); 2213553621c824afe1f3eacbe8555678005ca1264a1Erik } 2223553621c824afe1f3eacbe8555678005ca1264a1Erik mEvents = null; 2233553621c824afe1f3eacbe8555678005ca1264a1Erik return; 2243553621c824afe1f3eacbe8555678005ca1264a1Erik } 2253553621c824afe1f3eacbe8555678005ca1264a1Erik } 2263553621c824afe1f3eacbe8555678005ca1264a1Erik 2273553621c824afe1f3eacbe8555678005ca1264a1Erik protected void loadColors(Context context) { 2283553621c824afe1f3eacbe8555678005ca1264a1Erik Resources res = context.getResources(); 2293553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthWeekNumColor = res.getColor(R.color.month_week_num_color); 2303553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumColor = res.getColor(R.color.month_day_number); 2313553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumOtherColor = res.getColor(R.color.month_day_number_other); 2323553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumTodayColor = res.getColor(R.color.month_today_number); 2333553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNameColor = mMonthNumColor; 2343553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNameOtherColor = mMonthNumOtherColor; 2353553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthEventColor = res.getColor(R.color.month_event_color); 2363553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthEventExtraColor = res.getColor(R.color.month_event_extra_color); 2373553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthEventOtherColor = res.getColor(R.color.month_event_other_color); 2383553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthEventExtraOtherColor = res.getColor(R.color.month_event_extra_other_color); 23967d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthBGTodayColor = res.getColor(R.color.month_today_bgcolor); 24067d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthBGOtherColor = res.getColor(R.color.month_other_bgcolor); 24167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthBGColor = res.getColor(R.color.month_bgcolor); 242e9baa2499d9592343e30c983116e3f8dc921d3b0RoboErik mDaySeparatorInnerColor = res.getColor(R.color.month_grid_lines); 24340bcd101b212c9863c3110c05a487a7ae6ebc3caErik 24440bcd101b212c9863c3110c05a487a7ae6ebc3caErik mTodayDrawable = res.getDrawable(R.drawable.today_blue_week_holo_light); 2453553621c824afe1f3eacbe8555678005ca1264a1Erik } 2463553621c824afe1f3eacbe8555678005ca1264a1Erik 2473553621c824afe1f3eacbe8555678005ca1264a1Erik /** 2483553621c824afe1f3eacbe8555678005ca1264a1Erik * Sets up the text and style properties for painting. Override this if you 2493553621c824afe1f3eacbe8555678005ca1264a1Erik * want to use a different paint. 2503553621c824afe1f3eacbe8555678005ca1264a1Erik */ 2513553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 2527203d809b39fb07caab177d8e8bd9428097b73b6Erik protected void initView() { 2537203d809b39fb07caab177d8e8bd9428097b73b6Erik super.initView(); 2547203d809b39fb07caab177d8e8bd9428097b73b6Erik 2553bff945d29d6ef277391745cd160f3bf16b98905RoboErik if (!mScaled) { 2563bff945d29d6ef277391745cd160f3bf16b98905RoboErik Resources resources = getContext().getResources(); 2577d66103066f04ba2b7c4ddfcfdafd0368ad9d9cbAndy McFadden mShowDetailsInMonth = Utils.getConfigBool(getContext(), R.bool.show_details_in_month); 2583bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_MONTH_NUMBER = resources.getInteger(R.integer.text_size_month_number); 2593bff945d29d6ef277391745cd160f3bf16b98905RoboErik SIDE_PADDING_MONTH_NUMBER = resources.getInteger(R.integer.month_day_number_margin); 260092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik CONFLICT_COLOR = resources.getColor(R.color.month_dna_conflict_time_color); 2613bff945d29d6ef277391745cd160f3bf16b98905RoboErik if (mScale != 1) { 2623bff945d29d6ef277391745cd160f3bf16b98905RoboErik TOP_PADDING_MONTH_NUMBER *= mScale; 263092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik TOP_PADDING_WEEK_NUMBER *= mScale; 2643bff945d29d6ef277391745cd160f3bf16b98905RoboErik SIDE_PADDING_MONTH_NUMBER *= mScale; 2653bff945d29d6ef277391745cd160f3bf16b98905RoboErik SIDE_PADDING_WEEK_NUMBER *= mScale; 2663bff945d29d6ef277391745cd160f3bf16b98905RoboErik SPACING_WEEK_NUMBER *= mScale; 2673bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_MONTH_NUMBER *= mScale; 2683bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_EVENT *= mScale; 2693bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_MORE_EVENTS *= mScale; 2703bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_MONTH_NAME *= mScale; 2713bff945d29d6ef277391745cd160f3bf16b98905RoboErik TEXT_SIZE_WEEK_NUM *= mScale; 2723bff945d29d6ef277391745cd160f3bf16b98905RoboErik DAY_SEPARATOR_OUTER_WIDTH *= mScale; 2733bff945d29d6ef277391745cd160f3bf16b98905RoboErik DAY_SEPARATOR_INNER_WIDTH *= mScale; 2743bff945d29d6ef277391745cd160f3bf16b98905RoboErik DAY_SEPARATOR_VERTICAL_LENGTH *= mScale; 2753bff945d29d6ef277391745cd160f3bf16b98905RoboErik DAY_SEPARATOR_VERTICAL_LENGHT_PORTRAIT *= mScale; 2763bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_X_OFFSET_LANDSCAPE *= mScale; 2773bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_Y_OFFSET_LANDSCAPE *= mScale; 2783bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_Y_OFFSET_PORTRAIT *= mScale; 2793bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_SQUARE_WIDTH *= mScale; 280a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik EVENT_SQUARE_BORDER *= mScale; 2813bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_LINE_PADDING *= mScale; 2823bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_BOTTOM_PADDING *= mScale; 2833bff945d29d6ef277391745cd160f3bf16b98905RoboErik EVENT_RIGHT_PADDING *= mScale; 284092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_MARGIN *= mScale; 285092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_WIDTH *= mScale; 286092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_ALL_DAY_HEIGHT *= mScale; 287092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_MIN_SEGMENT_HEIGHT *= mScale; 288092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_SIDE_PADDING *= mScale; 2893bff945d29d6ef277391745cd160f3bf16b98905RoboErik DEFAULT_EDGE_SPACING *= mScale; 290092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_ALL_DAY_WIDTH *= mScale; 291092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 292092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (!mShowDetailsInMonth) { 293092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik TOP_PADDING_MONTH_NUMBER += DNA_ALL_DAY_HEIGHT + DNA_MARGIN; 2943bff945d29d6ef277391745cd160f3bf16b98905RoboErik } 2957203d809b39fb07caab177d8e8bd9428097b73b6Erik mScaled = true; 2967203d809b39fb07caab177d8e8bd9428097b73b6Erik } 2973bff945d29d6ef277391745cd160f3bf16b98905RoboErik mPadding = DEFAULT_EDGE_SPACING; 2983f888688c0f2644ad3de032d5d1cf623a7b092fdAndy McFadden loadColors(getContext()); 2993553621c824afe1f3eacbe8555678005ca1264a1Erik // TODO modify paint properties depending on isMini 3003553621c824afe1f3eacbe8555678005ca1264a1Erik 3013553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint = new Paint(); 30240bcd101b212c9863c3110c05a487a7ae6ebc3caErik mMonthNumPaint.setFakeBoldText(false); 3033553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setAntiAlias(true); 3043553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setTextSize(TEXT_SIZE_MONTH_NUMBER); 3053553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setColor(mMonthNumColor); 3063553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setStyle(Style.FILL); 307a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mMonthNumPaint.setTextAlign(Align.RIGHT); 30864d67bea6bdb8516c1685b0bb19bc217c3cbe14eRoboErik mMonthNumPaint.setTypeface(Typeface.DEFAULT); 3093553621c824afe1f3eacbe8555678005ca1264a1Erik 3103553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumHeight = (int) (-mMonthNumPaint.ascent()); 3113553621c824afe1f3eacbe8555678005ca1264a1Erik 31240bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventPaint = new TextPaint(); 313f658df6b9c285f24c45cdca3ab90f2ca65e5b7cfRoboErik mEventPaint.setFakeBoldText(true); 3143553621c824afe1f3eacbe8555678005ca1264a1Erik mEventPaint.setAntiAlias(true); 3153553621c824afe1f3eacbe8555678005ca1264a1Erik mEventPaint.setTextSize(TEXT_SIZE_EVENT); 3163553621c824afe1f3eacbe8555678005ca1264a1Erik mEventPaint.setColor(mMonthEventColor); 3173553621c824afe1f3eacbe8555678005ca1264a1Erik 3183553621c824afe1f3eacbe8555678005ca1264a1Erik mEventHeight = (int) (-mEventPaint.ascent()); 3193553621c824afe1f3eacbe8555678005ca1264a1Erik 32040bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventExtrasPaint = new TextPaint(); 3213553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setFakeBoldText(false); 3223553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setAntiAlias(true); 32340bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventExtrasPaint.setStrokeWidth(EVENT_SQUARE_BORDER); 3243553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setTextSize(TEXT_SIZE_EVENT); 3253553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setColor(mMonthEventExtraColor); 3263553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setStyle(Style.FILL); 3273553621c824afe1f3eacbe8555678005ca1264a1Erik mEventExtrasPaint.setTextAlign(Align.LEFT); 3283553621c824afe1f3eacbe8555678005ca1264a1Erik 3293553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint = new Paint(); 3303553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setFakeBoldText(false); 3313553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setAntiAlias(true); 3323553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setTextSize(TEXT_SIZE_WEEK_NUM); 3333553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setColor(mWeekNumColor); 3343553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setStyle(Style.FILL); 3353553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumPaint.setTextAlign(Align.RIGHT); 3363553621c824afe1f3eacbe8555678005ca1264a1Erik 3373553621c824afe1f3eacbe8555678005ca1264a1Erik mWeekNumHeight = (int) (-mWeekNumPaint.ascent()); 33871b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson 339092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint = new Paint(); 340092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint = new Paint(); 341092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setColor(mMonthBusyBitsBusyTimeColor); 342092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setStyle(Style.FILL_AND_STROKE); 343092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setStrokeWidth(DNA_WIDTH); 344092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setAntiAlias(false); 345092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setColor(mMonthBusyBitsConflictTimeColor); 346092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setStyle(Style.FILL_AND_STROKE); 347092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setStrokeWidth(DNA_ALL_DAY_WIDTH); 348092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setAntiAlias(false); 349a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik 350a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint = new Paint(); 351a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint.setStrokeWidth(EVENT_SQUARE_BORDER); 352a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint.setAntiAlias(false); 3533553621c824afe1f3eacbe8555678005ca1264a1Erik } 3543553621c824afe1f3eacbe8555678005ca1264a1Erik 3553553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 3563553621c824afe1f3eacbe8555678005ca1264a1Erik public void setWeekParams(HashMap<String, Integer> params, String tz) { 3573553621c824afe1f3eacbe8555678005ca1264a1Erik super.setWeekParams(params, tz); 3583553621c824afe1f3eacbe8555678005ca1264a1Erik 35940bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (params.containsKey(VIEW_PARAMS_ORIENTATION)) { 36040bcd101b212c9863c3110c05a487a7ae6ebc3caErik mOrientation = params.get(VIEW_PARAMS_ORIENTATION); 36140bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 36240bcd101b212c9863c3110c05a487a7ae6ebc3caErik 3633553621c824afe1f3eacbe8555678005ca1264a1Erik mToday.timezone = tz; 3643553621c824afe1f3eacbe8555678005ca1264a1Erik mToday.setToNow(); 3653553621c824afe1f3eacbe8555678005ca1264a1Erik mToday.normalize(true); 3663553621c824afe1f3eacbe8555678005ca1264a1Erik int julianToday = Time.getJulianDay(mToday.toMillis(false), mToday.gmtoff); 3673553621c824afe1f3eacbe8555678005ca1264a1Erik if (julianToday >= mFirstJulianDay && julianToday < mFirstJulianDay + mNumDays) { 3683553621c824afe1f3eacbe8555678005ca1264a1Erik mHasToday = true; 3693553621c824afe1f3eacbe8555678005ca1264a1Erik mTodayIndex = julianToday - mFirstJulianDay; 3703553621c824afe1f3eacbe8555678005ca1264a1Erik } else { 3713553621c824afe1f3eacbe8555678005ca1264a1Erik mHasToday = false; 3723553621c824afe1f3eacbe8555678005ca1264a1Erik mTodayIndex = -1; 3733553621c824afe1f3eacbe8555678005ca1264a1Erik } 374ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik mNumCells = mNumDays + 1; 3753553621c824afe1f3eacbe8555678005ca1264a1Erik } 3763553621c824afe1f3eacbe8555678005ca1264a1Erik 3773553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 37840bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected void onDraw(Canvas canvas) { 37940bcd101b212c9863c3110c05a487a7ae6ebc3caErik drawBackground(canvas); 38040bcd101b212c9863c3110c05a487a7ae6ebc3caErik drawWeekNums(canvas); 38140bcd101b212c9863c3110c05a487a7ae6ebc3caErik drawDaySeparators(canvas); 382ff5c4345f794ec12b0a92f284434ddc1c88ff3a8Isaac Katzenelson if (mShowDetailsInMonth) { 38396a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson drawEvents(canvas); 38482400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson } else { 385092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik drawDNA(canvas); 386092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 387092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 388092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 389092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // TODO move into SimpleWeekView 390092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Computes the x position for the left side of the given day 391092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik private int computeDayLeftPosition(int day) { 392092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int effectiveWidth = mWidth; 393092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int x = 0; 394092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int xOffset = 0; 395092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (mShowWeekNum) { 396092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik xOffset = SPACING_WEEK_NUMBER + mPadding; 397092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik effectiveWidth -= xOffset; 39896a0b5436f79157e8175b3b761fd5ccfe26a7f62Isaac Katzenelson } 399092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik x = day * effectiveWidth / mNumDays + xOffset; 400092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik return x; 40140bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 40240bcd101b212c9863c3110c05a487a7ae6ebc3caErik 40340bcd101b212c9863c3110c05a487a7ae6ebc3caErik @Override 40440bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected void drawDaySeparators(Canvas canvas) { 40540bcd101b212c9863c3110c05a487a7ae6ebc3caErik float lines[] = new float[8 * 4]; 406092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int count = 6 * 4; 40740bcd101b212c9863c3110c05a487a7ae6ebc3caErik int wkNumOffset = 0; 408092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int i = 0; 409092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (mShowWeekNum) { 410092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // This adds the first line separating the week number 411092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int xOffset = SPACING_WEEK_NUMBER + mPadding; 412092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik count += 4; 413092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = xOffset; 414092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = 0; 415092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = xOffset; 416092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = mHeight; 417092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik wkNumOffset++; 418092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 419bf4aa400663a072813c87cf9c8aaee2d07abc945Erik count += 4; 420092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = 0; 421092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = 0; 422092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = mWidth; 423092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik lines[i++] = 0; 4243bff945d29d6ef277391745cd160f3bf16b98905RoboErik int y0 = 0; 4253bff945d29d6ef277391745cd160f3bf16b98905RoboErik int y1 = mHeight; 42640bcd101b212c9863c3110c05a487a7ae6ebc3caErik 427092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik while (i < count) { 428092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int x = computeDayLeftPosition(i / 4 - wkNumOffset); 42940bcd101b212c9863c3110c05a487a7ae6ebc3caErik lines[i++] = x; 43040bcd101b212c9863c3110c05a487a7ae6ebc3caErik lines[i++] = y0; 43140bcd101b212c9863c3110c05a487a7ae6ebc3caErik lines[i++] = x; 43240bcd101b212c9863c3110c05a487a7ae6ebc3caErik lines[i++] = y1; 43340bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 43440bcd101b212c9863c3110c05a487a7ae6ebc3caErik p.setColor(mDaySeparatorInnerColor); 43540bcd101b212c9863c3110c05a487a7ae6ebc3caErik p.setStrokeWidth(DAY_SEPARATOR_INNER_WIDTH); 43640bcd101b212c9863c3110c05a487a7ae6ebc3caErik canvas.drawLines(lines, 0, count, p); 43740bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 43840bcd101b212c9863c3110c05a487a7ae6ebc3caErik 43940bcd101b212c9863c3110c05a487a7ae6ebc3caErik @Override 4403553621c824afe1f3eacbe8555678005ca1264a1Erik protected void drawBackground(Canvas canvas) { 44167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik int i = 0; 44267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik int offset = 0; 443092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik r.top = DAY_SEPARATOR_INNER_WIDTH; 4443553621c824afe1f3eacbe8555678005ca1264a1Erik r.bottom = mHeight; 44567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik if (mShowWeekNum) { 44667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik i++; 44767d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik offset++; 44867d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik } 449e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik if (!mFocusDay[i]) { 450e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik while (++i < mFocusDay.length && !mFocusDay[i]) 45167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik ; 45267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.right = computeDayLeftPosition(i - offset); 45367d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.left = 0; 454e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik p.setColor(mMonthBGOtherColor); 45567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik canvas.drawRect(r, p); 45667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik // compute left edge for i, set up r, draw 457e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik } else if (!mFocusDay[(i = mFocusDay.length - 1)]) { 458e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik while (--i >= offset && !mFocusDay[i]) 45967d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik ; 46067d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik i++; 46167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik // compute left edge for i, set up r, draw 46267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.right = mWidth; 46367d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.left = computeDayLeftPosition(i - offset); 464e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik p.setColor(mMonthBGOtherColor); 46567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik canvas.drawRect(r, p); 46667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik } 46767d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik if (mHasToday) { 46867d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik p.setColor(mMonthBGTodayColor); 46967d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.left = computeDayLeftPosition(mTodayIndex); 47067d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik r.right = computeDayLeftPosition(mTodayIndex + 1); 47167d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik canvas.drawRect(r, p); 47267d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik } 4733553621c824afe1f3eacbe8555678005ca1264a1Erik } 4743553621c824afe1f3eacbe8555678005ca1264a1Erik 4753553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 4763553621c824afe1f3eacbe8555678005ca1264a1Erik protected void drawWeekNums(Canvas canvas) { 477bf4aa400663a072813c87cf9c8aaee2d07abc945Erik int y; 4783553621c824afe1f3eacbe8555678005ca1264a1Erik 4793553621c824afe1f3eacbe8555678005ca1264a1Erik int i = 0; 480a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik int offset = -1; 4813553621c824afe1f3eacbe8555678005ca1264a1Erik int todayIndex = mTodayIndex; 482092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int x = 0; 483ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik int numCount = mNumDays; 4843553621c824afe1f3eacbe8555678005ca1264a1Erik if (mShowWeekNum) { 485092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik x = SIDE_PADDING_WEEK_NUMBER + mPadding; 486092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik y = mWeekNumHeight + TOP_PADDING_WEEK_NUMBER; 4873553621c824afe1f3eacbe8555678005ca1264a1Erik canvas.drawText(mDayNumbers[0], x, y, mWeekNumPaint); 488ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik numCount++; 489ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik i++; 490ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik todayIndex++; 491ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik offset++; 492092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik 4933553621c824afe1f3eacbe8555678005ca1264a1Erik } 4943553621c824afe1f3eacbe8555678005ca1264a1Erik 4953bff945d29d6ef277391745cd160f3bf16b98905RoboErik y = (mMonthNumHeight + TOP_PADDING_MONTH_NUMBER); 4963553621c824afe1f3eacbe8555678005ca1264a1Erik 4973553621c824afe1f3eacbe8555678005ca1264a1Erik boolean isFocusMonth = mFocusDay[i]; 49867d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik boolean isBold = false; 4993553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setColor(isFocusMonth ? mMonthNumColor : mMonthNumOtherColor); 500ef896fda8812d5f31aa87e8e1525d6f9d8b61e9cErik for (; i < numCount; i++) { 5013553621c824afe1f3eacbe8555678005ca1264a1Erik if (mHasToday && todayIndex == i) { 5023553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setColor(mMonthNumTodayColor); 50367d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthNumPaint.setFakeBoldText(isBold = true); 504259b8f9a21fffd3858218581e9daaf689b6b888fErik if (i + 1 < numCount) { 5053553621c824afe1f3eacbe8555678005ca1264a1Erik // Make sure the color will be set back on the next 5063553621c824afe1f3eacbe8555678005ca1264a1Erik // iteration 5073553621c824afe1f3eacbe8555678005ca1264a1Erik isFocusMonth = !mFocusDay[i + 1]; 5083553621c824afe1f3eacbe8555678005ca1264a1Erik } 5093553621c824afe1f3eacbe8555678005ca1264a1Erik } else if (mFocusDay[i] != isFocusMonth) { 5103553621c824afe1f3eacbe8555678005ca1264a1Erik isFocusMonth = mFocusDay[i]; 5113553621c824afe1f3eacbe8555678005ca1264a1Erik mMonthNumPaint.setColor(isFocusMonth ? mMonthNumColor : mMonthNumOtherColor); 5123553621c824afe1f3eacbe8555678005ca1264a1Erik } 513a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik x = computeDayLeftPosition(i - offset) - (SIDE_PADDING_MONTH_NUMBER); 5143553621c824afe1f3eacbe8555678005ca1264a1Erik canvas.drawText(mDayNumbers[i], x, y, mMonthNumPaint); 51567d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik if (isBold) { 51667d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik mMonthNumPaint.setFakeBoldText(isBold = false); 51767d628eaed439a4b109e5e35f2d536c99680aaf6RoboErik } 5183553621c824afe1f3eacbe8555678005ca1264a1Erik } 5193553621c824afe1f3eacbe8555678005ca1264a1Erik } 5203553621c824afe1f3eacbe8555678005ca1264a1Erik 52140bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected void drawEvents(Canvas canvas) { 52240bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (mEvents == null) { 52340bcd101b212c9863c3110c05a487a7ae6ebc3caErik return; 52440bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 52540bcd101b212c9863c3110c05a487a7ae6ebc3caErik 52640bcd101b212c9863c3110c05a487a7ae6ebc3caErik int day = -1; 52740bcd101b212c9863c3110c05a487a7ae6ebc3caErik for (ArrayList<Event> eventDay : mEvents) { 52840bcd101b212c9863c3110c05a487a7ae6ebc3caErik day++; 52940bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (eventDay == null || eventDay.size() == 0) { 53040bcd101b212c9863c3110c05a487a7ae6ebc3caErik continue; 53140bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 53240bcd101b212c9863c3110c05a487a7ae6ebc3caErik int ySquare; 533a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik int xSquare = computeDayLeftPosition(day) + SIDE_PADDING_MONTH_NUMBER + 1; 534a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik int rightEdge = computeDayLeftPosition(day + 1); 535a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik 53640bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (mOrientation == Configuration.ORIENTATION_PORTRAIT) { 5373bff945d29d6ef277391745cd160f3bf16b98905RoboErik ySquare = EVENT_Y_OFFSET_PORTRAIT + mMonthNumHeight + TOP_PADDING_MONTH_NUMBER; 538a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik rightEdge -= SIDE_PADDING_MONTH_NUMBER + 1; 53940bcd101b212c9863c3110c05a487a7ae6ebc3caErik } else { 54040bcd101b212c9863c3110c05a487a7ae6ebc3caErik ySquare = EVENT_Y_OFFSET_LANDSCAPE; 541a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik rightEdge -= EVENT_X_OFFSET_LANDSCAPE; 54240bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 54340bcd101b212c9863c3110c05a487a7ae6ebc3caErik int eventCount = 0; 54440bcd101b212c9863c3110c05a487a7ae6ebc3caErik Iterator<Event> iter = eventDay.iterator(); 54540bcd101b212c9863c3110c05a487a7ae6ebc3caErik while (iter.hasNext()) { 54640bcd101b212c9863c3110c05a487a7ae6ebc3caErik Event event = iter.next(); 54740bcd101b212c9863c3110c05a487a7ae6ebc3caErik int newY = drawEvent(canvas, event, xSquare, ySquare, rightEdge, iter.hasNext()); 54840bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (newY == ySquare) { 54940bcd101b212c9863c3110c05a487a7ae6ebc3caErik break; 55040bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 55140bcd101b212c9863c3110c05a487a7ae6ebc3caErik eventCount++; 55240bcd101b212c9863c3110c05a487a7ae6ebc3caErik ySquare = newY; 55340bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 55440bcd101b212c9863c3110c05a487a7ae6ebc3caErik 55540bcd101b212c9863c3110c05a487a7ae6ebc3caErik int remaining = eventDay.size() - eventCount; 55640bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (remaining > 0) { 55740bcd101b212c9863c3110c05a487a7ae6ebc3caErik drawMoreEvents(canvas, remaining, xSquare); 55840bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 55940bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 56040bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 56140bcd101b212c9863c3110c05a487a7ae6ebc3caErik 562f445411ff661014c4b5a37e2f97552989e9278ecRoboErik protected int addChipOutline(FloatRef lines, int count, int x, int y) { 563f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.ensureSize(count + 16); 56440bcd101b212c9863c3110c05a487a7ae6ebc3caErik // top of box 565f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x; 566f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y; 567f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x + EVENT_SQUARE_WIDTH; 568f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y; 56940bcd101b212c9863c3110c05a487a7ae6ebc3caErik // right side of box 570f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x + EVENT_SQUARE_WIDTH; 571f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y; 572f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x + EVENT_SQUARE_WIDTH; 573f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y + EVENT_SQUARE_WIDTH; 57440bcd101b212c9863c3110c05a487a7ae6ebc3caErik // left side of box 575f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x; 576f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y; 577f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x; 578f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y + EVENT_SQUARE_WIDTH + 1; 57940bcd101b212c9863c3110c05a487a7ae6ebc3caErik // bottom of box 580f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = x; 581f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y + EVENT_SQUARE_WIDTH; 5822fda24534978f55711526dbde747aa50d68dec40RoboErik lines.array[count++] = x + EVENT_SQUARE_WIDTH + 1; 583f445411ff661014c4b5a37e2f97552989e9278ecRoboErik lines.array[count++] = y + EVENT_SQUARE_WIDTH; 58440bcd101b212c9863c3110c05a487a7ae6ebc3caErik 58540bcd101b212c9863c3110c05a487a7ae6ebc3caErik return count; 58640bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 58740bcd101b212c9863c3110c05a487a7ae6ebc3caErik 58840bcd101b212c9863c3110c05a487a7ae6ebc3caErik /** 58940bcd101b212c9863c3110c05a487a7ae6ebc3caErik * Attempts to draw the given event. Returns the y for the next event or the 59040bcd101b212c9863c3110c05a487a7ae6ebc3caErik * original y if the event will not fit. An event is considered to not fit 59140bcd101b212c9863c3110c05a487a7ae6ebc3caErik * if the event and its extras won't fit or if there are more events and the 59240bcd101b212c9863c3110c05a487a7ae6ebc3caErik * more events line would not fit after drawing this event. 59340bcd101b212c9863c3110c05a487a7ae6ebc3caErik * 59440bcd101b212c9863c3110c05a487a7ae6ebc3caErik * @param event the event to draw 59540bcd101b212c9863c3110c05a487a7ae6ebc3caErik * @param x the top left corner for this event's color chip 59640bcd101b212c9863c3110c05a487a7ae6ebc3caErik * @param y the top left corner for this event's color chip 59740bcd101b212c9863c3110c05a487a7ae6ebc3caErik * @return the y for the next event or the original y if it won't fit 59840bcd101b212c9863c3110c05a487a7ae6ebc3caErik */ 59940bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected int drawEvent( 60040bcd101b212c9863c3110c05a487a7ae6ebc3caErik Canvas canvas, Event event, int x, int y, int rightEdge, boolean moreEvents) { 60140bcd101b212c9863c3110c05a487a7ae6ebc3caErik int requiredSpace = EVENT_LINE_PADDING + mEventHeight; 60240bcd101b212c9863c3110c05a487a7ae6ebc3caErik int multiplier = 1; 60340bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (moreEvents) { 60440bcd101b212c9863c3110c05a487a7ae6ebc3caErik multiplier++; 60540bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 60640bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (!event.allDay) { 60740bcd101b212c9863c3110c05a487a7ae6ebc3caErik multiplier++; 60840bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 60940bcd101b212c9863c3110c05a487a7ae6ebc3caErik requiredSpace *= multiplier; 610a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik // The last one doesn't need the EVENT_LINE_PADDING as it will have 611a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik // EVENT_BOTTOM_PADDING instead 612a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik requiredSpace -= EVENT_LINE_PADDING; 613a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik if (requiredSpace + y > mHeight - EVENT_BOTTOM_PADDING) { 61440bcd101b212c9863c3110c05a487a7ae6ebc3caErik // Not enough space, return 61540bcd101b212c9863c3110c05a487a7ae6ebc3caErik return y; 61640bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 61740bcd101b212c9863c3110c05a487a7ae6ebc3caErik r.left = x; 61840bcd101b212c9863c3110c05a487a7ae6ebc3caErik r.right = x + EVENT_SQUARE_WIDTH; 61940bcd101b212c9863c3110c05a487a7ae6ebc3caErik r.top = y; 62040bcd101b212c9863c3110c05a487a7ae6ebc3caErik r.bottom = y + EVENT_SQUARE_WIDTH; 621a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint.setColor(event.color); 622a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik Style style = event.selfAttendeeStatus == Attendees.ATTENDEE_STATUS_NONE ? Style.STROKE 623a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik : Style.FILL_AND_STROKE; 624a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint.setStyle(style); 625a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik canvas.drawRect(r, mEventSquarePaint); 62640bcd101b212c9863c3110c05a487a7ae6ebc3caErik 62740bcd101b212c9863c3110c05a487a7ae6ebc3caErik int textX = x + EVENT_SQUARE_WIDTH + EVENT_LINE_PADDING; 62840bcd101b212c9863c3110c05a487a7ae6ebc3caErik int textY = y + mEventHeight - EVENT_LINE_PADDING / 2; 62940bcd101b212c9863c3110c05a487a7ae6ebc3caErik float avail = rightEdge - textX; 63040bcd101b212c9863c3110c05a487a7ae6ebc3caErik CharSequence text = TextUtils.ellipsize( 63140bcd101b212c9863c3110c05a487a7ae6ebc3caErik event.title, mEventPaint, avail, TextUtils.TruncateAt.END); 63240bcd101b212c9863c3110c05a487a7ae6ebc3caErik canvas.drawText(text.toString(), textX, textY, mEventPaint); 63340bcd101b212c9863c3110c05a487a7ae6ebc3caErik if (!event.allDay) { 63440bcd101b212c9863c3110c05a487a7ae6ebc3caErik textY += mEventHeight + EVENT_LINE_PADDING; 63540bcd101b212c9863c3110c05a487a7ae6ebc3caErik mStringBuilder.setLength(0); 6363f888688c0f2644ad3de032d5d1cf623a7b092fdAndy McFadden text = DateUtils.formatDateRange(getContext(), mFormatter, event.startMillis, 63740bcd101b212c9863c3110c05a487a7ae6ebc3caErik event.endMillis, DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, 6383f888688c0f2644ad3de032d5d1cf623a7b092fdAndy McFadden Utils.getTimeZone(getContext(), null)).toString(); 63940bcd101b212c9863c3110c05a487a7ae6ebc3caErik text = TextUtils.ellipsize(text, mEventExtrasPaint, avail, TextUtils.TruncateAt.END); 64040bcd101b212c9863c3110c05a487a7ae6ebc3caErik canvas.drawText(text.toString(), textX, textY, mEventExtrasPaint); 64140bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 64240bcd101b212c9863c3110c05a487a7ae6ebc3caErik 64340bcd101b212c9863c3110c05a487a7ae6ebc3caErik return textY + EVENT_LINE_PADDING; 64440bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 64540bcd101b212c9863c3110c05a487a7ae6ebc3caErik 64640bcd101b212c9863c3110c05a487a7ae6ebc3caErik protected void drawMoreEvents(Canvas canvas, int remainingEvents, int x) { 64740bcd101b212c9863c3110c05a487a7ae6ebc3caErik int y = mHeight - EVENT_BOTTOM_PADDING + EVENT_LINE_PADDING / 2 - mEventHeight; 648a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik r.left = x; 649a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik r.top = y; 650a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik r.right = x + EVENT_SQUARE_WIDTH; 651a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik r.bottom = y + EVENT_SQUARE_WIDTH; 652a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint.setColor(mMonthEventExtraColor); 653a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik mEventSquarePaint.setStyle(Style.STROKE); 654a8d8ebd77b91ea94f9d680d343ee1c891bec7f5cRoboErik canvas.drawRect(r, mEventSquarePaint); 655e9cd8f4513c141ca486bbd141f0fe34bb3c27f3aRoboErik mEventExtrasPaint.setAntiAlias(true); 6563f888688c0f2644ad3de032d5d1cf623a7b092fdAndy McFadden String text = getContext().getResources().getQuantityString( 65740bcd101b212c9863c3110c05a487a7ae6ebc3caErik R.plurals.month_more_events, remainingEvents); 65840bcd101b212c9863c3110c05a487a7ae6ebc3caErik y = mHeight - EVENT_BOTTOM_PADDING; 65940bcd101b212c9863c3110c05a487a7ae6ebc3caErik x += EVENT_SQUARE_WIDTH + EVENT_LINE_PADDING; 66040bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventExtrasPaint.setFakeBoldText(true); 66140bcd101b212c9863c3110c05a487a7ae6ebc3caErik canvas.drawText(String.format(text, remainingEvents), x, y, mEventExtrasPaint); 66240bcd101b212c9863c3110c05a487a7ae6ebc3caErik mEventExtrasPaint.setFakeBoldText(false); 66340bcd101b212c9863c3110c05a487a7ae6ebc3caErik } 66440bcd101b212c9863c3110c05a487a7ae6ebc3caErik 66571b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson /** 666092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik * Draws a line showing busy times in each day of week The method draws 667092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik * non-conflicting times in the event color and times with conflicting 668092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik * events in the dna conflict color defined in colors. 66971b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson * 67071b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson * @param canvas 67171b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson */ 672092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik protected void drawDNA(Canvas canvas) { 673092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Draw event and conflict times 674092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (mDna != null) { 675092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik for (Utils.DNAStrand strand : mDna.values()) { 676092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (strand.color == CONFLICT_COLOR || strand.points == null 677092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik || strand.points.length == 0) { 678092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik continue; 679092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 680092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setColor(strand.color); 681092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik canvas.drawLines(strand.points, mDNATimePaint); 682092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 683092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // Draw black last to make sure it's on top 684092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik Utils.DNAStrand strand = mDna.get(CONFLICT_COLOR); 685092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (strand != null && strand.points != null && strand.points.length != 0) { 686092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNATimePaint.setColor(strand.color); 687092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik canvas.drawLines(strand.points, mDNATimePaint); 68871b9ce3a20ebaff8f7e40fc0e5ec2a388bcc394cIsaac Katzenelson } 689092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (mDayXs == null) { 690092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik return; 691092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 692092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int numDays = mDayXs.length; 693092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik int xOffset = (DNA_ALL_DAY_WIDTH - DNA_WIDTH) / 2; 694092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (strand != null && strand.allDays != null && strand.allDays.length == numDays) { 695092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik for (int i = 0; i < numDays; i++) { 696092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // this adds at most 7 draws. We could sort it by color and 697092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik // build an array instead but this is easier. 698092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik if (strand.allDays[i] != 0) { 699092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik mDNAAllDayPaint.setColor(strand.allDays[i]); 700092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik canvas.drawLine(mDayXs[i] + xOffset, DNA_MARGIN, mDayXs[i] + xOffset, 701092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik DNA_MARGIN + DNA_ALL_DAY_HEIGHT, mDNAAllDayPaint); 702092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 703092caec951caa0fabcd51729678e3ddcd6ca2f03RoboErik } 70482400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson } 70582400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson } 70682400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson } 70782400dd70331df7885dd59b809c4bc0667046320Isaac Katzenelson 7083553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 7093553621c824afe1f3eacbe8555678005ca1264a1Erik protected void updateSelectionPositions() { 7103553621c824afe1f3eacbe8555678005ca1264a1Erik if (mHasSelectedDay) { 7113553621c824afe1f3eacbe8555678005ca1264a1Erik int selectedPosition = mSelectedDay - mWeekStart; 7123553621c824afe1f3eacbe8555678005ca1264a1Erik if (selectedPosition < 0) { 7133553621c824afe1f3eacbe8555678005ca1264a1Erik selectedPosition += 7; 7143553621c824afe1f3eacbe8555678005ca1264a1Erik } 7153553621c824afe1f3eacbe8555678005ca1264a1Erik int effectiveWidth = mWidth - mPadding * 2; 716bf4aa400663a072813c87cf9c8aaee2d07abc945Erik effectiveWidth -= SPACING_WEEK_NUMBER; 7173553621c824afe1f3eacbe8555678005ca1264a1Erik mSelectedLeft = selectedPosition * effectiveWidth / mNumDays + mPadding; 7183553621c824afe1f3eacbe8555678005ca1264a1Erik mSelectedRight = (selectedPosition + 1) * effectiveWidth / mNumDays + mPadding; 719bf4aa400663a072813c87cf9c8aaee2d07abc945Erik mSelectedLeft += SPACING_WEEK_NUMBER; 720bf4aa400663a072813c87cf9c8aaee2d07abc945Erik mSelectedRight += SPACING_WEEK_NUMBER; 7213553621c824afe1f3eacbe8555678005ca1264a1Erik } 7223553621c824afe1f3eacbe8555678005ca1264a1Erik } 7233553621c824afe1f3eacbe8555678005ca1264a1Erik 7243553621c824afe1f3eacbe8555678005ca1264a1Erik @Override 7253553621c824afe1f3eacbe8555678005ca1264a1Erik public Time getDayFromLocation(float x) { 726da532a723613001f1175c067aece5f859d079bfcRoboErik int dayStart = mShowWeekNum ? SPACING_WEEK_NUMBER + mPadding : mPadding; 7273553621c824afe1f3eacbe8555678005ca1264a1Erik if (x < dayStart || x > mWidth - mPadding) { 7283553621c824afe1f3eacbe8555678005ca1264a1Erik return null; 7293553621c824afe1f3eacbe8555678005ca1264a1Erik } 7303553621c824afe1f3eacbe8555678005ca1264a1Erik // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels 7313553621c824afe1f3eacbe8555678005ca1264a1Erik int dayPosition = (int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding)); 7323553621c824afe1f3eacbe8555678005ca1264a1Erik int day = mFirstJulianDay + dayPosition; 7333553621c824afe1f3eacbe8555678005ca1264a1Erik 7343553621c824afe1f3eacbe8555678005ca1264a1Erik Time time = new Time(mTimeZone); 7353553621c824afe1f3eacbe8555678005ca1264a1Erik if (mWeek == 0) { 7363553621c824afe1f3eacbe8555678005ca1264a1Erik // This week is weird... 7373553621c824afe1f3eacbe8555678005ca1264a1Erik if (day < Time.EPOCH_JULIAN_DAY) { 7383553621c824afe1f3eacbe8555678005ca1264a1Erik day++; 7393553621c824afe1f3eacbe8555678005ca1264a1Erik } else if (day == Time.EPOCH_JULIAN_DAY) { 7403553621c824afe1f3eacbe8555678005ca1264a1Erik time.set(1, 0, 1970); 7413553621c824afe1f3eacbe8555678005ca1264a1Erik time.normalize(true); 7423553621c824afe1f3eacbe8555678005ca1264a1Erik return time; 7433553621c824afe1f3eacbe8555678005ca1264a1Erik } 7443553621c824afe1f3eacbe8555678005ca1264a1Erik } 7453553621c824afe1f3eacbe8555678005ca1264a1Erik 7463553621c824afe1f3eacbe8555678005ca1264a1Erik time.setJulianDay(day); 7473553621c824afe1f3eacbe8555678005ca1264a1Erik return time; 74882b318634af1b6594e60cfd1f2df4d3845f80587Erik } 74982b318634af1b6594e60cfd1f2df4d3845f80587Erik 75067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik @Override 75167f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik public boolean onHoverEvent(MotionEvent event) { 752f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik Context context = getContext(); 753f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik // only send accessibility events if accessibility and exploration are 754f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik // on. 75593c08b7693d8246305c75dc2416f70321ce9c1a2RoboErik AccessibilityManager am = (AccessibilityManager) context 75693c08b7693d8246305c75dc2416f70321ce9c1a2RoboErik .getSystemService(Service.ACCESSIBILITY_SERVICE); 757f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik if (!am.isEnabled() || !am.isTouchExplorationEnabled()) { 758f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik return super.onHoverEvent(event); 759f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik } 76067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik if (event.getAction() != MotionEvent.ACTION_HOVER_EXIT) { 76167f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik Time hover = getDayFromLocation(event.getX()); 76267f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik if (hover != null 76367f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik && (mLastHoverTime == null || Time.compare(hover, mLastHoverTime) != 0)) { 76467f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik Long millis = hover.toMillis(true); 765f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik String date = Utils.formatDateRange(context, millis, millis, 76667f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik DateUtils.FORMAT_SHOW_DATE); 76767f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik AccessibilityEvent accessEvent = AccessibilityEvent 76867f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik .obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); 76967f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik accessEvent.getText().add(date); 770044a43c3c1789ba93d83ae68d799d94dc4e4ecf2Michael Chan if (mShowDetailsInMonth && mEvents != null) { 77167f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik int dayStart = SPACING_WEEK_NUMBER + mPadding; 77267f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik int dayPosition = (int) ((event.getX() - dayStart) * mNumDays / (mWidth 77367f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik - dayStart - mPadding)); 77467f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik ArrayList<Event> events = mEvents.get(dayPosition); 77567f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik List<CharSequence> text = accessEvent.getText(); 77667f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik for (Event e : events) { 77767f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik text.add(e.getTitleAndLocation() + ". "); 77867f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR; 77967f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik if (!e.allDay) { 78067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik flags |= DateUtils.FORMAT_SHOW_TIME; 781f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik if (DateFormat.is24HourFormat(context)) { 78267f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik flags |= DateUtils.FORMAT_24HOUR; 78367f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 784aeebdbcf782a531bc972078cf05e70f21112ecafRoboErik } else { 785aeebdbcf782a531bc972078cf05e70f21112ecafRoboErik flags |= DateUtils.FORMAT_UTC; 78667f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 787f9cb58df1deab65ad426d7997fe3e3fdfeef2850RoboErik text.add(Utils.formatDateRange(context, e.startMillis, e.endMillis, 78867f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik flags) + ". "); 78967f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 79067f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 79167f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik sendAccessibilityEventUnchecked(accessEvent); 79267f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik mLastHoverTime = hover; 79367f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 79467f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 79567f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik return true; 79667f16905cd1efe0fef4e86ff5ddea7069b80b98dRoboErik } 79782b318634af1b6594e60cfd1f2df4d3845f80587Erik} 798