AOSP/Calendar - Add Kotlin copy of CalendarData.java and SimpleWeekView.java
Test: none, no functional change in this commit when merged with corresponding Kotlin conversion.
Change-Id: Ie7de49ede9e883c9f6cca688ba95cb90a1b594b2
diff --git a/src/com/android/calendar/CalendarData.kt b/src/com/android/calendar/CalendarData.kt
new file mode 100644
index 0000000..5c8456f
--- /dev/null
+++ b/src/com/android/calendar/CalendarData.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.calendar;
+
+public final class CalendarData {
+ static final String[] s12HoursNoAmPm = { "12", "1", "2", "3", "4",
+ "5", "6", "7", "8", "9", "10", "11", "12",
+ "1", "2", "3", "4", "5", "6", "7", "8",
+ "9", "10", "11", "12" };
+
+ static final String[] s24Hours = { "00", "01", "02", "03", "04", "05",
+ "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16",
+ "17", "18", "19", "20", "21", "22", "23", "00" };
+}
diff --git a/src/com/android/calendar/month/SimpleWeekView.kt b/src/com/android/calendar/month/SimpleWeekView.kt
new file mode 100644
index 0000000..4d0c09f
--- /dev/null
+++ b/src/com/android/calendar/month/SimpleWeekView.kt
@@ -0,0 +1,551 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.calendar.month;
+
+import com.android.calendar.R;
+import com.android.calendar.Utils;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Paint.Style;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.format.DateUtils;
+import android.text.format.Time;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import java.security.InvalidParameterException;
+import java.util.HashMap;
+
+/**
+ * <p>
+ * This is a dynamic view for drawing a single week. It can be configured to
+ * display the week number, start the week on a given day, or show a reduced
+ * number of days. It is intended for use as a single view within a ListView.
+ * See {@link SimpleWeeksAdapter} for usage.
+ * </p>
+ */
+public class SimpleWeekView extends View {
+ private static final String TAG = "MonthView";
+
+ /**
+ * These params can be passed into the view to control how it appears.
+ * {@link #VIEW_PARAMS_WEEK} is the only required field, though the default
+ * values are unlikely to fit most layouts correctly.
+ */
+ /**
+ * This sets the height of this week in pixels
+ */
+ public static final String VIEW_PARAMS_HEIGHT = "height";
+ /**
+ * This specifies the position (or weeks since the epoch) of this week,
+ * calculated using {@link Utils#getWeeksSinceEpochFromJulianDay}
+ */
+ public static final String VIEW_PARAMS_WEEK = "week";
+ /**
+ * This sets one of the days in this view as selected {@link Time#SUNDAY}
+ * through {@link Time#SATURDAY}.
+ */
+ public static final String VIEW_PARAMS_SELECTED_DAY = "selected_day";
+ /**
+ * Which day the week should start on. {@link Time#SUNDAY} through
+ * {@link Time#SATURDAY}.
+ */
+ public static final String VIEW_PARAMS_WEEK_START = "week_start";
+ /**
+ * How many days to display at a time. Days will be displayed starting with
+ * {@link #mWeekStart}.
+ */
+ public static final String VIEW_PARAMS_NUM_DAYS = "num_days";
+ /**
+ * Which month is currently in focus, as defined by {@link Time#month}
+ * [0-11].
+ */
+ public static final String VIEW_PARAMS_FOCUS_MONTH = "focus_month";
+ /**
+ * If this month should display week numbers. false if 0, true otherwise.
+ */
+ public static final String VIEW_PARAMS_SHOW_WK_NUM = "show_wk_num";
+
+ protected static int DEFAULT_HEIGHT = 32;
+ protected static int MIN_HEIGHT = 10;
+ protected static final int DEFAULT_SELECTED_DAY = -1;
+ protected static final int DEFAULT_WEEK_START = Time.SUNDAY;
+ protected static final int DEFAULT_NUM_DAYS = 7;
+ protected static final int DEFAULT_SHOW_WK_NUM = 0;
+ protected static final int DEFAULT_FOCUS_MONTH = -1;
+
+ protected static int DAY_SEPARATOR_WIDTH = 1;
+
+ protected static int MINI_DAY_NUMBER_TEXT_SIZE = 14;
+ protected static int MINI_WK_NUMBER_TEXT_SIZE = 12;
+ protected static int MINI_TODAY_NUMBER_TEXT_SIZE = 18;
+ protected static int MINI_TODAY_OUTLINE_WIDTH = 2;
+ protected static int WEEK_NUM_MARGIN_BOTTOM = 4;
+
+ // used for scaling to the device density
+ protected static float mScale = 0;
+
+ // affects the padding on the sides of this view
+ protected int mPadding = 0;
+
+ protected Rect r = new Rect();
+ protected Paint p = new Paint();
+ protected Paint mMonthNumPaint;
+ protected Drawable mSelectedDayLine;
+
+ // Cache the number strings so we don't have to recompute them each time
+ protected String[] mDayNumbers;
+ // Quick lookup for checking which days are in the focus month
+ protected boolean[] mFocusDay;
+ // Quick lookup for checking which days are in an odd month (to set a different background)
+ protected boolean[] mOddMonth;
+ // The Julian day of the first day displayed by this item
+ protected int mFirstJulianDay = -1;
+ // The month of the first day in this week
+ protected int mFirstMonth = -1;
+ // The month of the last day in this week
+ protected int mLastMonth = -1;
+ // The position of this week, equivalent to weeks since the week of Jan 1st,
+ // 1970
+ protected int mWeek = -1;
+ // Quick reference to the width of this view, matches parent
+ protected int mWidth;
+ // The height this view should draw at in pixels, set by height param
+ protected int mHeight = DEFAULT_HEIGHT;
+ // Whether the week number should be shown
+ protected boolean mShowWeekNum = false;
+ // If this view contains the selected day
+ protected boolean mHasSelectedDay = false;
+ // If this view contains the today
+ protected boolean mHasToday = false;
+ // Which day is selected [0-6] or -1 if no day is selected
+ protected int mSelectedDay = DEFAULT_SELECTED_DAY;
+ // Which day is today [0-6] or -1 if no day is today
+ protected int mToday = DEFAULT_SELECTED_DAY;
+ // Which day of the week to start on [0-6]
+ protected int mWeekStart = DEFAULT_WEEK_START;
+ // How many days to display
+ protected int mNumDays = DEFAULT_NUM_DAYS;
+ // The number of days + a spot for week number if it is displayed
+ protected int mNumCells = mNumDays;
+ // The left edge of the selected day
+ protected int mSelectedLeft = -1;
+ // The right edge of the selected day
+ protected int mSelectedRight = -1;
+ // The timezone to display times/dates in (used for determining when Today
+ // is)
+ protected String mTimeZone = Time.getCurrentTimezone();
+
+ protected int mBGColor;
+ protected int mSelectedWeekBGColor;
+ protected int mFocusMonthColor;
+ protected int mOtherMonthColor;
+ protected int mDaySeparatorColor;
+ protected int mTodayOutlineColor;
+ protected int mWeekNumColor;
+
+ public SimpleWeekView(Context context) {
+ super(context);
+
+ Resources res = context.getResources();
+
+ mBGColor = res.getColor(R.color.month_bgcolor);
+ mSelectedWeekBGColor = res.getColor(R.color.month_selected_week_bgcolor);
+ mFocusMonthColor = res.getColor(R.color.month_mini_day_number);
+ mOtherMonthColor = res.getColor(R.color.month_other_month_day_number);
+ mDaySeparatorColor = res.getColor(R.color.month_grid_lines);
+ mTodayOutlineColor = res.getColor(R.color.mini_month_today_outline_color);
+ mWeekNumColor = res.getColor(R.color.month_week_num_color);
+ mSelectedDayLine = res.getDrawable(R.drawable.dayline_minical_holo_light);
+
+ if (mScale == 0) {
+ mScale = context.getResources().getDisplayMetrics().density;
+ if (mScale != 1) {
+ DEFAULT_HEIGHT *= mScale;
+ MIN_HEIGHT *= mScale;
+ MINI_DAY_NUMBER_TEXT_SIZE *= mScale;
+ MINI_TODAY_NUMBER_TEXT_SIZE *= mScale;
+ MINI_TODAY_OUTLINE_WIDTH *= mScale;
+ WEEK_NUM_MARGIN_BOTTOM *= mScale;
+ DAY_SEPARATOR_WIDTH *= mScale;
+ MINI_WK_NUMBER_TEXT_SIZE *= mScale;
+ }
+ }
+
+ // Sets up any standard paints that will be used
+ initView();
+ }
+
+ /**
+ * Sets all the parameters for displaying this week. The only required
+ * parameter is the week number. Other parameters have a default value and
+ * will only update if a new value is included, except for focus month,
+ * which will always default to no focus month if no value is passed in. See
+ * {@link #VIEW_PARAMS_HEIGHT} for more info on parameters.
+ *
+ * @param params A map of the new parameters, see
+ * {@link #VIEW_PARAMS_HEIGHT}
+ * @param tz The time zone this view should reference times in
+ */
+ public void setWeekParams(HashMap<String, Integer> params, String tz) {
+ if (!params.containsKey(VIEW_PARAMS_WEEK)) {
+ throw new InvalidParameterException("You must specify the week number for this view");
+ }
+ setTag(params);
+ mTimeZone = tz;
+ // We keep the current value for any params not present
+ if (params.containsKey(VIEW_PARAMS_HEIGHT)) {
+ mHeight = params.get(VIEW_PARAMS_HEIGHT);
+ if (mHeight < MIN_HEIGHT) {
+ mHeight = MIN_HEIGHT;
+ }
+ }
+ if (params.containsKey(VIEW_PARAMS_SELECTED_DAY)) {
+ mSelectedDay = params.get(VIEW_PARAMS_SELECTED_DAY);
+ }
+ mHasSelectedDay = mSelectedDay != -1;
+ if (params.containsKey(VIEW_PARAMS_NUM_DAYS)) {
+ mNumDays = params.get(VIEW_PARAMS_NUM_DAYS);
+ }
+ if (params.containsKey(VIEW_PARAMS_SHOW_WK_NUM)) {
+ if (params.get(VIEW_PARAMS_SHOW_WK_NUM) != 0) {
+ mShowWeekNum = true;
+ } else {
+ mShowWeekNum = false;
+ }
+ }
+ mNumCells = mShowWeekNum ? mNumDays + 1 : mNumDays;
+
+ // Allocate space for caching the day numbers and focus values
+ mDayNumbers = new String[mNumCells];
+ mFocusDay = new boolean[mNumCells];
+ mOddMonth = new boolean[mNumCells];
+ mWeek = params.get(VIEW_PARAMS_WEEK);
+ int julianMonday = Utils.getJulianMondayFromWeeksSinceEpoch(mWeek);
+ Time time = new Time(tz);
+ time.setJulianDay(julianMonday);
+
+ // If we're showing the week number calculate it based on Monday
+ int i = 0;
+ if (mShowWeekNum) {
+ mDayNumbers[0] = Integer.toString(time.getWeekNumber());
+ i++;
+ }
+
+ if (params.containsKey(VIEW_PARAMS_WEEK_START)) {
+ mWeekStart = params.get(VIEW_PARAMS_WEEK_START);
+ }
+
+ // Now adjust our starting day based on the start day of the week
+ // If the week is set to start on a Saturday the first week will be
+ // Dec 27th 1969 -Jan 2nd, 1970
+ if (time.weekDay != mWeekStart) {
+ int diff = time.weekDay - mWeekStart;
+ if (diff < 0) {
+ diff += 7;
+ }
+ time.monthDay -= diff;
+ time.normalize(true);
+ }
+
+ mFirstJulianDay = Time.getJulianDay(time.toMillis(true), time.gmtoff);
+ mFirstMonth = time.month;
+
+ // Figure out what day today is
+ Time today = new Time(tz);
+ today.setToNow();
+ mHasToday = false;
+ mToday = -1;
+
+ int focusMonth = params.containsKey(VIEW_PARAMS_FOCUS_MONTH) ? params.get(
+ VIEW_PARAMS_FOCUS_MONTH)
+ : DEFAULT_FOCUS_MONTH;
+
+ for (; i < mNumCells; i++) {
+ if (time.monthDay == 1) {
+ mFirstMonth = time.month;
+ }
+ mOddMonth [i] = (time.month %2) == 1;
+ if (time.month == focusMonth) {
+ mFocusDay[i] = true;
+ } else {
+ mFocusDay[i] = false;
+ }
+ if (time.year == today.year && time.yearDay == today.yearDay) {
+ mHasToday = true;
+ mToday = i;
+ }
+ mDayNumbers[i] = Integer.toString(time.monthDay++);
+ time.normalize(true);
+ }
+ // We do one extra add at the end of the loop, if that pushed us to a
+ // new month undo it
+ if (time.monthDay == 1) {
+ time.monthDay--;
+ time.normalize(true);
+ }
+ mLastMonth = time.month;
+
+ updateSelectionPositions();
+ }
+
+ /**
+ * Sets up the text and style properties for painting. Override this if you
+ * want to use a different paint.
+ */
+ protected void initView() {
+ p.setFakeBoldText(false);
+ p.setAntiAlias(true);
+ p.setTextSize(MINI_DAY_NUMBER_TEXT_SIZE);
+ p.setStyle(Style.FILL);
+
+ mMonthNumPaint = new Paint();
+ mMonthNumPaint.setFakeBoldText(true);
+ mMonthNumPaint.setAntiAlias(true);
+ mMonthNumPaint.setTextSize(MINI_DAY_NUMBER_TEXT_SIZE);
+ mMonthNumPaint.setColor(mFocusMonthColor);
+ mMonthNumPaint.setStyle(Style.FILL);
+ mMonthNumPaint.setTextAlign(Align.CENTER);
+ }
+
+ /**
+ * Returns the month of the first day in this week
+ *
+ * @return The month the first day of this view is in
+ */
+ public int getFirstMonth() {
+ return mFirstMonth;
+ }
+
+ /**
+ * Returns the month of the last day in this week
+ *
+ * @return The month the last day of this view is in
+ */
+ public int getLastMonth() {
+ return mLastMonth;
+ }
+
+ /**
+ * Returns the julian day of the first day in this view.
+ *
+ * @return The julian day of the first day in the view.
+ */
+ public int getFirstJulianDay() {
+ return mFirstJulianDay;
+ }
+
+ /**
+ * Calculates the day that the given x position is in, accounting for week
+ * number. Returns a Time referencing that day or null if
+ *
+ * @param x The x position of the touch event
+ * @return A time object for the tapped day or null if the position wasn't
+ * in a day
+ */
+ public Time getDayFromLocation(float x) {
+ int dayStart = mShowWeekNum ? (mWidth - mPadding * 2) / mNumCells + mPadding : mPadding;
+ if (x < dayStart || x > mWidth - mPadding) {
+ return null;
+ }
+ // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels
+ int dayPosition = (int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding));
+ int day = mFirstJulianDay + dayPosition;
+
+ Time time = new Time(mTimeZone);
+ if (mWeek == 0) {
+ // This week is weird...
+ if (day < Time.EPOCH_JULIAN_DAY) {
+ day++;
+ } else if (day == Time.EPOCH_JULIAN_DAY) {
+ time.set(1, 0, 1970);
+ time.normalize(true);
+ return time;
+ }
+ }
+
+ time.setJulianDay(day);
+ return time;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ drawBackground(canvas);
+ drawWeekNums(canvas);
+ drawDaySeparators(canvas);
+ }
+
+ /**
+ * This draws the selection highlight if a day is selected in this week.
+ * Override this method if you wish to have a different background drawn.
+ *
+ * @param canvas The canvas to draw on
+ */
+ protected void drawBackground(Canvas canvas) {
+ if (mHasSelectedDay) {
+ p.setColor(mSelectedWeekBGColor);
+ p.setStyle(Style.FILL);
+ } else {
+ return;
+ }
+ r.top = 1;
+ r.bottom = mHeight - 1;
+ r.left = mPadding;
+ r.right = mSelectedLeft;
+ canvas.drawRect(r, p);
+ r.left = mSelectedRight;
+ r.right = mWidth - mPadding;
+ canvas.drawRect(r, p);
+ }
+
+ /**
+ * Draws the week and month day numbers for this week. Override this method
+ * if you need different placement.
+ *
+ * @param canvas The canvas to draw on
+ */
+ protected void drawWeekNums(Canvas canvas) {
+ int y = ((mHeight + MINI_DAY_NUMBER_TEXT_SIZE) / 2) - DAY_SEPARATOR_WIDTH;
+ int nDays = mNumCells;
+
+ int i = 0;
+ int divisor = 2 * nDays;
+ if (mShowWeekNum) {
+ p.setTextSize(MINI_WK_NUMBER_TEXT_SIZE);
+ p.setStyle(Style.FILL);
+ p.setTextAlign(Align.CENTER);
+ p.setAntiAlias(true);
+ p.setColor(mWeekNumColor);
+ int x = (mWidth - mPadding * 2) / divisor + mPadding;
+ canvas.drawText(mDayNumbers[0], x, y, p);
+ i++;
+ }
+
+ boolean isFocusMonth = mFocusDay[i];
+ mMonthNumPaint.setColor(isFocusMonth ? mFocusMonthColor : mOtherMonthColor);
+ mMonthNumPaint.setFakeBoldText(false);
+ for (; i < nDays; i++) {
+ if (mFocusDay[i] != isFocusMonth) {
+ isFocusMonth = mFocusDay[i];
+ mMonthNumPaint.setColor(isFocusMonth ? mFocusMonthColor : mOtherMonthColor);
+ }
+ if (mHasToday && mToday == i) {
+ mMonthNumPaint.setTextSize(MINI_TODAY_NUMBER_TEXT_SIZE);
+ mMonthNumPaint.setFakeBoldText(true);
+ }
+ int x = (2 * i + 1) * (mWidth - mPadding * 2) / (divisor) + mPadding;
+ canvas.drawText(mDayNumbers[i], x, y, mMonthNumPaint);
+ if (mHasToday && mToday == i) {
+ mMonthNumPaint.setTextSize(MINI_DAY_NUMBER_TEXT_SIZE);
+ mMonthNumPaint.setFakeBoldText(false);
+ }
+ }
+ }
+
+ /**
+ * Draws a horizontal line for separating the weeks. Override this method if
+ * you want custom separators.
+ *
+ * @param canvas The canvas to draw on
+ */
+ protected void drawDaySeparators(Canvas canvas) {
+ if (mHasSelectedDay) {
+ r.top = 1;
+ r.bottom = mHeight - 1;
+ r.left = mSelectedLeft + 1;
+ r.right = mSelectedRight - 1;
+ p.setStrokeWidth(MINI_TODAY_OUTLINE_WIDTH);
+ p.setStyle(Style.STROKE);
+ p.setColor(mTodayOutlineColor);
+ canvas.drawRect(r, p);
+ }
+ if (mShowWeekNum) {
+ p.setColor(mDaySeparatorColor);
+ p.setStrokeWidth(DAY_SEPARATOR_WIDTH);
+
+ int x = (mWidth - mPadding * 2) / mNumCells + mPadding;
+ canvas.drawLine(x, 0, x, mHeight, p);
+ }
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mWidth = w;
+ updateSelectionPositions();
+ }
+
+ /**
+ * This calculates the positions for the selected day lines.
+ */
+ protected void updateSelectionPositions() {
+ if (mHasSelectedDay) {
+ int selectedPosition = mSelectedDay - mWeekStart;
+ if (selectedPosition < 0) {
+ selectedPosition += 7;
+ }
+ if (mShowWeekNum) {
+ selectedPosition++;
+ }
+ mSelectedLeft = selectedPosition * (mWidth - mPadding * 2) / mNumCells
+ + mPadding;
+ mSelectedRight = (selectedPosition + 1) * (mWidth - mPadding * 2) / mNumCells
+ + mPadding;
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
+ }
+
+ @Override
+ public boolean onHoverEvent(MotionEvent event) {
+ Context context = getContext();
+ // only send accessibility events if accessibility and exploration are
+ // on.
+ AccessibilityManager am = (AccessibilityManager) context
+ .getSystemService(Service.ACCESSIBILITY_SERVICE);
+ if (!am.isEnabled() || !am.isTouchExplorationEnabled()) {
+ return super.onHoverEvent(event);
+ }
+ if (event.getAction() != MotionEvent.ACTION_HOVER_EXIT) {
+ Time hover = getDayFromLocation(event.getX());
+ if (hover != null
+ && (mLastHoverTime == null || Time.compare(hover, mLastHoverTime) != 0)) {
+ Long millis = hover.toMillis(true);
+ String date = Utils.formatDateRange(context, millis, millis,
+ DateUtils.FORMAT_SHOW_DATE);
+ AccessibilityEvent accessEvent =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+ accessEvent.getText().add(date);
+ sendAccessibilityEventUnchecked(accessEvent);
+ mLastHoverTime = hover;
+ }
+ }
+ return true;
+ }
+
+ Time mLastHoverTime = null;
+}
\ No newline at end of file