1 |
|
|
2 |
|
package pl.magot.vetch.ancal.views; |
3 |
|
|
4 |
|
|
5 |
|
import java.util.Calendar; |
6 |
|
|
7 |
|
import pl.magot.vetch.ancal.AnCalDateUtils; |
8 |
|
import pl.magot.vetch.ancal.Utils; |
9 |
|
import android.content.Context; |
10 |
|
import android.graphics.*; |
11 |
|
import android.view.*; |
12 |
|
import android.widget.LinearLayout; |
13 |
|
import android.widget.LinearLayout.LayoutParams; |
14 |
|
|
15 |
|
|
|
|
| 94,5% |
Uncovered Elements: 13 (235) |
Complexity: 49 |
Complexity Density: 0,3 |
|
16 |
|
public class ViewMonthWeekItem extends View |
17 |
|
{ |
18 |
|
|
|
|
| - |
Uncovered Elements: 0 (0) |
Complexity: 0 |
Complexity Density: - |
|
19 |
|
public interface OnItemClick |
20 |
|
{ |
21 |
|
public void OnClick(ViewMonthWeekItem item); |
22 |
|
} |
23 |
|
|
24 |
|
|
25 |
|
private final static Typeface tfMono = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL); |
26 |
|
|
27 |
|
|
28 |
|
private RectF rectDayHeaderFrame = new RectF(); |
29 |
|
private RectF rectDayView = new RectF(); |
30 |
|
|
31 |
|
|
32 |
|
private static final int iMargin = 1; |
33 |
|
private final static int iSpace = 4; |
34 |
|
private final static int iWeekNrFontSize = 12; |
35 |
|
private final static int iDayHeaderFontSize = 12; |
36 |
|
private final static int iAlphaInactiveMonth = 0x40; |
37 |
|
|
38 |
|
|
39 |
|
protected Paint mpt = null; |
40 |
|
protected OnItemClick itemClick = null; |
41 |
|
private boolean bEnableDaysHeader = false; |
42 |
|
private LayoutParams lparamsItem = new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT); |
43 |
|
|
44 |
|
|
45 |
|
private String sWeekNr = ""; |
46 |
|
private int[] vecWeekDaysId = new int[7]; |
47 |
|
private int[] vecDayNumbers = new int[7]; |
48 |
|
private byte[] vecDayState = new byte[7]; |
49 |
|
|
50 |
|
|
51 |
|
private int iHeaderHeight = 0; |
52 |
|
private int iWeekNrMarginWidth = 0; |
53 |
|
private int iWeekDayWidth = 0; |
54 |
|
private boolean bTouchedDown = false; |
55 |
|
private Calendar calWeekStart = Calendar.getInstance(); |
56 |
|
|
57 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (6) |
Complexity: 1 |
Complexity Density: 0,17 |
|
58 |
6
|
public ViewMonthWeekItem(Context context, int iHeaderHeight, int iWeekNrMarginWidth)... |
59 |
|
{ |
60 |
6
|
super(context); |
61 |
6
|
this.iHeaderHeight = iHeaderHeight; |
62 |
6
|
this.iWeekNrMarginWidth = iWeekNrMarginWidth; |
63 |
6
|
mpt = new Paint(); |
64 |
6
|
setFocusable(true); |
65 |
6
|
setLayoutParams(lparamsItem); |
66 |
|
} |
67 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (4) |
Complexity: 1 |
Complexity Density: 0,25 |
|
68 |
1
|
public static int GetSpaceWidthWeekNr(Paint mpt)... |
69 |
|
{ |
70 |
1
|
mpt.setTypeface(tfMono); |
71 |
1
|
mpt.setTextSize(iWeekNrFontSize); |
72 |
1
|
mpt.setFakeBoldText(true); |
73 |
1
|
return iSpace + (int)mpt.measureText("00") + iSpace; |
74 |
|
} |
75 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (4) |
Complexity: 1 |
Complexity Density: 0,25 |
|
76 |
1
|
public static int GetSpaceHeightHeader(Paint mpt)... |
77 |
|
{ |
78 |
1
|
mpt.setTypeface(null); |
79 |
1
|
mpt.setTextSize(iDayHeaderFontSize); |
80 |
1
|
mpt.setFakeBoldText(true); |
81 |
1
|
return ((int)(-mpt.ascent() + mpt.descent())) + iSpace + iSpace + iMargin + iMargin; |
82 |
|
} |
83 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 0,5 |
|
84 |
6
|
public void SetSize(int iWidth, int iHeight)... |
85 |
|
{ |
86 |
6
|
lparamsItem.width = iWidth; |
87 |
6
|
lparamsItem.height = iHeight; |
88 |
|
} |
89 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
90 |
6
|
public void SetItemClick(OnItemClick itemClick) ... |
91 |
|
{ |
92 |
6
|
this.itemClick = itemClick; |
93 |
|
} |
94 |
|
|
|
|
| 0% |
Uncovered Elements: 6 (6) |
Complexity: 3 |
Complexity Density: 0,75 |
|
95 |
0
|
@Override... |
96 |
|
public boolean onKeyDown(int keyCode, KeyEvent event) |
97 |
|
{ |
98 |
0
|
boolean bResult = super.onKeyDown(keyCode, event); |
99 |
0
|
if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER) || (keyCode == KeyEvent.KEYCODE_ENTER)) |
100 |
|
{ |
101 |
0
|
doItemClick(); |
102 |
|
} |
103 |
0
|
return bResult; |
104 |
|
} |
105 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 2 |
Complexity Density: 1 |
|
106 |
2
|
public void doItemClick()... |
107 |
|
{ |
108 |
2
|
if (itemClick != null) |
109 |
2
|
itemClick.OnClick(this); |
110 |
|
} |
111 |
|
|
|
|
| 0% |
Uncovered Elements: 2 (2) |
Complexity: 1 |
Complexity Density: 0,5 |
|
112 |
0
|
@Override... |
113 |
|
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) |
114 |
|
{ |
115 |
0
|
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); |
116 |
0
|
invalidate(); |
117 |
|
} |
118 |
|
|
|
|
| 66,7% |
Uncovered Elements: 1 (3) |
Complexity: 2 |
Complexity Density: 2 |
|
119 |
17
|
public void setDayData(int iDay, boolean bDayHasData)... |
120 |
|
{ |
121 |
17
|
vecDayState[iDay] |= (bDayHasData)?0x08:0x00; |
122 |
|
} |
123 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (46) |
Complexity: 10 |
Complexity Density: 0,33 |
|
124 |
126
|
public void SetWeekStartDate(boolean bEnableDaysHeader, Calendar dateStartDay, int iActiveMonth, Calendar dateToday)... |
125 |
|
{ |
126 |
126
|
this.bEnableDaysHeader = bEnableDaysHeader; |
127 |
126
|
this.calWeekStart.setTimeInMillis(dateStartDay.getTimeInMillis()); |
128 |
126
|
this.sWeekNr = Integer.toString(calWeekStart.get(Calendar.WEEK_OF_YEAR)); |
129 |
|
|
130 |
126
|
final int iTodayDateYear = dateToday.get(Calendar.YEAR); |
131 |
126
|
final int iTodayDateMonth = dateToday.get(Calendar.MONTH); |
132 |
126
|
final int iTodayDateDay = dateToday.get(Calendar.DAY_OF_MONTH); |
133 |
|
|
134 |
|
|
135 |
1008
|
for (int iDay = 0; iDay < 7; iDay++) |
136 |
|
{ |
137 |
|
|
138 |
882
|
final int iDateYear = calWeekStart.get(Calendar.YEAR); |
139 |
882
|
final int iDateMonth = calWeekStart.get(Calendar.MONTH); |
140 |
882
|
final int iDateDay = calWeekStart.get(Calendar.DAY_OF_MONTH); |
141 |
882
|
final int iDateDayOfWeek = calWeekStart.get(Calendar.DAY_OF_WEEK); |
142 |
|
|
143 |
882
|
final boolean bToday = ((iDateYear == iTodayDateYear) && (iDateMonth == iTodayDateMonth) && (iDateDay == iTodayDateDay)); |
144 |
|
|
145 |
882
|
boolean bHoliday = false; |
146 |
882
|
if (iDateDayOfWeek == Calendar.SATURDAY) |
147 |
126
|
bHoliday = true; |
148 |
882
|
if (iDateDayOfWeek == Calendar.SUNDAY) |
149 |
126
|
bHoliday = true; |
150 |
882
|
if ((iDateMonth == Calendar.JANUARY) && (iDateDay == 1)) |
151 |
12
|
bHoliday = true; |
152 |
|
|
153 |
882
|
final boolean bActiveMonth = (iDateMonth == iActiveMonth); |
154 |
|
|
155 |
882
|
byte byteDayState = 0; |
156 |
|
|
157 |
882
|
byteDayState |= (bToday)?0x01:0x00; |
158 |
882
|
byteDayState |= (bHoliday)?0x02:0x00; |
159 |
882
|
byteDayState |= (bActiveMonth)?0x04:0x00; |
160 |
|
|
161 |
882
|
vecDayState[iDay] = byteDayState; |
162 |
|
|
163 |
882
|
vecDayNumbers[iDay] = iDateDay; |
164 |
|
|
165 |
882
|
if (this.bEnableDaysHeader) |
166 |
147
|
vecWeekDaysId[iDay] = iDateDayOfWeek; |
167 |
|
|
168 |
882
|
calWeekStart.add(Calendar.DAY_OF_YEAR, 1); |
169 |
|
} |
170 |
|
|
171 |
|
|
172 |
126
|
this.calWeekStart.setTimeInMillis(dateStartDay.getTimeInMillis()); |
173 |
|
} |
174 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
175 |
2
|
public Calendar getWeekStartDate()... |
176 |
|
{ |
177 |
2
|
return calWeekStart; |
178 |
|
} |
179 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
180 |
1729
|
public float getTextHeight()... |
181 |
|
{ |
182 |
1729
|
return (-mpt.ascent() + mpt.descent()); |
183 |
|
} |
184 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (8) |
Complexity: 1 |
Complexity Density: 0,12 |
|
185 |
189
|
private void drawWeekNr(Canvas canvas)... |
186 |
|
{ |
187 |
189
|
mpt.setAntiAlias(true); |
188 |
189
|
mpt.setShader(null); |
189 |
189
|
mpt.setTypeface(tfMono); |
190 |
189
|
mpt.setTextSize(iWeekNrFontSize); |
191 |
189
|
mpt.setFakeBoldText(true); |
192 |
189
|
mpt.setColor(dayStyle.iColorTextWeek); |
193 |
|
|
194 |
189
|
final int iPosX = iWeekNrMarginWidth - (int)mpt.measureText(sWeekNr) - iSpace; |
195 |
|
|
196 |
189
|
canvas.drawText(sWeekNr, iPosX, getTextHeight() + iHeaderHeight, mpt); |
197 |
|
} |
198 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (9) |
Complexity: 2 |
Complexity Density: 0,29 |
|
199 |
189
|
private void initRectangles()... |
200 |
|
{ |
201 |
|
|
202 |
189
|
iWeekDayWidth = (this.getWidth() - iWeekNrMarginWidth - iMargin - iMargin) / 7; |
203 |
|
|
204 |
|
|
205 |
189
|
if (iHeaderHeight != 0) |
206 |
|
{ |
207 |
31
|
rectDayHeaderFrame.top = iMargin; |
208 |
31
|
rectDayHeaderFrame.left = iWeekNrMarginWidth + iMargin; |
209 |
31
|
rectDayHeaderFrame.right = this.getWidth() - iMargin; |
210 |
31
|
rectDayHeaderFrame.bottom = rectDayHeaderFrame.top + iHeaderHeight - iMargin - iMargin; |
211 |
|
} |
212 |
|
|
213 |
|
|
214 |
189
|
rectDayView.set(iWeekNrMarginWidth + iMargin, iMargin + iHeaderHeight, this.getWidth() - iMargin, this.getHeight() - iMargin); |
215 |
|
} |
216 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (14) |
Complexity: 2 |
Complexity Density: 0,17 |
|
217 |
1323
|
private void drawDayHeader(Canvas canvas, int iDay, boolean bToday, boolean bHoliday)... |
218 |
|
{ |
219 |
1323
|
if (this.bEnableDaysHeader) |
220 |
|
{ |
221 |
|
|
222 |
217
|
mpt.setColor(dayStyle.getColorFrame(bHoliday, bToday)); |
223 |
217
|
canvas.drawRoundRect(rectDayHeaderFrame, 2, 2, mpt); |
224 |
|
|
225 |
|
|
226 |
217
|
mpt.setTypeface(null); |
227 |
217
|
mpt.setTextSize(iDayHeaderFontSize); |
228 |
217
|
mpt.setAntiAlias(true); |
229 |
217
|
mpt.setFakeBoldText(true); |
230 |
217
|
mpt.setColor(dayStyle.getColorTextHeader(bHoliday, bToday)); |
231 |
|
|
232 |
217
|
final int iTextPosY = (int)getTextHeight(); |
233 |
217
|
final String sDayName = AnCalDateUtils.getAbbrevDayOfWeekString(vecWeekDaysId[iDay]); |
234 |
|
|
235 |
|
|
236 |
217
|
final int iDayNamePosX = (int)rectDayHeaderFrame.left + ((int)rectDayHeaderFrame.width() >> 1) - ((int)mpt.measureText(sDayName) >> 1); |
237 |
217
|
canvas.drawText(sDayName, iDayNamePosX, rectDayHeaderFrame.top + iTextPosY + 2, mpt); |
238 |
|
} |
239 |
|
} |
240 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (14) |
Complexity: 3 |
Complexity Density: 0,3 |
|
241 |
1323
|
private void drawDayView(Canvas canvas, boolean bActiveMonth, boolean bFocused, boolean bToday, boolean bHoliday)... |
242 |
|
{ |
243 |
1323
|
mpt.setAlpha(0xff); |
244 |
|
|
245 |
1323
|
if (bFocused) |
246 |
|
{ |
247 |
|
|
248 |
35
|
LinearGradient lGradBkg = new LinearGradient(rectDayView.left, 0, rectDayView.right, 0, |
249 |
|
dayStyle.iColorBkgFocusDark, dayStyle.iColorBkgFocusLight, Shader.TileMode.CLAMP); |
250 |
35
|
mpt.setShader(lGradBkg); |
251 |
35
|
canvas.drawRoundRect(rectDayView, 2, 2, mpt); |
252 |
35
|
mpt.setShader(null); |
253 |
|
|
254 |
|
} else { |
255 |
|
|
256 |
1288
|
mpt.setColor(dayStyle.getColorBkg(bHoliday, bToday)); |
257 |
1288
|
if (!bActiveMonth) |
258 |
341
|
mpt.setAlpha(iAlphaInactiveMonth); |
259 |
1288
|
canvas.drawRoundRect(rectDayView, 2, 2, mpt); |
260 |
|
|
261 |
|
} |
262 |
|
} |
263 |
|
|
|
|
| 96,7% |
Uncovered Elements: 1 (30) |
Complexity: 5 |
Complexity Density: 0,23 |
|
264 |
1323
|
public void drawDayNumber(Canvas canvas, int iDayNumber, boolean bActiveMonth, boolean bFocused, boolean bToday, boolean bHoliday)... |
265 |
|
{ |
266 |
1323
|
final String sDate = Integer.toString(iDayNumber); |
267 |
|
|
268 |
|
|
269 |
1323
|
mpt.setTypeface(null); |
270 |
1323
|
mpt.setAntiAlias(true); |
271 |
1323
|
mpt.setShader(null); |
272 |
1323
|
mpt.setFakeBoldText(true); |
273 |
|
|
274 |
1323
|
mpt.setAlpha(0xff); |
275 |
|
|
276 |
1323
|
mpt.setUnderlineText(false); |
277 |
1323
|
if (bToday) |
278 |
23
|
mpt.setUnderlineText(true); |
279 |
|
|
280 |
1323
|
float iFontSize = (int)rectDayView.height() / 1.1F; |
281 |
1323
|
if (iFontSize > 20) |
282 |
1323
|
iFontSize = 20; |
283 |
1323
|
mpt.setTextSize(iFontSize); |
284 |
|
|
285 |
1323
|
final int iTextPosX = (int)rectDayView.right - (int)mpt.measureText(sDate) - iSpace - (iSpace >> 1); |
286 |
1323
|
final int iTextPosY = (int)rectDayView.bottom + (int)(-mpt.ascent()) - (int)getTextHeight() - iSpace; |
287 |
|
|
288 |
|
|
289 |
1323
|
if (bFocused) |
290 |
35
|
mpt.setColor(dayStyle.iColorTextFocused); |
291 |
|
else |
292 |
1288
|
mpt.setColor(dayStyle.getColorText(bHoliday, bToday)); |
293 |
1323
|
if (!bActiveMonth) |
294 |
341
|
mpt.setAlpha(iAlphaInactiveMonth); |
295 |
|
|
296 |
1323
|
canvas.drawText(sDate, iTextPosX, iTextPosY + iMargin, mpt); |
297 |
|
|
298 |
1323
|
mpt.setUnderlineText(false); |
299 |
|
} |
300 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 0,5 |
|
301 |
2646
|
private void initDayRectangle(RectF src, int iDay)... |
302 |
|
{ |
303 |
2646
|
src.left = iWeekNrMarginWidth + iMargin + (iDay * iWeekDayWidth); |
304 |
2646
|
src.right = src.left + iWeekDayWidth - iMargin - iMargin; |
305 |
|
} |
306 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (34) |
Complexity: 5 |
Complexity Density: 0,19 |
|
307 |
189
|
@Override... |
308 |
|
protected void onDraw(Canvas canvas) |
309 |
|
{ |
310 |
189
|
super.onDraw(canvas); |
311 |
|
|
312 |
189
|
initRectangles(); |
313 |
|
|
314 |
189
|
drawWeekNr(canvas); |
315 |
|
|
316 |
1512
|
for (int iDay = 0; iDay < 7; iDay++) |
317 |
|
{ |
318 |
1323
|
final int iDayNumber = vecDayNumbers[iDay]; |
319 |
1323
|
final boolean bFocused = IsViewFocused(); |
320 |
|
|
321 |
1323
|
final byte byteDayState = vecDayState[iDay]; |
322 |
|
|
323 |
1323
|
final boolean bToday = ((byteDayState & 0x01) != 0); |
324 |
1323
|
final boolean bHoliday = ((byteDayState & 0x02) != 0); |
325 |
1323
|
final boolean bActiveMonth = ((byteDayState & 0x04) != 0); |
326 |
1323
|
final boolean bDayHasData = ((byteDayState & 0x08) != 0); |
327 |
|
|
328 |
1323
|
initDayRectangle(rectDayHeaderFrame, iDay); |
329 |
1323
|
drawDayHeader(canvas, iDay, bToday, bHoliday); |
330 |
|
|
331 |
1323
|
initDayRectangle(rectDayView, iDay); |
332 |
1323
|
drawDayView(canvas, bActiveMonth, bFocused, bToday, bHoliday); |
333 |
1323
|
drawDayNumber(canvas, iDayNumber, bActiveMonth, bFocused, bToday, bHoliday); |
334 |
|
|
335 |
|
|
336 |
1323
|
if (bDayHasData) |
337 |
|
{ |
338 |
28
|
mpt.setShader(null); |
339 |
28
|
mpt.setAntiAlias(true); |
340 |
28
|
mpt.setAlpha(0xff); |
341 |
|
|
342 |
28
|
if (bFocused) |
343 |
3
|
mpt.setColor(dayStyle.iColorTextFocused); |
344 |
|
else |
345 |
25
|
mpt.setColor(dayStyle.getColorText(bHoliday, bToday)); |
346 |
28
|
if (!bActiveMonth) |
347 |
3
|
mpt.setAlpha(iAlphaInactiveMonth); |
348 |
|
|
349 |
28
|
canvas.drawCircle(rectDayView.left + 9, rectDayView.top + 9, 3, mpt); |
350 |
|
} |
351 |
|
} |
352 |
|
|
353 |
|
} |
354 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
355 |
1323
|
public boolean IsViewFocused()... |
356 |
|
{ |
357 |
1323
|
return (this.isFocused() || bTouchedDown); |
358 |
|
} |
359 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (22) |
Complexity: 4 |
Complexity Density: 0,25 |
|
360 |
8
|
@Override... |
361 |
|
public boolean onTouchEvent(MotionEvent event) |
362 |
|
{ |
363 |
8
|
boolean bHandled = false; |
364 |
8
|
if (event.getAction() == MotionEvent.ACTION_DOWN) |
365 |
|
{ |
366 |
2
|
bHandled = true; |
367 |
2
|
bTouchedDown = true; |
368 |
2
|
invalidate(); |
369 |
2
|
Utils.startAlphaAnimIn(ViewMonthWeekItem.this); |
370 |
|
} |
371 |
8
|
if (event.getAction() == MotionEvent.ACTION_CANCEL) |
372 |
|
{ |
373 |
2
|
bHandled = true; |
374 |
2
|
bTouchedDown = false; |
375 |
2
|
invalidate(); |
376 |
|
} |
377 |
8
|
if (event.getAction() == MotionEvent.ACTION_UP) |
378 |
|
{ |
379 |
2
|
bHandled = true; |
380 |
2
|
bTouchedDown = false; |
381 |
2
|
invalidate(); |
382 |
2
|
doItemClick(); |
383 |
|
} |
384 |
8
|
return bHandled; |
385 |
|
} |
386 |
|
|
387 |
|
} |