1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.calendar;
18 
19 import android.graphics.Rect;
20 
21 public class EventGeometry {
22     // This is the space from the grid line to the event rectangle.
23     private int mCellMargin = 0;
24 
25     private float mMinuteHeight;
26 
27     private float mHourGap;
28     private float mMinEventHeight;
29 
setCellMargin(int cellMargin)30     void setCellMargin(int cellMargin) {
31         mCellMargin = cellMargin;
32     }
33 
setHourGap(float gap)34     public void setHourGap(float gap) {
35         mHourGap = gap;
36     }
37 
setMinEventHeight(float height)38     public void setMinEventHeight(float height) {
39         mMinEventHeight = height;
40     }
41 
setHourHeight(float height)42     public void setHourHeight(float height) {
43         mMinuteHeight = height / 60.0f;
44     }
45 
46     // Computes the rectangle coordinates of the given event on the screen.
47     // Returns true if the rectangle is visible on the screen.
computeEventRect(int date, int left, int top, int cellWidth, Event event)48     public boolean computeEventRect(int date, int left, int top, int cellWidth, Event event) {
49         if (event.drawAsAllday()) {
50             return false;
51         }
52 
53         float cellMinuteHeight = mMinuteHeight;
54         int startDay = event.startDay;
55         int endDay = event.endDay;
56 
57         if (startDay > date || endDay < date) {
58             return false;
59         }
60 
61         int startTime = event.startTime;
62         int endTime = event.endTime;
63 
64         // If the event started on a previous day, then show it starting
65         // at the beginning of this day.
66         if (startDay < date) {
67             startTime = 0;
68         }
69 
70         // If the event ends on a future day, then show it extending to
71         // the end of this day.
72         if (endDay > date) {
73             endTime = DayView.MINUTES_PER_DAY;
74         }
75 
76         int col = event.getColumn();
77         int maxCols = event.getMaxColumns();
78         int startHour = startTime / 60;
79         int endHour = endTime / 60;
80 
81         // If the end point aligns on a cell boundary then count it as
82         // ending in the previous cell so that we don't cross the border
83         // between hours.
84         if (endHour * 60 == endTime)
85             endHour -= 1;
86 
87         event.top = top;
88         event.top += (int) (startTime * cellMinuteHeight);
89         event.top += startHour * mHourGap;
90 
91         event.bottom = top;
92         event.bottom += (int) (endTime * cellMinuteHeight);
93         event.bottom += endHour * mHourGap - 1;
94 
95         // Make the rectangle be at least mMinEventHeight pixels high
96         if (event.bottom < event.top + mMinEventHeight) {
97             event.bottom = event.top + mMinEventHeight;
98         }
99 
100         float colWidth = (float) (cellWidth - (maxCols + 1) * mCellMargin) / (float) maxCols;
101         event.left = left + col * (colWidth + mCellMargin);
102         event.right = event.left + colWidth;
103         return true;
104     }
105 
106     /**
107      * Returns true if this event intersects the selection region.
108      */
eventIntersectsSelection(Event event, Rect selection)109     boolean eventIntersectsSelection(Event event, Rect selection) {
110         if (event.left < selection.right && event.right >= selection.left
111                 && event.top < selection.bottom && event.bottom >= selection.top) {
112             return true;
113         }
114         return false;
115     }
116 
117     /**
118      * Computes the distance from the given point to the given event.
119      */
pointToEvent(float x, float y, Event event)120     float pointToEvent(float x, float y, Event event) {
121         float left = event.left;
122         float right = event.right;
123         float top = event.top;
124         float bottom = event.bottom;
125 
126         if (x >= left) {
127             if (x <= right) {
128                 if (y >= top) {
129                     if (y <= bottom) {
130                         // x,y is inside the event rectangle
131                         return 0f;
132                     }
133                     // x,y is below the event rectangle
134                     return y - bottom;
135                 }
136                 // x,y is above the event rectangle
137                 return top - y;
138             }
139 
140             // x > right
141             float dx = x - right;
142             if (y < top) {
143                 // the upper right corner
144                 float dy = top - y;
145                 return (float) Math.sqrt(dx * dx + dy * dy);
146             }
147             if (y > bottom) {
148                 // the lower right corner
149                 float dy = y - bottom;
150                 return (float) Math.sqrt(dx * dx + dy * dy);
151             }
152             // x,y is to the right of the event rectangle
153             return dx;
154         }
155         // x < left
156         float dx = left - x;
157         if (y < top) {
158             // the upper left corner
159             float dy = top - y;
160             return (float) Math.sqrt(dx * dx + dy * dy);
161         }
162         if (y > bottom) {
163             // the lower left corner
164             float dy = y - bottom;
165             return (float) Math.sqrt(dx * dx + dy * dy);
166         }
167         // x,y is to the left of the event rectangle
168         return dx;
169     }
170 }
171