summaryrefslogtreecommitdiff
path: root/src/com/android/calendar/EventGeometry.kt
blob: 43fc3e773a76f55c42dfc9ace49cc372eb20a254 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
 * 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.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.calendar

import android.graphics.Rect

class EventGeometry {
    // This is the space from the grid line to the event rectangle.
    private var mCellMargin = 0
    private var mMinuteHeight = 0f
    private var mHourGap = 0f
    private var mMinEventHeight = 0f
    fun setCellMargin(cellMargin: Int) {
        mCellMargin = cellMargin
    }

    fun setHourGap(gap: Float) {
        mHourGap = gap
    }

    fun setMinEventHeight(height: Float) {
        mMinEventHeight = height
    }

    fun setHourHeight(height: Float) {
        mMinuteHeight = height / 60.0f
    }

    // Computes the rectangle coordinates of the given event on the screen.
    // Returns true if the rectangle is visible on the screen.
    fun computeEventRect(date: Int, left: Int, top: Int, cellWidth: Int, event: Event): Boolean {
        if (event.drawAsAllday()) {
            return false
        }
        val cellMinuteHeight = mMinuteHeight
        val startDay: Int = event.startDay
        val endDay: Int = event.endDay
        if (startDay > date || endDay < date) {
            return false
        }
        var startTime: Int = event.startTime
        var endTime: Int = event.endTime

        // If the event started on a previous day, then show it starting
        // at the beginning of this day.
        if (startDay < date) {
            startTime = 0
        }

        // If the event ends on a future day, then show it extending to
        // the end of this day.
        if (endDay > date) {
            endTime = DayView.MINUTES_PER_DAY
        }
        val col: Int = event.column
        val maxCols: Int = event.maxColumns
        val startHour = startTime / 60
        var endHour = endTime / 60

        // If the end point aligns on a cell boundary then count it as
        // ending in the previous cell so that we don't cross the border
        // between hours.
        if (endHour * 60 == endTime) endHour -= 1
        event.top = top as Float
        event.top += (startTime * cellMinuteHeight).toInt()
        event.top += startHour * mHourGap
        event.bottom = top as Float
        event.bottom += (endTime * cellMinuteHeight).toInt()
        event.bottom += endHour * mHourGap - 1

        // Make the rectangle be at least mMinEventHeight pixels high
        if (event.bottom < event.top + mMinEventHeight) {
            event.bottom = event.top + mMinEventHeight
        }
        val colWidth = (cellWidth - (maxCols + 1) * mCellMargin).toFloat() / maxCols.toFloat()
        event.left = left + col * (colWidth + mCellMargin)
        event.right = event.left + colWidth
        return true
    }

    /**
     * Returns true if this event intersects the selection region.
     */
    fun eventIntersectsSelection(event: Event, selection: Rect): Boolean {
        return if (event.left < selection.right && event.right >= selection.left &&
            event.top < selection.bottom && event.bottom >= selection.top) {
            true
        } else false
    }

    /**
     * Computes the distance from the given point to the given event.
     */
    fun pointToEvent(x: Float, y: Float, event: Event): Float {
        val left: Float = event.left
        val right: Float = event.right
        val top: Float = event.top
        val bottom: Float = event.bottom
        if (x >= left) {
            if (x <= right) {
                return if (y >= top) {
                    if (y <= bottom) {
                        // x,y is inside the event rectangle
                        0f
                    } else y - bottom
                    // x,y is below the event rectangle
                } else top - y
                // x,y is above the event rectangle
            }

            // x > right
            val dx = x - right
            if (y < top) {
                // the upper right corner
                val dy = top - y
                return (Math.sqrt(dx as Double * dx + dy as Double * dy)) as Float
            }
            if (y > bottom) {
                // the lower right corner
                val dy = y - bottom
                return (Math.sqrt(dx as Double * dx + dy as Double * dy)) as Float
            }
            // x,y is to the right of the event rectangle
            return dx
        }
        // x < left
        val dx = left - x
        if (y < top) {
            // the upper left corner
            val dy = top - y
            return (Math.sqrt(dx as Double * dx + dy as Double * dy)) as Float
        }
        if (y > bottom) {
            // the lower left corner
            val dy = y - bottom
            return (Math.sqrt(dx as Double * dx + dy as Double * dy)) as Float
        }
        // x,y is to the left of the event rectangle
        return dx
    }
}