diff options
author | Damian Patel <damianpatel@google.com> | 2021-07-01 17:39:42 +0000 |
---|---|---|
committer | Damian Patel <damianpatel@google.com> | 2021-07-03 13:48:08 +0000 |
commit | 9b97629d83b230d421c2c8591eaad0e279851bc7 (patch) | |
tree | dcdd0fdffe2fa7aa6f1a2fd7c93d542bcad8dabf | |
parent | eeb807f78665ec690b050ae8d116bccbc6026e64 (diff) | |
download | Calendar-9b97629d83b230d421c2c8591eaad0e279851bc7.tar.gz |
AOSP/Calendar - Initial Conversion of DayView
This is how Android Studio's built-in converter
converted DayView.java to Kotlin without any
additional edits.
Change-Id: Icc9a779706d9962b2edd4975d1df2b209cb9dea0
-rw-r--r-- | src/com/android/calendar/DayView.kt | 5140 |
1 files changed, 2514 insertions, 2626 deletions
diff --git a/src/com/android/calendar/DayView.kt b/src/com/android/calendar/DayView.kt index 2fc00b3c..ce8ad124 100644 --- a/src/com/android/calendar/DayView.kt +++ b/src/com/android/calendar/DayView.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2021 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. @@ -13,119 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.android.calendar -package com.android.calendar; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.app.AlertDialog; -import android.app.Service; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.Context; -import android.content.DialogInterface; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.database.Cursor; -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.Typeface; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Handler; -import android.provider.CalendarContract.Attendees; -import android.provider.CalendarContract.Calendars; -import android.provider.CalendarContract.Events; -import android.text.Layout.Alignment; -import android.text.SpannableStringBuilder; -import android.text.StaticLayout; -import android.text.TextPaint; -import android.text.TextUtils; -import android.text.format.DateFormat; -import android.text.format.DateUtils; -import android.text.format.Time; -import android.text.style.StyleSpan; -import android.util.Log; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.GestureDetector; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.ScaleGestureDetector; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.Animation; -import android.view.animation.Interpolator; -import android.view.animation.TranslateAnimation; -import android.widget.EdgeEffect; -import android.widget.ImageView; -import android.widget.OverScroller; -import android.widget.PopupWindow; -import android.widget.TextView; -import android.widget.ViewSwitcher; - -import com.android.calendar.CalendarController.EventType; -import com.android.calendar.CalendarController.ViewType; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Formatter; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import android.animation.Animator /** * View for multi-day view. So far only 1 and 7 day have been tested. */ -public class DayView extends View implements View.OnCreateContextMenuListener, - ScaleGestureDetector.OnScaleGestureListener, View.OnClickListener, View.OnLongClickListener - { - private static String TAG = "DayView"; - private static boolean DEBUG = false; - private static boolean DEBUG_SCALING = false; - private static final String PERIOD_SPACE = ". "; - - private static float mScale = 0; // Used for supporting different screen densities - private static final long INVALID_EVENT_ID = -1; //This is used for remembering a null event - // Duration of the allday expansion - private static final long ANIMATION_DURATION = 400; - // duration of the more allday event text fade - private static final long ANIMATION_SECONDARY_DURATION = 200; - // duration of the scroll to go to a specified time - private static final int GOTO_SCROLL_DURATION = 200; - // duration for events' cross-fade animation - private static final int EVENTS_CROSS_FADE_DURATION = 400; - // duration to show the event clicked - private static final int CLICK_DISPLAY_DURATION = 50; - - private static final int MENU_DAY = 3; - private static final int MENU_EVENT_VIEW = 5; - private static final int MENU_EVENT_CREATE = 6; - private static final int MENU_EVENT_EDIT = 7; - private static final int MENU_EVENT_DELETE = 8; - - private static int DEFAULT_CELL_HEIGHT = 64; - private static int MAX_CELL_HEIGHT = 150; - private static int MIN_Y_SPAN = 100; - - private boolean mOnFlingCalled; - private boolean mStartingScroll = false; - protected boolean mPaused = true; - private Handler mHandler; +class DayView( + context: Context, controller: CalendarController, + viewSwitcher: ViewSwitcher, eventLoader: EventLoader, numDays: Int +) : View(context), View.OnCreateContextMenuListener, ScaleGestureDetector.OnScaleGestureListener, + View.OnClickListener, View.OnLongClickListener { + private var mOnFlingCalled = false + private var mStartingScroll = false + protected var mPaused = true + private var mHandler: Handler? = null + /** * ID of the last event which was displayed with the toast popup. * @@ -134,166 +38,137 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * on starting calendar or by scrolling to an event. It becomes invalid when the user * explicitly scrolls to an empty time slot, changes views, or deletes the event. */ - private long mLastPopupEventID; - - protected Context mContext; - - private static final String[] CALENDARS_PROJECTION = new String[] { - Calendars._ID, // 0 - Calendars.CALENDAR_ACCESS_LEVEL, // 1 - Calendars.OWNER_ACCOUNT, // 2 - }; - private static final int CALENDARS_INDEX_ACCESS_LEVEL = 1; - private static final int CALENDARS_INDEX_OWNER_ACCOUNT = 2; - private static final String CALENDARS_WHERE = Calendars._ID + "=%d"; - - private static final int FROM_NONE = 0; - private static final int FROM_ABOVE = 1; - private static final int FROM_BELOW = 2; - private static final int FROM_LEFT = 4; - private static final int FROM_RIGHT = 8; - - private static final int ACCESS_LEVEL_NONE = 0; - private static final int ACCESS_LEVEL_DELETE = 1; - private static final int ACCESS_LEVEL_EDIT = 2; - - private static int mHorizontalSnapBackThreshold = 128; - - private final ContinueScroll mContinueScroll = new ContinueScroll(); + private var mLastPopupEventID: Long + protected var mContext: Context + private val mContinueScroll: ContinueScroll = ContinueScroll() // Make this visible within the package for more informative debugging - Time mBaseDate; - private Time mCurrentTime; - //Update the current time line every five minutes if the window is left open that long - private static final int UPDATE_CURRENT_TIME_DELAY = 300000; - private final UpdateCurrentTime mUpdateCurrentTime = new UpdateCurrentTime(); - private int mTodayJulianDay; - - private final Typeface mBold = Typeface.DEFAULT_BOLD; - private int mFirstJulianDay; - private int mLoadedFirstJulianDay = -1; - private int mLastJulianDay; - - private int mMonthLength; - private int mFirstVisibleDate; - private int mFirstVisibleDayOfWeek; - private int[] mEarliestStartHour; // indexed by the week day offset - private boolean[] mHasAllDayEvent; // indexed by the week day offset - private String mEventCountTemplate; - private Event mClickedEvent; // The event the user clicked on - private Event mSavedClickedEvent; - private static int mOnDownDelay; - private int mClickedYLocation; - private long mDownTouchTime; - - private int mEventsAlpha = 255; - private ObjectAnimator mEventsCrossFadeAnimation; - - protected static StringBuilder mStringBuilder = new StringBuilder(50); - // TODO recreate formatter when locale changes - protected static Formatter mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); - - private final Runnable mTZUpdater = new Runnable() { + var mBaseDate: Time? = null + private var mCurrentTime: Time? = null + private val mUpdateCurrentTime: UpdateCurrentTime = UpdateCurrentTime() + private var mTodayJulianDay = 0 + private val mBold: Typeface = Typeface.DEFAULT_BOLD + private var mFirstJulianDay = 0 + private var mLoadedFirstJulianDay = -1 + private var mLastJulianDay = 0 + private var mMonthLength = 0 + private var mFirstVisibleDate = 0 + private var mFirstVisibleDayOfWeek = 0 + private var mEarliestStartHour // indexed by the week day offset + : IntArray + private var mHasAllDayEvent // indexed by the week day offset + : BooleanArray + private var mEventCountTemplate: String? = null + private var mClickedEvent // The event the user clicked on + : Event? = null + private var mSavedClickedEvent: Event? = null + private var mClickedYLocation = 0 + private var mDownTouchTime: Long = 0 + private var mEventsAlpha = 255 + private var mEventsCrossFadeAnimation: ObjectAnimator? = null + private val mTZUpdater: Runnable = object : Runnable() { @Override - public void run() { - String tz = Utils.getTimeZone(mContext, this); - mBaseDate.timezone = tz; - mBaseDate.normalize(true); - mCurrentTime.switchTimezone(tz); - invalidate(); + fun run() { + val tz: String = Utils.getTimeZone(mContext, this) + mBaseDate.timezone = tz + mBaseDate.normalize(true) + mCurrentTime.switchTimezone(tz) + invalidate() } - }; + } // Sets the "clicked" color from the clicked event - private final Runnable mSetClick = new Runnable() { + private val mSetClick: Runnable = object : Runnable() { @Override - public void run() { - mClickedEvent = mSavedClickedEvent; - mSavedClickedEvent = null; - DayView.this.invalidate(); + fun run() { + mClickedEvent = mSavedClickedEvent + mSavedClickedEvent = null + this@DayView.invalidate() } - }; + } // Clears the "clicked" color from the clicked event and launch the event - private final Runnable mClearClick = new Runnable() { + private val mClearClick: Runnable = object : Runnable() { @Override - public void run() { + fun run() { if (mClickedEvent != null) { - mController.sendEventRelatedEvent(this, EventType.VIEW_EVENT, mClickedEvent.id, - mClickedEvent.startMillis, mClickedEvent.endMillis, - DayView.this.getWidth() / 2, mClickedYLocation, - getSelectedTimeInMillis()); + mController.sendEventRelatedEvent( + this, EventType.VIEW_EVENT, mClickedEvent.id, + mClickedEvent.startMillis, mClickedEvent.endMillis, + this@DayView.getWidth() / 2, mClickedYLocation, + selectedTimeInMillis + ) } - mClickedEvent = null; - DayView.this.invalidate(); + mClickedEvent = null + this@DayView.invalidate() } - }; - - private final TodayAnimatorListener mTodayAnimatorListener = new TodayAnimatorListener(); + } + private val mTodayAnimatorListener: TodayAnimatorListener = TodayAnimatorListener() - class TodayAnimatorListener extends AnimatorListenerAdapter { - private volatile Animator mAnimator = null; - private volatile boolean mFadingIn = false; + internal inner class TodayAnimatorListener : AnimatorListenerAdapter() { + @Volatile + private var mAnimator: Animator? = null + @Volatile + private var mFadingIn = false @Override - public void onAnimationEnd(Animator animation) { - synchronized (this) { - if (mAnimator != animation) { - animation.removeAllListeners(); - animation.cancel(); - return; + fun onAnimationEnd(animation: Animator) { + synchronized(this) { + if (mAnimator !== animation) { + animation.removeAllListeners() + animation.cancel() + return } if (mFadingIn) { if (mTodayAnimator != null) { - mTodayAnimator.removeAllListeners(); - mTodayAnimator.cancel(); + mTodayAnimator.removeAllListeners() + mTodayAnimator.cancel() } mTodayAnimator = ObjectAnimator - .ofInt(DayView.this, "animateTodayAlpha", 255, 0); - mAnimator = mTodayAnimator; - mFadingIn = false; - mTodayAnimator.addListener(this); - mTodayAnimator.setDuration(600); - mTodayAnimator.start(); + .ofInt(this@DayView, "animateTodayAlpha", 255, 0) + mAnimator = mTodayAnimator + mFadingIn = false + mTodayAnimator.addListener(this) + mTodayAnimator.setDuration(600) + mTodayAnimator.start() } else { - mAnimateToday = false; - mAnimateTodayAlpha = 0; - mAnimator.removeAllListeners(); - mAnimator = null; - mTodayAnimator = null; - invalidate(); + mAnimateToday = false + mAnimateTodayAlpha = 0 + mAnimator.removeAllListeners() + mAnimator = null + mTodayAnimator = null + invalidate() } } } - public void setAnimator(Animator animation) { - mAnimator = animation; + fun setAnimator(animation: Animator?) { + mAnimator = animation } - public void setFadingIn(boolean fadingIn) { - mFadingIn = fadingIn; + fun setFadingIn(fadingIn: Boolean) { + mFadingIn = fadingIn } - } - AnimatorListenerAdapter mAnimatorListener = new AnimatorListenerAdapter() { + var mAnimatorListener: AnimatorListenerAdapter = object : AnimatorListenerAdapter() { @Override - public void onAnimationStart(Animator animation) { - mScrolling = true; + fun onAnimationStart(animation: Animator?) { + mScrolling = true } @Override - public void onAnimationCancel(Animator animation) { - mScrolling = false; + fun onAnimationCancel(animation: Animator?) { + mScrolling = false } @Override - public void onAnimationEnd(Animator animation) { - mScrolling = false; - resetSelectedHour(); - invalidate(); + fun onAnimationEnd(animation: Animator?) { + mScrolling = false + resetSelectedHour() + invalidate() } - }; + } /** * This variable helps to avoid unnecessarily reloading events by keeping @@ -302,824 +177,550 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * reloaded. To force a reload, set this to zero (this is set to zero * in the method clearCachedEvents()). */ - private long mLastReloadMillis; - - private ArrayList<Event> mEvents = new ArrayList<Event>(); - private ArrayList<Event> mAllDayEvents = new ArrayList<Event>(); - private StaticLayout[] mLayouts = null; - private StaticLayout[] mAllDayLayouts = null; - private int mSelectionDay; // Julian day - private int mSelectionHour; - - boolean mSelectionAllday; + private var mLastReloadMillis: Long = 0 + private var mEvents: ArrayList<Event> = ArrayList<Event>() + private var mAllDayEvents: ArrayList<Event>? = ArrayList<Event>() + private var mLayouts: Array<StaticLayout?>? = null + private var mAllDayLayouts: Array<StaticLayout?>? = null + private var mSelectionDay // Julian day + = 0 + private var mSelectionHour = 0 + var mSelectionAllday = false // Current selection info for accessibility - private int mSelectionDayForAccessibility; // Julian day - private int mSelectionHourForAccessibility; - private Event mSelectedEventForAccessibility; - // Last selection info for accessibility - private int mLastSelectionDayForAccessibility; - private int mLastSelectionHourForAccessibility; - private Event mLastSelectedEventForAccessibility; + private var mSelectionDayForAccessibility // Julian day + = 0 + private var mSelectionHourForAccessibility = 0 + private var mSelectedEventForAccessibility: Event? = null + // Last selection info for accessibility + private var mLastSelectionDayForAccessibility = 0 + private var mLastSelectionHourForAccessibility = 0 + private var mLastSelectedEventForAccessibility: Event? = null - /** Width of a day or non-conflicting event */ - private int mCellWidth; + /** Width of a day or non-conflicting event */ + private var mCellWidth = 0 // Pre-allocate these objects and re-use them - private final Rect mRect = new Rect(); - private final Rect mDestRect = new Rect(); - private final Rect mSelectionRect = new Rect(); - // This encloses the more allDay events icon - private final Rect mExpandAllDayRect = new Rect(); - // TODO Clean up paint usage - private final Paint mPaint = new Paint(); - private final Paint mEventTextPaint = new Paint(); - private final Paint mSelectionPaint = new Paint(); - private float[] mLines; - - private int mFirstDayOfWeek; // First day of the week - - private PopupWindow mPopup; - private View mPopupView; - - // The number of milliseconds to show the popup window - private static final int POPUP_DISMISS_DELAY = 3000; - private final DismissPopup mDismissPopup = new DismissPopup(); + private val mRect: Rect = Rect() + private val mDestRect: Rect = Rect() + private val mSelectionRect: Rect = Rect() - private boolean mRemeasure = true; - - private final EventLoader mEventLoader; - protected final EventGeometry mEventGeometry; - - private static float GRID_LINE_LEFT_MARGIN = 0; - private static final float GRID_LINE_INNER_WIDTH = 1; + // This encloses the more allDay events icon + private val mExpandAllDayRect: Rect = Rect() - private static final int DAY_GAP = 1; - private static final int HOUR_GAP = 1; - // This is the standard height of an allday event with no restrictions - private static int SINGLE_ALLDAY_HEIGHT = 34; - /** - * This is the minimum desired height of a allday event. - * When unexpanded, allday events will use this height. - * When expanded allDay events will attempt to grow to fit all - * events at this height. - */ - private static float MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT = 28.0F; // in pixels - /** - * This is how big the unexpanded allday height is allowed to be. - * It will get adjusted based on screen size - */ - private static int MAX_UNEXPANDED_ALLDAY_HEIGHT = - (int) (MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT * 4); - /** - * This is the minimum size reserved for displaying regular events. - * The expanded allDay region can't expand into this. - */ - private static int MIN_HOURS_HEIGHT = 180; - private static int ALLDAY_TOP_MARGIN = 1; - // The largest a single allDay event will become. - private static int MAX_HEIGHT_OF_ONE_ALLDAY_EVENT = 34; - - private static int HOURS_TOP_MARGIN = 2; - private static int HOURS_LEFT_MARGIN = 2; - private static int HOURS_RIGHT_MARGIN = 4; - private static int HOURS_MARGIN = HOURS_LEFT_MARGIN + HOURS_RIGHT_MARGIN; - private static int NEW_EVENT_MARGIN = 4; - private static int NEW_EVENT_WIDTH = 2; - private static int NEW_EVENT_MAX_LENGTH = 16; - - private static int CURRENT_TIME_LINE_SIDE_BUFFER = 4; - private static int CURRENT_TIME_LINE_TOP_OFFSET = 2; - - /* package */ static final int MINUTES_PER_HOUR = 60; - /* package */ static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * 24; - /* package */ static final int MILLIS_PER_MINUTE = 60 * 1000; - /* package */ static final int MILLIS_PER_HOUR = (3600 * 1000); - /* package */ static final int MILLIS_PER_DAY = MILLIS_PER_HOUR * 24; - - // More events text will transition between invisible and this alpha - private static final int MORE_EVENTS_MAX_ALPHA = 0x4C; - private static int DAY_HEADER_ONE_DAY_LEFT_MARGIN = 0; - private static int DAY_HEADER_ONE_DAY_RIGHT_MARGIN = 5; - private static int DAY_HEADER_ONE_DAY_BOTTOM_MARGIN = 6; - private static int DAY_HEADER_RIGHT_MARGIN = 4; - private static int DAY_HEADER_BOTTOM_MARGIN = 3; - private static float DAY_HEADER_FONT_SIZE = 14; - private static float DATE_HEADER_FONT_SIZE = 32; - private static float NORMAL_FONT_SIZE = 12; - private static float EVENT_TEXT_FONT_SIZE = 12; - private static float HOURS_TEXT_SIZE = 12; - private static float AMPM_TEXT_SIZE = 9; - private static int MIN_HOURS_WIDTH = 96; - private static int MIN_CELL_WIDTH_FOR_TEXT = 20; - private static final int MAX_EVENT_TEXT_LEN = 500; - // smallest height to draw an event with - private static float MIN_EVENT_HEIGHT = 24.0F; // in pixels - private static int CALENDAR_COLOR_SQUARE_SIZE = 10; - private static int EVENT_RECT_TOP_MARGIN = 1; - private static int EVENT_RECT_BOTTOM_MARGIN = 0; - private static int EVENT_RECT_LEFT_MARGIN = 1; - private static int EVENT_RECT_RIGHT_MARGIN = 0; - private static int EVENT_RECT_STROKE_WIDTH = 2; - private static int EVENT_TEXT_TOP_MARGIN = 2; - private static int EVENT_TEXT_BOTTOM_MARGIN = 2; - private static int EVENT_TEXT_LEFT_MARGIN = 6; - private static int EVENT_TEXT_RIGHT_MARGIN = 6; - private static int ALL_DAY_EVENT_RECT_BOTTOM_MARGIN = 1; - private static int EVENT_ALL_DAY_TEXT_TOP_MARGIN = EVENT_TEXT_TOP_MARGIN; - private static int EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN = EVENT_TEXT_BOTTOM_MARGIN; - private static int EVENT_ALL_DAY_TEXT_LEFT_MARGIN = EVENT_TEXT_LEFT_MARGIN; - private static int EVENT_ALL_DAY_TEXT_RIGHT_MARGIN = EVENT_TEXT_RIGHT_MARGIN; - // margins and sizing for the expand allday icon - private static int EXPAND_ALL_DAY_BOTTOM_MARGIN = 10; - // sizing for "box +n" in allDay events - private static int EVENT_SQUARE_WIDTH = 10; - private static int EVENT_LINE_PADDING = 4; - private static int NEW_EVENT_HINT_FONT_SIZE = 12; - - private static int mEventTextColor; - private static int mMoreEventsTextColor; - - private static int mWeek_saturdayColor; - private static int mWeek_sundayColor; - private static int mCalendarDateBannerTextColor; - private static int mCalendarAmPmLabel; - private static int mCalendarGridAreaSelected; - private static int mCalendarGridLineInnerHorizontalColor; - private static int mCalendarGridLineInnerVerticalColor; - private static int mFutureBgColor; - private static int mFutureBgColorRes; - private static int mBgColor; - private static int mNewEventHintColor; - private static int mCalendarHourLabelColor; - private static int mMoreAlldayEventsTextAlpha = MORE_EVENTS_MAX_ALPHA; - - private float mAnimationDistance = 0; - private int mViewStartX; - private int mViewStartY; - private int mMaxViewStartY; - private int mViewHeight; - private int mViewWidth; - private int mGridAreaHeight = -1; - private static int mCellHeight = 0; // shared among all DayViews - private static int mMinCellHeight = 32; - private int mScrollStartY; - private int mPreviousDirection; - private static int mScaledPagingTouchSlop = 0; + // TODO Clean up paint usage + private val mPaint: Paint = Paint() + private val mEventTextPaint: Paint = Paint() + private val mSelectionPaint: Paint = Paint() + private var mLines: FloatArray + private var mFirstDayOfWeek // First day of the week + = 0 + private var mPopup: PopupWindow? = null + private var mPopupView: View? = null + private val mDismissPopup: DismissPopup = DismissPopup() + private var mRemeasure = true + private val mEventLoader: EventLoader + protected val mEventGeometry: EventGeometry + private var mAnimationDistance = 0f + private var mViewStartX = 0 + private var mViewStartY = 0 + private var mMaxViewStartY = 0 + private var mViewHeight = 0 + private var mViewWidth = 0 + private var mGridAreaHeight = -1 + private var mScrollStartY = 0 + private var mPreviousDirection = 0 /** * Vertical distance or span between the two touch points at the start of a * scaling gesture */ - private float mStartingSpanY = 0; - /** Height of 1 hour in pixels at the start of a scaling gesture */ - private int mCellHeightBeforeScaleGesture; - /** The hour at the center two touch points */ - private float mGestureCenterHour = 0; + private var mStartingSpanY = 0f - private boolean mRecalCenterHour = false; + /** Height of 1 hour in pixels at the start of a scaling gesture */ + private var mCellHeightBeforeScaleGesture = 0 + + /** The hour at the center two touch points */ + private var mGestureCenterHour = 0f + private var mRecalCenterHour = false /** * Flag to decide whether to handle the up event. Cases where up events * should be ignored are 1) right after a scale gesture and 2) finger was * down before app launch */ - private boolean mHandleActionUp = true; + private var mHandleActionUp = true + private var mHoursTextHeight = 0 - private int mHoursTextHeight; /** * The height of the area used for allday events */ - private int mAlldayHeight; - /** - * The height of the allday event area used during animation - */ - private int mAnimateDayHeight = 0; - /** - * The height of an individual allday event during animation - */ - private int mAnimateDayEventHeight = (int) MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT; - /** - * Whether to use the expand or collapse icon. - */ - private static boolean mUseExpandIcon = true; - /** - * The height of the day names/numbers - */ - private static int DAY_HEADER_HEIGHT = 45; - /** - * The height of the day names/numbers for multi-day views - */ - private static int MULTI_DAY_HEADER_HEIGHT = DAY_HEADER_HEIGHT; - /** - * The height of the day names/numbers when viewing a single day - */ - private static int ONE_DAY_HEADER_HEIGHT = DAY_HEADER_HEIGHT; - /** - * Max of all day events in a given day in this view. - */ - private int mMaxAlldayEvents; - /** - * A count of the number of allday events that were not drawn for each day - */ - private int[] mSkippedAlldayEvents; - /** - * The number of allDay events at which point we start hiding allDay events. - */ - private int mMaxUnexpandedAlldayEventCount = 4; - /** - * Whether or not to expand the allDay area to fill the screen - */ - private static boolean mShowAllAllDayEvents = false; - - protected int mNumDays = 7; - private int mNumHours = 10; - - /** Width of the time line (list of hours) to the left. */ - private int mHoursWidth; - private int mDateStrWidth; - /** Top of the scrollable region i.e. below date labels and all day events */ - private int mFirstCell; - /** First fully visibile hour */ - private int mFirstHour = -1; - /** Distance between the mFirstCell and the top of first fully visible hour. */ - private int mFirstHourOffset; - private String[] mHourStrs; - private String[] mDayStrs; - private String[] mDayStrs2Letter; - private boolean mIs24HourFormat; - - private final ArrayList<Event> mSelectedEvents = new ArrayList<Event>(); - private boolean mComputeSelectedEvents; - private boolean mUpdateToast; - private Event mSelectedEvent; - private Event mPrevSelectedEvent; - private final Rect mPrevBox = new Rect(); - protected final Resources mResources; - protected final Drawable mCurrentTimeLine; - protected final Drawable mCurrentTimeAnimateLine; - protected final Drawable mTodayHeaderDrawable; - protected final Drawable mExpandAlldayDrawable; - protected final Drawable mCollapseAlldayDrawable; - protected Drawable mAcceptedOrTentativeEventBoxDrawable; - private String mAmString; - private String mPmString; - private static int sCounter = 0; - - ScaleGestureDetector mScaleGestureDetector; + private var mAlldayHeight = 0 /** - * The initial state of the touch mode when we enter this view. + * The height of the allday event area used during animation */ - private static final int TOUCH_MODE_INITIAL_STATE = 0; + private var mAnimateDayHeight = 0 /** - * Indicates we just received the touch event and we are waiting to see if - * it is a tap or a scroll gesture. + * The height of an individual allday event during animation */ - private static final int TOUCH_MODE_DOWN = 1; + private var mAnimateDayEventHeight = MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt() /** - * Indicates the touch gesture is a vertical scroll + * Max of all day events in a given day in this view. */ - private static final int TOUCH_MODE_VSCROLL = 0x20; + private var mMaxAlldayEvents = 0 /** - * Indicates the touch gesture is a horizontal scroll + * A count of the number of allday events that were not drawn for each day */ - private static final int TOUCH_MODE_HSCROLL = 0x40; - - private int mTouchMode = TOUCH_MODE_INITIAL_STATE; + private var mSkippedAlldayEvents: IntArray? /** - * The selection modes are HIDDEN, PRESSED, SELECTED, and LONGPRESS. + * The number of allDay events at which point we start hiding allDay events. */ - private static final int SELECTION_HIDDEN = 0; - private static final int SELECTION_PRESSED = 1; // D-pad down but not up yet - private static final int SELECTION_SELECTED = 2; - private static final int SELECTION_LONGPRESS = 3; - - private int mSelectionMode = SELECTION_HIDDEN; - - private boolean mScrolling = false; + private var mMaxUnexpandedAlldayEventCount = 4 + protected var mNumDays = 7 + private var mNumHours = 10 + + /** Width of the time line (list of hours) to the left. */ + private var mHoursWidth = 0 + private var mDateStrWidth = 0 + + /** Top of the scrollable region i.e. below date labels and all day events */ + private var mFirstCell = 0 + + /** First fully visible hour */ + private var mFirstHour = -1 + + /** Distance between the mFirstCell and the top of first fully visible hour. */ + private var mFirstHourOffset = 0 + private var mHourStrs: Array<String> + private var mDayStrs: Array<String?> + private var mDayStrs2Letter: Array<String?> + private var mIs24HourFormat = false + private val mSelectedEvents: ArrayList<Event> = ArrayList<Event>() + private var mComputeSelectedEvents = false + private var mUpdateToast = false + private var mSelectedEvent: Event? = null + private var mPrevSelectedEvent: Event? = null + private val mPrevBox: Rect = Rect() + protected val mResources: Resources + protected val mCurrentTimeLine: Drawable + protected val mCurrentTimeAnimateLine: Drawable + protected val mTodayHeaderDrawable: Drawable + protected val mExpandAlldayDrawable: Drawable + protected val mCollapseAlldayDrawable: Drawable + protected var mAcceptedOrTentativeEventBoxDrawable: Drawable + private var mAmString: String? = null + private var mPmString: String? = null + var mScaleGestureDetector: ScaleGestureDetector + private var mTouchMode = TOUCH_MODE_INITIAL_STATE + private var mSelectionMode = SELECTION_HIDDEN + private var mScrolling = false // Pixels scrolled - private float mInitialScrollX; - private float mInitialScrollY; - - private boolean mAnimateToday = false; - private int mAnimateTodayAlpha = 0; + private var mInitialScrollX = 0f + private var mInitialScrollY = 0f + private var mAnimateToday = false + private var mAnimateTodayAlpha = 0 // Animates the height of the allday region - ObjectAnimator mAlldayAnimator; + var mAlldayAnimator: ObjectAnimator? = null + // Animates the height of events in the allday region - ObjectAnimator mAlldayEventAnimator; + var mAlldayEventAnimator: ObjectAnimator? = null + // Animates the transparency of the more events text - ObjectAnimator mMoreAlldayEventsAnimator; + var mMoreAlldayEventsAnimator: ObjectAnimator? = null + // Animates the current time marker when Today is pressed - ObjectAnimator mTodayAnimator; - // whether or not an event is stopping because it was cancelled - private boolean mCancellingAnimations = false; - // tracks whether a touch originated in the allday area - private boolean mTouchStartedInAlldayArea = false; - - private final CalendarController mController; - private final ViewSwitcher mViewSwitcher; - private final GestureDetector mGestureDetector; - private final OverScroller mScroller; - private final EdgeEffect mEdgeEffectTop; - private final EdgeEffect mEdgeEffectBottom; - private boolean mCallEdgeEffectOnAbsorb; - private final int OVERFLING_DISTANCE; - private float mLastVelocity; - - private final ScrollInterpolator mHScrollInterpolator; - private AccessibilityManager mAccessibilityMgr = null; - private boolean mIsAccessibilityEnabled = false; - private boolean mTouchExplorationEnabled = false; - private final String mNewEventHintString; - - public DayView(Context context, CalendarController controller, - ViewSwitcher viewSwitcher, EventLoader eventLoader, int numDays) { - super(context); - mContext = context; - initAccessibilityVariables(); - - mResources = context.getResources(); - mNewEventHintString = mResources.getString(R.string.day_view_new_event_hint); - mNumDays = numDays; - - DATE_HEADER_FONT_SIZE = (int) mResources.getDimension(R.dimen.date_header_text_size); - DAY_HEADER_FONT_SIZE = (int) mResources.getDimension(R.dimen.day_label_text_size); - ONE_DAY_HEADER_HEIGHT = (int) mResources.getDimension(R.dimen.one_day_header_height); - DAY_HEADER_BOTTOM_MARGIN = (int) mResources.getDimension(R.dimen.day_header_bottom_margin); - EXPAND_ALL_DAY_BOTTOM_MARGIN = (int) mResources.getDimension(R.dimen.all_day_bottom_margin); - HOURS_TEXT_SIZE = (int) mResources.getDimension(R.dimen.hours_text_size); - AMPM_TEXT_SIZE = (int) mResources.getDimension(R.dimen.ampm_text_size); - MIN_HOURS_WIDTH = (int) mResources.getDimension(R.dimen.min_hours_width); - HOURS_LEFT_MARGIN = (int) mResources.getDimension(R.dimen.hours_left_margin); - HOURS_RIGHT_MARGIN = (int) mResources.getDimension(R.dimen.hours_right_margin); - MULTI_DAY_HEADER_HEIGHT = (int) mResources.getDimension(R.dimen.day_header_height); - int eventTextSizeId; - if (mNumDays == 1) { - eventTextSizeId = R.dimen.day_view_event_text_size; - } else { - eventTextSizeId = R.dimen.week_view_event_text_size; - } - EVENT_TEXT_FONT_SIZE = (int) mResources.getDimension(eventTextSizeId); - NEW_EVENT_HINT_FONT_SIZE = (int) mResources.getDimension(R.dimen.new_event_hint_text_size); - MIN_EVENT_HEIGHT = mResources.getDimension(R.dimen.event_min_height); - MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT = MIN_EVENT_HEIGHT; - EVENT_TEXT_TOP_MARGIN = (int) mResources.getDimension(R.dimen.event_text_vertical_margin); - EVENT_TEXT_BOTTOM_MARGIN = EVENT_TEXT_TOP_MARGIN; - EVENT_ALL_DAY_TEXT_TOP_MARGIN = EVENT_TEXT_TOP_MARGIN; - EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN = EVENT_TEXT_TOP_MARGIN; - - EVENT_TEXT_LEFT_MARGIN = (int) mResources - .getDimension(R.dimen.event_text_horizontal_margin); - EVENT_TEXT_RIGHT_MARGIN = EVENT_TEXT_LEFT_MARGIN; - EVENT_ALL_DAY_TEXT_LEFT_MARGIN = EVENT_TEXT_LEFT_MARGIN; - EVENT_ALL_DAY_TEXT_RIGHT_MARGIN = EVENT_TEXT_LEFT_MARGIN; - - if (mScale == 0) { - - mScale = mResources.getDisplayMetrics().density; - if (mScale != 1) { - SINGLE_ALLDAY_HEIGHT *= mScale; - ALLDAY_TOP_MARGIN *= mScale; - MAX_HEIGHT_OF_ONE_ALLDAY_EVENT *= mScale; - - NORMAL_FONT_SIZE *= mScale; - GRID_LINE_LEFT_MARGIN *= mScale; - HOURS_TOP_MARGIN *= mScale; - MIN_CELL_WIDTH_FOR_TEXT *= mScale; - MAX_UNEXPANDED_ALLDAY_HEIGHT *= mScale; - mAnimateDayEventHeight = (int) MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT; - - CURRENT_TIME_LINE_SIDE_BUFFER *= mScale; - CURRENT_TIME_LINE_TOP_OFFSET *= mScale; - - MIN_Y_SPAN *= mScale; - MAX_CELL_HEIGHT *= mScale; - DEFAULT_CELL_HEIGHT *= mScale; - DAY_HEADER_HEIGHT *= mScale; - DAY_HEADER_RIGHT_MARGIN *= mScale; - DAY_HEADER_ONE_DAY_LEFT_MARGIN *= mScale; - DAY_HEADER_ONE_DAY_RIGHT_MARGIN *= mScale; - DAY_HEADER_ONE_DAY_BOTTOM_MARGIN *= mScale; - CALENDAR_COLOR_SQUARE_SIZE *= mScale; - EVENT_RECT_TOP_MARGIN *= mScale; - EVENT_RECT_BOTTOM_MARGIN *= mScale; - ALL_DAY_EVENT_RECT_BOTTOM_MARGIN *= mScale; - EVENT_RECT_LEFT_MARGIN *= mScale; - EVENT_RECT_RIGHT_MARGIN *= mScale; - EVENT_RECT_STROKE_WIDTH *= mScale; - EVENT_SQUARE_WIDTH *= mScale; - EVENT_LINE_PADDING *= mScale; - NEW_EVENT_MARGIN *= mScale; - NEW_EVENT_WIDTH *= mScale; - NEW_EVENT_MAX_LENGTH *= mScale; - } - } - HOURS_MARGIN = HOURS_LEFT_MARGIN + HOURS_RIGHT_MARGIN; - DAY_HEADER_HEIGHT = mNumDays == 1 ? ONE_DAY_HEADER_HEIGHT : MULTI_DAY_HEADER_HEIGHT; - - mCurrentTimeLine = mResources.getDrawable(R.drawable.timeline_indicator_holo_light); - mCurrentTimeAnimateLine = mResources - .getDrawable(R.drawable.timeline_indicator_activated_holo_light); - mTodayHeaderDrawable = mResources.getDrawable(R.drawable.today_blue_week_holo_light); - mExpandAlldayDrawable = mResources.getDrawable(R.drawable.ic_expand_holo_light); - mCollapseAlldayDrawable = mResources.getDrawable(R.drawable.ic_collapse_holo_light); - mNewEventHintColor = mResources.getColor(R.color.new_event_hint_text_color); - mAcceptedOrTentativeEventBoxDrawable = mResources - .getDrawable(R.drawable.panel_month_event_holo_light); - - mEventLoader = eventLoader; - mEventGeometry = new EventGeometry(); - mEventGeometry.setMinEventHeight(MIN_EVENT_HEIGHT); - mEventGeometry.setHourGap(HOUR_GAP); - mEventGeometry.setCellMargin(DAY_GAP); - mLastPopupEventID = INVALID_EVENT_ID; - mController = controller; - mViewSwitcher = viewSwitcher; - mGestureDetector = new GestureDetector(context, new CalendarGestureListener()); - mScaleGestureDetector = new ScaleGestureDetector(getContext(), this); - if (mCellHeight == 0) { - mCellHeight = Utils.getSharedPreference(mContext, - GeneralPreferences.KEY_DEFAULT_CELL_HEIGHT, DEFAULT_CELL_HEIGHT); - } - mScroller = new OverScroller(context); - mHScrollInterpolator = new ScrollInterpolator(); - mEdgeEffectTop = new EdgeEffect(context); - mEdgeEffectBottom = new EdgeEffect(context); - ViewConfiguration vc = ViewConfiguration.get(context); - mScaledPagingTouchSlop = vc.getScaledPagingTouchSlop(); - mOnDownDelay = ViewConfiguration.getTapTimeout(); - OVERFLING_DISTANCE = vc.getScaledOverflingDistance(); + var mTodayAnimator: ObjectAnimator? = null - init(context); - } + // whether or not an event is stopping because it was cancelled + private var mCancellingAnimations = false + // tracks whether a touch originated in the allday area + private var mTouchStartedInAlldayArea = false + private val mController: CalendarController + private val mViewSwitcher: ViewSwitcher + private val mGestureDetector: GestureDetector + private val mScroller: OverScroller + private val mEdgeEffectTop: EdgeEffect + private val mEdgeEffectBottom: EdgeEffect + private var mCallEdgeEffectOnAbsorb = false + private val OVERFLING_DISTANCE: Int + private var mLastVelocity = 0f + private val mHScrollInterpolator: ScrollInterpolator + private var mAccessibilityMgr: AccessibilityManager? = null + private var mIsAccessibilityEnabled = false + private var mTouchExplorationEnabled = false + private val mNewEventHintString: String @Override - protected void onAttachedToWindow() { + protected fun onAttachedToWindow() { if (mHandler == null) { - mHandler = getHandler(); - mHandler.post(mUpdateCurrentTime); + mHandler = getHandler() + mHandler.post(mUpdateCurrentTime) } } - private void init(Context context) { - setFocusable(true); + private fun init(context: Context) { + setFocusable(true) // Allow focus in touch mode so that we can do keyboard shortcuts // even after we've entered touch mode. - setFocusableInTouchMode(true); - setClickable(true); - setOnCreateContextMenuListener(this); - - mFirstDayOfWeek = Utils.getFirstDayOfWeek(context); - - mCurrentTime = new Time(Utils.getTimeZone(context, mTZUpdater)); - long currentTime = System.currentTimeMillis(); - mCurrentTime.set(currentTime); - mTodayJulianDay = Time.getJulianDay(currentTime, mCurrentTime.gmtoff); - - mWeek_saturdayColor = mResources.getColor(R.color.week_saturday); - mWeek_sundayColor = mResources.getColor(R.color.week_sunday); - mCalendarDateBannerTextColor = mResources.getColor(R.color.calendar_date_banner_text_color); - mFutureBgColorRes = mResources.getColor(R.color.calendar_future_bg_color); - mBgColor = mResources.getColor(R.color.calendar_hour_background); - mCalendarAmPmLabel = mResources.getColor(R.color.calendar_ampm_label); - mCalendarGridAreaSelected = mResources.getColor(R.color.calendar_grid_area_selected); + setFocusableInTouchMode(true) + setClickable(true) + setOnCreateContextMenuListener(this) + mFirstDayOfWeek = Utils.getFirstDayOfWeek(context) + mCurrentTime = Time(Utils.getTimeZone(context, mTZUpdater)) + val currentTime: Long = System.currentTimeMillis() + mCurrentTime.set(currentTime) + mTodayJulianDay = Time.getJulianDay(currentTime, mCurrentTime.gmtoff) + mWeek_saturdayColor = mResources.getColor(R.color.week_saturday) + mWeek_sundayColor = mResources.getColor(R.color.week_sunday) + mCalendarDateBannerTextColor = mResources.getColor(R.color.calendar_date_banner_text_color) + mFutureBgColorRes = mResources.getColor(R.color.calendar_future_bg_color) + mBgColor = mResources.getColor(R.color.calendar_hour_background) + mCalendarAmPmLabel = mResources.getColor(R.color.calendar_ampm_label) + mCalendarGridAreaSelected = mResources.getColor(R.color.calendar_grid_area_selected) mCalendarGridLineInnerHorizontalColor = mResources - .getColor(R.color.calendar_grid_line_inner_horizontal_color); + .getColor(R.color.calendar_grid_line_inner_horizontal_color) mCalendarGridLineInnerVerticalColor = mResources - .getColor(R.color.calendar_grid_line_inner_vertical_color); - mCalendarHourLabelColor = mResources.getColor(R.color.calendar_hour_label); - mEventTextColor = mResources.getColor(R.color.calendar_event_text_color); - mMoreEventsTextColor = mResources.getColor(R.color.month_event_other_color); - - mEventTextPaint.setTextSize(EVENT_TEXT_FONT_SIZE); - mEventTextPaint.setTextAlign(Paint.Align.LEFT); - mEventTextPaint.setAntiAlias(true); - - int gridLineColor = mResources.getColor(R.color.calendar_grid_line_highlight_color); - Paint p = mSelectionPaint; - p.setColor(gridLineColor); - p.setStyle(Style.FILL); - p.setAntiAlias(false); - - p = mPaint; - p.setAntiAlias(true); + .getColor(R.color.calendar_grid_line_inner_vertical_color) + mCalendarHourLabelColor = mResources.getColor(R.color.calendar_hour_label) + mEventTextColor = mResources.getColor(R.color.calendar_event_text_color) + mMoreEventsTextColor = mResources.getColor(R.color.month_event_other_color) + mEventTextPaint.setTextSize(EVENT_TEXT_FONT_SIZE) + mEventTextPaint.setTextAlign(Paint.Align.LEFT) + mEventTextPaint.setAntiAlias(true) + val gridLineColor: Int = mResources.getColor(R.color.calendar_grid_line_highlight_color) + var p: Paint = mSelectionPaint + p.setColor(gridLineColor) + p.setStyle(Style.FILL) + p.setAntiAlias(false) + p = mPaint + p.setAntiAlias(true) // Allocate space for 2 weeks worth of weekday names so that we can // easily start the week display at any week day. - mDayStrs = new String[14]; + mDayStrs = arrayOfNulls(14) // Also create an array of 2-letter abbreviations. - mDayStrs2Letter = new String[14]; - - for (int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) { - int index = i - Calendar.SUNDAY; + mDayStrs2Letter = arrayOfNulls(14) + for (i in Calendar.SUNDAY..Calendar.SATURDAY) { + val index: Int = i - Calendar.SUNDAY // e.g. Tue for Tuesday mDayStrs[index] = DateUtils.getDayOfWeekString(i, DateUtils.LENGTH_MEDIUM) - .toUpperCase(); - mDayStrs[index + 7] = mDayStrs[index]; + .toUpperCase() + mDayStrs[index + 7] = mDayStrs[index] // e.g. Tu for Tuesday mDayStrs2Letter[index] = DateUtils.getDayOfWeekString(i, DateUtils.LENGTH_SHORT) - .toUpperCase(); + .toUpperCase() // If we don't have 2-letter day strings, fall back to 1-letter. - if (mDayStrs2Letter[index].equals(mDayStrs[index])) { - mDayStrs2Letter[index] = DateUtils.getDayOfWeekString(i, DateUtils.LENGTH_SHORTEST); + if (mDayStrs2Letter[index]!!.equals(mDayStrs[index])) { + mDayStrs2Letter[index] = DateUtils.getDayOfWeekString(i, DateUtils.LENGTH_SHORTEST) } - - mDayStrs2Letter[index + 7] = mDayStrs2Letter[index]; + mDayStrs2Letter[index + 7] = mDayStrs2Letter[index] } // Figure out how much space we need for the 3-letter abbrev names // in the worst case. - p.setTextSize(DATE_HEADER_FONT_SIZE); - p.setTypeface(mBold); - String[] dateStrs = {" 28", " 30"}; - mDateStrWidth = computeMaxStringWidth(0, dateStrs, p); - p.setTextSize(DAY_HEADER_FONT_SIZE); - mDateStrWidth += computeMaxStringWidth(0, mDayStrs, p); - - p.setTextSize(HOURS_TEXT_SIZE); - p.setTypeface(null); - handleOnResume(); - - mAmString = DateUtils.getAMPMString(Calendar.AM).toUpperCase(); - mPmString = DateUtils.getAMPMString(Calendar.PM).toUpperCase(); - String[] ampm = {mAmString, mPmString}; - p.setTextSize(AMPM_TEXT_SIZE); - mHoursWidth = Math.max(HOURS_MARGIN, computeMaxStringWidth(mHoursWidth, ampm, p) - + HOURS_RIGHT_MARGIN); - mHoursWidth = Math.max(MIN_HOURS_WIDTH, mHoursWidth); - - LayoutInflater inflater; - inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - mPopupView = inflater.inflate(R.layout.bubble_event, null); - mPopupView.setLayoutParams(new ViewGroup.LayoutParams( + p.setTextSize(DATE_HEADER_FONT_SIZE) + p.setTypeface(mBold) + val dateStrs = arrayOf<String?>(" 28", " 30") + mDateStrWidth = computeMaxStringWidth(0, dateStrs, p) + p.setTextSize(DAY_HEADER_FONT_SIZE) + mDateStrWidth += computeMaxStringWidth(0, mDayStrs, p) + p.setTextSize(HOURS_TEXT_SIZE) + p.setTypeface(null) + handleOnResume() + mAmString = DateUtils.getAMPMString(Calendar.AM).toUpperCase() + mPmString = DateUtils.getAMPMString(Calendar.PM).toUpperCase() + val ampm = arrayOf(mAmString, mPmString) + p.setTextSize(AMPM_TEXT_SIZE) + mHoursWidth = Math.max( + HOURS_MARGIN, computeMaxStringWidth(mHoursWidth, ampm, p) + + HOURS_RIGHT_MARGIN + ) + mHoursWidth = Math.max(MIN_HOURS_WIDTH, mHoursWidth) + val inflater: LayoutInflater + inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + mPopupView = inflater.inflate(R.layout.bubble_event, null) + mPopupView.setLayoutParams( + LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - mPopup = new PopupWindow(context); - mPopup.setContentView(mPopupView); - Resources.Theme dialogTheme = getResources().newTheme(); - dialogTheme.applyStyle(android.R.style.Theme_Dialog, true); - TypedArray ta = dialogTheme.obtainStyledAttributes(new int[] { - android.R.attr.windowBackground }); - mPopup.setBackgroundDrawable(ta.getDrawable(0)); - ta.recycle(); + ViewGroup.LayoutParams.WRAP_CONTENT + ) + ) + mPopup = PopupWindow(context) + mPopup.setContentView(mPopupView) + val dialogTheme: Resources.Theme = getResources().newTheme() + dialogTheme.applyStyle(android.R.style.Theme_Dialog, true) + val ta: TypedArray = dialogTheme.obtainStyledAttributes( + intArrayOf( + android.R.attr.windowBackground + ) + ) + mPopup.setBackgroundDrawable(ta.getDrawable(0)) + ta.recycle() // Enable touching the popup window - mPopupView.setOnClickListener(this); + mPopupView.setOnClickListener(this) // Catch long clicks for creating a new event - setOnLongClickListener(this); - - mBaseDate = new Time(Utils.getTimeZone(context, mTZUpdater)); - long millis = System.currentTimeMillis(); - mBaseDate.set(millis); - - mEarliestStartHour = new int[mNumDays]; - mHasAllDayEvent = new boolean[mNumDays]; + setOnLongClickListener(this) + mBaseDate = Time(Utils.getTimeZone(context, mTZUpdater)) + val millis: Long = System.currentTimeMillis() + mBaseDate.set(millis) + mEarliestStartHour = IntArray(mNumDays) + mHasAllDayEvent = BooleanArray(mNumDays) // mLines is the array of points used with Canvas.drawLines() in // drawGridBackground() and drawAllDayEvents(). Its size depends // on the max number of lines that can ever be drawn by any single // drawLines() call in either of those methods. - final int maxGridLines = (24 + 1) // max horizontal lines we might draw - + (mNumDays + 1); // max vertical lines we might draw - mLines = new float[maxGridLines * 4]; + val maxGridLines = (24 + 1 // max horizontal lines we might draw + + (mNumDays + 1)) // max vertical lines we might draw + mLines = FloatArray(maxGridLines * 4) } /** * This is called when the popup window is pressed. */ - public void onClick(View v) { - if (v == mPopupView) { + fun onClick(v: View) { + if (v === mPopupView) { // Pretend it was a trackball click because that will always // jump to the "View event" screen. - switchViews(true /* trackball */); + switchViews(true /* trackball */) } } - public void handleOnResume() { - initAccessibilityVariables(); - if(Utils.getSharedPreference(mContext, OtherPreferences.KEY_OTHER_1, false)) { - mFutureBgColor = 0; + fun handleOnResume() { + initAccessibilityVariables() + if (Utils.getSharedPreference(mContext, OtherPreferences.KEY_OTHER_1, false)) { + mFutureBgColor = 0 } else { - mFutureBgColor = mFutureBgColorRes; - } - mIs24HourFormat = DateFormat.is24HourFormat(mContext); - mHourStrs = mIs24HourFormat ? CalendarData.s24Hours : CalendarData.s12HoursNoAmPm; - mFirstDayOfWeek = Utils.getFirstDayOfWeek(mContext); - mLastSelectionDayForAccessibility = 0; - mLastSelectionHourForAccessibility = 0; - mLastSelectedEventForAccessibility = null; - mSelectionMode = SELECTION_HIDDEN; - } - - private void initAccessibilityVariables() { - mAccessibilityMgr = (AccessibilityManager) mContext - .getSystemService(Service.ACCESSIBILITY_SERVICE); - mIsAccessibilityEnabled = mAccessibilityMgr != null && mAccessibilityMgr.isEnabled(); - mTouchExplorationEnabled = isTouchExplorationEnabled(); - } - + mFutureBgColor = mFutureBgColorRes + } + mIs24HourFormat = DateFormat.is24HourFormat(mContext) + mHourStrs = if (mIs24HourFormat) CalendarData.s24Hours else CalendarData.s12HoursNoAmPm + mFirstDayOfWeek = Utils.getFirstDayOfWeek(mContext) + mLastSelectionDayForAccessibility = 0 + mLastSelectionHourForAccessibility = 0 + mLastSelectedEventForAccessibility = null + mSelectionMode = SELECTION_HIDDEN + } + + private fun initAccessibilityVariables() { + mAccessibilityMgr = mContext + .getSystemService(Service.ACCESSIBILITY_SERVICE) as AccessibilityManager + mIsAccessibilityEnabled = mAccessibilityMgr != null && mAccessibilityMgr.isEnabled() + mTouchExplorationEnabled = isTouchExplorationEnabled + }/* ignore isDst */// We ignore the "isDst" field because we want normalize() to figure + // out the correct DST value and not adjust the selected time based + // on the current setting of DST. /** * Returns the start of the selected time in milliseconds since the epoch. * * @return selected time in UTC milliseconds since the epoch. */ - long getSelectedTimeInMillis() { - Time time = new Time(mBaseDate); - time.setJulianDay(mSelectionDay); - time.hour = mSelectionHour; - - // We ignore the "isDst" field because we want normalize() to figure - // out the correct DST value and not adjust the selected time based - // on the current setting of DST. - return time.normalize(true /* ignore isDst */); - } - - Time getSelectedTime() { - Time time = new Time(mBaseDate); - time.setJulianDay(mSelectionDay); - time.hour = mSelectionHour; - - // We ignore the "isDst" field because we want normalize() to figure - // out the correct DST value and not adjust the selected time based - // on the current setting of DST. - time.normalize(true /* ignore isDst */); - return time; - } - - Time getSelectedTimeForAccessibility() { - Time time = new Time(mBaseDate); - time.setJulianDay(mSelectionDayForAccessibility); - time.hour = mSelectionHourForAccessibility; - - // We ignore the "isDst" field because we want normalize() to figure - // out the correct DST value and not adjust the selected time based - // on the current setting of DST. - time.normalize(true /* ignore isDst */); - return time; - } + val selectedTimeInMillis: Long + get() { + val time = Time(mBaseDate) + time.setJulianDay(mSelectionDay) + time.hour = mSelectionHour + + // We ignore the "isDst" field because we want normalize() to figure + // out the correct DST value and not adjust the selected time based + // on the current setting of DST. + return time.normalize(true /* ignore isDst */) + }/* ignore isDst */ + + // We ignore the "isDst" field because we want normalize() to figure + // out the correct DST value and not adjust the selected time based + // on the current setting of DST. + val selectedTime: Time + get() { + val time = Time(mBaseDate) + time.setJulianDay(mSelectionDay) + time.hour = mSelectionHour + + // We ignore the "isDst" field because we want normalize() to figure + // out the correct DST value and not adjust the selected time based + // on the current setting of DST. + time.normalize(true /* ignore isDst */) + return time + }/* ignore isDst */ + + // We ignore the "isDst" field because we want normalize() to figure + // out the correct DST value and not adjust the selected time based + // on the current setting of DST. + val selectedTimeForAccessibility: Time + get() { + val time = Time(mBaseDate) + time.setJulianDay(mSelectionDayForAccessibility) + time.hour = mSelectionHourForAccessibility + + // We ignore the "isDst" field because we want normalize() to figure + // out the correct DST value and not adjust the selected time based + // on the current setting of DST. + time.normalize(true /* ignore isDst */) + return time + } /** * Returns the start of the selected time in minutes since midnight, * local time. The derived class must ensure that this is consistent * with the return value from getSelectedTimeInMillis(). */ - int getSelectedMinutesSinceMidnight() { - return mSelectionHour * MINUTES_PER_HOUR; - } - - int getFirstVisibleHour() { - return mFirstHour; - } - - void setFirstVisibleHour(int firstHour) { - mFirstHour = firstHour; - mFirstHourOffset = 0; - } - - public void setSelected(Time time, boolean ignoreTime, boolean animateToday) { - mBaseDate.set(time); - setSelectedHour(mBaseDate.hour); - setSelectedEvent(null); - mPrevSelectedEvent = null; - long millis = mBaseDate.toMillis(false /* use isDst */); - setSelectedDay(Time.getJulianDay(millis, mBaseDate.gmtoff)); - mSelectedEvents.clear(); - mComputeSelectedEvents = true; - - int gotoY = Integer.MIN_VALUE; - + val selectedMinutesSinceMidnight: Int + get() = mSelectionHour * MINUTES_PER_HOUR + var firstVisibleHour: Int + get() = mFirstHour + set(firstHour) { + mFirstHour = firstHour + mFirstHourOffset = 0 + } + + fun setSelected(time: Time?, ignoreTime: Boolean, animateToday: Boolean) { + mBaseDate.set(time) + setSelectedHour(mBaseDate.hour) + setSelectedEvent(null) + mPrevSelectedEvent = null + val millis: Long = mBaseDate.toMillis(false /* use isDst */) + selectedDay = Time.getJulianDay(millis, mBaseDate.gmtoff) + mSelectedEvents.clear() + mComputeSelectedEvents = true + var gotoY: Int = Integer.MIN_VALUE if (!ignoreTime && mGridAreaHeight != -1) { - int lastHour = 0; - + var lastHour = 0 if (mBaseDate.hour < mFirstHour) { // Above visible region - gotoY = mBaseDate.hour * (mCellHeight + HOUR_GAP); + gotoY = mBaseDate.hour * (mCellHeight + HOUR_GAP) } else { - lastHour = (mGridAreaHeight - mFirstHourOffset) / (mCellHeight + HOUR_GAP) - + mFirstHour; - + lastHour = ((mGridAreaHeight - mFirstHourOffset) / (mCellHeight + HOUR_GAP) + + mFirstHour) if (mBaseDate.hour >= lastHour) { // Below visible region // target hour + 1 (to give it room to see the event) - // grid height (to get the y of the top of the visible // region) - gotoY = (int) ((mBaseDate.hour + 1 + mBaseDate.minute / 60.0f) - * (mCellHeight + HOUR_GAP) - mGridAreaHeight); + gotoY = ((mBaseDate.hour + 1 + mBaseDate.minute / 60.0f) + * (mCellHeight + HOUR_GAP) - mGridAreaHeight) } } - if (DEBUG) { - Log.e(TAG, "Go " + gotoY + " 1st " + mFirstHour + ":" + mFirstHourOffset + "CH " - + (mCellHeight + HOUR_GAP) + " lh " + lastHour + " gh " + mGridAreaHeight - + " ymax " + mMaxViewStartY); + Log.e( + TAG, "Go " + gotoY + " 1st " + mFirstHour + ":" + mFirstHourOffset + "CH " + + (mCellHeight + HOUR_GAP) + " lh " + lastHour + " gh " + mGridAreaHeight + + " ymax " + mMaxViewStartY + ) } - if (gotoY > mMaxViewStartY) { - gotoY = mMaxViewStartY; + gotoY = mMaxViewStartY } else if (gotoY < 0 && gotoY != Integer.MIN_VALUE) { - gotoY = 0; + gotoY = 0 } } - - recalc(); - - mRemeasure = true; - invalidate(); - - boolean delayAnimateToday = false; + recalc() + mRemeasure = true + invalidate() + var delayAnimateToday = false if (gotoY != Integer.MIN_VALUE) { - ValueAnimator scrollAnim = ObjectAnimator.ofInt(this, "viewStartY", mViewStartY, gotoY); - scrollAnim.setDuration(GOTO_SCROLL_DURATION); - scrollAnim.setInterpolator(new AccelerateDecelerateInterpolator()); - scrollAnim.addListener(mAnimatorListener); - scrollAnim.start(); - delayAnimateToday = true; + val scrollAnim: ValueAnimator = + ObjectAnimator.ofInt(this, "viewStartY", mViewStartY, gotoY) + scrollAnim.setDuration(GOTO_SCROLL_DURATION) + scrollAnim.setInterpolator(AccelerateDecelerateInterpolator()) + scrollAnim.addListener(mAnimatorListener) + scrollAnim.start() + delayAnimateToday = true } if (animateToday) { - synchronized (mTodayAnimatorListener) { + synchronized(mTodayAnimatorListener) { if (mTodayAnimator != null) { - mTodayAnimator.removeAllListeners(); - mTodayAnimator.cancel(); + mTodayAnimator.removeAllListeners() + mTodayAnimator.cancel() } - mTodayAnimator = ObjectAnimator.ofInt(this, "animateTodayAlpha", - mAnimateTodayAlpha, 255); - mAnimateToday = true; - mTodayAnimatorListener.setFadingIn(true); - mTodayAnimatorListener.setAnimator(mTodayAnimator); - mTodayAnimator.addListener(mTodayAnimatorListener); - mTodayAnimator.setDuration(150); + mTodayAnimator = ObjectAnimator.ofInt( + this, "animateTodayAlpha", + mAnimateTodayAlpha, 255 + ) + mAnimateToday = true + mTodayAnimatorListener.setFadingIn(true) + mTodayAnimatorListener.setAnimator(mTodayAnimator) + mTodayAnimator.addListener(mTodayAnimatorListener) + mTodayAnimator.setDuration(150) if (delayAnimateToday) { - mTodayAnimator.setStartDelay(GOTO_SCROLL_DURATION); + mTodayAnimator.setStartDelay(GOTO_SCROLL_DURATION) } - mTodayAnimator.start(); + mTodayAnimator.start() } } - sendAccessibilityEventAsNeeded(false); + sendAccessibilityEventAsNeeded(false) } // Called from animation framework via reflection. Do not remove - public void setViewStartY(int viewStartY) { + fun setViewStartY(viewStartY: Int) { + var viewStartY = viewStartY if (viewStartY > mMaxViewStartY) { - viewStartY = mMaxViewStartY; - } - - mViewStartY = viewStartY; - - computeFirstHour(); - invalidate(); - } - - public void setAnimateTodayAlpha(int todayAlpha) { - mAnimateTodayAlpha = todayAlpha; - invalidate(); - } - - public Time getSelectedDay() { - Time time = new Time(mBaseDate); - time.setJulianDay(mSelectionDay); - time.hour = mSelectionHour; - - // We ignore the "isDst" field because we want normalize() to figure - // out the correct DST value and not adjust the selected time based - // on the current setting of DST. - time.normalize(true /* ignore isDst */); - return time; - } - - public void updateTitle() { - Time start = new Time(mBaseDate); - start.normalize(true); - Time end = new Time(start); - end.monthDay += mNumDays - 1; + viewStartY = mMaxViewStartY + } + mViewStartY = viewStartY + computeFirstHour() + invalidate() + } + + fun setAnimateTodayAlpha(todayAlpha: Int) { + mAnimateTodayAlpha = todayAlpha + invalidate() + }/* ignore isDst */ + + // We ignore the "isDst" field because we want normalize() to figure + // out the correct DST value and not adjust the selected time based + // on the current setting of DST. + var selectedDay: Time + get() { + val time = Time(mBaseDate) + time.setJulianDay(mSelectionDay) + time.hour = mSelectionHour + + // We ignore the "isDst" field because we want normalize() to figure + // out the correct DST value and not adjust the selected time based + // on the current setting of DST. + time.normalize(true /* ignore isDst */) + return time + } + private set(d) { + mSelectionDay = d + mSelectionDayForAccessibility = d + } + + fun updateTitle() { + val start = Time(mBaseDate) + start.normalize(true) + val end = Time(start) + end.monthDay += mNumDays - 1 // Move it forward one minute so the formatter doesn't lose a day - end.minute += 1; - end.normalize(true); - - long formatFlags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR; + end.minute += 1 + end.normalize(true) + var formatFlags: Long = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_YEAR if (mNumDays != 1) { // Don't show day of the month if for multi-day view - formatFlags |= DateUtils.FORMAT_NO_MONTH_DAY; + formatFlags = formatFlags or DateUtils.FORMAT_NO_MONTH_DAY // Abbreviate the month if showing multiple months - if (start.month != end.month) { - formatFlags |= DateUtils.FORMAT_ABBREV_MONTH; + if (start.month !== end.month) { + formatFlags = formatFlags or DateUtils.FORMAT_ABBREV_MONTH } } - - mController.sendEvent(this, EventType.UPDATE_TITLE, start, end, null, -1, ViewType.CURRENT, - formatFlags, null, null); + mController.sendEvent( + this, EventType.UPDATE_TITLE, start, end, null, -1, ViewType.CURRENT, + formatFlags, null, null + ) } /** @@ -1127,139 +728,130 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * range, a positive number if "time" is after the visible time range, and 0 * if it is in the visible time range. */ - public int compareToVisibleTimeRange(Time time) { - - int savedHour = mBaseDate.hour; - int savedMinute = mBaseDate.minute; - int savedSec = mBaseDate.second; - - mBaseDate.hour = 0; - mBaseDate.minute = 0; - mBaseDate.second = 0; - + fun compareToVisibleTimeRange(time: Time): Int { + val savedHour: Int = mBaseDate.hour + val savedMinute: Int = mBaseDate.minute + val savedSec: Int = mBaseDate.second + mBaseDate.hour = 0 + mBaseDate.minute = 0 + mBaseDate.second = 0 if (DEBUG) { - Log.d(TAG, "Begin " + mBaseDate.toString()); - Log.d(TAG, "Diff " + time.toString()); + Log.d(TAG, "Begin " + mBaseDate.toString()) + Log.d(TAG, "Diff " + time.toString()) } // Compare beginning of range - int diff = Time.compare(time, mBaseDate); + var diff: Int = Time.compare(time, mBaseDate) if (diff > 0) { // Compare end of range - mBaseDate.monthDay += mNumDays; - mBaseDate.normalize(true); - diff = Time.compare(time, mBaseDate); - - if (DEBUG) Log.d(TAG, "End " + mBaseDate.toString()); - - mBaseDate.monthDay -= mNumDays; - mBaseDate.normalize(true); + mBaseDate.monthDay += mNumDays + mBaseDate.normalize(true) + diff = Time.compare(time, mBaseDate) + if (DEBUG) Log.d(TAG, "End " + mBaseDate.toString()) + mBaseDate.monthDay -= mNumDays + mBaseDate.normalize(true) if (diff < 0) { // in visible time - diff = 0; + diff = 0 } else if (diff == 0) { // Midnight of following day - diff = 1; + diff = 1 } } - - if (DEBUG) Log.d(TAG, "Diff: " + diff); - - mBaseDate.hour = savedHour; - mBaseDate.minute = savedMinute; - mBaseDate.second = savedSec; - return diff; + if (DEBUG) Log.d(TAG, "Diff: $diff") + mBaseDate.hour = savedHour + mBaseDate.minute = savedMinute + mBaseDate.second = savedSec + return diff } - private void recalc() { + private fun recalc() { // Set the base date to the beginning of the week if we are displaying // 7 days at a time. if (mNumDays == 7) { - adjustToBeginningOfWeek(mBaseDate); + adjustToBeginningOfWeek(mBaseDate) } - - final long start = mBaseDate.toMillis(false /* use isDst */); - mFirstJulianDay = Time.getJulianDay(start, mBaseDate.gmtoff); - mLastJulianDay = mFirstJulianDay + mNumDays - 1; - - mMonthLength = mBaseDate.getActualMaximum(Time.MONTH_DAY); - mFirstVisibleDate = mBaseDate.monthDay; - mFirstVisibleDayOfWeek = mBaseDate.weekDay; + val start: Long = mBaseDate.toMillis(false /* use isDst */) + mFirstJulianDay = Time.getJulianDay(start, mBaseDate.gmtoff) + mLastJulianDay = mFirstJulianDay + mNumDays - 1 + mMonthLength = mBaseDate.getActualMaximum(Time.MONTH_DAY) + mFirstVisibleDate = mBaseDate.monthDay + mFirstVisibleDayOfWeek = mBaseDate.weekDay } - private void adjustToBeginningOfWeek(Time time) { - int dayOfWeek = time.weekDay; - int diff = dayOfWeek - mFirstDayOfWeek; + private fun adjustToBeginningOfWeek(time: Time?) { + val dayOfWeek: Int = time.weekDay + var diff = dayOfWeek - mFirstDayOfWeek if (diff != 0) { if (diff < 0) { - diff += 7; + diff += 7 } - time.monthDay -= diff; - time.normalize(true /* ignore isDst */); + time.monthDay -= diff + time.normalize(true /* ignore isDst */) } } @Override - protected void onSizeChanged(int width, int height, int oldw, int oldh) { - mViewWidth = width; - mViewHeight = height; - mEdgeEffectTop.setSize(mViewWidth, mViewHeight); - mEdgeEffectBottom.setSize(mViewWidth, mViewHeight); - int gridAreaWidth = width - mHoursWidth; - mCellWidth = (gridAreaWidth - (mNumDays * DAY_GAP)) / mNumDays; + protected fun onSizeChanged(width: Int, height: Int, oldw: Int, oldh: Int) { + mViewWidth = width + mViewHeight = height + mEdgeEffectTop.setSize(mViewWidth, mViewHeight) + mEdgeEffectBottom.setSize(mViewWidth, mViewHeight) + val gridAreaWidth = width - mHoursWidth + mCellWidth = (gridAreaWidth - mNumDays * DAY_GAP) / mNumDays // This would be about 1 day worth in a 7 day view - mHorizontalSnapBackThreshold = width / 7; - - Paint p = new Paint(); - p.setTextSize(HOURS_TEXT_SIZE); - mHoursTextHeight = (int) Math.abs(p.ascent()); - remeasure(width, height); + mHorizontalSnapBackThreshold = width / 7 + val p = Paint() + p.setTextSize(HOURS_TEXT_SIZE) + mHoursTextHeight = Math.abs(p.ascent()) + remeasure(width, height) } /** * Measures the space needed for various parts of the view after * loading new events. This can change if there are all-day events. */ - private void remeasure(int width, int height) { + private fun remeasure(width: Int, height: Int) { // Shrink to fit available space but make sure we can display at least two events - MAX_UNEXPANDED_ALLDAY_HEIGHT = (int) (MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT * 4); - MAX_UNEXPANDED_ALLDAY_HEIGHT = Math.min(MAX_UNEXPANDED_ALLDAY_HEIGHT, height / 6); - MAX_UNEXPANDED_ALLDAY_HEIGHT = Math.max(MAX_UNEXPANDED_ALLDAY_HEIGHT, - (int) MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT * 2); + MAX_UNEXPANDED_ALLDAY_HEIGHT = (MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT * 4).toInt() + MAX_UNEXPANDED_ALLDAY_HEIGHT = Math.min(MAX_UNEXPANDED_ALLDAY_HEIGHT, height / 6) + MAX_UNEXPANDED_ALLDAY_HEIGHT = Math.max( + MAX_UNEXPANDED_ALLDAY_HEIGHT, + MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt() * 2 + ) mMaxUnexpandedAlldayEventCount = - (int) (MAX_UNEXPANDED_ALLDAY_HEIGHT / MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT); + (MAX_UNEXPANDED_ALLDAY_HEIGHT / MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt() // First, clear the array of earliest start times, and the array // indicating presence of an all-day event. - for (int day = 0; day < mNumDays; day++) { - mEarliestStartHour[day] = 25; // some big number - mHasAllDayEvent[day] = false; + for (day in 0 until mNumDays) { + mEarliestStartHour[day] = 25 // some big number + mHasAllDayEvent[day] = false } - - int maxAllDayEvents = mMaxAlldayEvents; + val maxAllDayEvents = mMaxAlldayEvents // The min is where 24 hours cover the entire visible area - mMinCellHeight = Math.max((height - DAY_HEADER_HEIGHT) / 24, (int) MIN_EVENT_HEIGHT); + mMinCellHeight = Math.max((height - DAY_HEADER_HEIGHT) / 24, MIN_EVENT_HEIGHT.toInt()) if (mCellHeight < mMinCellHeight) { - mCellHeight = mMinCellHeight; + mCellHeight = mMinCellHeight } // Calculate mAllDayHeight - mFirstCell = DAY_HEADER_HEIGHT; - int allDayHeight = 0; + mFirstCell = DAY_HEADER_HEIGHT + var allDayHeight = 0 if (maxAllDayEvents > 0) { - int maxAllAllDayHeight = height - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT; + val maxAllAllDayHeight = height - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT // If there is at most one all-day event per day, then use less // space (but more than the space for a single event). if (maxAllDayEvents == 1) { - allDayHeight = SINGLE_ALLDAY_HEIGHT; - } else if (maxAllDayEvents <= mMaxUnexpandedAlldayEventCount){ + allDayHeight = SINGLE_ALLDAY_HEIGHT + } else if (maxAllDayEvents <= mMaxUnexpandedAlldayEventCount) { // Allow the all-day area to grow in height depending on the // number of all-day events we need to show, up to a limit. - allDayHeight = maxAllDayEvents * MAX_HEIGHT_OF_ONE_ALLDAY_EVENT; + allDayHeight = maxAllDayEvents * MAX_HEIGHT_OF_ONE_ALLDAY_EVENT if (allDayHeight > MAX_UNEXPANDED_ALLDAY_HEIGHT) { - allDayHeight = MAX_UNEXPANDED_ALLDAY_HEIGHT; + allDayHeight = MAX_UNEXPANDED_ALLDAY_HEIGHT } } else { // if we have more than the magic number, check if we're animating @@ -1268,58 +860,58 @@ public class DayView extends View implements View.OnCreateContextMenuListener, // Don't shrink the space past the final allDay space. The animation // continues to hide the last event so the more events text can // fade in. - allDayHeight = Math.max(mAnimateDayHeight, MAX_UNEXPANDED_ALLDAY_HEIGHT); + allDayHeight = Math.max(mAnimateDayHeight, MAX_UNEXPANDED_ALLDAY_HEIGHT) } else { // Try to fit all the events in - allDayHeight = (int) (maxAllDayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT); + allDayHeight = (maxAllDayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt() // But clip the area depending on which mode we're in if (!mShowAllAllDayEvents && allDayHeight > MAX_UNEXPANDED_ALLDAY_HEIGHT) { - allDayHeight = (int) (mMaxUnexpandedAlldayEventCount * - MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT); + allDayHeight = (mMaxUnexpandedAlldayEventCount * + MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt() } else if (allDayHeight > maxAllAllDayHeight) { - allDayHeight = maxAllAllDayHeight; + allDayHeight = maxAllAllDayHeight } } } - mFirstCell = DAY_HEADER_HEIGHT + allDayHeight + ALLDAY_TOP_MARGIN; + mFirstCell = DAY_HEADER_HEIGHT + allDayHeight + ALLDAY_TOP_MARGIN } else { - mSelectionAllday = false; + mSelectionAllday = false } - mAlldayHeight = allDayHeight; - - mGridAreaHeight = height - mFirstCell; + mAlldayHeight = allDayHeight + mGridAreaHeight = height - mFirstCell // Set up the expand icon position - int allDayIconWidth = mExpandAlldayDrawable.getIntrinsicWidth(); - mExpandAllDayRect.left = Math.max((mHoursWidth - allDayIconWidth) / 2, - EVENT_ALL_DAY_TEXT_LEFT_MARGIN); - mExpandAllDayRect.right = Math.min(mExpandAllDayRect.left + allDayIconWidth, mHoursWidth - - EVENT_ALL_DAY_TEXT_RIGHT_MARGIN); - mExpandAllDayRect.bottom = mFirstCell - EXPAND_ALL_DAY_BOTTOM_MARGIN; - mExpandAllDayRect.top = mExpandAllDayRect.bottom - - mExpandAlldayDrawable.getIntrinsicHeight(); - - mNumHours = mGridAreaHeight / (mCellHeight + HOUR_GAP); - mEventGeometry.setHourHeight(mCellHeight); - - final long minimumDurationMillis = (long) - (MIN_EVENT_HEIGHT * DateUtils.MINUTE_IN_MILLIS / (mCellHeight / 60.0f)); - Event.computePositions(mEvents, minimumDurationMillis); + val allDayIconWidth: Int = mExpandAlldayDrawable.getIntrinsicWidth() + mExpandAllDayRect.left = Math.max( + (mHoursWidth - allDayIconWidth) / 2, + EVENT_ALL_DAY_TEXT_LEFT_MARGIN + ) + mExpandAllDayRect.right = Math.min( + mExpandAllDayRect.left + allDayIconWidth, mHoursWidth + - EVENT_ALL_DAY_TEXT_RIGHT_MARGIN + ) + mExpandAllDayRect.bottom = mFirstCell - EXPAND_ALL_DAY_BOTTOM_MARGIN + mExpandAllDayRect.top = (mExpandAllDayRect.bottom + - mExpandAlldayDrawable.getIntrinsicHeight()) + mNumHours = mGridAreaHeight / (mCellHeight + HOUR_GAP) + mEventGeometry.setHourHeight(mCellHeight) + val minimumDurationMillis = + (MIN_EVENT_HEIGHT * DateUtils.MINUTE_IN_MILLIS / (mCellHeight / 60.0f)) as Long + Event.computePositions(mEvents, minimumDurationMillis) // Compute the top of our reachable view - mMaxViewStartY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP) - mGridAreaHeight; + mMaxViewStartY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP) - mGridAreaHeight if (DEBUG) { - Log.e(TAG, "mViewStartY: " + mViewStartY); - Log.e(TAG, "mMaxViewStartY: " + mMaxViewStartY); + Log.e(TAG, "mViewStartY: $mViewStartY") + Log.e(TAG, "mMaxViewStartY: $mMaxViewStartY") } if (mViewStartY > mMaxViewStartY) { - mViewStartY = mMaxViewStartY; - computeFirstHour(); + mViewStartY = mMaxViewStartY + computeFirstHour() } - if (mFirstHour == -1) { - initFirstHour(); - mFirstHourOffset = 0; + initFirstHour() + mFirstHourOffset = 0 } // When we change the base date, the number of all-day events may @@ -1327,17 +919,16 @@ public class DayView extends View implements View.OnCreateContextMenuListener, // we use the mFirstHourOffset from the previous view, but that may // be too large for the new view if the cell height is smaller. if (mFirstHourOffset >= mCellHeight + HOUR_GAP) { - mFirstHourOffset = mCellHeight + HOUR_GAP - 1; + mFirstHourOffset = mCellHeight + HOUR_GAP - 1 } - mViewStartY = mFirstHour * (mCellHeight + HOUR_GAP) - mFirstHourOffset; - - final int eventAreaWidth = mNumDays * (mCellWidth + DAY_GAP); + mViewStartY = mFirstHour * (mCellHeight + HOUR_GAP) - mFirstHourOffset + val eventAreaWidth = mNumDays * (mCellWidth + DAY_GAP) //When we get new events we don't want to dismiss the popup unless the event changes if (mSelectedEvent != null && mLastPopupEventID != mSelectedEvent.id) { - mPopup.dismiss(); + mPopup.dismiss() } - mPopup.setWidth(eventAreaWidth - 20); - mPopup.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); + mPopup.setWidth(eventAreaWidth - 20) + mPopup.setHeight(WindowManager.LayoutParams.WRAP_CONTENT) } /** @@ -1348,28 +939,27 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * * @param view the view to initialize. */ - private void initView(DayView view) { - view.setSelectedHour(mSelectionHour); - view.mSelectedEvents.clear(); - view.mComputeSelectedEvents = true; - view.mFirstHour = mFirstHour; - view.mFirstHourOffset = mFirstHourOffset; - view.remeasure(getWidth(), getHeight()); - view.initAllDayHeights(); - - view.setSelectedEvent(null); - view.mPrevSelectedEvent = null; - view.mFirstDayOfWeek = mFirstDayOfWeek; + private fun initView(view: DayView) { + view.setSelectedHour(mSelectionHour) + view.mSelectedEvents.clear() + view.mComputeSelectedEvents = true + view.mFirstHour = mFirstHour + view.mFirstHourOffset = mFirstHourOffset + view.remeasure(getWidth(), getHeight()) + view.initAllDayHeights() + view.setSelectedEvent(null) + view.mPrevSelectedEvent = null + view.mFirstDayOfWeek = mFirstDayOfWeek if (view.mEvents.size() > 0) { - view.mSelectionAllday = mSelectionAllday; + view.mSelectionAllday = mSelectionAllday } else { - view.mSelectionAllday = false; + view.mSelectionAllday = false } // Redraw the screen so that the selection box will be redrawn. We may // have scrolled to a different part of the day in some other view // so the selection box in this view may no longer be visible. - view.recalc(); + view.recalc() } /** @@ -1379,11 +969,10 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * @param trackBallSelection true if the selection was made using the * trackball. */ - private void switchViews(boolean trackBallSelection) { - Event selectedEvent = mSelectedEvent; - - mPopup.dismiss(); - mLastPopupEventID = INVALID_EVENT_ID; + private fun switchViews(trackBallSelection: Boolean) { + val selectedEvent: Event? = mSelectedEvent + mPopup.dismiss() + mLastPopupEventID = INVALID_EVENT_ID if (mNumDays > 1) { // This is the Week view. // With touch, we always switch to Day/Agenda View @@ -1392,7 +981,7 @@ public class DayView extends View implements View.OnCreateContextMenuListener, if (trackBallSelection) { if (selectedEvent != null) { if (mIsAccessibilityEnabled) { - mAccessibilityMgr.interrupt(); + mAccessibilityMgr.interrupt() } } } @@ -1400,91 +989,89 @@ public class DayView extends View implements View.OnCreateContextMenuListener, } @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - mScrolling = false; - return super.onKeyUp(keyCode, event); + fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { + mScrolling = false + return super.onKeyUp(keyCode, event) } @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - return super.onKeyDown(keyCode, event); + fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { + return super.onKeyDown(keyCode, event) } - @Override - public boolean onHoverEvent(MotionEvent event) { - return true; + fun onHoverEvent(event: MotionEvent?): Boolean { + return true } - private boolean isTouchExplorationEnabled() { - return mIsAccessibilityEnabled && mAccessibilityMgr.isTouchExplorationEnabled(); - } + private val isTouchExplorationEnabled: Boolean + private get() = mIsAccessibilityEnabled && mAccessibilityMgr.isTouchExplorationEnabled() - private void sendAccessibilityEventAsNeeded(boolean speakEvents) { + private fun sendAccessibilityEventAsNeeded(speakEvents: Boolean) { if (!mIsAccessibilityEnabled) { - return; + return } - boolean dayChanged = mLastSelectionDayForAccessibility != mSelectionDayForAccessibility; - boolean hourChanged = mLastSelectionHourForAccessibility != mSelectionHourForAccessibility; - if (dayChanged || hourChanged || - mLastSelectedEventForAccessibility != mSelectedEventForAccessibility) { - mLastSelectionDayForAccessibility = mSelectionDayForAccessibility; - mLastSelectionHourForAccessibility = mSelectionHourForAccessibility; - mLastSelectedEventForAccessibility = mSelectedEventForAccessibility; - - StringBuilder b = new StringBuilder(); + val dayChanged = mLastSelectionDayForAccessibility != mSelectionDayForAccessibility + val hourChanged = mLastSelectionHourForAccessibility != mSelectionHourForAccessibility + if (dayChanged || hourChanged || mLastSelectedEventForAccessibility !== mSelectedEventForAccessibility) { + mLastSelectionDayForAccessibility = mSelectionDayForAccessibility + mLastSelectionHourForAccessibility = mSelectionHourForAccessibility + mLastSelectedEventForAccessibility = mSelectedEventForAccessibility + val b = StringBuilder() // Announce only the changes i.e. day or hour or both if (dayChanged) { - b.append(getSelectedTimeForAccessibility().format("%A ")); + b.append(selectedTimeForAccessibility.format("%A ")) } if (hourChanged) { - b.append(getSelectedTimeForAccessibility().format(mIs24HourFormat ? "%k" : "%l%p")); + b.append(selectedTimeForAccessibility.format(if (mIs24HourFormat) "%k" else "%l%p")) } if (dayChanged || hourChanged) { - b.append(PERIOD_SPACE); + b.append(PERIOD_SPACE) } - if (speakEvents) { if (mEventCountTemplate == null) { - mEventCountTemplate = mContext.getString(R.string.template_announce_item_index); + mEventCountTemplate = mContext.getString(R.string.template_announce_item_index) } // Read out the relevant event(s) - int numEvents = mSelectedEvents.size(); + val numEvents: Int = mSelectedEvents.size() if (numEvents > 0) { if (mSelectedEventForAccessibility == null) { // Read out all the events - int i = 1; - for (Event calEvent : mSelectedEvents) { + var i = 1 + for (calEvent in mSelectedEvents) { if (numEvents > 1) { // Read out x of numEvents if there are more than one event - mStringBuilder.setLength(0); - b.append(mFormatter.format(mEventCountTemplate, i++, numEvents)); - b.append(" "); + mStringBuilder.setLength(0) + b.append(mFormatter.format(mEventCountTemplate, i++, numEvents)) + b.append(" ") } - appendEventAccessibilityString(b, calEvent); + appendEventAccessibilityString(b, calEvent) } } else { if (numEvents > 1) { // Read out x of numEvents if there are more than one event - mStringBuilder.setLength(0); - b.append(mFormatter.format(mEventCountTemplate, mSelectedEvents - .indexOf(mSelectedEventForAccessibility) + 1, numEvents)); - b.append(" "); + mStringBuilder.setLength(0) + b.append( + mFormatter.format( + mEventCountTemplate, mSelectedEvents + .indexOf(mSelectedEventForAccessibility) + 1, numEvents + ) + ) + b.append(" ") } - appendEventAccessibilityString(b, mSelectedEventForAccessibility); + appendEventAccessibilityString(b, mSelectedEventForAccessibility) } } } - if (dayChanged || hourChanged || speakEvents) { - AccessibilityEvent event = AccessibilityEvent - .obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED); - CharSequence msg = b.toString(); - event.getText().add(msg); - event.setAddedCount(msg.length()); - sendAccessibilityEventUnchecked(event); + val event: AccessibilityEvent = AccessibilityEvent + .obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED) + val msg: CharSequence = b.toString() + event.getText().add(msg) + event.setAddedCount(msg.length()) + sendAccessibilityEventUnchecked(event) } } } @@ -1493,159 +1080,153 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * @param b * @param calEvent */ - private void appendEventAccessibilityString(StringBuilder b, Event calEvent) { - b.append(calEvent.getTitleAndLocation()); - b.append(PERIOD_SPACE); - String when; - int flags = DateUtils.FORMAT_SHOW_DATE; + private fun appendEventAccessibilityString(b: StringBuilder, calEvent: Event?) { + b.append(calEvent.getTitleAndLocation()) + b.append(PERIOD_SPACE) + val `when`: String + var flags: Int = DateUtils.FORMAT_SHOW_DATE if (calEvent.allDay) { - flags |= DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_WEEKDAY; + flags = flags or (DateUtils.FORMAT_UTC or DateUtils.FORMAT_SHOW_WEEKDAY) } else { - flags |= DateUtils.FORMAT_SHOW_TIME; + flags = flags or DateUtils.FORMAT_SHOW_TIME if (DateFormat.is24HourFormat(mContext)) { - flags |= DateUtils.FORMAT_24HOUR; + flags = flags or DateUtils.FORMAT_24HOUR } } - when = Utils.formatDateRange(mContext, calEvent.startMillis, calEvent.endMillis, flags); - b.append(when); - b.append(PERIOD_SPACE); + `when` = Utils.formatDateRange(mContext, calEvent.startMillis, calEvent.endMillis, flags) + b.append(`when`) + b.append(PERIOD_SPACE) } - private class GotoBroadcaster implements Animation.AnimationListener { - private final int mCounter; - private final Time mStart; - private final Time mEnd; - - public GotoBroadcaster(Time start, Time end) { - mCounter = ++sCounter; - mStart = start; - mEnd = end; - } - + private inner class GotoBroadcaster(start: Time, end: Time) : Animation.AnimationListener { + private val mCounter: Int + private val mStart: Time + private val mEnd: Time @Override - public void onAnimationEnd(Animation animation) { - DayView view = (DayView) mViewSwitcher.getCurrentView(); - view.mViewStartX = 0; - view = (DayView) mViewSwitcher.getNextView(); - view.mViewStartX = 0; - + fun onAnimationEnd(animation: Animation?) { + var view = mViewSwitcher.getCurrentView() as DayView + view.mViewStartX = 0 + view = mViewSwitcher.getNextView() + view.mViewStartX = 0 if (mCounter == sCounter) { - mController.sendEvent(this, EventType.GO_TO, mStart, mEnd, null, -1, - ViewType.CURRENT, CalendarController.EXTRA_GOTO_DATE, null, null); + mController.sendEvent( + this, EventType.GO_TO, mStart, mEnd, null, -1, + ViewType.CURRENT, CalendarController.EXTRA_GOTO_DATE, null, null + ) } } @Override - public void onAnimationRepeat(Animation animation) { + fun onAnimationRepeat(animation: Animation?) { } @Override - public void onAnimationStart(Animation animation) { + fun onAnimationStart(animation: Animation?) { + } + + init { + mCounter = ++sCounter + mStart = start + mEnd = end } } - private View switchViews(boolean forward, float xOffSet, float width, float velocity) { - mAnimationDistance = width - xOffSet; + private fun switchViews(forward: Boolean, xOffSet: Float, width: Float, velocity: Float): View { + mAnimationDistance = width - xOffSet if (DEBUG) { - Log.d(TAG, "switchViews(" + forward + ") O:" + xOffSet + " Dist:" + mAnimationDistance); + Log.d(TAG, "switchViews($forward) O:$xOffSet Dist:$mAnimationDistance") } - - float progress = Math.abs(xOffSet) / width; + var progress: Float = Math.abs(xOffSet) / width if (progress > 1.0f) { - progress = 1.0f; + progress = 1.0f } - - float inFromXValue, inToXValue; - float outFromXValue, outToXValue; + val inFromXValue: Float + val inToXValue: Float + val outFromXValue: Float + val outToXValue: Float if (forward) { - inFromXValue = 1.0f - progress; - inToXValue = 0.0f; - outFromXValue = -progress; - outToXValue = -1.0f; + inFromXValue = 1.0f - progress + inToXValue = 0.0f + outFromXValue = -progress + outToXValue = -1.0f } else { - inFromXValue = progress - 1.0f; - inToXValue = 0.0f; - outFromXValue = progress; - outToXValue = 1.0f; + inFromXValue = progress - 1.0f + inToXValue = 0.0f + outFromXValue = progress + outToXValue = 1.0f } - - final Time start = new Time(mBaseDate.timezone); - start.set(mController.getTime()); + val start = Time(mBaseDate.timezone) + start.set(mController.getTime()) if (forward) { - start.monthDay += mNumDays; + start.monthDay += mNumDays } else { - start.monthDay -= mNumDays; + start.monthDay -= mNumDays } - mController.setTime(start.normalize(true)); - - Time newSelected = start; - + mController.setTime(start.normalize(true)) + var newSelected: Time? = start if (mNumDays == 7) { - newSelected = new Time(start); - adjustToBeginningOfWeek(start); + newSelected = Time(start) + adjustToBeginningOfWeek(start) } - - final Time end = new Time(start); - end.monthDay += mNumDays - 1; + val end = Time(start) + end.monthDay += mNumDays - 1 // We have to allocate these animation objects each time we switch views // because that is the only way to set the animation parameters. - TranslateAnimation inAnimation = new TranslateAnimation( - Animation.RELATIVE_TO_SELF, inFromXValue, - Animation.RELATIVE_TO_SELF, inToXValue, - Animation.ABSOLUTE, 0.0f, - Animation.ABSOLUTE, 0.0f); - - TranslateAnimation outAnimation = new TranslateAnimation( - Animation.RELATIVE_TO_SELF, outFromXValue, - Animation.RELATIVE_TO_SELF, outToXValue, - Animation.ABSOLUTE, 0.0f, - Animation.ABSOLUTE, 0.0f); - - long duration = calculateDuration(width - Math.abs(xOffSet), width, velocity); - inAnimation.setDuration(duration); - inAnimation.setInterpolator(mHScrollInterpolator); - outAnimation.setInterpolator(mHScrollInterpolator); - outAnimation.setDuration(duration); - outAnimation.setAnimationListener(new GotoBroadcaster(start, end)); - mViewSwitcher.setInAnimation(inAnimation); - mViewSwitcher.setOutAnimation(outAnimation); - - DayView view = (DayView) mViewSwitcher.getCurrentView(); - view.cleanup(); - mViewSwitcher.showNext(); - view = (DayView) mViewSwitcher.getCurrentView(); - view.setSelected(newSelected, true, false); - view.requestFocus(); - view.reloadEvents(); - view.updateTitle(); - view.restartCurrentTimeUpdates(); - - return view; + val inAnimation = TranslateAnimation( + Animation.RELATIVE_TO_SELF, inFromXValue, + Animation.RELATIVE_TO_SELF, inToXValue, + Animation.ABSOLUTE, 0.0f, + Animation.ABSOLUTE, 0.0f + ) + val outAnimation = TranslateAnimation( + Animation.RELATIVE_TO_SELF, outFromXValue, + Animation.RELATIVE_TO_SELF, outToXValue, + Animation.ABSOLUTE, 0.0f, + Animation.ABSOLUTE, 0.0f + ) + val duration = calculateDuration(width - Math.abs(xOffSet), width, velocity) + inAnimation.setDuration(duration) + inAnimation.setInterpolator(mHScrollInterpolator) + outAnimation.setInterpolator(mHScrollInterpolator) + outAnimation.setDuration(duration) + outAnimation.setAnimationListener(GotoBroadcaster(start, end)) + mViewSwitcher.setInAnimation(inAnimation) + mViewSwitcher.setOutAnimation(outAnimation) + var view = mViewSwitcher.getCurrentView() as DayView + view.cleanup() + mViewSwitcher.showNext() + view = mViewSwitcher.getCurrentView() + view.setSelected(newSelected, true, false) + view.requestFocus() + view.reloadEvents() + view.updateTitle() + view.restartCurrentTimeUpdates() + return view } // This is called after scrolling stops to move the selected hour // to the visible part of the screen. - private void resetSelectedHour() { + private fun resetSelectedHour() { if (mSelectionHour < mFirstHour + 1) { - setSelectedHour(mFirstHour + 1); - setSelectedEvent(null); - mSelectedEvents.clear(); - mComputeSelectedEvents = true; + setSelectedHour(mFirstHour + 1) + setSelectedEvent(null) + mSelectedEvents.clear() + mComputeSelectedEvents = true } else if (mSelectionHour > mFirstHour + mNumHours - 3) { - setSelectedHour(mFirstHour + mNumHours - 3); - setSelectedEvent(null); - mSelectedEvents.clear(); - mComputeSelectedEvents = true; + setSelectedHour(mFirstHour + mNumHours - 3) + setSelectedEvent(null) + mSelectedEvents.clear() + mComputeSelectedEvents = true } } - private void initFirstHour() { - mFirstHour = mSelectionHour - mNumHours / 5; + private fun initFirstHour() { + mFirstHour = mSelectionHour - mNumHours / 5 if (mFirstHour < 0) { - mFirstHour = 0; + mFirstHour = 0 } else if (mFirstHour + mNumHours > 24) { - mFirstHour = 24 - mNumHours; + mFirstHour = 24 - mNumHours } } @@ -1653,23 +1234,22 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * Recomputes the first full hour that is visible on screen after the * screen is scrolled. */ - private void computeFirstHour() { + private fun computeFirstHour() { // Compute the first full hour that is visible on screen - mFirstHour = (mViewStartY + mCellHeight + HOUR_GAP - 1) / (mCellHeight + HOUR_GAP); - mFirstHourOffset = mFirstHour * (mCellHeight + HOUR_GAP) - mViewStartY; + mFirstHour = (mViewStartY + mCellHeight + HOUR_GAP - 1) / (mCellHeight + HOUR_GAP) + mFirstHourOffset = mFirstHour * (mCellHeight + HOUR_GAP) - mViewStartY } - private void adjustHourSelection() { + private fun adjustHourSelection() { if (mSelectionHour < 0) { - setSelectedHour(0); + setSelectedHour(0) if (mMaxAlldayEvents > 0) { - mPrevSelectedEvent = null; - mSelectionAllday = true; + mPrevSelectedEvent = null + mSelectionAllday = true } } - if (mSelectionHour > 23) { - setSelectedHour(23); + setSelectedHour(23) } // If the selected hour is at least 2 time slots from the top and @@ -1682,52 +1262,48 @@ public class DayView extends View implements View.OnCreateContextMenuListener, // before jumping to the all-day event area. // Exception 2: if 12am is on screen, then allow the user to select // 12am before going up to the all-day event area. - int daynum = mSelectionDay - mFirstJulianDay; - if (daynum < mEarliestStartHour.length && daynum >= 0 - && mMaxAlldayEvents > 0 - && mEarliestStartHour[daynum] > mSelectionHour - && mFirstHour > 0 && mFirstHour < 8) { - mPrevSelectedEvent = null; - mSelectionAllday = true; - setSelectedHour(mFirstHour + 1); - return; + val daynum = mSelectionDay - mFirstJulianDay + if (daynum < mEarliestStartHour.size && daynum >= 0 && mMaxAlldayEvents > 0 && mEarliestStartHour[daynum] > mSelectionHour && mFirstHour > 0 && mFirstHour < 8) { + mPrevSelectedEvent = null + mSelectionAllday = true + setSelectedHour(mFirstHour + 1) + return } - if (mFirstHour > 0) { - mFirstHour -= 1; - mViewStartY -= (mCellHeight + HOUR_GAP); + mFirstHour -= 1 + mViewStartY -= mCellHeight + HOUR_GAP if (mViewStartY < 0) { - mViewStartY = 0; + mViewStartY = 0 } - return; + return } } - if (mSelectionHour > mFirstHour + mNumHours - 3) { if (mFirstHour < 24 - mNumHours) { - mFirstHour += 1; - mViewStartY += (mCellHeight + HOUR_GAP); + mFirstHour += 1 + mViewStartY += mCellHeight + HOUR_GAP if (mViewStartY > mMaxViewStartY) { - mViewStartY = mMaxViewStartY; + mViewStartY = mMaxViewStartY } - return; + return } else if (mFirstHour == 24 - mNumHours && mFirstHourOffset > 0) { - mViewStartY = mMaxViewStartY; + mViewStartY = mMaxViewStartY } } } - void clearCachedEvents() { - mLastReloadMillis = 0; + fun clearCachedEvents() { + mLastReloadMillis = 0 } - private final Runnable mCancelCallback = new Runnable() { - public void run() { - clearCachedEvents(); + private val mCancelCallback: Runnable = object : Runnable() { + fun run() { + clearCachedEvents() } - }; + } - /* package */ void reloadEvents() { + /* package */ + fun reloadEvents() { // Protect against this being called before this view has been // initialized. // if (mContext == null) { @@ -1735,99 +1311,92 @@ public class DayView extends View implements View.OnCreateContextMenuListener, // } // Make sure our time zones are up to date - mTZUpdater.run(); - - setSelectedEvent(null); - mPrevSelectedEvent = null; - mSelectedEvents.clear(); + mTZUpdater.run() + setSelectedEvent(null) + mPrevSelectedEvent = null + mSelectedEvents.clear() // The start date is the beginning of the week at 12am - Time weekStart = new Time(Utils.getTimeZone(mContext, mTZUpdater)); - weekStart.set(mBaseDate); - weekStart.hour = 0; - weekStart.minute = 0; - weekStart.second = 0; - long millis = weekStart.normalize(true /* ignore isDst */); + val weekStart = Time(Utils.getTimeZone(mContext, mTZUpdater)) + weekStart.set(mBaseDate) + weekStart.hour = 0 + weekStart.minute = 0 + weekStart.second = 0 + val millis: Long = weekStart.normalize(true /* ignore isDst */) // Avoid reloading events unnecessarily. if (millis == mLastReloadMillis) { - return; + return } - mLastReloadMillis = millis; + mLastReloadMillis = millis // load events in the background // mContext.startProgressSpinner(); - final ArrayList<Event> events = new ArrayList<Event>(); - mEventLoader.loadEventsInBackground(mNumDays, events, mFirstJulianDay, new Runnable() { - - public void run() { - boolean fadeinEvents = mFirstJulianDay != mLoadedFirstJulianDay; - mEvents = events; - mLoadedFirstJulianDay = mFirstJulianDay; + val events: ArrayList<Event> = ArrayList<Event>() + mEventLoader.loadEventsInBackground(mNumDays, events, mFirstJulianDay, object : Runnable() { + fun run() { + val fadeinEvents = mFirstJulianDay != mLoadedFirstJulianDay + mEvents = events + mLoadedFirstJulianDay = mFirstJulianDay if (mAllDayEvents == null) { - mAllDayEvents = new ArrayList<Event>(); + mAllDayEvents = ArrayList<Event>() } else { - mAllDayEvents.clear(); + mAllDayEvents.clear() } // Create a shorter array for all day events - for (Event e : events) { + for (e in events) { if (e.drawAsAllday()) { - mAllDayEvents.add(e); + mAllDayEvents.add(e) } } // New events, new layouts - if (mLayouts == null || mLayouts.length < events.size()) { - mLayouts = new StaticLayout[events.size()]; + if (mLayouts == null || mLayouts!!.size < events.size()) { + mLayouts = arrayOfNulls<StaticLayout>(events.size()) } else { - Arrays.fill(mLayouts, null); + Arrays.fill(mLayouts, null) } - - if (mAllDayLayouts == null || mAllDayLayouts.length < mAllDayEvents.size()) { - mAllDayLayouts = new StaticLayout[events.size()]; + if (mAllDayLayouts == null || mAllDayLayouts!!.size < mAllDayEvents.size()) { + mAllDayLayouts = arrayOfNulls<StaticLayout>(events.size()) } else { - Arrays.fill(mAllDayLayouts, null); + Arrays.fill(mAllDayLayouts, null) } - - computeEventRelations(); - - mRemeasure = true; - mComputeSelectedEvents = true; - recalc(); + computeEventRelations() + mRemeasure = true + mComputeSelectedEvents = true + recalc() // Start animation to cross fade the events if (fadeinEvents) { if (mEventsCrossFadeAnimation == null) { mEventsCrossFadeAnimation = - ObjectAnimator.ofInt(DayView.this, "EventsAlpha", 0, 255); - mEventsCrossFadeAnimation.setDuration(EVENTS_CROSS_FADE_DURATION); + ObjectAnimator.ofInt(this@DayView, "EventsAlpha", 0, 255) + mEventsCrossFadeAnimation.setDuration(EVENTS_CROSS_FADE_DURATION) } - mEventsCrossFadeAnimation.start(); - } else{ - invalidate(); + mEventsCrossFadeAnimation.start() + } else { + invalidate() } } - }, mCancelCallback); + }, mCancelCallback) } - public void setEventsAlpha(int alpha) { - mEventsAlpha = alpha; - invalidate(); - } - - public int getEventsAlpha() { - return mEventsAlpha; - } + var eventsAlpha: Int + get() = mEventsAlpha + set(alpha) { + mEventsAlpha = alpha + invalidate() + } - public void stopEventsAnimation() { + fun stopEventsAnimation() { if (mEventsCrossFadeAnimation != null) { - mEventsCrossFadeAnimation.cancel(); + mEventsCrossFadeAnimation.cancel() } - mEventsAlpha = 255; + mEventsAlpha = 255 } - private void computeEventRelations() { + private fun computeEventRelations() { // Compute the layout relation between each event before measuring cell // width, as the cell width should be adjusted along with the relation. // @@ -1840,235 +1409,227 @@ public class DayView extends View implements View.OnCreateContextMenuListener, // Make a pass over all the events, and keep track of the maximum // number of all-day events in any one day. Also, keep track of // the earliest event in each day. - int maxAllDayEvents = 0; - final ArrayList<Event> events = mEvents; - final int len = events.size(); + var maxAllDayEvents = 0 + val events: ArrayList<Event> = mEvents + val len: Int = events.size() // Num of all-day-events on each day. - final int eventsCount[] = new int[mLastJulianDay - mFirstJulianDay + 1]; - Arrays.fill(eventsCount, 0); - for (int ii = 0; ii < len; ii++) { - Event event = events.get(ii); + val eventsCount = IntArray(mLastJulianDay - mFirstJulianDay + 1) + Arrays.fill(eventsCount, 0) + for (ii in 0 until len) { + val event: Event = events.get(ii) if (event.startDay > mLastJulianDay || event.endDay < mFirstJulianDay) { - continue; + continue } if (event.drawAsAllday()) { // Count all the events being drawn as allDay events - final int firstDay = Math.max(event.startDay, mFirstJulianDay); - final int lastDay = Math.min(event.endDay, mLastJulianDay); - for (int day = firstDay; day <= lastDay; day++) { - final int count = ++eventsCount[day - mFirstJulianDay]; + val firstDay: Int = Math.max(event.startDay, mFirstJulianDay) + val lastDay: Int = Math.min(event.endDay, mLastJulianDay) + for (day in firstDay..lastDay) { + val count = ++eventsCount[day - mFirstJulianDay] if (maxAllDayEvents < count) { - maxAllDayEvents = count; + maxAllDayEvents = count } } - - int daynum = event.startDay - mFirstJulianDay; - int durationDays = event.endDay - event.startDay + 1; + var daynum: Int = event.startDay - mFirstJulianDay + var durationDays: Int = event.endDay - event.startDay + 1 if (daynum < 0) { - durationDays += daynum; - daynum = 0; + durationDays += daynum + daynum = 0 } if (daynum + durationDays > mNumDays) { - durationDays = mNumDays - daynum; + durationDays = mNumDays - daynum } - for (int day = daynum; durationDays > 0; day++, durationDays--) { - mHasAllDayEvent[day] = true; + var day = daynum + while (durationDays > 0) { + mHasAllDayEvent[day] = true + day++ + durationDays-- } } else { - int daynum = event.startDay - mFirstJulianDay; - int hour = event.startTime / 60; + var daynum: Int = event.startDay - mFirstJulianDay + var hour: Int = event.startTime / 60 if (daynum >= 0 && hour < mEarliestStartHour[daynum]) { - mEarliestStartHour[daynum] = hour; + mEarliestStartHour[daynum] = hour } // Also check the end hour in case the event spans more than // one day. - daynum = event.endDay - mFirstJulianDay; - hour = event.endTime / 60; + daynum = event.endDay - mFirstJulianDay + hour = event.endTime / 60 if (daynum < mNumDays && hour < mEarliestStartHour[daynum]) { - mEarliestStartHour[daynum] = hour; + mEarliestStartHour[daynum] = hour } } } - mMaxAlldayEvents = maxAllDayEvents; - initAllDayHeights(); + mMaxAlldayEvents = maxAllDayEvents + initAllDayHeights() } @Override - protected void onDraw(Canvas canvas) { + protected fun onDraw(canvas: Canvas) { if (mRemeasure) { - remeasure(getWidth(), getHeight()); - mRemeasure = false; + remeasure(getWidth(), getHeight()) + mRemeasure = false } - canvas.save(); - - float yTranslate = -mViewStartY + DAY_HEADER_HEIGHT + mAlldayHeight; + canvas.save() + val yTranslate = (-mViewStartY + DAY_HEADER_HEIGHT + mAlldayHeight).toFloat() // offset canvas by the current drag and header position - canvas.translate(-mViewStartX, yTranslate); + canvas.translate(-mViewStartX, yTranslate) // clip to everything below the allDay area - Rect dest = mDestRect; - dest.top = (int) (mFirstCell - yTranslate); - dest.bottom = (int) (mViewHeight - yTranslate); - dest.left = 0; - dest.right = mViewWidth; - canvas.save(); - canvas.clipRect(dest); + val dest: Rect = mDestRect + dest.top = (mFirstCell - yTranslate).toInt() + dest.bottom = (mViewHeight - yTranslate).toInt() + dest.left = 0 + dest.right = mViewWidth + canvas.save() + canvas.clipRect(dest) // Draw the movable part of the view - doDraw(canvas); + doDraw(canvas) // restore to having no clip - canvas.restore(); - - if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) { - float xTranslate; - if (mViewStartX > 0) { - xTranslate = mViewWidth; + canvas.restore() + if (mTouchMode and TOUCH_MODE_HSCROLL != 0) { + val xTranslate: Float + xTranslate = if (mViewStartX > 0) { + mViewWidth.toFloat() } else { - xTranslate = -mViewWidth; + -mViewWidth.toFloat() } // Move the canvas around to prep it for the next view // specifically, shift it by a screen and undo the // yTranslation which will be redone in the nextView's onDraw(). - canvas.translate(xTranslate, -yTranslate); - DayView nextView = (DayView) mViewSwitcher.getNextView(); + canvas.translate(xTranslate, -yTranslate) + val nextView = mViewSwitcher.getNextView() as DayView // Prevent infinite recursive calls to onDraw(). - nextView.mTouchMode = TOUCH_MODE_INITIAL_STATE; - - nextView.onDraw(canvas); + nextView.mTouchMode = TOUCH_MODE_INITIAL_STATE + nextView.onDraw(canvas) // Move it back for this view - canvas.translate(-xTranslate, 0); + canvas.translate(-xTranslate, 0) } else { // If we drew another view we already translated it back // If we didn't draw another view we should be at the edge of the // screen - canvas.translate(mViewStartX, -yTranslate); + canvas.translate(mViewStartX, -yTranslate) } // Draw the fixed areas (that don't scroll) directly to the canvas. - drawAfterScroll(canvas); + drawAfterScroll(canvas) if (mComputeSelectedEvents && mUpdateToast) { - mUpdateToast = false; + mUpdateToast = false } - mComputeSelectedEvents = false; + mComputeSelectedEvents = false // Draw overscroll glow if (!mEdgeEffectTop.isFinished()) { if (DAY_HEADER_HEIGHT != 0) { - canvas.translate(0, DAY_HEADER_HEIGHT); + canvas.translate(0, DAY_HEADER_HEIGHT) } if (mEdgeEffectTop.draw(canvas)) { - invalidate(); + invalidate() } if (DAY_HEADER_HEIGHT != 0) { - canvas.translate(0, -DAY_HEADER_HEIGHT); + canvas.translate(0, -DAY_HEADER_HEIGHT) } } if (!mEdgeEffectBottom.isFinished()) { - canvas.rotate(180, mViewWidth/2, mViewHeight/2); + canvas.rotate(180, mViewWidth / 2, mViewHeight / 2) if (mEdgeEffectBottom.draw(canvas)) { - invalidate(); + invalidate() } } - canvas.restore(); + canvas.restore() } - private void drawAfterScroll(Canvas canvas) { - Paint p = mPaint; - Rect r = mRect; - - drawAllDayHighlights(r, canvas, p); + private fun drawAfterScroll(canvas: Canvas) { + val p: Paint = mPaint + val r: Rect = mRect + drawAllDayHighlights(r, canvas, p) if (mMaxAlldayEvents != 0) { - drawAllDayEvents(mFirstJulianDay, mNumDays, canvas, p); - drawUpperLeftCorner(r, canvas, p); + drawAllDayEvents(mFirstJulianDay, mNumDays, canvas, p) + drawUpperLeftCorner(r, canvas, p) } - - drawScrollLine(r, canvas, p); - drawDayHeaderLoop(r, canvas, p); + drawScrollLine(r, canvas, p) + drawDayHeaderLoop(r, canvas, p) // Draw the AM and PM indicators if we're in 12 hour mode if (!mIs24HourFormat) { - drawAmPm(canvas, p); + drawAmPm(canvas, p) } } // This isn't really the upper-left corner. It's the square area just // below the upper-left corner, above the hours and to the left of the // all-day area. - private void drawUpperLeftCorner(Rect r, Canvas canvas, Paint p) { - setupHourTextPaint(p); + private fun drawUpperLeftCorner(r: Rect, canvas: Canvas, p: Paint) { + setupHourTextPaint(p) if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) { // Draw the allDay expand/collapse icon if (mUseExpandIcon) { - mExpandAlldayDrawable.setBounds(mExpandAllDayRect); - mExpandAlldayDrawable.draw(canvas); + mExpandAlldayDrawable.setBounds(mExpandAllDayRect) + mExpandAlldayDrawable.draw(canvas) } else { - mCollapseAlldayDrawable.setBounds(mExpandAllDayRect); - mCollapseAlldayDrawable.draw(canvas); + mCollapseAlldayDrawable.setBounds(mExpandAllDayRect) + mCollapseAlldayDrawable.draw(canvas) } } } - private void drawScrollLine(Rect r, Canvas canvas, Paint p) { - final int right = computeDayLeftPosition(mNumDays); - final int y = mFirstCell - 1; - - p.setAntiAlias(false); - p.setStyle(Style.FILL); - - p.setColor(mCalendarGridLineInnerHorizontalColor); - p.setStrokeWidth(GRID_LINE_INNER_WIDTH); - canvas.drawLine(GRID_LINE_LEFT_MARGIN, y, right, y, p); - p.setAntiAlias(true); + private fun drawScrollLine(r: Rect, canvas: Canvas, p: Paint) { + val right = computeDayLeftPosition(mNumDays) + val y = mFirstCell - 1 + p.setAntiAlias(false) + p.setStyle(Style.FILL) + p.setColor(mCalendarGridLineInnerHorizontalColor) + p.setStrokeWidth(GRID_LINE_INNER_WIDTH) + canvas.drawLine(GRID_LINE_LEFT_MARGIN, y, right, y, p) + p.setAntiAlias(true) } // Computes the x position for the left side of the given day (base 0) - private int computeDayLeftPosition(int day) { - int effectiveWidth = mViewWidth - mHoursWidth; - return day * effectiveWidth / mNumDays + mHoursWidth; + private fun computeDayLeftPosition(day: Int): Int { + val effectiveWidth = mViewWidth - mHoursWidth + return day * effectiveWidth / mNumDays + mHoursWidth } - private void drawAllDayHighlights(Rect r, Canvas canvas, Paint p) { + private fun drawAllDayHighlights(r: Rect, canvas: Canvas, p: Paint) { if (mFutureBgColor != 0) { // First, color the labels area light gray - r.top = 0; - r.bottom = DAY_HEADER_HEIGHT; - r.left = 0; - r.right = mViewWidth; - p.setColor(mBgColor); - p.setStyle(Style.FILL); - canvas.drawRect(r, p); + r.top = 0 + r.bottom = DAY_HEADER_HEIGHT + r.left = 0 + r.right = mViewWidth + p.setColor(mBgColor) + p.setStyle(Style.FILL) + canvas.drawRect(r, p) // and the area that says All day - r.top = DAY_HEADER_HEIGHT; - r.bottom = mFirstCell - 1; - r.left = 0; - r.right = mHoursWidth; - canvas.drawRect(r, p); - - int startIndex = -1; - - int todayIndex = mTodayJulianDay - mFirstJulianDay; + r.top = DAY_HEADER_HEIGHT + r.bottom = mFirstCell - 1 + r.left = 0 + r.right = mHoursWidth + canvas.drawRect(r, p) + var startIndex = -1 + val todayIndex = mTodayJulianDay - mFirstJulianDay if (todayIndex < 0) { // Future - startIndex = 0; + startIndex = 0 } else if (todayIndex >= 1 && todayIndex + 1 < mNumDays) { // Multiday - tomorrow is visible. - startIndex = todayIndex + 1; + startIndex = todayIndex + 1 } - if (startIndex >= 0) { // Draw the future highlight - r.top = 0; - r.bottom = mFirstCell - 1; - r.left = computeDayLeftPosition(startIndex) + 1; - r.right = computeDayLeftPosition(mNumDays); - p.setColor(mFutureBgColor); - p.setStyle(Style.FILL); - canvas.drawRect(r, p); + r.top = 0 + r.bottom = mFirstCell - 1 + r.left = computeDayLeftPosition(startIndex) + 1 + r.right = computeDayLeftPosition(mNumDays) + p.setColor(mFutureBgColor) + p.setStyle(Style.FILL) + canvas.drawRect(r, p) } } } - private void drawDayHeaderLoop(Rect r, Canvas canvas, Paint p) { + private fun drawDayHeaderLoop(r: Rect, canvas: Canvas, p: Paint) { // Draw the horizontal day background banner // p.setColor(mCalendarDateBannerBackground); // r.top = 0; @@ -2083,231 +1644,226 @@ public class DayView extends View implements View.OnCreateContextMenuListener, // p.setColor(mCalendarGridAreaBackground); // canvas.drawRect(r, p); if (mNumDays == 1 && ONE_DAY_HEADER_HEIGHT == 0) { - return; - } - - p.setTypeface(mBold); - p.setTextAlign(Paint.Align.RIGHT); - int cell = mFirstJulianDay; - - String[] dayNames; - if (mDateStrWidth < mCellWidth) { - dayNames = mDayStrs; + return + } + p.setTypeface(mBold) + p.setTextAlign(Paint.Align.RIGHT) + var cell = mFirstJulianDay + val dayNames: Array<String?> + dayNames = if (mDateStrWidth < mCellWidth) { + mDayStrs } else { - dayNames = mDayStrs2Letter; + mDayStrs2Letter } - - p.setAntiAlias(true); - for (int day = 0; day < mNumDays; day++, cell++) { - int dayOfWeek = day + mFirstVisibleDayOfWeek; + p.setAntiAlias(true) + var day = 0 + while (day < mNumDays) { + var dayOfWeek = day + mFirstVisibleDayOfWeek if (dayOfWeek >= 14) { - dayOfWeek -= 14; + dayOfWeek -= 14 } - - int color = mCalendarDateBannerTextColor; + var color = mCalendarDateBannerTextColor if (mNumDays == 1) { if (dayOfWeek == Time.SATURDAY) { - color = mWeek_saturdayColor; + color = mWeek_saturdayColor } else if (dayOfWeek == Time.SUNDAY) { - color = mWeek_sundayColor; + color = mWeek_sundayColor } } else { - final int column = day % 7; + val column = day % 7 if (Utils.isSaturday(column, mFirstDayOfWeek)) { - color = mWeek_saturdayColor; + color = mWeek_saturdayColor } else if (Utils.isSunday(column, mFirstDayOfWeek)) { - color = mWeek_sundayColor; + color = mWeek_sundayColor } } - - p.setColor(color); - drawDayHeader(dayNames[dayOfWeek], day, cell, canvas, p); + p.setColor(color) + drawDayHeader(dayNames[dayOfWeek], day, cell, canvas, p) + day++ + cell++ } - p.setTypeface(null); + p.setTypeface(null) } - private void drawAmPm(Canvas canvas, Paint p) { - p.setColor(mCalendarAmPmLabel); - p.setTextSize(AMPM_TEXT_SIZE); - p.setTypeface(mBold); - p.setAntiAlias(true); - p.setTextAlign(Paint.Align.RIGHT); - String text = mAmString; + private fun drawAmPm(canvas: Canvas, p: Paint) { + p.setColor(mCalendarAmPmLabel) + p.setTextSize(AMPM_TEXT_SIZE) + p.setTypeface(mBold) + p.setAntiAlias(true) + p.setTextAlign(Paint.Align.RIGHT) + var text = mAmString if (mFirstHour >= 12) { - text = mPmString; + text = mPmString } - int y = mFirstCell + mFirstHourOffset + 2 * mHoursTextHeight + HOUR_GAP; - canvas.drawText(text, HOURS_LEFT_MARGIN, y, p); - + var y = mFirstCell + mFirstHourOffset + 2 * mHoursTextHeight + HOUR_GAP + canvas.drawText(text, HOURS_LEFT_MARGIN, y, p) if (mFirstHour < 12 && mFirstHour + mNumHours > 12) { // Also draw the "PM" - text = mPmString; - y = mFirstCell + mFirstHourOffset + (12 - mFirstHour) * (mCellHeight + HOUR_GAP) - + 2 * mHoursTextHeight + HOUR_GAP; - canvas.drawText(text, HOURS_LEFT_MARGIN, y, p); - } - } - - private void drawCurrentTimeLine(Rect r, final int day, final int top, Canvas canvas, - Paint p) { - r.left = computeDayLeftPosition(day) - CURRENT_TIME_LINE_SIDE_BUFFER + 1; - r.right = computeDayLeftPosition(day + 1) + CURRENT_TIME_LINE_SIDE_BUFFER + 1; - - r.top = top - CURRENT_TIME_LINE_TOP_OFFSET; - r.bottom = r.top + mCurrentTimeLine.getIntrinsicHeight(); - - mCurrentTimeLine.setBounds(r); - mCurrentTimeLine.draw(canvas); + text = mPmString + y = + mFirstCell + mFirstHourOffset + (12 - mFirstHour) * (mCellHeight + HOUR_GAP) + 2 * mHoursTextHeight + HOUR_GAP + canvas.drawText(text, HOURS_LEFT_MARGIN, y, p) + } + } + + private fun drawCurrentTimeLine( + r: Rect, day: Int, top: Int, canvas: Canvas, + p: Paint + ) { + r.left = computeDayLeftPosition(day) - CURRENT_TIME_LINE_SIDE_BUFFER + 1 + r.right = computeDayLeftPosition(day + 1) + CURRENT_TIME_LINE_SIDE_BUFFER + 1 + r.top = top - CURRENT_TIME_LINE_TOP_OFFSET + r.bottom = r.top + mCurrentTimeLine.getIntrinsicHeight() + mCurrentTimeLine.setBounds(r) + mCurrentTimeLine.draw(canvas) if (mAnimateToday) { - mCurrentTimeAnimateLine.setBounds(r); - mCurrentTimeAnimateLine.setAlpha(mAnimateTodayAlpha); - mCurrentTimeAnimateLine.draw(canvas); + mCurrentTimeAnimateLine.setBounds(r) + mCurrentTimeAnimateLine.setAlpha(mAnimateTodayAlpha) + mCurrentTimeAnimateLine.draw(canvas) } } - private void doDraw(Canvas canvas) { - Paint p = mPaint; - Rect r = mRect; - + private fun doDraw(canvas: Canvas) { + val p: Paint = mPaint + val r: Rect = mRect if (mFutureBgColor != 0) { - drawBgColors(r, canvas, p); + drawBgColors(r, canvas, p) } - drawGridBackground(r, canvas, p); - drawHours(r, canvas, p); + drawGridBackground(r, canvas, p) + drawHours(r, canvas, p) // Draw each day - int cell = mFirstJulianDay; - p.setAntiAlias(false); - int alpha = p.getAlpha(); - p.setAlpha(mEventsAlpha); - for (int day = 0; day < mNumDays; day++, cell++) { + var cell = mFirstJulianDay + p.setAntiAlias(false) + val alpha: Int = p.getAlpha() + p.setAlpha(mEventsAlpha) + var day = 0 + while (day < mNumDays) { + // TODO Wow, this needs cleanup. drawEvents loop through all the // events on every call. - drawEvents(cell, day, HOUR_GAP, canvas, p); + drawEvents(cell, day, HOUR_GAP, canvas, p) // If this is today if (cell == mTodayJulianDay) { - int lineY = mCurrentTime.hour * (mCellHeight + HOUR_GAP) - + ((mCurrentTime.minute * mCellHeight) / 60) + 1; + val lineY: Int = + mCurrentTime.hour * (mCellHeight + HOUR_GAP) + mCurrentTime.minute * mCellHeight / 60 + 1 // And the current time shows up somewhere on the screen if (lineY >= mViewStartY && lineY < mViewStartY + mViewHeight - 2) { - drawCurrentTimeLine(r, day, lineY, canvas, p); + drawCurrentTimeLine(r, day, lineY, canvas, p) } } + day++ + cell++ } - p.setAntiAlias(true); - p.setAlpha(alpha); + p.setAntiAlias(true) + p.setAlpha(alpha) } - private void drawHours(Rect r, Canvas canvas, Paint p) { - setupHourTextPaint(p); - - int y = HOUR_GAP + mHoursTextHeight + HOURS_TOP_MARGIN; - - for (int i = 0; i < 24; i++) { - String time = mHourStrs[i]; - canvas.drawText(time, HOURS_LEFT_MARGIN, y, p); - y += mCellHeight + HOUR_GAP; + private fun drawHours(r: Rect, canvas: Canvas, p: Paint) { + setupHourTextPaint(p) + var y = HOUR_GAP + mHoursTextHeight + HOURS_TOP_MARGIN + for (i in 0..23) { + val time = mHourStrs[i] + canvas.drawText(time, HOURS_LEFT_MARGIN, y, p) + y += mCellHeight + HOUR_GAP } } - private void setupHourTextPaint(Paint p) { - p.setColor(mCalendarHourLabelColor); - p.setTextSize(HOURS_TEXT_SIZE); - p.setTypeface(Typeface.DEFAULT); - p.setTextAlign(Paint.Align.RIGHT); - p.setAntiAlias(true); + private fun setupHourTextPaint(p: Paint) { + p.setColor(mCalendarHourLabelColor) + p.setTextSize(HOURS_TEXT_SIZE) + p.setTypeface(Typeface.DEFAULT) + p.setTextAlign(Paint.Align.RIGHT) + p.setAntiAlias(true) } - private void drawDayHeader(String dayStr, int day, int cell, Canvas canvas, Paint p) { - int dateNum = mFirstVisibleDate + day; - int x; + private fun drawDayHeader(dayStr: String?, day: Int, cell: Int, canvas: Canvas, p: Paint) { + var dateNum = mFirstVisibleDate + day + val x: Int if (dateNum > mMonthLength) { - dateNum -= mMonthLength; + dateNum -= mMonthLength } - p.setAntiAlias(true); - - int todayIndex = mTodayJulianDay - mFirstJulianDay; + p.setAntiAlias(true) + val todayIndex = mTodayJulianDay - mFirstJulianDay // Draw day of the month - String dateNumStr = String.valueOf(dateNum); + val dateNumStr: String = String.valueOf(dateNum) if (mNumDays > 1) { - float y = DAY_HEADER_HEIGHT - DAY_HEADER_BOTTOM_MARGIN; + val y = (DAY_HEADER_HEIGHT - DAY_HEADER_BOTTOM_MARGIN).toFloat() // Draw day of the month - x = computeDayLeftPosition(day + 1) - DAY_HEADER_RIGHT_MARGIN; - p.setTextAlign(Align.RIGHT); - p.setTextSize(DATE_HEADER_FONT_SIZE); - - p.setTypeface(todayIndex == day ? mBold : Typeface.DEFAULT); - canvas.drawText(dateNumStr, x, y, p); + x = computeDayLeftPosition(day + 1) - DAY_HEADER_RIGHT_MARGIN + p.setTextAlign(Align.RIGHT) + p.setTextSize(DATE_HEADER_FONT_SIZE) + p.setTypeface(if (todayIndex == day) mBold else Typeface.DEFAULT) + canvas.drawText(dateNumStr, x, y, p) // Draw day of the week - x -= p.measureText(" " + dateNumStr); - p.setTextSize(DAY_HEADER_FONT_SIZE); - p.setTypeface(Typeface.DEFAULT); - canvas.drawText(dayStr, x, y, p); + x -= p.measureText(" $dateNumStr") + p.setTextSize(DAY_HEADER_FONT_SIZE) + p.setTypeface(Typeface.DEFAULT) + canvas.drawText(dayStr, x, y, p) } else { - float y = ONE_DAY_HEADER_HEIGHT - DAY_HEADER_ONE_DAY_BOTTOM_MARGIN; - p.setTextAlign(Align.LEFT); + val y = (ONE_DAY_HEADER_HEIGHT - DAY_HEADER_ONE_DAY_BOTTOM_MARGIN).toFloat() + p.setTextAlign(Align.LEFT) // Draw day of the week - x = computeDayLeftPosition(day) + DAY_HEADER_ONE_DAY_LEFT_MARGIN; - p.setTextSize(DAY_HEADER_FONT_SIZE); - p.setTypeface(Typeface.DEFAULT); - canvas.drawText(dayStr, x, y, p); + x = computeDayLeftPosition(day) + DAY_HEADER_ONE_DAY_LEFT_MARGIN + p.setTextSize(DAY_HEADER_FONT_SIZE) + p.setTypeface(Typeface.DEFAULT) + canvas.drawText(dayStr, x, y, p) // Draw day of the month - x += p.measureText(dayStr) + DAY_HEADER_ONE_DAY_RIGHT_MARGIN; - p.setTextSize(DATE_HEADER_FONT_SIZE); - p.setTypeface(todayIndex == day ? mBold : Typeface.DEFAULT); - canvas.drawText(dateNumStr, x, y, p); + x += p.measureText(dayStr) + DAY_HEADER_ONE_DAY_RIGHT_MARGIN + p.setTextSize(DATE_HEADER_FONT_SIZE) + p.setTypeface(if (todayIndex == day) mBold else Typeface.DEFAULT) + canvas.drawText(dateNumStr, x, y, p) } } - private void drawGridBackground(Rect r, Canvas canvas, Paint p) { - Paint.Style savedStyle = p.getStyle(); - - final float stopX = computeDayLeftPosition(mNumDays); - float y = 0; - final float deltaY = mCellHeight + HOUR_GAP; - int linesIndex = 0; - final float startY = 0; - final float stopY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP); - float x = mHoursWidth; + private fun drawGridBackground(r: Rect, canvas: Canvas, p: Paint) { + val savedStyle: Style = p.getStyle() + val stopX = computeDayLeftPosition(mNumDays).toFloat() + var y = 0f + val deltaY = (mCellHeight + HOUR_GAP).toFloat() + var linesIndex = 0 + val startY = 0f + val stopY = (HOUR_GAP + 24 * (mCellHeight + HOUR_GAP)).toFloat() + var x = mHoursWidth.toFloat() // Draw the inner horizontal grid lines - p.setColor(mCalendarGridLineInnerHorizontalColor); - p.setStrokeWidth(GRID_LINE_INNER_WIDTH); - p.setAntiAlias(false); - y = 0; - linesIndex = 0; - for (int hour = 0; hour <= 24; hour++) { - mLines[linesIndex++] = GRID_LINE_LEFT_MARGIN; - mLines[linesIndex++] = y; - mLines[linesIndex++] = stopX; - mLines[linesIndex++] = y; - y += deltaY; + p.setColor(mCalendarGridLineInnerHorizontalColor) + p.setStrokeWidth(GRID_LINE_INNER_WIDTH) + p.setAntiAlias(false) + y = 0f + linesIndex = 0 + for (hour in 0..24) { + mLines[linesIndex++] = GRID_LINE_LEFT_MARGIN + mLines[linesIndex++] = y + mLines[linesIndex++] = stopX + mLines[linesIndex++] = y + y += deltaY } if (mCalendarGridLineInnerVerticalColor != mCalendarGridLineInnerHorizontalColor) { - canvas.drawLines(mLines, 0, linesIndex, p); - linesIndex = 0; - p.setColor(mCalendarGridLineInnerVerticalColor); + canvas.drawLines(mLines, 0, linesIndex, p) + linesIndex = 0 + p.setColor(mCalendarGridLineInnerVerticalColor) } // Draw the inner vertical grid lines - for (int day = 0; day <= mNumDays; day++) { - x = computeDayLeftPosition(day); - mLines[linesIndex++] = x; - mLines[linesIndex++] = startY; - mLines[linesIndex++] = x; - mLines[linesIndex++] = stopY; + for (day in 0..mNumDays) { + x = computeDayLeftPosition(day).toFloat() + mLines[linesIndex++] = x + mLines[linesIndex++] = startY + mLines[linesIndex++] = x + mLines[linesIndex++] = stopY } - canvas.drawLines(mLines, 0, linesIndex, p); + canvas.drawLines(mLines, 0, linesIndex, p) // Restore the saved style. - p.setStyle(savedStyle); - p.setAntiAlias(true); + p.setStyle(savedStyle) + p.setAntiAlias(true) } /** @@ -2315,366 +1871,359 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * @param canvas * @param p */ - private void drawBgColors(Rect r, Canvas canvas, Paint p) { - int todayIndex = mTodayJulianDay - mFirstJulianDay; + private fun drawBgColors(r: Rect, canvas: Canvas, p: Paint) { + val todayIndex = mTodayJulianDay - mFirstJulianDay // Draw the hours background color - r.top = mDestRect.top; - r.bottom = mDestRect.bottom; - r.left = 0; - r.right = mHoursWidth; - p.setColor(mBgColor); - p.setStyle(Style.FILL); - p.setAntiAlias(false); - canvas.drawRect(r, p); + r.top = mDestRect.top + r.bottom = mDestRect.bottom + r.left = 0 + r.right = mHoursWidth + p.setColor(mBgColor) + p.setStyle(Style.FILL) + p.setAntiAlias(false) + canvas.drawRect(r, p) // Draw background for grid area if (mNumDays == 1 && todayIndex == 0) { // Draw a white background for the time later than current time - int lineY = mCurrentTime.hour * (mCellHeight + HOUR_GAP) - + ((mCurrentTime.minute * mCellHeight) / 60) + 1; + var lineY: Int = + mCurrentTime.hour * (mCellHeight + HOUR_GAP) + mCurrentTime.minute * mCellHeight / 60 + 1 if (lineY < mViewStartY + mViewHeight) { - lineY = Math.max(lineY, mViewStartY); - r.left = mHoursWidth; - r.right = mViewWidth; - r.top = lineY; - r.bottom = mViewStartY + mViewHeight; - p.setColor(mFutureBgColor); - canvas.drawRect(r, p); + lineY = Math.max(lineY, mViewStartY) + r.left = mHoursWidth + r.right = mViewWidth + r.top = lineY + r.bottom = mViewStartY + mViewHeight + p.setColor(mFutureBgColor) + canvas.drawRect(r, p) } } else if (todayIndex >= 0 && todayIndex < mNumDays) { // Draw today with a white background for the time later than current time - int lineY = mCurrentTime.hour * (mCellHeight + HOUR_GAP) - + ((mCurrentTime.minute * mCellHeight) / 60) + 1; + var lineY: Int = + mCurrentTime.hour * (mCellHeight + HOUR_GAP) + mCurrentTime.minute * mCellHeight / 60 + 1 if (lineY < mViewStartY + mViewHeight) { - lineY = Math.max(lineY, mViewStartY); - r.left = computeDayLeftPosition(todayIndex) + 1; - r.right = computeDayLeftPosition(todayIndex + 1); - r.top = lineY; - r.bottom = mViewStartY + mViewHeight; - p.setColor(mFutureBgColor); - canvas.drawRect(r, p); + lineY = Math.max(lineY, mViewStartY) + r.left = computeDayLeftPosition(todayIndex) + 1 + r.right = computeDayLeftPosition(todayIndex + 1) + r.top = lineY + r.bottom = mViewStartY + mViewHeight + p.setColor(mFutureBgColor) + canvas.drawRect(r, p) } // Paint Tomorrow and later days with future color if (todayIndex + 1 < mNumDays) { - r.left = computeDayLeftPosition(todayIndex + 1) + 1; - r.right = computeDayLeftPosition(mNumDays); - r.top = mDestRect.top; - r.bottom = mDestRect.bottom; - p.setColor(mFutureBgColor); - canvas.drawRect(r, p); + r.left = computeDayLeftPosition(todayIndex + 1) + 1 + r.right = computeDayLeftPosition(mNumDays) + r.top = mDestRect.top + r.bottom = mDestRect.bottom + p.setColor(mFutureBgColor) + canvas.drawRect(r, p) } } else if (todayIndex < 0) { // Future - r.left = computeDayLeftPosition(0) + 1; - r.right = computeDayLeftPosition(mNumDays); - r.top = mDestRect.top; - r.bottom = mDestRect.bottom; - p.setColor(mFutureBgColor); - canvas.drawRect(r, p); + r.left = computeDayLeftPosition(0) + 1 + r.right = computeDayLeftPosition(mNumDays) + r.top = mDestRect.top + r.bottom = mDestRect.bottom + p.setColor(mFutureBgColor) + canvas.drawRect(r, p) } - p.setAntiAlias(true); + p.setAntiAlias(true) } - private int computeMaxStringWidth(int currentMax, String[] strings, Paint p) { - float maxWidthF = 0.0f; - - int len = strings.length; - for (int i = 0; i < len; i++) { - float width = p.measureText(strings[i]); - maxWidthF = Math.max(width, maxWidthF); + private fun computeMaxStringWidth(currentMax: Int, strings: Array<String?>, p: Paint): Int { + var maxWidthF = 0.0f + val len = strings.size + for (i in 0 until len) { + val width: Float = p.measureText(strings[i]) + maxWidthF = Math.max(width, maxWidthF) } - int maxWidth = (int) (maxWidthF + 0.5); + var maxWidth = (maxWidthF + 0.5).toInt() if (maxWidth < currentMax) { - maxWidth = currentMax; + maxWidth = currentMax } - return maxWidth; + return maxWidth } - private void saveSelectionPosition(float left, float top, float right, float bottom) { - mPrevBox.left = (int) left; - mPrevBox.right = (int) right; - mPrevBox.top = (int) top; - mPrevBox.bottom = (int) bottom; + private fun saveSelectionPosition(left: Float, top: Float, right: Float, bottom: Float) { + mPrevBox.left = left.toInt() + mPrevBox.right = right.toInt() + mPrevBox.top = top.toInt() + mPrevBox.bottom = bottom.toInt() } - private void setupTextRect(Rect r) { + private fun setupTextRect(r: Rect) { if (r.bottom <= r.top || r.right <= r.left) { - r.bottom = r.top; - r.right = r.left; - return; + r.bottom = r.top + r.right = r.left + return } - if (r.bottom - r.top > EVENT_TEXT_TOP_MARGIN + EVENT_TEXT_BOTTOM_MARGIN) { - r.top += EVENT_TEXT_TOP_MARGIN; - r.bottom -= EVENT_TEXT_BOTTOM_MARGIN; + r.top += EVENT_TEXT_TOP_MARGIN + r.bottom -= EVENT_TEXT_BOTTOM_MARGIN } if (r.right - r.left > EVENT_TEXT_LEFT_MARGIN + EVENT_TEXT_RIGHT_MARGIN) { - r.left += EVENT_TEXT_LEFT_MARGIN; - r.right -= EVENT_TEXT_RIGHT_MARGIN; + r.left += EVENT_TEXT_LEFT_MARGIN + r.right -= EVENT_TEXT_RIGHT_MARGIN } } - private void setupAllDayTextRect(Rect r) { + private fun setupAllDayTextRect(r: Rect) { if (r.bottom <= r.top || r.right <= r.left) { - r.bottom = r.top; - r.right = r.left; - return; + r.bottom = r.top + r.right = r.left + return } - if (r.bottom - r.top > EVENT_ALL_DAY_TEXT_TOP_MARGIN + EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN) { - r.top += EVENT_ALL_DAY_TEXT_TOP_MARGIN; - r.bottom -= EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN; + r.top += EVENT_ALL_DAY_TEXT_TOP_MARGIN + r.bottom -= EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN } if (r.right - r.left > EVENT_ALL_DAY_TEXT_LEFT_MARGIN + EVENT_ALL_DAY_TEXT_RIGHT_MARGIN) { - r.left += EVENT_ALL_DAY_TEXT_LEFT_MARGIN; - r.right -= EVENT_ALL_DAY_TEXT_RIGHT_MARGIN; + r.left += EVENT_ALL_DAY_TEXT_LEFT_MARGIN + r.right -= EVENT_ALL_DAY_TEXT_RIGHT_MARGIN } } /** * Return the layout for a numbered event. Create it if not already existing */ - private StaticLayout getEventLayout(StaticLayout[] layouts, int i, Event event, Paint paint, - Rect r) { - if (i < 0 || i >= layouts.length) { - return null; - } - - StaticLayout layout = layouts[i]; + private fun getEventLayout( + layouts: Array<StaticLayout?>?, i: Int, event: Event, paint: Paint, + r: Rect + ): StaticLayout? { + if (i < 0 || i >= layouts!!.size) { + return null + } + var layout: StaticLayout? = layouts!![i] // Check if we have already initialized the StaticLayout and that // the width hasn't changed (due to vertical resizing which causes // re-layout of events at min height) - if (layout == null || r.width() != layout.getWidth()) { - SpannableStringBuilder bob = new SpannableStringBuilder(); + if (layout == null || r.width() !== layout.getWidth()) { + val bob = SpannableStringBuilder() if (event.title != null) { // MAX - 1 since we add a space - bob.append(drawTextSanitizer(event.title.toString(), MAX_EVENT_TEXT_LEN - 1)); - bob.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, bob.length(), 0); - bob.append(' '); + bob.append(drawTextSanitizer(event.title.toString(), MAX_EVENT_TEXT_LEN - 1)) + bob.setSpan(StyleSpan(android.graphics.Typeface.BOLD), 0, bob.length(), 0) + bob.append(' ') } if (event.location != null) { - bob.append(drawTextSanitizer(event.location.toString(), - MAX_EVENT_TEXT_LEN - bob.length())); - } - - switch (event.selfAttendeeStatus) { - case Attendees.ATTENDEE_STATUS_INVITED: - paint.setColor(event.color); - break; - case Attendees.ATTENDEE_STATUS_DECLINED: - paint.setColor(mEventTextColor); - paint.setAlpha(Utils.DECLINED_EVENT_TEXT_ALPHA); - break; - case Attendees.ATTENDEE_STATUS_NONE: // Your own events - case Attendees.ATTENDEE_STATUS_ACCEPTED: - case Attendees.ATTENDEE_STATUS_TENTATIVE: - default: - paint.setColor(mEventTextColor); - break; + bob.append( + drawTextSanitizer( + event.location.toString(), + MAX_EVENT_TEXT_LEN - bob.length() + ) + ) + } + when (event.selfAttendeeStatus) { + Attendees.ATTENDEE_STATUS_INVITED -> paint.setColor(event.color) + Attendees.ATTENDEE_STATUS_DECLINED -> { + paint.setColor(mEventTextColor) + paint.setAlpha(Utils.DECLINED_EVENT_TEXT_ALPHA) + } + Attendees.ATTENDEE_STATUS_NONE, Attendees.ATTENDEE_STATUS_ACCEPTED, Attendees.ATTENDEE_STATUS_TENTATIVE -> paint.setColor( + mEventTextColor + ) + else -> paint.setColor(mEventTextColor) } // Leave a one pixel boundary on the left and right of the rectangle for the event - layout = new StaticLayout(bob, 0, bob.length(), new TextPaint(paint), r.width(), - Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true, null, r.width()); - - layouts[i] = layout; + layout = StaticLayout( + bob, 0, bob.length(), TextPaint(paint), r.width(), + Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true, null, r.width() + ) + layouts[i] = layout } - layout.getPaint().setAlpha(mEventsAlpha); - return layout; + layout.getPaint().setAlpha(mEventsAlpha) + return layout } - private void drawAllDayEvents(int firstDay, int numDays, Canvas canvas, Paint p) { - - p.setTextSize(NORMAL_FONT_SIZE); - p.setTextAlign(Paint.Align.LEFT); - Paint eventTextPaint = mEventTextPaint; - - final float startY = DAY_HEADER_HEIGHT; - final float stopY = startY + mAlldayHeight + ALLDAY_TOP_MARGIN; - float x = 0; - int linesIndex = 0; + private fun drawAllDayEvents(firstDay: Int, numDays: Int, canvas: Canvas, p: Paint) { + p.setTextSize(NORMAL_FONT_SIZE) + p.setTextAlign(Paint.Align.LEFT) + val eventTextPaint: Paint = mEventTextPaint + val startY = DAY_HEADER_HEIGHT.toFloat() + val stopY = startY + mAlldayHeight + ALLDAY_TOP_MARGIN + var x = 0f + var linesIndex = 0 // Draw the inner vertical grid lines - p.setColor(mCalendarGridLineInnerVerticalColor); - x = mHoursWidth; - p.setStrokeWidth(GRID_LINE_INNER_WIDTH); + p.setColor(mCalendarGridLineInnerVerticalColor) + x = mHoursWidth.toFloat() + p.setStrokeWidth(GRID_LINE_INNER_WIDTH) // Line bounding the top of the all day area - mLines[linesIndex++] = GRID_LINE_LEFT_MARGIN; - mLines[linesIndex++] = startY; - mLines[linesIndex++] = computeDayLeftPosition(mNumDays); - mLines[linesIndex++] = startY; - - for (int day = 0; day <= mNumDays; day++) { - x = computeDayLeftPosition(day); - mLines[linesIndex++] = x; - mLines[linesIndex++] = startY; - mLines[linesIndex++] = x; - mLines[linesIndex++] = stopY; - } - p.setAntiAlias(false); - canvas.drawLines(mLines, 0, linesIndex, p); - p.setStyle(Style.FILL); - - int y = DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN; - int lastDay = firstDay + numDays - 1; - final ArrayList<Event> events = mAllDayEvents; - int numEvents = events.size(); + mLines[linesIndex++] = GRID_LINE_LEFT_MARGIN + mLines[linesIndex++] = startY + mLines[linesIndex++] = computeDayLeftPosition(mNumDays).toFloat() + mLines[linesIndex++] = startY + for (day in 0..mNumDays) { + x = computeDayLeftPosition(day).toFloat() + mLines[linesIndex++] = x + mLines[linesIndex++] = startY + mLines[linesIndex++] = x + mLines[linesIndex++] = stopY + } + p.setAntiAlias(false) + canvas.drawLines(mLines, 0, linesIndex, p) + p.setStyle(Style.FILL) + val y = DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN + val lastDay = firstDay + numDays - 1 + val events: ArrayList<Event>? = mAllDayEvents + val numEvents: Int = events.size() // Whether or not we should draw the more events text - boolean hasMoreEvents = false; + var hasMoreEvents = false // size of the allDay area - float drawHeight = mAlldayHeight; + val drawHeight = mAlldayHeight.toFloat() // max number of events being drawn in one day of the allday area - float numRectangles = mMaxAlldayEvents; + var numRectangles = mMaxAlldayEvents.toFloat() // Where to cut off drawn allday events - int allDayEventClip = DAY_HEADER_HEIGHT + mAlldayHeight + ALLDAY_TOP_MARGIN; + var allDayEventClip = DAY_HEADER_HEIGHT + mAlldayHeight + ALLDAY_TOP_MARGIN // The number of events that weren't drawn in each day - mSkippedAlldayEvents = new int[numDays]; - if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount && !mShowAllAllDayEvents && - mAnimateDayHeight == 0) { + mSkippedAlldayEvents = IntArray(numDays) + if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount && !mShowAllAllDayEvents && mAnimateDayHeight == 0) { // We draw one fewer event than will fit so that more events text // can be drawn - numRectangles = mMaxUnexpandedAlldayEventCount - 1; + numRectangles = (mMaxUnexpandedAlldayEventCount - 1).toFloat() // We also clip the events above the more events text - allDayEventClip -= MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT; - hasMoreEvents = true; + allDayEventClip -= MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt() + hasMoreEvents = true } else if (mAnimateDayHeight != 0) { // clip at the end of the animating space - allDayEventClip = DAY_HEADER_HEIGHT + mAnimateDayHeight + ALLDAY_TOP_MARGIN; - } - - int alpha = eventTextPaint.getAlpha(); - eventTextPaint.setAlpha(mEventsAlpha); - for (int i = 0; i < numEvents; i++) { - Event event = events.get(i); - int startDay = event.startDay; - int endDay = event.endDay; + allDayEventClip = DAY_HEADER_HEIGHT + mAnimateDayHeight + ALLDAY_TOP_MARGIN + } + var alpha: Int = eventTextPaint.getAlpha() + eventTextPaint.setAlpha(mEventsAlpha) + for (i in 0 until numEvents) { + val event: Event = events.get(i) + var startDay: Int = event.startDay + var endDay: Int = event.endDay if (startDay > lastDay || endDay < firstDay) { - continue; + continue } if (startDay < firstDay) { - startDay = firstDay; + startDay = firstDay } if (endDay > lastDay) { - endDay = lastDay; + endDay = lastDay } - int startIndex = startDay - firstDay; - int endIndex = endDay - firstDay; - float height = mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount ? mAnimateDayEventHeight : - drawHeight / numRectangles; + val startIndex = startDay - firstDay + val endIndex = endDay - firstDay + var height = + if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) mAnimateDayEventHeight.toFloat() else drawHeight / numRectangles // Prevent a single event from getting too big if (height > MAX_HEIGHT_OF_ONE_ALLDAY_EVENT) { - height = MAX_HEIGHT_OF_ONE_ALLDAY_EVENT; + height = MAX_HEIGHT_OF_ONE_ALLDAY_EVENT.toFloat() } // Leave a one-pixel space between the vertical day lines and the // event rectangle. - event.left = computeDayLeftPosition(startIndex); - event.right = computeDayLeftPosition(endIndex + 1) - DAY_GAP; - event.top = y + height * event.getColumn(); - event.bottom = event.top + height - ALL_DAY_EVENT_RECT_BOTTOM_MARGIN; + event.left = computeDayLeftPosition(startIndex) + event.right = computeDayLeftPosition(endIndex + 1) - DAY_GAP + event.top = y + height * event.getColumn() + event.bottom = event.top + height - ALL_DAY_EVENT_RECT_BOTTOM_MARGIN if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) { // check if we should skip this event. We skip if it starts // after the clip bound or ends after the skip bound and we're // not animating. if (event.top >= allDayEventClip) { - incrementSkipCount(mSkippedAlldayEvents, startIndex, endIndex); - continue; + incrementSkipCount(mSkippedAlldayEvents, startIndex, endIndex) + continue } else if (event.bottom > allDayEventClip) { if (hasMoreEvents) { - incrementSkipCount(mSkippedAlldayEvents, startIndex, endIndex); - continue; + incrementSkipCount(mSkippedAlldayEvents, startIndex, endIndex) + continue } - event.bottom = allDayEventClip; + event.bottom = allDayEventClip } } - Rect r = drawEventRect(event, canvas, p, eventTextPaint, (int) event.top, - (int) event.bottom); - setupAllDayTextRect(r); - StaticLayout layout = getEventLayout(mAllDayLayouts, i, event, eventTextPaint, r); - drawEventText(layout, r, canvas, r.top, r.bottom, true); + val r: Rect = drawEventRect( + event, canvas, p, eventTextPaint, event.top as Int, + event.bottom as Int + ) + setupAllDayTextRect(r) + val layout: StaticLayout? = getEventLayout(mAllDayLayouts, i, event, eventTextPaint, r) + drawEventText(layout, r, canvas, r.top, r.bottom, true) // Check if this all-day event intersects the selected day if (mSelectionAllday && mComputeSelectedEvents) { if (startDay <= mSelectionDay && endDay >= mSelectionDay) { - mSelectedEvents.add(event); + mSelectedEvents.add(event) } } } - eventTextPaint.setAlpha(alpha); - + eventTextPaint.setAlpha(alpha) if (mMoreAlldayEventsTextAlpha != 0 && mSkippedAlldayEvents != null) { // If the more allday text should be visible, draw it. - alpha = p.getAlpha(); - p.setAlpha(mEventsAlpha); - p.setColor(mMoreAlldayEventsTextAlpha << 24 & mMoreEventsTextColor); - for (int i = 0; i < mSkippedAlldayEvents.length; i++) { - if (mSkippedAlldayEvents[i] > 0) { - drawMoreAlldayEvents(canvas, mSkippedAlldayEvents[i], i, p); + alpha = p.getAlpha() + p.setAlpha(mEventsAlpha) + p.setColor(mMoreAlldayEventsTextAlpha shl 24 and mMoreEventsTextColor) + for (i in mSkippedAlldayEvents.indices) { + if (mSkippedAlldayEvents!![i] > 0) { + drawMoreAlldayEvents(canvas, mSkippedAlldayEvents!![i], i, p) } } - p.setAlpha(alpha); + p.setAlpha(alpha) } - if (mSelectionAllday) { // Compute the neighbors for the list of all-day events that // intersect the selected day. - computeAllDayNeighbors(); + computeAllDayNeighbors() // Set the selection position to zero so that when we move down // to the normal event area, we will highlight the topmost event. - saveSelectionPosition(0f, 0f, 0f, 0f); + saveSelectionPosition(0f, 0f, 0f, 0f) } } // Helper method for counting the number of allday events skipped on each day - private void incrementSkipCount(int[] counts, int startIndex, int endIndex) { - if (counts == null || startIndex < 0 || endIndex > counts.length) { - return; + private fun incrementSkipCount(counts: IntArray?, startIndex: Int, endIndex: Int) { + if (counts == null || startIndex < 0 || endIndex > counts.size) { + return } - for (int i = startIndex; i <= endIndex; i++) { - counts[i]++; + for (i in startIndex..endIndex) { + counts[i]++ } } // Draws the "box +n" text for hidden allday events - protected void drawMoreAlldayEvents(Canvas canvas, int remainingEvents, int day, Paint p) { - int x = computeDayLeftPosition(day) + EVENT_ALL_DAY_TEXT_LEFT_MARGIN; - int y = (int) (mAlldayHeight - .5f * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT - .5f - * EVENT_SQUARE_WIDTH + DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN); - Rect r = mRect; - r.top = y; - r.left = x; - r.bottom = y + EVENT_SQUARE_WIDTH; - r.right = x + EVENT_SQUARE_WIDTH; - p.setColor(mMoreEventsTextColor); - p.setStrokeWidth(EVENT_RECT_STROKE_WIDTH); - p.setStyle(Style.STROKE); - p.setAntiAlias(false); - canvas.drawRect(r, p); - p.setAntiAlias(true); - p.setStyle(Style.FILL); - p.setTextSize(EVENT_TEXT_FONT_SIZE); - String text = mResources.getQuantityString(R.plurals.month_more_events, remainingEvents); - y += EVENT_SQUARE_WIDTH; - x += EVENT_SQUARE_WIDTH + EVENT_LINE_PADDING; - canvas.drawText(String.format(text, remainingEvents), x, y, p); - } - - private void computeAllDayNeighbors() { - int len = mSelectedEvents.size(); + protected fun drawMoreAlldayEvents(canvas: Canvas, remainingEvents: Int, day: Int, p: Paint) { + var x = computeDayLeftPosition(day) + EVENT_ALL_DAY_TEXT_LEFT_MARGIN + var y = (mAlldayHeight - .5f * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT - (.5f + * EVENT_SQUARE_WIDTH) + DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN).toInt() + val r: Rect = mRect + r.top = y + r.left = x + r.bottom = y + EVENT_SQUARE_WIDTH + r.right = x + EVENT_SQUARE_WIDTH + p.setColor(mMoreEventsTextColor) + p.setStrokeWidth(EVENT_RECT_STROKE_WIDTH) + p.setStyle(Style.STROKE) + p.setAntiAlias(false) + canvas.drawRect(r, p) + p.setAntiAlias(true) + p.setStyle(Style.FILL) + p.setTextSize(EVENT_TEXT_FONT_SIZE) + val text: String = + mResources.getQuantityString(R.plurals.month_more_events, remainingEvents) + y += EVENT_SQUARE_WIDTH + x += EVENT_SQUARE_WIDTH + EVENT_LINE_PADDING + canvas.drawText(String.format(text, remainingEvents), x, y, p) + } + + private fun computeAllDayNeighbors() { + val len: Int = mSelectedEvents.size() if (len == 0 || mSelectedEvent != null) { - return; + return } // First, clear all the links - for (int ii = 0; ii < len; ii++) { - Event ev = mSelectedEvents.get(ii); - ev.nextUp = null; - ev.nextDown = null; - ev.nextLeft = null; - ev.nextRight = null; + for (ii in 0 until len) { + val ev: Event = mSelectedEvents.get(ii) + ev.nextUp = null + ev.nextDown = null + ev.nextLeft = null + ev.nextRight = null } // For each event in the selected event list "mSelectedEvents", find @@ -2684,294 +2233,295 @@ public class DayView extends View implements View.OnCreateContextMenuListener, // Find the event in the same row as the previously selected all-day // event, if any. - int startPosition = -1; + var startPosition = -1 if (mPrevSelectedEvent != null && mPrevSelectedEvent.drawAsAllday()) { - startPosition = mPrevSelectedEvent.getColumn(); - } - int maxPosition = -1; - Event startEvent = null; - Event maxPositionEvent = null; - for (int ii = 0; ii < len; ii++) { - Event ev = mSelectedEvents.get(ii); - int position = ev.getColumn(); + startPosition = mPrevSelectedEvent.getColumn() + } + var maxPosition = -1 + var startEvent: Event? = null + var maxPositionEvent: Event? = null + for (ii in 0 until len) { + val ev: Event = mSelectedEvents.get(ii) + val position: Int = ev.getColumn() if (position == startPosition) { - startEvent = ev; + startEvent = ev } else if (position > maxPosition) { - maxPositionEvent = ev; - maxPosition = position; + maxPositionEvent = ev + maxPosition = position } - for (int jj = 0; jj < len; jj++) { + for (jj in 0 until len) { if (jj == ii) { - continue; + continue } - Event neighbor = mSelectedEvents.get(jj); - int neighborPosition = neighbor.getColumn(); + val neighbor: Event = mSelectedEvents.get(jj) + val neighborPosition: Int = neighbor.getColumn() if (neighborPosition == position - 1) { - ev.nextUp = neighbor; + ev.nextUp = neighbor } else if (neighborPosition == position + 1) { - ev.nextDown = neighbor; + ev.nextDown = neighbor } } } if (startEvent != null) { - setSelectedEvent(startEvent); + setSelectedEvent(startEvent) } else { - setSelectedEvent(maxPositionEvent); + setSelectedEvent(maxPositionEvent) } } - private void drawEvents(int date, int dayIndex, int top, Canvas canvas, Paint p) { - Paint eventTextPaint = mEventTextPaint; - int left = computeDayLeftPosition(dayIndex) + 1; - int cellWidth = computeDayLeftPosition(dayIndex + 1) - left + 1; - int cellHeight = mCellHeight; + private fun drawEvents(date: Int, dayIndex: Int, top: Int, canvas: Canvas, p: Paint) { + val eventTextPaint: Paint = mEventTextPaint + val left = computeDayLeftPosition(dayIndex) + 1 + val cellWidth = computeDayLeftPosition(dayIndex + 1) - left + 1 + val cellHeight = mCellHeight // Use the selected hour as the selection region - Rect selectionArea = mSelectionRect; - selectionArea.top = top + mSelectionHour * (cellHeight + HOUR_GAP); - selectionArea.bottom = selectionArea.top + cellHeight; - selectionArea.left = left; - selectionArea.right = selectionArea.left + cellWidth; - - final ArrayList<Event> events = mEvents; - int numEvents = events.size(); - EventGeometry geometry = mEventGeometry; - - final int viewEndY = mViewStartY + mViewHeight - DAY_HEADER_HEIGHT - mAlldayHeight; - - int alpha = eventTextPaint.getAlpha(); - eventTextPaint.setAlpha(mEventsAlpha); - for (int i = 0; i < numEvents; i++) { - Event event = events.get(i); + val selectionArea: Rect = mSelectionRect + selectionArea.top = top + mSelectionHour * (cellHeight + HOUR_GAP) + selectionArea.bottom = selectionArea.top + cellHeight + selectionArea.left = left + selectionArea.right = selectionArea.left + cellWidth + val events: ArrayList<Event> = mEvents + val numEvents: Int = events.size() + val geometry: EventGeometry = mEventGeometry + val viewEndY = mViewStartY + mViewHeight - DAY_HEADER_HEIGHT - mAlldayHeight + val alpha: Int = eventTextPaint.getAlpha() + eventTextPaint.setAlpha(mEventsAlpha) + for (i in 0 until numEvents) { + val event: Event = events.get(i) if (!geometry.computeEventRect(date, left, top, cellWidth, event)) { - continue; + continue } // Don't draw it if it is not visible if (event.bottom < mViewStartY || event.top > viewEndY) { - continue; + continue } - if (date == mSelectionDay && !mSelectionAllday && mComputeSelectedEvents - && geometry.eventIntersectsSelection(event, selectionArea)) { - mSelectedEvents.add(event); + && geometry.eventIntersectsSelection(event, selectionArea) + ) { + mSelectedEvents.add(event) } - - Rect r = drawEventRect(event, canvas, p, eventTextPaint, mViewStartY, viewEndY); - setupTextRect(r); + val r: Rect = drawEventRect(event, canvas, p, eventTextPaint, mViewStartY, viewEndY) + setupTextRect(r) // Don't draw text if it is not visible if (r.top > viewEndY || r.bottom < mViewStartY) { - continue; + continue } - StaticLayout layout = getEventLayout(mLayouts, i, event, eventTextPaint, r); + val layout: StaticLayout? = getEventLayout(mLayouts, i, event, eventTextPaint, r) // TODO: not sure why we are 4 pixels off - drawEventText(layout, r, canvas, mViewStartY + 4, mViewStartY + mViewHeight - - DAY_HEADER_HEIGHT - mAlldayHeight, false); - } - eventTextPaint.setAlpha(alpha); - } - - private Rect drawEventRect(Event event, Canvas canvas, Paint p, Paint eventTextPaint, - int visibleTop, int visibleBot) { + drawEventText( + layout, + r, + canvas, + mViewStartY + 4, + mViewStartY + mViewHeight - DAY_HEADER_HEIGHT - mAlldayHeight, + false + ) + } + eventTextPaint.setAlpha(alpha) + } + + private fun drawEventRect( + event: Event, canvas: Canvas, p: Paint, eventTextPaint: Paint, + visibleTop: Int, visibleBot: Int + ): Rect { // Draw the Event Rect - Rect r = mRect; - r.top = Math.max((int) event.top + EVENT_RECT_TOP_MARGIN, visibleTop); - r.bottom = Math.min((int) event.bottom - EVENT_RECT_BOTTOM_MARGIN, visibleBot); - r.left = (int) event.left + EVENT_RECT_LEFT_MARGIN; - r.right = (int) event.right; - - int color = event.color; - switch (event.selfAttendeeStatus) { - case Attendees.ATTENDEE_STATUS_INVITED: - if (event != mClickedEvent) { - p.setStyle(Style.STROKE); + val r: Rect = mRect + r.top = Math.max(event.top as Int + EVENT_RECT_TOP_MARGIN, visibleTop) + r.bottom = Math.min(event.bottom as Int - EVENT_RECT_BOTTOM_MARGIN, visibleBot) + r.left = event.left as Int + EVENT_RECT_LEFT_MARGIN + r.right = event.right + var color: Int = event.color + when (event.selfAttendeeStatus) { + Attendees.ATTENDEE_STATUS_INVITED -> if (event !== mClickedEvent) { + p.setStyle(Style.STROKE) + } + Attendees.ATTENDEE_STATUS_DECLINED -> { + if (event !== mClickedEvent) { + color = Utils.getDeclinedColorFromColor(color) } - break; - case Attendees.ATTENDEE_STATUS_DECLINED: - if (event != mClickedEvent) { - color = Utils.getDeclinedColorFromColor(color); - } - case Attendees.ATTENDEE_STATUS_NONE: // Your own events - case Attendees.ATTENDEE_STATUS_ACCEPTED: - case Attendees.ATTENDEE_STATUS_TENTATIVE: - default: - p.setStyle(Style.FILL_AND_STROKE); - break; - } - - p.setAntiAlias(false); - - int floorHalfStroke = (int) Math.floor(EVENT_RECT_STROKE_WIDTH / 2.0f); - int ceilHalfStroke = (int) Math.ceil(EVENT_RECT_STROKE_WIDTH / 2.0f); - r.top = Math.max((int) event.top + EVENT_RECT_TOP_MARGIN + floorHalfStroke, visibleTop); - r.bottom = Math.min((int) event.bottom - EVENT_RECT_BOTTOM_MARGIN - ceilHalfStroke, - visibleBot); - r.left += floorHalfStroke; - r.right -= ceilHalfStroke; - p.setStrokeWidth(EVENT_RECT_STROKE_WIDTH); - p.setColor(color); - int alpha = p.getAlpha(); - p.setAlpha(mEventsAlpha); - canvas.drawRect(r, p); - p.setAlpha(alpha); - p.setStyle(Style.FILL); + p.setStyle(Style.FILL_AND_STROKE) + } + Attendees.ATTENDEE_STATUS_NONE, Attendees.ATTENDEE_STATUS_ACCEPTED, Attendees.ATTENDEE_STATUS_TENTATIVE -> p.setStyle( + Style.FILL_AND_STROKE + ) + else -> p.setStyle(Style.FILL_AND_STROKE) + } + p.setAntiAlias(false) + val floorHalfStroke = Math.floor(EVENT_RECT_STROKE_WIDTH / 2.0f) as Int + val ceilHalfStroke = Math.ceil(EVENT_RECT_STROKE_WIDTH / 2.0f) as Int + r.top = Math.max(event.top as Int + EVENT_RECT_TOP_MARGIN + floorHalfStroke, visibleTop) + r.bottom = Math.min( + event.bottom as Int - EVENT_RECT_BOTTOM_MARGIN - ceilHalfStroke, + visibleBot + ) + r.left += floorHalfStroke + r.right -= ceilHalfStroke + p.setStrokeWidth(EVENT_RECT_STROKE_WIDTH) + p.setColor(color) + val alpha: Int = p.getAlpha() + p.setAlpha(mEventsAlpha) + canvas.drawRect(r, p) + p.setAlpha(alpha) + p.setStyle(Style.FILL) // Setup rect for drawEventText which follows - r.top = (int) event.top + EVENT_RECT_TOP_MARGIN; - r.bottom = (int) event.bottom - EVENT_RECT_BOTTOM_MARGIN; - r.left = (int) event.left + EVENT_RECT_LEFT_MARGIN; - r.right = (int) event.right - EVENT_RECT_RIGHT_MARGIN; - return r; + r.top = event.top as Int + EVENT_RECT_TOP_MARGIN + r.bottom = event.bottom as Int - EVENT_RECT_BOTTOM_MARGIN + r.left = event.left as Int + EVENT_RECT_LEFT_MARGIN + r.right = event.right as Int - EVENT_RECT_RIGHT_MARGIN + return r } - private final Pattern drawTextSanitizerFilter = Pattern.compile("[\t\n],"); + private val drawTextSanitizerFilter: Pattern = Pattern.compile("[\t\n],") // Sanitize a string before passing it to drawText or else we get little // squares. For newlines and tabs before a comma, delete the character. // Otherwise, just replace them with a space. - private String drawTextSanitizer(String string, int maxEventTextLen) { - Matcher m = drawTextSanitizerFilter.matcher(string); - string = m.replaceAll(","); - - int len = string.length(); + private fun drawTextSanitizer(string: String, maxEventTextLen: Int): String { + var string = string + val m: Matcher = drawTextSanitizerFilter.matcher(string) + string = m.replaceAll(",") + var len: Int = string.length() if (maxEventTextLen <= 0) { - string = ""; - len = 0; + string = "" + len = 0 } else if (len > maxEventTextLen) { - string = string.substring(0, maxEventTextLen); - len = maxEventTextLen; + string = string.substring(0, maxEventTextLen) + len = maxEventTextLen } - - return string.replace('\n', ' '); + return string.replace('\n', ' ') } - private void drawEventText(StaticLayout eventLayout, Rect rect, Canvas canvas, int top, - int bottom, boolean center) { + private fun drawEventText( + eventLayout: StaticLayout?, rect: Rect, canvas: Canvas, top: Int, + bottom: Int, center: Boolean + ) { // drawEmptyRect(canvas, rect, 0xFFFF00FF); // for debugging - - int width = rect.right - rect.left; - int height = rect.bottom - rect.top; + val width: Int = rect.right - rect.left + val height: Int = rect.bottom - rect.top // If the rectangle is too small for text, then return if (eventLayout == null || width < MIN_CELL_WIDTH_FOR_TEXT) { - return; - } - - int totalLineHeight = 0; - int lineCount = eventLayout.getLineCount(); - for (int i = 0; i < lineCount; i++) { - int lineBottom = eventLayout.getLineBottom(i); - if (lineBottom <= height) { - totalLineHeight = lineBottom; + return + } + var totalLineHeight = 0 + val lineCount: Int = eventLayout.getLineCount() + for (i in 0 until lineCount) { + val lineBottom: Int = eventLayout.getLineBottom(i) + totalLineHeight = if (lineBottom <= height) { + lineBottom } else { - break; + break } } - // + 2 is small workaround when the font is slightly bigger then the rect. This will + // + 2 is small workaround when the font is slightly bigger than the rect. This will // still allow the text to be shown without overflowing into the other all day rects. if (totalLineHeight == 0 || rect.top > bottom || rect.top + totalLineHeight + 2 < top) { - return; + return } // Use a StaticLayout to format the string. - canvas.save(); - // canvas.translate(rect.left, rect.top + (rect.bottom - rect.top / 2)); - int padding = center? (rect.bottom - rect.top - totalLineHeight) / 2 : 0; - canvas.translate(rect.left, rect.top + padding); - rect.left = 0; - rect.right = width; - rect.top = 0; - rect.bottom = totalLineHeight; + canvas.save() + // canvas.translate(rect.left, rect.top + (rect.bottom - rect.top / 2)); + val padding = if (center) (rect.bottom - rect.top - totalLineHeight) / 2 else 0 + canvas.translate(rect.left, rect.top + padding) + rect.left = 0 + rect.right = width + rect.top = 0 + rect.bottom = totalLineHeight // There's a bug somewhere. If this rect is outside of a previous // cliprect, this becomes a no-op. What happens is that the text draw // past the event rect. The current fix is to not draw the staticLayout // at all if it is completely out of bound. - canvas.clipRect(rect); - eventLayout.draw(canvas); - canvas.restore(); + canvas.clipRect(rect) + eventLayout.draw(canvas) + canvas.restore() } // The following routines are called from the parent activity when certain // touch events occur. - private void doDown(MotionEvent ev) { - mTouchMode = TOUCH_MODE_DOWN; - mViewStartX = 0; - mOnFlingCalled = false; - mHandler.removeCallbacks(mContinueScroll); - int x = (int) ev.getX(); - int y = (int) ev.getY(); + private fun doDown(ev: MotionEvent) { + mTouchMode = TOUCH_MODE_DOWN + mViewStartX = 0 + mOnFlingCalled = false + mHandler.removeCallbacks(mContinueScroll) + val x = ev.getX() as Int + val y = ev.getY() as Int // Save selection information: we use setSelectionFromPosition to find the selected event // in order to show the "clicked" color. But since it is also setting the selected info // for new events, we need to restore the old info after calling the function. - Event oldSelectedEvent = mSelectedEvent; - int oldSelectionDay = mSelectionDay; - int oldSelectionHour = mSelectionHour; + val oldSelectedEvent: Event? = mSelectedEvent + val oldSelectionDay = mSelectionDay + val oldSelectionHour = mSelectionHour if (setSelectionFromPosition(x, y, false)) { // If a time was selected (a blue selection box is visible) and the click location // is in the selected time, do not show a click on an event to prevent a situation // of both a selection and an event are clicked when they overlap. - boolean pressedSelected = (mSelectionMode != SELECTION_HIDDEN) - && oldSelectionDay == mSelectionDay && oldSelectionHour == mSelectionHour; + val pressedSelected = (mSelectionMode != SELECTION_HIDDEN + && oldSelectionDay == mSelectionDay && oldSelectionHour == mSelectionHour) if (!pressedSelected && mSelectedEvent != null) { - mSavedClickedEvent = mSelectedEvent; - mDownTouchTime = System.currentTimeMillis(); - postDelayed (mSetClick,mOnDownDelay); + mSavedClickedEvent = mSelectedEvent + mDownTouchTime = System.currentTimeMillis() + postDelayed(mSetClick, mOnDownDelay) } else { - eventClickCleanup(); + eventClickCleanup() } } - mSelectedEvent = oldSelectedEvent; - mSelectionDay = oldSelectionDay; - mSelectionHour = oldSelectionHour; - invalidate(); + mSelectedEvent = oldSelectedEvent + mSelectionDay = oldSelectionDay + mSelectionHour = oldSelectionHour + invalidate() } // Kicks off all the animations when the expand allday area is tapped - private void doExpandAllDayClick() { - mShowAllAllDayEvents = !mShowAllAllDayEvents; - - ObjectAnimator.setFrameDelay(0); + private fun doExpandAllDayClick() { + mShowAllAllDayEvents = !mShowAllAllDayEvents + ObjectAnimator.setFrameDelay(0) // Determine the starting height if (mAnimateDayHeight == 0) { - mAnimateDayHeight = mShowAllAllDayEvents ? - mAlldayHeight - (int) MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT : mAlldayHeight; + mAnimateDayHeight = + if (mShowAllAllDayEvents) mAlldayHeight - MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt() else mAlldayHeight } // Cancel current animations - mCancellingAnimations = true; + mCancellingAnimations = true if (mAlldayAnimator != null) { - mAlldayAnimator.cancel(); + mAlldayAnimator.cancel() } if (mAlldayEventAnimator != null) { - mAlldayEventAnimator.cancel(); + mAlldayEventAnimator.cancel() } if (mMoreAlldayEventsAnimator != null) { - mMoreAlldayEventsAnimator.cancel(); + mMoreAlldayEventsAnimator.cancel() } - mCancellingAnimations = false; + mCancellingAnimations = false // get new animators - mAlldayAnimator = getAllDayAnimator(); - mAlldayEventAnimator = getAllDayEventAnimator(); - mMoreAlldayEventsAnimator = ObjectAnimator.ofInt(this, - "moreAllDayEventsTextAlpha", - mShowAllAllDayEvents ? MORE_EVENTS_MAX_ALPHA : 0, - mShowAllAllDayEvents ? 0 : MORE_EVENTS_MAX_ALPHA); + mAlldayAnimator = allDayAnimator + mAlldayEventAnimator = allDayEventAnimator + mMoreAlldayEventsAnimator = ObjectAnimator.ofInt( + this, + "moreAllDayEventsTextAlpha", + if (mShowAllAllDayEvents) MORE_EVENTS_MAX_ALPHA else 0, + if (mShowAllAllDayEvents) 0 else MORE_EVENTS_MAX_ALPHA + ) // Set up delays and start the animators - mAlldayAnimator.setStartDelay(mShowAllAllDayEvents ? ANIMATION_SECONDARY_DURATION : 0); - mAlldayAnimator.start(); - mMoreAlldayEventsAnimator.setStartDelay(mShowAllAllDayEvents ? 0 : ANIMATION_DURATION); - mMoreAlldayEventsAnimator.setDuration(ANIMATION_SECONDARY_DURATION); - mMoreAlldayEventsAnimator.start(); + mAlldayAnimator.setStartDelay(if (mShowAllAllDayEvents) ANIMATION_SECONDARY_DURATION else 0) + mAlldayAnimator.start() + mMoreAlldayEventsAnimator.setStartDelay(if (mShowAllAllDayEvents) 0 else ANIMATION_DURATION) + mMoreAlldayEventsAnimator.setDuration(ANIMATION_SECONDARY_DURATION) + mMoreAlldayEventsAnimator.start() if (mAlldayEventAnimator != null) { // This is the only animator that can return null, so check it mAlldayEventAnimator - .setStartDelay(mShowAllAllDayEvents ? ANIMATION_SECONDARY_DURATION : 0); - mAlldayEventAnimator.start(); + .setStartDelay(if (mShowAllAllDayEvents) ANIMATION_SECONDARY_DURATION else 0) + mAlldayEventAnimator.start() } } @@ -2979,570 +2529,579 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * Figures out the initial heights for allDay events and space when * a view is being set up. */ - public void initAllDayHeights() { + fun initAllDayHeights() { if (mMaxAlldayEvents <= mMaxUnexpandedAlldayEventCount) { - return; + return } if (mShowAllAllDayEvents) { - int maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT; - maxADHeight = Math.min(maxADHeight, - (int)(mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT)); - mAnimateDayEventHeight = maxADHeight / mMaxAlldayEvents; + var maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT + maxADHeight = Math.min( + maxADHeight, + (mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt() + ) + mAnimateDayEventHeight = maxADHeight / mMaxAlldayEvents } else { - mAnimateDayEventHeight = (int)MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT; + mAnimateDayEventHeight = MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt() } - } + }// First calculate the absolute max height + // Now expand to fit but not beyond the absolute max + // calculate the height of individual events in order to fit + // if there's nothing to animate just return + // Set up the animator with the calculated values // Sets up an animator for changing the height of allday events - private ObjectAnimator getAllDayEventAnimator() { - // First calculate the absolute max height - int maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT; - // Now expand to fit but not beyond the absolute max - maxADHeight = - Math.min(maxADHeight, (int)(mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT)); - // calculate the height of individual events in order to fit - int fitHeight = maxADHeight / mMaxAlldayEvents; - int currentHeight = mAnimateDayEventHeight; - int desiredHeight = - mShowAllAllDayEvents ? fitHeight : (int)MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT; - // if there's nothing to animate just return - if (currentHeight == desiredHeight) { - return null; - } - - // Set up the animator with the calculated values - ObjectAnimator animator = ObjectAnimator.ofInt(this, "animateDayEventHeight", - currentHeight, desiredHeight); - animator.setDuration(ANIMATION_DURATION); - return animator; - } - + private val allDayEventAnimator: ObjectAnimator? + private get() { + // First calculate the absolute max height + var maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT + // Now expand to fit but not beyond the absolute max + maxADHeight = Math.min( + maxADHeight, + (mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt() + ) + // calculate the height of individual events in order to fit + val fitHeight = maxADHeight / mMaxAlldayEvents + val currentHeight = mAnimateDayEventHeight + val desiredHeight = + if (mShowAllAllDayEvents) fitHeight else MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt() + // if there's nothing to animate just return + if (currentHeight == desiredHeight) { + return null + } + + // Set up the animator with the calculated values + val animator: ObjectAnimator = ObjectAnimator.ofInt( + this, "animateDayEventHeight", + currentHeight, desiredHeight + ) + animator.setDuration(ANIMATION_DURATION) + return animator + }// when finished, set this to 0 to signify not animating// Calculate the absolute max height + // Find the desired height but don't exceed abs max + // calculate the current and desired heights + + // Set up the animator with the calculated values // Sets up an animator for changing the height of the allday area - private ObjectAnimator getAllDayAnimator() { - // Calculate the absolute max height - int maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT; - // Find the desired height but don't exceed abs max - maxADHeight = - Math.min(maxADHeight, (int)(mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT)); - // calculate the current and desired heights - int currentHeight = mAnimateDayHeight != 0 ? mAnimateDayHeight : mAlldayHeight; - int desiredHeight = mShowAllAllDayEvents ? maxADHeight : - (int) (MAX_UNEXPANDED_ALLDAY_HEIGHT - MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT - 1); - - // Set up the animator with the calculated values - ObjectAnimator animator = ObjectAnimator.ofInt(this, "animateDayHeight", - currentHeight, desiredHeight); - animator.setDuration(ANIMATION_DURATION); - - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (!mCancellingAnimations) { - // when finished, set this to 0 to signify not animating - mAnimateDayHeight = 0; - mUseExpandIcon = !mShowAllAllDayEvents; + private val allDayAnimator: ObjectAnimator + private get() { + // Calculate the absolute max height + var maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT + // Find the desired height but don't exceed abs max + maxADHeight = Math.min( + maxADHeight, + (mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt() + ) + // calculate the current and desired heights + val currentHeight = if (mAnimateDayHeight != 0) mAnimateDayHeight else mAlldayHeight + val desiredHeight = + if (mShowAllAllDayEvents) maxADHeight else (MAX_UNEXPANDED_ALLDAY_HEIGHT - MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT - 1).toInt() + + // Set up the animator with the calculated values + val animator: ObjectAnimator = ObjectAnimator.ofInt( + this, "animateDayHeight", + currentHeight, desiredHeight + ) + animator.setDuration(ANIMATION_DURATION) + animator.addListener(object : AnimatorListenerAdapter() { + @Override + fun onAnimationEnd(animation: Animator?) { + if (!mCancellingAnimations) { + // when finished, set this to 0 to signify not animating + mAnimateDayHeight = 0 + mUseExpandIcon = !mShowAllAllDayEvents + } + mRemeasure = true + invalidate() } - mRemeasure = true; - invalidate(); - } - }); - return animator; - } + }) + return animator + } // setter for the 'box +n' alpha text used by the animator - public void setMoreAllDayEventsTextAlpha(int alpha) { - mMoreAlldayEventsTextAlpha = alpha; - invalidate(); + fun setMoreAllDayEventsTextAlpha(alpha: Int) { + mMoreAlldayEventsTextAlpha = alpha + invalidate() } // setter for the height of the allday area used by the animator - public void setAnimateDayHeight(int height) { - mAnimateDayHeight = height; - mRemeasure = true; - invalidate(); + fun setAnimateDayHeight(height: Int) { + mAnimateDayHeight = height + mRemeasure = true + invalidate() } // setter for the height of allday events used by the animator - public void setAnimateDayEventHeight(int height) { - mAnimateDayEventHeight = height; - mRemeasure = true; - invalidate(); + fun setAnimateDayEventHeight(height: Int) { + mAnimateDayEventHeight = height + mRemeasure = true + invalidate() } - private void doSingleTapUp(MotionEvent ev) { + private fun doSingleTapUp(ev: MotionEvent) { if (!mHandleActionUp || mScrolling) { - return; + return } - - int x = (int) ev.getX(); - int y = (int) ev.getY(); - int selectedDay = mSelectionDay; - int selectedHour = mSelectionHour; - + val x = ev.getX() as Int + val y = ev.getY() as Int + val selectedDay = mSelectionDay + val selectedHour = mSelectionHour if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) { // check if the tap was in the allday expansion area - int bottom = mFirstCell; - if((x < mHoursWidth && y > DAY_HEADER_HEIGHT && y < DAY_HEADER_HEIGHT + mAlldayHeight) - || (!mShowAllAllDayEvents && mAnimateDayHeight == 0 && y < bottom && - y >= bottom - MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT)) { - doExpandAllDayClick(); - return; + val bottom = mFirstCell + if (x < mHoursWidth && y > DAY_HEADER_HEIGHT && y < DAY_HEADER_HEIGHT + mAlldayHeight + || !mShowAllAllDayEvents && mAnimateDayHeight == 0 && y < bottom && y >= bottom - MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT + ) { + doExpandAllDayClick() + return } } - - boolean validPosition = setSelectionFromPosition(x, y, false); + val validPosition = setSelectionFromPosition(x, y, false) if (!validPosition) { if (y < DAY_HEADER_HEIGHT) { - Time selectedTime = new Time(mBaseDate); - selectedTime.setJulianDay(mSelectionDay); - selectedTime.hour = mSelectionHour; - selectedTime.normalize(true /* ignore isDst */); - mController.sendEvent(this, EventType.GO_TO, null, null, selectedTime, -1, - ViewType.DAY, CalendarController.EXTRA_GOTO_DATE, null, null); - } - return; - } - - boolean hasSelection = mSelectionMode != SELECTION_HIDDEN; - boolean pressedSelected = (hasSelection || mTouchExplorationEnabled) - && selectedDay == mSelectionDay && selectedHour == mSelectionHour; - + val selectedTime = Time(mBaseDate) + selectedTime.setJulianDay(mSelectionDay) + selectedTime.hour = mSelectionHour + selectedTime.normalize(true /* ignore isDst */) + mController.sendEvent( + this, EventType.GO_TO, null, null, selectedTime, -1, + ViewType.DAY, CalendarController.EXTRA_GOTO_DATE, null, null + ) + } + return + } + val hasSelection = mSelectionMode != SELECTION_HIDDEN + val pressedSelected = ((hasSelection || mTouchExplorationEnabled) + && selectedDay == mSelectionDay && selectedHour == mSelectionHour) if (mSelectedEvent != null) { // If the tap is on an event, launch the "View event" view if (mIsAccessibilityEnabled) { - mAccessibilityMgr.interrupt(); + mAccessibilityMgr.interrupt() } - - mSelectionMode = SELECTION_HIDDEN; - - int yLocation = - (int)((mSelectedEvent.top + mSelectedEvent.bottom)/2); + mSelectionMode = SELECTION_HIDDEN + var yLocation = ((mSelectedEvent.top + mSelectedEvent.bottom) / 2) as Int // Y location is affected by the position of the event in the scrolling // view (mViewStartY) and the presence of all day events (mFirstCell) if (!mSelectedEvent.allDay) { - yLocation += (mFirstCell - mViewStartY); + yLocation += mFirstCell - mViewStartY } - mClickedYLocation = yLocation; - long clearDelay = (CLICK_DISPLAY_DURATION + mOnDownDelay) - - (System.currentTimeMillis() - mDownTouchTime); + mClickedYLocation = yLocation + val clearDelay: Long = CLICK_DISPLAY_DURATION + mOnDownDelay - + (System.currentTimeMillis() - mDownTouchTime) if (clearDelay > 0) { - this.postDelayed(mClearClick, clearDelay); + this.postDelayed(mClearClick, clearDelay) } else { - this.post(mClearClick); + this.post(mClearClick) } } - invalidate(); + invalidate() } - private void doLongPress(MotionEvent ev) { - eventClickCleanup(); + private fun doLongPress(ev: MotionEvent) { + eventClickCleanup() if (mScrolling) { - return; + return } // Scale gesture in progress - if (mStartingSpanY != 0) { - return; + if (mStartingSpanY != 0f) { + return } - - int x = (int) ev.getX(); - int y = (int) ev.getY(); - - boolean validPosition = setSelectionFromPosition(x, y, false); + val x = ev.getX() as Int + val y = ev.getY() as Int + val validPosition = setSelectionFromPosition(x, y, false) if (!validPosition) { // return if the touch wasn't on an area of concern - return; + return } - - invalidate(); - performLongClick(); + invalidate() + performLongClick() } - private void doScroll(MotionEvent e1, MotionEvent e2, float deltaX, float deltaY) { - cancelAnimation(); + private fun doScroll(e1: MotionEvent, e2: MotionEvent, deltaX: Float, deltaY: Float) { + cancelAnimation() if (mStartingScroll) { - mInitialScrollX = 0; - mInitialScrollY = 0; - mStartingScroll = false; - } - - mInitialScrollX += deltaX; - mInitialScrollY += deltaY; - int distanceX = (int) mInitialScrollX; - int distanceY = (int) mInitialScrollY; - - final float focusY = getAverageY(e2); + mInitialScrollX = 0f + mInitialScrollY = 0f + mStartingScroll = false + } + mInitialScrollX += deltaX + mInitialScrollY += deltaY + val distanceX = mInitialScrollX.toInt() + val distanceY = mInitialScrollY.toInt() + val focusY = getAverageY(e2) if (mRecalCenterHour) { // Calculate the hour that correspond to the average of the Y touch points - mGestureCenterHour = (mViewStartY + focusY - DAY_HEADER_HEIGHT - mAlldayHeight) - / (mCellHeight + DAY_GAP); - mRecalCenterHour = false; + mGestureCenterHour = ((mViewStartY + focusY - DAY_HEADER_HEIGHT - mAlldayHeight) + / (mCellHeight + DAY_GAP)) + mRecalCenterHour = false } // If we haven't figured out the predominant scroll direction yet, // then do it now. if (mTouchMode == TOUCH_MODE_DOWN) { - int absDistanceX = Math.abs(distanceX); - int absDistanceY = Math.abs(distanceY); - mScrollStartY = mViewStartY; - mPreviousDirection = 0; - + val absDistanceX: Int = Math.abs(distanceX) + val absDistanceY: Int = Math.abs(distanceY) + mScrollStartY = mViewStartY + mPreviousDirection = 0 if (absDistanceX > absDistanceY) { - int slopFactor = mScaleGestureDetector.isInProgress() ? 20 : 2; + val slopFactor = if (mScaleGestureDetector.isInProgress()) 20 else 2 if (absDistanceX > mScaledPagingTouchSlop * slopFactor) { - mTouchMode = TOUCH_MODE_HSCROLL; - mViewStartX = distanceX; - initNextView(-mViewStartX); + mTouchMode = TOUCH_MODE_HSCROLL + mViewStartX = distanceX + initNextView(-mViewStartX) } } else { - mTouchMode = TOUCH_MODE_VSCROLL; + mTouchMode = TOUCH_MODE_VSCROLL } - } else if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) { + } else if (mTouchMode and TOUCH_MODE_HSCROLL != 0) { // We are already scrolling horizontally, so check if we // changed the direction of scrolling so that the other week // is now visible. - mViewStartX = distanceX; + mViewStartX = distanceX if (distanceX != 0) { - int direction = (distanceX > 0) ? 1 : -1; + val direction = if (distanceX > 0) 1 else -1 if (direction != mPreviousDirection) { // The user has switched the direction of scrolling // so re-init the next view - initNextView(-mViewStartX); - mPreviousDirection = direction; + initNextView(-mViewStartX) + mPreviousDirection = direction } } } - - if ((mTouchMode & TOUCH_MODE_VSCROLL) != 0) { + if (mTouchMode and TOUCH_MODE_VSCROLL != 0) { // Calculate the top of the visible region in the calendar grid. // Increasing/decrease this will scroll the calendar grid up/down. - mViewStartY = (int) ((mGestureCenterHour * (mCellHeight + DAY_GAP)) - - focusY + DAY_HEADER_HEIGHT + mAlldayHeight); + mViewStartY = ((mGestureCenterHour * (mCellHeight + DAY_GAP) + - focusY) + DAY_HEADER_HEIGHT + mAlldayHeight).toInt() // If dragging while already at the end, do a glow - final int pulledToY = (int) (mScrollStartY + deltaY); + val pulledToY = (mScrollStartY + deltaY).toInt() if (pulledToY < 0) { - mEdgeEffectTop.onPull(deltaY / mViewHeight); + mEdgeEffectTop.onPull(deltaY / mViewHeight) if (!mEdgeEffectBottom.isFinished()) { - mEdgeEffectBottom.onRelease(); + mEdgeEffectBottom.onRelease() } } else if (pulledToY > mMaxViewStartY) { - mEdgeEffectBottom.onPull(deltaY / mViewHeight); + mEdgeEffectBottom.onPull(deltaY / mViewHeight) if (!mEdgeEffectTop.isFinished()) { - mEdgeEffectTop.onRelease(); + mEdgeEffectTop.onRelease() } } - if (mViewStartY < 0) { - mViewStartY = 0; - mRecalCenterHour = true; + mViewStartY = 0 + mRecalCenterHour = true } else if (mViewStartY > mMaxViewStartY) { - mViewStartY = mMaxViewStartY; - mRecalCenterHour = true; + mViewStartY = mMaxViewStartY + mRecalCenterHour = true } if (mRecalCenterHour) { // Calculate the hour that correspond to the average of the Y touch points - mGestureCenterHour = (mViewStartY + focusY - DAY_HEADER_HEIGHT - mAlldayHeight) - / (mCellHeight + DAY_GAP); - mRecalCenterHour = false; + mGestureCenterHour = ((mViewStartY + focusY - DAY_HEADER_HEIGHT - mAlldayHeight) + / (mCellHeight + DAY_GAP)) + mRecalCenterHour = false } - computeFirstHour(); + computeFirstHour() } - - mScrolling = true; - - mSelectionMode = SELECTION_HIDDEN; - invalidate(); + mScrolling = true + mSelectionMode = SELECTION_HIDDEN + invalidate() } - private float getAverageY(MotionEvent me) { - int count = me.getPointerCount(); - float focusY = 0; - for (int i = 0; i < count; i++) { - focusY += me.getY(i); + private fun getAverageY(me: MotionEvent): Float { + val count: Int = me.getPointerCount() + var focusY = 0f + for (i in 0 until count) { + focusY += me.getY(i) } - focusY /= count; - return focusY; + focusY /= count.toFloat() + return focusY } - private void cancelAnimation() { - Animation in = mViewSwitcher.getInAnimation(); - if (in != null) { + private fun cancelAnimation() { + val `in`: Animation = mViewSwitcher.getInAnimation() + if (`in` != null) { // cancel() doesn't terminate cleanly. - in.scaleCurrentDuration(0); + `in`.scaleCurrentDuration(0) } - Animation out = mViewSwitcher.getOutAnimation(); + val out: Animation = mViewSwitcher.getOutAnimation() if (out != null) { // cancel() doesn't terminate cleanly. - out.scaleCurrentDuration(0); + out.scaleCurrentDuration(0) } } - private void doFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - cancelAnimation(); - - mSelectionMode = SELECTION_HIDDEN; - eventClickCleanup(); - - mOnFlingCalled = true; - - if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) { + private fun doFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float) { + cancelAnimation() + mSelectionMode = SELECTION_HIDDEN + eventClickCleanup() + mOnFlingCalled = true + if (mTouchMode and TOUCH_MODE_HSCROLL != 0) { // Horizontal fling. // initNextView(deltaX); - mTouchMode = TOUCH_MODE_INITIAL_STATE; - if (DEBUG) Log.d(TAG, "doFling: velocityX " + velocityX); - int deltaX = (int) e2.getX() - (int) e1.getX(); - switchViews(deltaX < 0, mViewStartX, mViewWidth, velocityX); - mViewStartX = 0; - return; + mTouchMode = TOUCH_MODE_INITIAL_STATE + if (DEBUG) Log.d(TAG, "doFling: velocityX $velocityX") + val deltaX = e2.getX() as Int - e1.getX() as Int + switchViews(deltaX < 0, mViewStartX.toFloat(), mViewWidth.toFloat(), velocityX) + mViewStartX = 0 + return } - - if ((mTouchMode & TOUCH_MODE_VSCROLL) == 0) { - if (DEBUG) Log.d(TAG, "doFling: no fling"); - return; + if (mTouchMode and TOUCH_MODE_VSCROLL == 0) { + if (DEBUG) Log.d(TAG, "doFling: no fling") + return } // Vertical fling. - mTouchMode = TOUCH_MODE_INITIAL_STATE; - mViewStartX = 0; - + mTouchMode = TOUCH_MODE_INITIAL_STATE + mViewStartX = 0 if (DEBUG) { - Log.d(TAG, "doFling: mViewStartY" + mViewStartY + " velocityY " + velocityY); + Log.d(TAG, "doFling: mViewStartY$mViewStartY velocityY $velocityY") } // Continue scrolling vertically - mScrolling = true; - mScroller.fling(0 /* startX */, mViewStartY /* startY */, 0 /* velocityX */, - (int) -velocityY, 0 /* minX */, 0 /* maxX */, 0 /* minY */, - mMaxViewStartY /* maxY */, OVERFLING_DISTANCE, OVERFLING_DISTANCE); + mScrolling = true + mScroller.fling( + 0 /* startX */, mViewStartY /* startY */, 0 /* velocityX */, + (-velocityY).toInt(), 0 /* minX */, 0 /* maxX */, 0 /* minY */, + mMaxViewStartY /* maxY */, OVERFLING_DISTANCE, OVERFLING_DISTANCE + ) // When flinging down, show a glow when it hits the end only if it // wasn't started at the top if (velocityY > 0 && mViewStartY != 0) { - mCallEdgeEffectOnAbsorb = true; - } - // When flinging up, show a glow when it hits the end only if it wasn't - // started at the bottom - else if (velocityY < 0 && mViewStartY != mMaxViewStartY) { - mCallEdgeEffectOnAbsorb = true; + mCallEdgeEffectOnAbsorb = true + } else if (velocityY < 0 && mViewStartY != mMaxViewStartY) { + mCallEdgeEffectOnAbsorb = true } - mHandler.post(mContinueScroll); + mHandler.post(mContinueScroll) } - private boolean initNextView(int deltaX) { + private fun initNextView(deltaX: Int): Boolean { // Change the view to the previous day or week - DayView view = (DayView) mViewSwitcher.getNextView(); - Time date = view.mBaseDate; - date.set(mBaseDate); - boolean switchForward; + val view = mViewSwitcher.getNextView() as DayView + val date: Time? = view.mBaseDate + date.set(mBaseDate) + val switchForward: Boolean if (deltaX > 0) { - date.monthDay -= mNumDays; - view.setSelectedDay(mSelectionDay - mNumDays); - switchForward = false; + date.monthDay -= mNumDays + view.selectedDay = mSelectionDay - mNumDays + switchForward = false } else { - date.monthDay += mNumDays; - view.setSelectedDay(mSelectionDay + mNumDays); - switchForward = true; + date.monthDay += mNumDays + view.selectedDay = mSelectionDay + mNumDays + switchForward = true } - date.normalize(true /* ignore isDst */); - initView(view); - view.layout(getLeft(), getTop(), getRight(), getBottom()); - view.reloadEvents(); - return switchForward; + date.normalize(true /* ignore isDst */) + initView(view) + view.layout(getLeft(), getTop(), getRight(), getBottom()) + view.reloadEvents() + return switchForward } // ScaleGestureDetector.OnScaleGestureListener - public boolean onScaleBegin(ScaleGestureDetector detector) { - mHandleActionUp = false; - float gestureCenterInPixels = detector.getFocusY() - DAY_HEADER_HEIGHT - mAlldayHeight; - mGestureCenterHour = (mViewStartY + gestureCenterInPixels) / (mCellHeight + DAY_GAP); - - mStartingSpanY = Math.max(MIN_Y_SPAN, Math.abs(detector.getCurrentSpanY())); - mCellHeightBeforeScaleGesture = mCellHeight; - + fun onScaleBegin(detector: ScaleGestureDetector): Boolean { + mHandleActionUp = false + val gestureCenterInPixels: Float = detector.getFocusY() - DAY_HEADER_HEIGHT - mAlldayHeight + mGestureCenterHour = (mViewStartY + gestureCenterInPixels) / (mCellHeight + DAY_GAP) + mStartingSpanY = Math.max(MIN_Y_SPAN, Math.abs(detector.getCurrentSpanY())) + mCellHeightBeforeScaleGesture = mCellHeight if (DEBUG_SCALING) { - float ViewStartHour = mViewStartY / (float) (mCellHeight + DAY_GAP); - Log.d(TAG, "onScaleBegin: mGestureCenterHour:" + mGestureCenterHour - + "\tViewStartHour: " + ViewStartHour + "\tmViewStartY:" + mViewStartY - + "\tmCellHeight:" + mCellHeight + " SpanY:" + detector.getCurrentSpanY()); + val ViewStartHour = mViewStartY / (mCellHeight + DAY_GAP).toFloat() + Log.d( + TAG, "onScaleBegin: mGestureCenterHour:" + mGestureCenterHour + + "\tViewStartHour: " + ViewStartHour + "\tmViewStartY:" + mViewStartY + + "\tmCellHeight:" + mCellHeight + " SpanY:" + detector.getCurrentSpanY() + ) } - - return true; + return true } // ScaleGestureDetector.OnScaleGestureListener - public boolean onScale(ScaleGestureDetector detector) { - float spanY = Math.max(MIN_Y_SPAN, Math.abs(detector.getCurrentSpanY())); - - mCellHeight = (int) (mCellHeightBeforeScaleGesture * spanY / mStartingSpanY); - + fun onScale(detector: ScaleGestureDetector): Boolean { + val spanY: Float = Math.max(MIN_Y_SPAN, Math.abs(detector.getCurrentSpanY())) + mCellHeight = (mCellHeightBeforeScaleGesture * spanY / mStartingSpanY).toInt() if (mCellHeight < mMinCellHeight) { // If mStartingSpanY is too small, even a small increase in the // gesture can bump the mCellHeight beyond MAX_CELL_HEIGHT - mStartingSpanY = spanY; - mCellHeight = mMinCellHeight; - mCellHeightBeforeScaleGesture = mMinCellHeight; + mStartingSpanY = spanY + mCellHeight = mMinCellHeight + mCellHeightBeforeScaleGesture = mMinCellHeight } else if (mCellHeight > MAX_CELL_HEIGHT) { - mStartingSpanY = spanY; - mCellHeight = MAX_CELL_HEIGHT; - mCellHeightBeforeScaleGesture = MAX_CELL_HEIGHT; + mStartingSpanY = spanY + mCellHeight = MAX_CELL_HEIGHT + mCellHeightBeforeScaleGesture = MAX_CELL_HEIGHT } - - int gestureCenterInPixels = (int) detector.getFocusY() - DAY_HEADER_HEIGHT - mAlldayHeight; - mViewStartY = (int) (mGestureCenterHour * (mCellHeight + DAY_GAP)) - gestureCenterInPixels; - mMaxViewStartY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP) - mGridAreaHeight; - + val gestureCenterInPixels = detector.getFocusY() as Int - DAY_HEADER_HEIGHT - mAlldayHeight + mViewStartY = (mGestureCenterHour * (mCellHeight + DAY_GAP)).toInt() - gestureCenterInPixels + mMaxViewStartY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP) - mGridAreaHeight if (DEBUG_SCALING) { - float ViewStartHour = mViewStartY / (float) (mCellHeight + DAY_GAP); - Log.d(TAG, "onScale: mGestureCenterHour:" + mGestureCenterHour + "\tViewStartHour: " - + ViewStartHour + "\tmViewStartY:" + mViewStartY + "\tmCellHeight:" - + mCellHeight + " SpanY:" + detector.getCurrentSpanY()); + val ViewStartHour = mViewStartY / (mCellHeight + DAY_GAP).toFloat() + Log.d( + TAG, "onScale: mGestureCenterHour:" + mGestureCenterHour + "\tViewStartHour: " + + ViewStartHour + "\tmViewStartY:" + mViewStartY + "\tmCellHeight:" + + mCellHeight + " SpanY:" + detector.getCurrentSpanY() + ) } - if (mViewStartY < 0) { - mViewStartY = 0; - mGestureCenterHour = (mViewStartY + gestureCenterInPixels) - / (float) (mCellHeight + DAY_GAP); + mViewStartY = 0 + mGestureCenterHour = ((mViewStartY + gestureCenterInPixels) + / (mCellHeight + DAY_GAP).toFloat()) } else if (mViewStartY > mMaxViewStartY) { - mViewStartY = mMaxViewStartY; - mGestureCenterHour = (mViewStartY + gestureCenterInPixels) - / (float) (mCellHeight + DAY_GAP); + mViewStartY = mMaxViewStartY + mGestureCenterHour = ((mViewStartY + gestureCenterInPixels) + / (mCellHeight + DAY_GAP).toFloat()) } - computeFirstHour(); - - mRemeasure = true; - invalidate(); - return true; + computeFirstHour() + mRemeasure = true + invalidate() + return true } // ScaleGestureDetector.OnScaleGestureListener - public void onScaleEnd(ScaleGestureDetector detector) { - mScrollStartY = mViewStartY; - mInitialScrollY = 0; - mInitialScrollX = 0; - mStartingSpanY = 0; + fun onScaleEnd(detector: ScaleGestureDetector?) { + mScrollStartY = mViewStartY + mInitialScrollY = 0f + mInitialScrollX = 0f + mStartingSpanY = 0f } @Override - public boolean onTouchEvent(MotionEvent ev) { - int action = ev.getAction(); - if (DEBUG) Log.e(TAG, "" + action + " ev.getPointerCount() = " + ev.getPointerCount()); - - if ((ev.getActionMasked() == MotionEvent.ACTION_DOWN) || - (ev.getActionMasked() == MotionEvent.ACTION_UP) || - (ev.getActionMasked() == MotionEvent.ACTION_POINTER_UP) || - (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN)) { - mRecalCenterHour = true; - } - - if ((mTouchMode & TOUCH_MODE_HSCROLL) == 0) { - mScaleGestureDetector.onTouchEvent(ev); - } - - switch (action) { - case MotionEvent.ACTION_DOWN: - mStartingScroll = true; + fun onTouchEvent(ev: MotionEvent): Boolean { + val action: Int = ev.getAction() + if (DEBUG) Log.e(TAG, "" + action + " ev.getPointerCount() = " + ev.getPointerCount()) + if (ev.getActionMasked() === MotionEvent.ACTION_DOWN || + ev.getActionMasked() === MotionEvent.ACTION_UP || + ev.getActionMasked() === MotionEvent.ACTION_POINTER_UP || + ev.getActionMasked() === MotionEvent.ACTION_POINTER_DOWN + ) { + mRecalCenterHour = true + } + if (mTouchMode and TOUCH_MODE_HSCROLL == 0) { + mScaleGestureDetector.onTouchEvent(ev) + } + return when (action) { + MotionEvent.ACTION_DOWN -> { + mStartingScroll = true if (DEBUG) { - Log.e(TAG, "ACTION_DOWN ev.getDownTime = " + ev.getDownTime() + " Cnt=" - + ev.getPointerCount()); + Log.e( + TAG, + "ACTION_DOWN ev.getDownTime = " + ev.getDownTime().toString() + " Cnt=" + + ev.getPointerCount() + ) } - - int bottom = mAlldayHeight + DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN; - if (ev.getY() < bottom) { - mTouchStartedInAlldayArea = true; + val bottom = + mAlldayHeight + DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN + mTouchStartedInAlldayArea = if (ev.getY() < bottom) { + true } else { - mTouchStartedInAlldayArea = false; + false } - mHandleActionUp = true; - mGestureDetector.onTouchEvent(ev); - return true; - - case MotionEvent.ACTION_MOVE: - if (DEBUG) Log.e(TAG, "ACTION_MOVE Cnt=" + ev.getPointerCount() + DayView.this); - mGestureDetector.onTouchEvent(ev); - return true; - - case MotionEvent.ACTION_UP: - if (DEBUG) Log.e(TAG, "ACTION_UP Cnt=" + ev.getPointerCount() + mHandleActionUp); - mEdgeEffectTop.onRelease(); - mEdgeEffectBottom.onRelease(); - mStartingScroll = false; - mGestureDetector.onTouchEvent(ev); + mHandleActionUp = true + mGestureDetector.onTouchEvent(ev) + true + } + MotionEvent.ACTION_MOVE -> { + if (DEBUG) Log.e( + TAG, + "ACTION_MOVE Cnt=" + ev.getPointerCount() + this@DayView + ) + mGestureDetector.onTouchEvent(ev) + true + } + MotionEvent.ACTION_UP -> { + if (DEBUG) Log.e( + TAG, + "ACTION_UP Cnt=" + ev.getPointerCount() + mHandleActionUp + ) + mEdgeEffectTop.onRelease() + mEdgeEffectBottom.onRelease() + mStartingScroll = false + mGestureDetector.onTouchEvent(ev) if (!mHandleActionUp) { - mHandleActionUp = true; - mViewStartX = 0; - invalidate(); - return true; + mHandleActionUp = true + mViewStartX = 0 + invalidate() + return true } - if (mOnFlingCalled) { - return true; + return true } // If we were scrolling, then reset the selected hour so that it // is visible. if (mScrolling) { - mScrolling = false; - resetSelectedHour(); - invalidate(); + mScrolling = false + resetSelectedHour() + invalidate() } - - if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) { - mTouchMode = TOUCH_MODE_INITIAL_STATE; + if (mTouchMode and TOUCH_MODE_HSCROLL != 0) { + mTouchMode = TOUCH_MODE_INITIAL_STATE if (Math.abs(mViewStartX) > mHorizontalSnapBackThreshold) { // The user has gone beyond the threshold so switch views - if (DEBUG) Log.d(TAG, "- horizontal scroll: switch views"); - switchViews(mViewStartX > 0, mViewStartX, mViewWidth, 0); - mViewStartX = 0; - return true; + if (DEBUG) Log.d( + TAG, + "- horizontal scroll: switch views" + ) + switchViews( + mViewStartX > 0, + mViewStartX.toFloat(), + mViewWidth.toFloat(), + 0f + ) + mViewStartX = 0 + return true } else { // Not beyond the threshold so invalidate which will cause // the view to snap back. Also call recalc() to ensure // that we have the correct starting date and title. - if (DEBUG) Log.d(TAG, "- horizontal scroll: snap back"); - recalc(); - invalidate(); - mViewStartX = 0; + if (DEBUG) Log.d( + TAG, + "- horizontal scroll: snap back" + ) + recalc() + invalidate() + mViewStartX = 0 } } - - return true; - - // This case isn't expected to happen. - case MotionEvent.ACTION_CANCEL: - if (DEBUG) Log.e(TAG, "ACTION_CANCEL"); - mGestureDetector.onTouchEvent(ev); - mScrolling = false; - resetSelectedHour(); - return true; - - default: - if (DEBUG) Log.e(TAG, "Not MotionEvent " + ev.toString()); + true + } + MotionEvent.ACTION_CANCEL -> { + if (DEBUG) Log.e( + TAG, + "ACTION_CANCEL" + ) + mGestureDetector.onTouchEvent(ev) + mScrolling = false + resetSelectedHour() + true + } + else -> { + if (DEBUG) Log.e( + TAG, + "Not MotionEvent " + ev.toString() + ) if (mGestureDetector.onTouchEvent(ev)) { - return true; - } - return super.onTouchEvent(ev); + true + } else super.onTouchEvent(ev) + } } } - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { - MenuItem item; + fun onCreateContextMenu(menu: ContextMenu, view: View?, menuInfo: ContextMenuInfo?) { + var item: MenuItem // If the trackball is held down, then the context menu pops up and // we never get onKeyUp() for the long-press. So check for it here // and change the selection to the long-press state. if (mSelectionMode != SELECTION_LONGPRESS) { - invalidate(); + invalidate() } - - final long startMillis = getSelectedTimeInMillis(); - int flags = DateUtils.FORMAT_SHOW_TIME - | DateUtils.FORMAT_CAP_NOON_MIDNIGHT - | DateUtils.FORMAT_SHOW_WEEKDAY; - final String title = Utils.formatDateRange(mContext, startMillis, startMillis, flags); - menu.setHeaderTitle(title); - - mPopup.dismiss(); + val startMillis = selectedTimeInMillis + val flags: Int = (DateUtils.FORMAT_SHOW_TIME + or DateUtils.FORMAT_CAP_NOON_MIDNIGHT + or DateUtils.FORMAT_SHOW_WEEKDAY) + val title: String = Utils.formatDateRange(mContext, startMillis, startMillis, flags) + menu.setHeaderTitle(title) + mPopup.dismiss() } /** @@ -3553,201 +3112,191 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * @param x the x position of the touch * @param y the y position of the touch * @param keepOldSelection - do not change the selection info (used for invoking accessibility - * messages) + * messages) * @return true if the touch position is valid */ - private boolean setSelectionFromPosition(int x, final int y, boolean keepOldSelection) { - - Event savedEvent = null; - int savedDay = 0; - int savedHour = 0; - boolean savedAllDay = false; + private fun setSelectionFromPosition(x: Int, y: Int, keepOldSelection: Boolean): Boolean { + var x = x + var savedEvent: Event? = null + var savedDay = 0 + var savedHour = 0 + var savedAllDay = false if (keepOldSelection) { // Store selection info and restore it at the end. This way, we can invoke the // right accessibility message without affecting the selection. - savedEvent = mSelectedEvent; - savedDay = mSelectionDay; - savedHour = mSelectionHour; - savedAllDay = mSelectionAllday; + savedEvent = mSelectedEvent + savedDay = mSelectionDay + savedHour = mSelectionHour + savedAllDay = mSelectionAllday } if (x < mHoursWidth) { - x = mHoursWidth; + x = mHoursWidth } - - int day = (x - mHoursWidth) / (mCellWidth + DAY_GAP); + var day = (x - mHoursWidth) / (mCellWidth + DAY_GAP) if (day >= mNumDays) { - day = mNumDays - 1; + day = mNumDays - 1 } - day += mFirstJulianDay; - setSelectedDay(day); - + day += mFirstJulianDay + selectedDay = day if (y < DAY_HEADER_HEIGHT) { - sendAccessibilityEventAsNeeded(false); - return false; + sendAccessibilityEventAsNeeded(false) + return false } - - setSelectedHour(mFirstHour); /* First fully visible hour */ - - if (y < mFirstCell) { - mSelectionAllday = true; + setSelectedHour(mFirstHour) /* First fully visible hour */ + mSelectionAllday = if (y < mFirstCell) { + true } else { // y is now offset from top of the scrollable region - int adjustedY = y - mFirstCell; - + val adjustedY = y - mFirstCell if (adjustedY < mFirstHourOffset) { - setSelectedHour(mSelectionHour - 1); /* In the partially visible hour */ + setSelectedHour(mSelectionHour - 1) /* In the partially visible hour */ } else { - setSelectedHour(mSelectionHour + - (adjustedY - mFirstHourOffset) / (mCellHeight + HOUR_GAP)); + setSelectedHour( + mSelectionHour + + (adjustedY - mFirstHourOffset) / (mCellHeight + HOUR_GAP) + ) } - - mSelectionAllday = false; + false } - - findSelectedEvent(x, y); - - sendAccessibilityEventAsNeeded(true); + findSelectedEvent(x, y) + sendAccessibilityEventAsNeeded(true) // Restore old values if (keepOldSelection) { - mSelectedEvent = savedEvent; - mSelectionDay = savedDay; - mSelectionHour = savedHour; - mSelectionAllday = savedAllDay; - } - return true; - } - - private void findSelectedEvent(int x, int y) { - int date = mSelectionDay; - int cellWidth = mCellWidth; - ArrayList<Event> events = mEvents; - int numEvents = events.size(); - int left = computeDayLeftPosition(mSelectionDay - mFirstJulianDay); - int top = 0; - setSelectedEvent(null); - - mSelectedEvents.clear(); + mSelectedEvent = savedEvent + mSelectionDay = savedDay + mSelectionHour = savedHour + mSelectionAllday = savedAllDay + } + return true + } + + private fun findSelectedEvent(x: Int, y: Int) { + var y = y + val date = mSelectionDay + val cellWidth = mCellWidth + var events: ArrayList<Event>? = mEvents + var numEvents: Int = events.size() + val left = computeDayLeftPosition(mSelectionDay - mFirstJulianDay) + val top = 0 + setSelectedEvent(null) + mSelectedEvents.clear() if (mSelectionAllday) { - float yDistance; - float minYdistance = 10000.0f; // any large number - Event closestEvent = null; - float drawHeight = mAlldayHeight; - int yOffset = DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN; - int maxUnexpandedColumn = mMaxUnexpandedAlldayEventCount; + var yDistance: Float + var minYdistance = 10000.0f // any large number + var closestEvent: Event? = null + val drawHeight = mAlldayHeight.toFloat() + val yOffset = DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN + var maxUnexpandedColumn = mMaxUnexpandedAlldayEventCount if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) { // Leave a gap for the 'box +n' text - maxUnexpandedColumn--; + maxUnexpandedColumn-- } - events = mAllDayEvents; - numEvents = events.size(); - for (int i = 0; i < numEvents; i++) { - Event event = events.get(i); + events = mAllDayEvents + numEvents = events.size() + for (i in 0 until numEvents) { + val event: Event = events.get(i) if (!event.drawAsAllday() || - (!mShowAllAllDayEvents && event.getColumn() >= maxUnexpandedColumn)) { + !mShowAllAllDayEvents && event.getColumn() >= maxUnexpandedColumn + ) { // Don't check non-allday events or events that aren't shown - continue; + continue } - if (event.startDay <= mSelectionDay && event.endDay >= mSelectionDay) { - float numRectangles = mShowAllAllDayEvents ? mMaxAlldayEvents - : mMaxUnexpandedAlldayEventCount; - float height = drawHeight / numRectangles; + val numRectangles = + if (mShowAllAllDayEvents) mMaxAlldayEvents.toFloat() else mMaxUnexpandedAlldayEventCount.toFloat() + var height = drawHeight / numRectangles if (height > MAX_HEIGHT_OF_ONE_ALLDAY_EVENT) { - height = MAX_HEIGHT_OF_ONE_ALLDAY_EVENT; + height = MAX_HEIGHT_OF_ONE_ALLDAY_EVENT.toFloat() } - float eventTop = yOffset + height * event.getColumn(); - float eventBottom = eventTop + height; + val eventTop: Float = yOffset + height * event.getColumn() + val eventBottom = eventTop + height if (eventTop < y && eventBottom > y) { // If the touch is inside the event rectangle, then // add the event. - mSelectedEvents.add(event); - closestEvent = event; - break; + mSelectedEvents.add(event) + closestEvent = event + break } else { // Find the closest event - if (eventTop >= y) { - yDistance = eventTop - y; + yDistance = if (eventTop >= y) { + eventTop - y } else { - yDistance = y - eventBottom; + y - eventBottom } if (yDistance < minYdistance) { - minYdistance = yDistance; - closestEvent = event; + minYdistance = yDistance + closestEvent = event } } } } - setSelectedEvent(closestEvent); - return; + setSelectedEvent(closestEvent) + return } // Adjust y for the scrollable bitmap - y += mViewStartY - mFirstCell; + y += mViewStartY - mFirstCell // Use a region around (x,y) for the selection region - Rect region = mRect; - region.left = x - 10; - region.right = x + 10; - region.top = y - 10; - region.bottom = y + 10; - - EventGeometry geometry = mEventGeometry; - - for (int i = 0; i < numEvents; i++) { - Event event = events.get(i); + val region: Rect = mRect + region.left = x - 10 + region.right = x + 10 + region.top = y - 10 + region.bottom = y + 10 + val geometry: EventGeometry = mEventGeometry + for (i in 0 until numEvents) { + val event: Event = events.get(i) // Compute the event rectangle. if (!geometry.computeEventRect(date, left, top, cellWidth, event)) { - continue; + continue } // If the event intersects the selection region, then add it to // mSelectedEvents. if (geometry.eventIntersectsSelection(event, region)) { - mSelectedEvents.add(event); + mSelectedEvents.add(event) } } // If there are any events in the selected region, then assign the // closest one to mSelectedEvent. if (mSelectedEvents.size() > 0) { - int len = mSelectedEvents.size(); - Event closestEvent = null; - float minDist = mViewWidth + mViewHeight; // some large distance - for (int index = 0; index < len; index++) { - Event ev = mSelectedEvents.get(index); - float dist = geometry.pointToEvent(x, y, ev); + val len: Int = mSelectedEvents.size() + var closestEvent: Event? = null + var minDist = (mViewWidth + mViewHeight).toFloat() // some large distance + for (index in 0 until len) { + val ev: Event = mSelectedEvents.get(index) + val dist: Float = geometry.pointToEvent(x, y, ev) if (dist < minDist) { - minDist = dist; - closestEvent = ev; + minDist = dist + closestEvent = ev } } - setSelectedEvent(closestEvent); + setSelectedEvent(closestEvent) // Keep the selected hour and day consistent with the selected // event. They could be different if we touched on an empty hour // slot very close to an event in the previous hour slot. In // that case we will select the nearby event. - int startDay = mSelectedEvent.startDay; - int endDay = mSelectedEvent.endDay; + val startDay: Int = mSelectedEvent.startDay + val endDay: Int = mSelectedEvent.endDay if (mSelectionDay < startDay) { - setSelectedDay(startDay); + selectedDay = startDay } else if (mSelectionDay > endDay) { - setSelectedDay(endDay); + selectedDay = endDay } - - int startHour = mSelectedEvent.startTime / 60; - int endHour; - if (mSelectedEvent.startTime < mSelectedEvent.endTime) { - endHour = (mSelectedEvent.endTime - 1) / 60; + val startHour: Int = mSelectedEvent.startTime / 60 + val endHour: Int + endHour = if (mSelectedEvent.startTime < mSelectedEvent.endTime) { + (mSelectedEvent.endTime - 1) / 60 } else { - endHour = mSelectedEvent.endTime / 60; + mSelectedEvent.endTime / 60 } - if (mSelectionHour < startHour && mSelectionDay == startDay) { - setSelectedHour(startHour); + setSelectedHour(startHour) } else if (mSelectionHour > endHour && mSelectionDay == endDay) { - setSelectedHour(endHour); + setSelectedHour(endHour) } } } @@ -3755,213 +3304,204 @@ public class DayView extends View implements View.OnCreateContextMenuListener, // Encapsulates the code to continue the scrolling after the // finger is lifted. Instead of stopping the scroll immediately, // the scroll continues to "free spin" and gradually slows down. - private class ContinueScroll implements Runnable { - - public void run() { - mScrolling = mScrolling && mScroller.computeScrollOffset(); + private inner class ContinueScroll : Runnable { + fun run() { + mScrolling = mScrolling && mScroller.computeScrollOffset() if (!mScrolling || mPaused) { - resetSelectedHour(); - invalidate(); - return; + resetSelectedHour() + invalidate() + return } - - mViewStartY = mScroller.getCurrY(); - + mViewStartY = mScroller.getCurrY() if (mCallEdgeEffectOnAbsorb) { if (mViewStartY < 0) { - mEdgeEffectTop.onAbsorb((int) mLastVelocity); - mCallEdgeEffectOnAbsorb = false; + mEdgeEffectTop.onAbsorb(mLastVelocity.toInt()) + mCallEdgeEffectOnAbsorb = false } else if (mViewStartY > mMaxViewStartY) { - mEdgeEffectBottom.onAbsorb((int) mLastVelocity); - mCallEdgeEffectOnAbsorb = false; + mEdgeEffectBottom.onAbsorb(mLastVelocity.toInt()) + mCallEdgeEffectOnAbsorb = false } - mLastVelocity = mScroller.getCurrVelocity(); + mLastVelocity = mScroller.getCurrVelocity() } - if (mScrollStartY == 0 || mScrollStartY == mMaxViewStartY) { // Allow overscroll/springback only on a fling, // not a pull/fling from the end if (mViewStartY < 0) { - mViewStartY = 0; + mViewStartY = 0 } else if (mViewStartY > mMaxViewStartY) { - mViewStartY = mMaxViewStartY; + mViewStartY = mMaxViewStartY } } - - computeFirstHour(); - mHandler.post(this); - invalidate(); + computeFirstHour() + mHandler.post(this) + invalidate() } } /** * Cleanup the pop-up and timers. */ - public void cleanup() { + fun cleanup() { // Protect against null-pointer exceptions if (mPopup != null) { - mPopup.dismiss(); + mPopup.dismiss() } - mPaused = true; - mLastPopupEventID = INVALID_EVENT_ID; + mPaused = true + mLastPopupEventID = INVALID_EVENT_ID if (mHandler != null) { - mHandler.removeCallbacks(mDismissPopup); - mHandler.removeCallbacks(mUpdateCurrentTime); + mHandler.removeCallbacks(mDismissPopup) + mHandler.removeCallbacks(mUpdateCurrentTime) } - - Utils.setSharedPreference(mContext, GeneralPreferences.KEY_DEFAULT_CELL_HEIGHT, - mCellHeight); + Utils.setSharedPreference( + mContext, GeneralPreferences.KEY_DEFAULT_CELL_HEIGHT, + mCellHeight + ) // Clear all click animations - eventClickCleanup(); + eventClickCleanup() // Turn off redraw - mRemeasure = false; + mRemeasure = false // Turn off scrolling to make sure the view is in the correct state if we fling back to it - mScrolling = false; + mScrolling = false } - private void eventClickCleanup() { - this.removeCallbacks(mClearClick); - this.removeCallbacks(mSetClick); - mClickedEvent = null; - mSavedClickedEvent = null; + private fun eventClickCleanup() { + this.removeCallbacks(mClearClick) + this.removeCallbacks(mSetClick) + mClickedEvent = null + mSavedClickedEvent = null } - private void setSelectedEvent(Event e) { - mSelectedEvent = e; - mSelectedEventForAccessibility = e; + private fun setSelectedEvent(e: Event?) { + mSelectedEvent = e + mSelectedEventForAccessibility = e } - private void setSelectedHour(int h) { - mSelectionHour = h; - mSelectionHourForAccessibility = h; - } - private void setSelectedDay(int d) { - mSelectionDay = d; - mSelectionDayForAccessibility = d; + private fun setSelectedHour(h: Int) { + mSelectionHour = h + mSelectionHourForAccessibility = h } /** * Restart the update timer */ - public void restartCurrentTimeUpdates() { - mPaused = false; + fun restartCurrentTimeUpdates() { + mPaused = false if (mHandler != null) { - mHandler.removeCallbacks(mUpdateCurrentTime); - mHandler.post(mUpdateCurrentTime); + mHandler.removeCallbacks(mUpdateCurrentTime) + mHandler.post(mUpdateCurrentTime) } } @Override - protected void onDetachedFromWindow() { - cleanup(); - super.onDetachedFromWindow(); + protected fun onDetachedFromWindow() { + cleanup() + super.onDetachedFromWindow() } - class DismissPopup implements Runnable { - - public void run() { + internal inner class DismissPopup : Runnable { + fun run() { // Protect against null-pointer exceptions if (mPopup != null) { - mPopup.dismiss(); + mPopup.dismiss() } } } - class UpdateCurrentTime implements Runnable { - - public void run() { - long currentTime = System.currentTimeMillis(); - mCurrentTime.set(currentTime); + internal inner class UpdateCurrentTime : Runnable { + fun run() { + val currentTime: Long = System.currentTimeMillis() + mCurrentTime.set(currentTime) //% causes update to occur on 5 minute marks (11:10, 11:15, 11:20, etc.) - if (!DayView.this.mPaused) { - mHandler.postDelayed(mUpdateCurrentTime, UPDATE_CURRENT_TIME_DELAY - - (currentTime % UPDATE_CURRENT_TIME_DELAY)); + if (!mPaused) { + mHandler.postDelayed( + mUpdateCurrentTime, UPDATE_CURRENT_TIME_DELAY + - currentTime % UPDATE_CURRENT_TIME_DELAY + ) } - mTodayJulianDay = Time.getJulianDay(currentTime, mCurrentTime.gmtoff); - invalidate(); + mTodayJulianDay = Time.getJulianDay(currentTime, mCurrentTime.gmtoff) + invalidate() } } - class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener { + internal inner class CalendarGestureListener : GestureDetector.SimpleOnGestureListener() { @Override - public boolean onSingleTapUp(MotionEvent ev) { - if (DEBUG) Log.e(TAG, "GestureDetector.onSingleTapUp"); - DayView.this.doSingleTapUp(ev); - return true; + fun onSingleTapUp(ev: MotionEvent): Boolean { + if (DEBUG) Log.e(TAG, "GestureDetector.onSingleTapUp") + doSingleTapUp(ev) + return true } @Override - public void onLongPress(MotionEvent ev) { - if (DEBUG) Log.e(TAG, "GestureDetector.onLongPress"); - DayView.this.doLongPress(ev); + fun onLongPress(ev: MotionEvent) { + if (DEBUG) Log.e(TAG, "GestureDetector.onLongPress") + doLongPress(ev) } @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - if (DEBUG) Log.e(TAG, "GestureDetector.onScroll"); - eventClickCleanup(); + fun onScroll( + e1: MotionEvent, + e2: MotionEvent, + distanceX: Float, + distanceY: Float + ): Boolean { + var distanceY = distanceY + if (DEBUG) Log.e(TAG, "GestureDetector.onScroll") + eventClickCleanup() if (mTouchStartedInAlldayArea) { if (Math.abs(distanceX) < Math.abs(distanceY)) { // Make sure that click feedback is gone when you scroll from the // all day area - invalidate(); - return false; + invalidate() + return false } // don't scroll vertically if this started in the allday area - distanceY = 0; + distanceY = 0f } - DayView.this.doScroll(e1, e2, distanceX, distanceY); - return true; + doScroll(e1, e2, distanceX, distanceY) + return true } @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if (DEBUG) Log.e(TAG, "GestureDetector.onFling"); - + fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { + var velocityY = velocityY + if (DEBUG) Log.e(TAG, "GestureDetector.onFling") if (mTouchStartedInAlldayArea) { if (Math.abs(velocityX) < Math.abs(velocityY)) { - return false; + return false } // don't fling vertically if this started in the allday area - velocityY = 0; + velocityY = 0f } - DayView.this.doFling(e1, e2, velocityX, velocityY); - return true; + doFling(e1, e2, velocityX, velocityY) + return true } @Override - public boolean onDown(MotionEvent ev) { - if (DEBUG) Log.e(TAG, "GestureDetector.onDown"); - DayView.this.doDown(ev); - return true; + fun onDown(ev: MotionEvent): Boolean { + if (DEBUG) Log.e(TAG, "GestureDetector.onDown") + doDown(ev) + return true } } @Override - public boolean onLongClick(View v) { - return true; + fun onLongClick(v: View?): Boolean { + return true } - // The rest of this file was borrowed from Launcher2 - PagedView.java - private static final int MINIMUM_SNAP_VELOCITY = 2200; - - private class ScrollInterpolator implements Interpolator { - public ScrollInterpolator() { - } - - public float getInterpolation(float t) { - t -= 1.0f; - t = t * t * t * t * t + 1; - + private inner class ScrollInterpolator : Interpolator { + fun getInterpolation(t: Float): Float { + var t = t + t -= 1.0f + t = t * t * t * t * t + 1 if ((1 - t) * mAnimationDistance < 1) { - cancelAnimation(); + cancelAnimation() } - - return t; + return t } } - private long calculateDuration(float delta, float width, float velocity) { + private fun calculateDuration(delta: Float, width: Float, velocity: Float): Long { /* * Here we compute a "distance" that will be used in the computation of * the overall snap duration. This is a function of the actual distance @@ -3969,13 +3509,13 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * size in order to reduce the variance in snap duration as a function * of the distance the page needs to travel. */ - final float halfScreenSize = width / 2; - float distanceRatio = delta / width; - float distanceInfluenceForSnapDuration = distanceInfluenceForSnapDuration(distanceRatio); - float distance = halfScreenSize + halfScreenSize * distanceInfluenceForSnapDuration; - - velocity = Math.abs(velocity); - velocity = Math.max(MINIMUM_SNAP_VELOCITY, velocity); + var velocity = velocity + val halfScreenSize = width / 2 + val distanceRatio = delta / width + val distanceInfluenceForSnapDuration = distanceInfluenceForSnapDuration(distanceRatio) + val distance = halfScreenSize + halfScreenSize * distanceInfluenceForSnapDuration + velocity = Math.abs(velocity) + velocity = Math.max(MINIMUM_SNAP_VELOCITY, velocity) /* * we want the page's snap velocity to approximately match the velocity @@ -3983,14 +3523,16 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * the derivative of the scroll interpolator at zero, ie. 5. We use 6 to * make it a little slower. */ - long duration = 6 * Math.round(1000 * Math.abs(distance / velocity)); + val duration: Long = 6 * Math.round(1000 * Math.abs(distance / velocity)) if (DEBUG) { - Log.e(TAG, "halfScreenSize:" + halfScreenSize + " delta:" + delta + " distanceRatio:" - + distanceRatio + " distance:" + distance + " velocity:" + velocity - + " duration:" + duration + " distanceInfluenceForSnapDuration:" - + distanceInfluenceForSnapDuration); + Log.e( + TAG, "halfScreenSize:" + halfScreenSize + " delta:" + delta + " distanceRatio:" + + distanceRatio + " distance:" + distance + " velocity:" + velocity + + " duration:" + duration + " distanceInfluenceForSnapDuration:" + + distanceInfluenceForSnapDuration + ) } - return duration; + return duration } /* @@ -4000,9 +3542,355 @@ public class DayView extends View implements View.OnCreateContextMenuListener, * method to moderate the effect that the distance of travel has on the * overall snap duration. */ - private float distanceInfluenceForSnapDuration(float f) { - f -= 0.5f; // center the values about 0. - f *= 0.3f * Math.PI / 2.0f; - return (float) Math.sin(f); - } -} + private fun distanceInfluenceForSnapDuration(f: Float): Float { + var f = f + f -= 0.5f // center the values about 0. + f *= 0.3f * Math.PI / 2.0f + return Math.sin(f) + } + + companion object { + private const val TAG = "DayView" + private const val DEBUG = false + private const val DEBUG_SCALING = false + private const val PERIOD_SPACE = ". " + private var mScale = 0f // Used for supporting different screen densities + private const val INVALID_EVENT_ID: Long = -1 //This is used for remembering a null event + + // Duration of the allday expansion + private const val ANIMATION_DURATION: Long = 400 + + // duration of the more allday event text fade + private const val ANIMATION_SECONDARY_DURATION: Long = 200 + + // duration of the scroll to go to a specified time + private const val GOTO_SCROLL_DURATION = 200 + + // duration for events' cross-fade animation + private const val EVENTS_CROSS_FADE_DURATION = 400 + + // duration to show the event clicked + private const val CLICK_DISPLAY_DURATION = 50 + private const val MENU_DAY = 3 + private const val MENU_EVENT_VIEW = 5 + private const val MENU_EVENT_CREATE = 6 + private const val MENU_EVENT_EDIT = 7 + private const val MENU_EVENT_DELETE = 8 + private var DEFAULT_CELL_HEIGHT = 64 + private var MAX_CELL_HEIGHT = 150 + private var MIN_Y_SPAN = 100 + private val CALENDARS_PROJECTION = arrayOf<String>( + Calendars._ID, // 0 + Calendars.CALENDAR_ACCESS_LEVEL, // 1 + Calendars.OWNER_ACCOUNT + ) + private const val CALENDARS_INDEX_ACCESS_LEVEL = 1 + private const val CALENDARS_INDEX_OWNER_ACCOUNT = 2 + private val CALENDARS_WHERE: String = Calendars._ID.toString() + "=%d" + private const val FROM_NONE = 0 + private const val FROM_ABOVE = 1 + private const val FROM_BELOW = 2 + private const val FROM_LEFT = 4 + private const val FROM_RIGHT = 8 + private const val ACCESS_LEVEL_NONE = 0 + private const val ACCESS_LEVEL_DELETE = 1 + private const val ACCESS_LEVEL_EDIT = 2 + private var mHorizontalSnapBackThreshold = 128 + + //Update the current time line every five minutes if the window is left open that long + private const val UPDATE_CURRENT_TIME_DELAY = 300000 + private var mOnDownDelay: Int + protected var mStringBuilder: StringBuilder = StringBuilder(50) + + // TODO recreate formatter when locale changes + protected var mFormatter: Formatter = Formatter(mStringBuilder, Locale.getDefault()) + + // The number of milliseconds to show the popup window + private const val POPUP_DISMISS_DELAY = 3000 + private var GRID_LINE_LEFT_MARGIN = 0f + private const val GRID_LINE_INNER_WIDTH = 1f + private const val DAY_GAP = 1 + private const val HOUR_GAP = 1 + + // This is the standard height of an allday event with no restrictions + private var SINGLE_ALLDAY_HEIGHT = 34 + + /** + * This is the minimum desired height of a allday event. + * When unexpanded, allday events will use this height. + * When expanded allDay events will attempt to grow to fit all + * events at this height. + */ + private var MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT = 28.0f // in pixels + + /** + * This is how big the unexpanded allday height is allowed to be. + * It will get adjusted based on screen size + */ + private var MAX_UNEXPANDED_ALLDAY_HEIGHT = (MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT * 4).toInt() + + /** + * This is the minimum size reserved for displaying regular events. + * The expanded allDay region can't expand into this. + */ + private const val MIN_HOURS_HEIGHT = 180 + private var ALLDAY_TOP_MARGIN = 1 + + // The largest a single allDay event will become. + private var MAX_HEIGHT_OF_ONE_ALLDAY_EVENT = 34 + private var HOURS_TOP_MARGIN = 2 + private var HOURS_LEFT_MARGIN = 2 + private var HOURS_RIGHT_MARGIN = 4 + private var HOURS_MARGIN = HOURS_LEFT_MARGIN + HOURS_RIGHT_MARGIN + private var NEW_EVENT_MARGIN = 4 + private var NEW_EVENT_WIDTH = 2 + private var NEW_EVENT_MAX_LENGTH = 16 + private var CURRENT_TIME_LINE_SIDE_BUFFER = 4 + private var CURRENT_TIME_LINE_TOP_OFFSET = 2 + + /* package */ + const val MINUTES_PER_HOUR = 60 + + /* package */ + const val MINUTES_PER_DAY = MINUTES_PER_HOUR * 24 + + /* package */ + const val MILLIS_PER_MINUTE = 60 * 1000 + + /* package */ + const val MILLIS_PER_HOUR = 3600 * 1000 + + /* package */ + const val MILLIS_PER_DAY = MILLIS_PER_HOUR * 24 + + // More events text will transition between invisible and this alpha + private const val MORE_EVENTS_MAX_ALPHA = 0x4C + private var DAY_HEADER_ONE_DAY_LEFT_MARGIN = 0 + private var DAY_HEADER_ONE_DAY_RIGHT_MARGIN = 5 + private var DAY_HEADER_ONE_DAY_BOTTOM_MARGIN = 6 + private var DAY_HEADER_RIGHT_MARGIN = 4 + private var DAY_HEADER_BOTTOM_MARGIN = 3 + private var DAY_HEADER_FONT_SIZE = 14f + private var DATE_HEADER_FONT_SIZE = 32f + private var NORMAL_FONT_SIZE = 12f + private var EVENT_TEXT_FONT_SIZE = 12f + private var HOURS_TEXT_SIZE = 12f + private var AMPM_TEXT_SIZE = 9f + private var MIN_HOURS_WIDTH = 96 + private var MIN_CELL_WIDTH_FOR_TEXT = 20 + private const val MAX_EVENT_TEXT_LEN = 500 + + // smallest height to draw an event with + private var MIN_EVENT_HEIGHT = 24.0f // in pixels + private var CALENDAR_COLOR_SQUARE_SIZE = 10 + private var EVENT_RECT_TOP_MARGIN = 1 + private var EVENT_RECT_BOTTOM_MARGIN = 0 + private var EVENT_RECT_LEFT_MARGIN = 1 + private var EVENT_RECT_RIGHT_MARGIN = 0 + private var EVENT_RECT_STROKE_WIDTH = 2 + private var EVENT_TEXT_TOP_MARGIN = 2 + private var EVENT_TEXT_BOTTOM_MARGIN = 2 + private var EVENT_TEXT_LEFT_MARGIN = 6 + private var EVENT_TEXT_RIGHT_MARGIN = 6 + private var ALL_DAY_EVENT_RECT_BOTTOM_MARGIN = 1 + private var EVENT_ALL_DAY_TEXT_TOP_MARGIN = EVENT_TEXT_TOP_MARGIN + private var EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN = EVENT_TEXT_BOTTOM_MARGIN + private var EVENT_ALL_DAY_TEXT_LEFT_MARGIN = EVENT_TEXT_LEFT_MARGIN + private var EVENT_ALL_DAY_TEXT_RIGHT_MARGIN = EVENT_TEXT_RIGHT_MARGIN + + // margins and sizing for the expand allday icon + private var EXPAND_ALL_DAY_BOTTOM_MARGIN = 10 + + // sizing for "box +n" in allDay events + private var EVENT_SQUARE_WIDTH = 10 + private var EVENT_LINE_PADDING = 4 + private var NEW_EVENT_HINT_FONT_SIZE = 12 + private var mEventTextColor = 0 + private var mMoreEventsTextColor = 0 + private var mWeek_saturdayColor = 0 + private var mWeek_sundayColor = 0 + private var mCalendarDateBannerTextColor = 0 + private var mCalendarAmPmLabel = 0 + private var mCalendarGridAreaSelected = 0 + private var mCalendarGridLineInnerHorizontalColor = 0 + private var mCalendarGridLineInnerVerticalColor = 0 + private var mFutureBgColor = 0 + private var mFutureBgColorRes = 0 + private var mBgColor = 0 + private var mNewEventHintColor: Int + private var mCalendarHourLabelColor = 0 + private var mMoreAlldayEventsTextAlpha = MORE_EVENTS_MAX_ALPHA + private var mCellHeight = 0 // shared among all DayViews + private var mMinCellHeight = 32 + private var mScaledPagingTouchSlop = 0 + + /** + * Whether to use the expand or collapse icon. + */ + private var mUseExpandIcon = true + + /** + * The height of the day names/numbers + */ + private var DAY_HEADER_HEIGHT = 45 + + /** + * The height of the day names/numbers for multi-day views + */ + private var MULTI_DAY_HEADER_HEIGHT = DAY_HEADER_HEIGHT + + /** + * The height of the day names/numbers when viewing a single day + */ + private var ONE_DAY_HEADER_HEIGHT = DAY_HEADER_HEIGHT + + /** + * Whether or not to expand the allDay area to fill the screen + */ + private var mShowAllAllDayEvents = false + private var sCounter = 0 + + /** + * The initial state of the touch mode when we enter this view. + */ + private const val TOUCH_MODE_INITIAL_STATE = 0 + + /** + * Indicates we just received the touch event and we are waiting to see if + * it is a tap or a scroll gesture. + */ + private const val TOUCH_MODE_DOWN = 1 + + /** + * Indicates the touch gesture is a vertical scroll + */ + private const val TOUCH_MODE_VSCROLL = 0x20 + + /** + * Indicates the touch gesture is a horizontal scroll + */ + private const val TOUCH_MODE_HSCROLL = 0x40 + + /** + * The selection modes are HIDDEN, PRESSED, SELECTED, and LONGPRESS. + */ + private const val SELECTION_HIDDEN = 0 + private const val SELECTION_PRESSED = 1 // D-pad down but not up yet + private const val SELECTION_SELECTED = 2 + private const val SELECTION_LONGPRESS = 3 + + // The rest of this file was borrowed from Launcher2 - PagedView.java + private const val MINIMUM_SNAP_VELOCITY = 2200 + } + + init { + mContext = context + initAccessibilityVariables() + mResources = context.getResources() + mNewEventHintString = mResources.getString(R.string.day_view_new_event_hint) + mNumDays = numDays + DATE_HEADER_FONT_SIZE = + mResources.getDimension(R.dimen.date_header_text_size) as Int.toFloat() + DAY_HEADER_FONT_SIZE = mResources.getDimension(R.dimen.day_label_text_size) as Int.toFloat() + ONE_DAY_HEADER_HEIGHT = mResources.getDimension(R.dimen.one_day_header_height) + DAY_HEADER_BOTTOM_MARGIN = mResources.getDimension(R.dimen.day_header_bottom_margin) + EXPAND_ALL_DAY_BOTTOM_MARGIN = mResources.getDimension(R.dimen.all_day_bottom_margin) + HOURS_TEXT_SIZE = mResources.getDimension(R.dimen.hours_text_size) as Int.toFloat() + AMPM_TEXT_SIZE = mResources.getDimension(R.dimen.ampm_text_size) as Int.toFloat() + MIN_HOURS_WIDTH = mResources.getDimension(R.dimen.min_hours_width) + HOURS_LEFT_MARGIN = mResources.getDimension(R.dimen.hours_left_margin) + HOURS_RIGHT_MARGIN = mResources.getDimension(R.dimen.hours_right_margin) + MULTI_DAY_HEADER_HEIGHT = mResources.getDimension(R.dimen.day_header_height) + val eventTextSizeId: Int + eventTextSizeId = if (mNumDays == 1) { + R.dimen.day_view_event_text_size + } else { + R.dimen.week_view_event_text_size + } + EVENT_TEXT_FONT_SIZE = mResources.getDimension(eventTextSizeId) as Int.toFloat() + NEW_EVENT_HINT_FONT_SIZE = mResources.getDimension(R.dimen.new_event_hint_text_size) + MIN_EVENT_HEIGHT = mResources.getDimension(R.dimen.event_min_height) + MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT = MIN_EVENT_HEIGHT + EVENT_TEXT_TOP_MARGIN = mResources.getDimension(R.dimen.event_text_vertical_margin) + EVENT_TEXT_BOTTOM_MARGIN = EVENT_TEXT_TOP_MARGIN + EVENT_ALL_DAY_TEXT_TOP_MARGIN = EVENT_TEXT_TOP_MARGIN + EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN = EVENT_TEXT_TOP_MARGIN + EVENT_TEXT_LEFT_MARGIN = mResources + .getDimension(R.dimen.event_text_horizontal_margin) + EVENT_TEXT_RIGHT_MARGIN = EVENT_TEXT_LEFT_MARGIN + EVENT_ALL_DAY_TEXT_LEFT_MARGIN = EVENT_TEXT_LEFT_MARGIN + EVENT_ALL_DAY_TEXT_RIGHT_MARGIN = EVENT_TEXT_LEFT_MARGIN + if (mScale == 0f) { + mScale = mResources.getDisplayMetrics().density + if (mScale != 1f) { + SINGLE_ALLDAY_HEIGHT *= mScale.toInt() + ALLDAY_TOP_MARGIN *= mScale.toInt() + MAX_HEIGHT_OF_ONE_ALLDAY_EVENT *= mScale.toInt() + NORMAL_FONT_SIZE *= mScale + GRID_LINE_LEFT_MARGIN *= mScale + HOURS_TOP_MARGIN *= mScale.toInt() + MIN_CELL_WIDTH_FOR_TEXT *= mScale.toInt() + MAX_UNEXPANDED_ALLDAY_HEIGHT *= mScale.toInt() + mAnimateDayEventHeight = MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt() + CURRENT_TIME_LINE_SIDE_BUFFER *= mScale.toInt() + CURRENT_TIME_LINE_TOP_OFFSET *= mScale.toInt() + MIN_Y_SPAN *= mScale.toInt() + MAX_CELL_HEIGHT *= mScale.toInt() + DEFAULT_CELL_HEIGHT *= mScale.toInt() + DAY_HEADER_HEIGHT *= mScale.toInt() + DAY_HEADER_RIGHT_MARGIN *= mScale.toInt() + DAY_HEADER_ONE_DAY_LEFT_MARGIN *= mScale.toInt() + DAY_HEADER_ONE_DAY_RIGHT_MARGIN *= mScale.toInt() + DAY_HEADER_ONE_DAY_BOTTOM_MARGIN *= mScale.toInt() + CALENDAR_COLOR_SQUARE_SIZE *= mScale.toInt() + EVENT_RECT_TOP_MARGIN *= mScale.toInt() + EVENT_RECT_BOTTOM_MARGIN *= mScale.toInt() + ALL_DAY_EVENT_RECT_BOTTOM_MARGIN *= mScale.toInt() + EVENT_RECT_LEFT_MARGIN *= mScale.toInt() + EVENT_RECT_RIGHT_MARGIN *= mScale.toInt() + EVENT_RECT_STROKE_WIDTH *= mScale.toInt() + EVENT_SQUARE_WIDTH *= mScale.toInt() + EVENT_LINE_PADDING *= mScale.toInt() + NEW_EVENT_MARGIN *= mScale.toInt() + NEW_EVENT_WIDTH *= mScale.toInt() + NEW_EVENT_MAX_LENGTH *= mScale.toInt() + } + } + HOURS_MARGIN = HOURS_LEFT_MARGIN + HOURS_RIGHT_MARGIN + DAY_HEADER_HEIGHT = if (mNumDays == 1) ONE_DAY_HEADER_HEIGHT else MULTI_DAY_HEADER_HEIGHT + mCurrentTimeLine = mResources.getDrawable(R.drawable.timeline_indicator_holo_light) + mCurrentTimeAnimateLine = mResources + .getDrawable(R.drawable.timeline_indicator_activated_holo_light) + mTodayHeaderDrawable = mResources.getDrawable(R.drawable.today_blue_week_holo_light) + mExpandAlldayDrawable = mResources.getDrawable(R.drawable.ic_expand_holo_light) + mCollapseAlldayDrawable = mResources.getDrawable(R.drawable.ic_collapse_holo_light) + mNewEventHintColor = mResources.getColor(R.color.new_event_hint_text_color) + mAcceptedOrTentativeEventBoxDrawable = mResources + .getDrawable(R.drawable.panel_month_event_holo_light) + mEventLoader = eventLoader + mEventGeometry = EventGeometry() + mEventGeometry.setMinEventHeight(MIN_EVENT_HEIGHT) + mEventGeometry.setHourGap(HOUR_GAP) + mEventGeometry.setCellMargin(DAY_GAP) + mLastPopupEventID = INVALID_EVENT_ID + mController = controller + mViewSwitcher = viewSwitcher + mGestureDetector = GestureDetector(context, CalendarGestureListener()) + mScaleGestureDetector = ScaleGestureDetector(getContext(), this) + if (mCellHeight == 0) { + mCellHeight = Utils.getSharedPreference( + mContext, + GeneralPreferences.KEY_DEFAULT_CELL_HEIGHT, DEFAULT_CELL_HEIGHT + ) + } + mScroller = OverScroller(context) + mHScrollInterpolator = ScrollInterpolator() + mEdgeEffectTop = EdgeEffect(context) + mEdgeEffectBottom = EdgeEffect(context) + val vc: ViewConfiguration = ViewConfiguration.get(context) + mScaledPagingTouchSlop = vc.getScaledPagingTouchSlop() + mOnDownDelay = ViewConfiguration.getTapTimeout() + OVERFLING_DISTANCE = vc.getScaledOverflingDistance() + init(context) + } +}
\ No newline at end of file |