diff options
author | Daniel Stenberg <daniel@haxx.se> | 2003-07-24 10:03:33 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2003-07-24 10:03:33 +0000 |
commit | c1512e1a9b27d66072c5d15f19692120bfee9a5a (patch) | |
tree | 3053fd249003740fcd79337e959cef63b7b18da5 /apps | |
parent | 7b247093c8ae7d380e9c06ab0b82f807814a8f78 (diff) | |
download | rockbox-c1512e1a9b27d66072c5d15f19692120bfee9a5a.tar.gz rockbox-c1512e1a9b27d66072c5d15f19692120bfee9a5a.zip |
Huw Smith's calendar plugin
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3877 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/calendar.c | 722 |
1 files changed, 722 insertions, 0 deletions
diff --git a/apps/plugins/calendar.c b/apps/plugins/calendar.c new file mode 100644 index 0000000000..448c1a824f --- /dev/null +++ b/apps/plugins/calendar.c | |||
@@ -0,0 +1,722 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * (based upon 1.1 by calpefrosch) www.HuwSy.ukhackers.net | ||
10 | * | ||
11 | * Copyright (C) 2002 | ||
12 | * | ||
13 | * All files in this archive are subject to the GNU General Public License. | ||
14 | * See the file COPYING in the source tree root for full license agreement. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | #include "plugin.h" | ||
21 | |||
22 | #ifdef HAVE_LCD_BITMAP | ||
23 | |||
24 | #include <timefuncs.h> | ||
25 | |||
26 | static struct plugin_api* rb; | ||
27 | |||
28 | static bool leap_year; | ||
29 | static int days_in_month[2][13] = { | ||
30 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, | ||
31 | {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, | ||
32 | }; | ||
33 | |||
34 | struct today { | ||
35 | int mday; /* day of the month */ | ||
36 | int mon; /* month */ | ||
37 | int year; /* year since 1900 */ | ||
38 | int wday; /* day of the week */ | ||
39 | }; | ||
40 | |||
41 | struct shown { | ||
42 | int mday; /* day of the month */ | ||
43 | int mon; /* month */ | ||
44 | int year; /* year since 1900 */ | ||
45 | int wday; /* day of the week */ | ||
46 | int firstday; /* first (w)day of month */ | ||
47 | int lastday; /* last (w)day of month */ | ||
48 | }; | ||
49 | |||
50 | /* leap year -- account for gregorian reformation in 1752 */ | ||
51 | static int is_leap_year(int yr) | ||
52 | { | ||
53 | return ((yr) <= 1752 ? !((yr) % 4) : \ | ||
54 | (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400)) ? 1:0 ; | ||
55 | } | ||
56 | |||
57 | /* searches the weekday of the first day in month, relative to the given values */ | ||
58 | static int calc_weekday( struct shown *shown ) | ||
59 | { | ||
60 | return ( shown->wday + 36 - shown->mday ) % 7 ; | ||
61 | |||
62 | } | ||
63 | |||
64 | static void calendar_init(struct today *today, struct shown *shown) | ||
65 | { | ||
66 | int w,h; | ||
67 | rb->lcd_getstringsize("A",&w,&h); | ||
68 | if ( ((w * 14) > LCD_WIDTH) || ((h * 7) > LCD_HEIGHT) ) | ||
69 | rb->lcd_setfont(FONT_SYSFIXED); | ||
70 | rb->lcd_clear_display(); | ||
71 | #ifdef HAVE_RTC | ||
72 | struct tm *tm; | ||
73 | tm = rb->get_time(); | ||
74 | today->mon = tm->tm_mon +1; | ||
75 | today->year = 2000+tm->tm_year%100; | ||
76 | today->wday = tm->tm_wday-1; | ||
77 | today->mday = tm->tm_mday; | ||
78 | #ifdef SIMULATOR | ||
79 | today->wday = 3; | ||
80 | today->mday = 13; | ||
81 | #endif | ||
82 | shown->mday = today->mday; | ||
83 | shown->mon = today->mon; | ||
84 | shown->year = today->year; | ||
85 | shown->wday = today->wday; | ||
86 | #endif | ||
87 | shown->firstday = calc_weekday(shown); | ||
88 | leap_year = is_leap_year(shown->year); | ||
89 | } | ||
90 | |||
91 | static int space = LCD_WIDTH / 7; | ||
92 | static void draw_headers(void) | ||
93 | { | ||
94 | int i,w,h; | ||
95 | rb->lcd_getstringsize("A",&w,&h); | ||
96 | char *Dayname[7] = {"M","T","W","T","F","S","S"}; | ||
97 | int ws = 2; | ||
98 | for (i = 0; i < 8;) | ||
99 | { | ||
100 | rb->lcd_putsxy(ws, 0 , Dayname[i++]); | ||
101 | ws += space; | ||
102 | } | ||
103 | rb->lcd_drawline(0 ,h ,LCD_WIDTH ,h); | ||
104 | } | ||
105 | |||
106 | static bool day_has_memo[31]; | ||
107 | static bool wday_has_memo[6]; | ||
108 | static void draw_calendar(struct shown *shown) | ||
109 | { | ||
110 | int w,h; | ||
111 | rb->lcd_getstringsize("A",&w,&h); | ||
112 | char *Monthname[] = { | ||
113 | "Jan", | ||
114 | "Feb", | ||
115 | "Mar", | ||
116 | "Apr", | ||
117 | "May", | ||
118 | "Jun", | ||
119 | "Jul", | ||
120 | "Aug", | ||
121 | "Sep", | ||
122 | "Oct", | ||
123 | "Nov", | ||
124 | "Dec" | ||
125 | }; | ||
126 | rb->lcd_clear_display(); | ||
127 | draw_headers(); | ||
128 | int row,pos,days_per_month,j; | ||
129 | if (shown->firstday > 6) | ||
130 | shown->firstday -= 7; | ||
131 | char buffer[7]; | ||
132 | row = 1; | ||
133 | pos = shown->firstday; | ||
134 | days_per_month = days_in_month[leap_year][shown->mon]; | ||
135 | int ws = 2 + (pos * space); | ||
136 | for (j = 0; j < days_per_month;) | ||
137 | { | ||
138 | if ( (day_has_memo[++j]) || (wday_has_memo[pos]) ) | ||
139 | rb->snprintf(buffer,3,"%02d.", j); | ||
140 | else | ||
141 | rb->snprintf(buffer,3,"%02d", j); | ||
142 | rb->lcd_putsxy(ws, (row * h) + 5 ,buffer); | ||
143 | if (shown->mday == j) | ||
144 | { | ||
145 | rb->lcd_invertrect(ws, row*h+5, space, h); | ||
146 | shown->wday = pos; | ||
147 | } | ||
148 | ws += space; | ||
149 | pos++; | ||
150 | if (pos >= 7) | ||
151 | { | ||
152 | row++; | ||
153 | pos = 0; | ||
154 | ws = 2; | ||
155 | } | ||
156 | } | ||
157 | rb->lcd_drawline(60,LCD_HEIGHT-h-3,60,LCD_HEIGHT-1); | ||
158 | rb->lcd_drawline(60,LCD_HEIGHT-h-3,LCD_WIDTH-1,LCD_HEIGHT-h-3); | ||
159 | rb->snprintf(buffer,8,"%s %04d",Monthname[shown->mon-1],shown->year); | ||
160 | rb->lcd_putsxy(62,(LCD_HEIGHT-h-1),buffer); | ||
161 | shown->lastday = pos; | ||
162 | rb->lcd_update(); | ||
163 | } | ||
164 | |||
165 | #define MAX_CHAR_MEMO_LEN 63 | ||
166 | #define MAX_MEMOS_IN_A_MONTH 127 | ||
167 | struct memo { | ||
168 | char message[MAX_CHAR_MEMO_LEN]; | ||
169 | int day; | ||
170 | int month; | ||
171 | int file_pointer_start; | ||
172 | int file_pointer_end; | ||
173 | int year; | ||
174 | int wday; | ||
175 | int type; | ||
176 | } memos[MAX_MEMOS_IN_A_MONTH]; | ||
177 | static int pointer_array[MAX_MEMOS_IN_A_MONTH]; | ||
178 | static int memos_in_memory = 0; | ||
179 | static int memos_in_shown_memory = 0; | ||
180 | static void load_memo(struct shown *shown) | ||
181 | { | ||
182 | int i, k, fp; | ||
183 | bool exit = false; | ||
184 | char temp_memo0[0]; | ||
185 | char temp_memo1[1]; | ||
186 | char temp_memo3[3]; | ||
187 | for (k = 0; k < memos_in_memory; k++) | ||
188 | { | ||
189 | memos[k].day = 0; | ||
190 | memos[k].month = 0; | ||
191 | memos[k].file_pointer_start = 0; | ||
192 | memos[k].file_pointer_end = 0; | ||
193 | memos[k].year = 0; | ||
194 | memos[k].type = 0; | ||
195 | memos[k].wday = 0; | ||
196 | for (i = 0; i <= MAX_CHAR_MEMO_LEN; i++) | ||
197 | rb->strcpy(&memos[k].message[i],""); | ||
198 | } | ||
199 | for (k = 1; k < 32; k++) | ||
200 | day_has_memo[k] = false; | ||
201 | for (k = 0; k < 7; k++) | ||
202 | wday_has_memo[k] = false; | ||
203 | memos_in_memory = 0; | ||
204 | fp = rb->open("/.rockbox/.memo",O_RDONLY); | ||
205 | if (fp > -1) | ||
206 | { | ||
207 | int count = rb->filesize(fp); | ||
208 | rb->lseek(fp, 0, SEEK_SET); | ||
209 | while (!exit) | ||
210 | { | ||
211 | memos[memos_in_memory].file_pointer_start = rb->lseek(fp, 0, | ||
212 | SEEK_CUR); | ||
213 | if (rb->read(fp, temp_memo1, 2) == 2) | ||
214 | memos[memos_in_memory].day = rb->atoi(&temp_memo1[0]); | ||
215 | else | ||
216 | memos[memos_in_memory].day = 0; | ||
217 | if (rb->read(fp, temp_memo1, 2) == 2) | ||
218 | memos[memos_in_memory].month = rb->atoi(&temp_memo1[0]); | ||
219 | else | ||
220 | memos[memos_in_memory].month = 0; | ||
221 | if (rb->read(fp, temp_memo3, 4) == 4) | ||
222 | memos[memos_in_memory].year = rb->atoi(&temp_memo3[0]); | ||
223 | else | ||
224 | memos[memos_in_memory].year = 0; | ||
225 | /* as the year returned is sometimes yearmonth, ie if yr should = | ||
226 | 2003, and month = 06, then it returns 200306 */ | ||
227 | if (memos[memos_in_memory].year > (shown->year * 10)) | ||
228 | memos[memos_in_memory].year = (memos[memos_in_memory].year - | ||
229 | memos[memos_in_memory].month) / | ||
230 | 100; | ||
231 | if (rb->read(fp, temp_memo0, 1) == 1) | ||
232 | memos[memos_in_memory].wday = rb->atoi(&temp_memo0[0]); | ||
233 | else | ||
234 | memos[memos_in_memory].wday = 0; | ||
235 | if (rb->read(fp, temp_memo0, 1) == 1) | ||
236 | memos[memos_in_memory].type = rb->atoi(&temp_memo0[0]); | ||
237 | else | ||
238 | memos[memos_in_memory].type = 0; | ||
239 | for (k = 0; k <= count; k++) | ||
240 | { | ||
241 | if (rb->read(fp, temp_memo0, 1) == 1) | ||
242 | { | ||
243 | if ( | ||
244 | (memos[memos_in_memory].type < 2) | ||
245 | || | ||
246 | ( | ||
247 | (memos[memos_in_memory].type == 2) | ||
248 | && | ||
249 | (memos[memos_in_memory].month == shown->mon) | ||
250 | ) | ||
251 | || | ||
252 | ( | ||
253 | (memos[memos_in_memory].type > 2) | ||
254 | && | ||
255 | (memos[memos_in_memory].month == shown->mon) | ||
256 | && | ||
257 | (memos[memos_in_memory].year == shown->year) | ||
258 | ) | ||
259 | ) | ||
260 | { | ||
261 | if (temp_memo0[0] == '\n') | ||
262 | { | ||
263 | if (memos[memos_in_memory].type > 0) | ||
264 | day_has_memo[memos[memos_in_memory].day] = | ||
265 | true; | ||
266 | else | ||
267 | wday_has_memo[memos[memos_in_memory].wday] = | ||
268 | true; | ||
269 | memos[memos_in_memory++].file_pointer_end = | ||
270 | rb->lseek(fp, 0, SEEK_CUR); | ||
271 | } | ||
272 | else if ( (temp_memo0[0] != '\r') && | ||
273 | (temp_memo0[0] != '\t') ) | ||
274 | memos[memos_in_memory].message[k] = temp_memo0[0]; | ||
275 | } | ||
276 | if (temp_memo0[0] == '\n') | ||
277 | break; | ||
278 | } | ||
279 | else | ||
280 | { | ||
281 | memos[memos_in_memory].day = 0; | ||
282 | memos[memos_in_memory].month = 0; | ||
283 | memos[memos_in_memory].file_pointer_start = 0; | ||
284 | memos[memos_in_memory].file_pointer_end = 0; | ||
285 | memos[memos_in_memory].year = 0; | ||
286 | memos[memos_in_memory].type = 0; | ||
287 | memos[memos_in_memory].wday = 0; | ||
288 | rb->strcpy(&memos[memos_in_memory].message[0], ""); | ||
289 | exit = true; | ||
290 | break; | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | rb->close(fp); | ||
296 | } | ||
297 | |||
298 | static bool save_memo(int changed, bool new_mod, struct shown *shown) | ||
299 | { | ||
300 | int fp,fq; | ||
301 | fp = rb->open("/.rockbox/.memo",O_RDONLY | O_CREAT); | ||
302 | fq = rb->open("/.rockbox/~temp",O_RDWR | O_CREAT | O_TRUNC); | ||
303 | if ( (fq != -1) && (fp != -1) ) | ||
304 | { | ||
305 | int i; | ||
306 | char temp[MAX_CHAR_MEMO_LEN + 1]; | ||
307 | rb->lseek(fp, 0, SEEK_SET); | ||
308 | if ( (memos[changed].file_pointer_start == 0) && | ||
309 | (memos[changed].file_pointer_end == 0) && (new_mod) ) | ||
310 | { | ||
311 | rb->close(fp); | ||
312 | rb->close(fq); | ||
313 | fq = rb->open("/.rockbox/.memo",O_RDONLY | O_CREAT | O_APPEND); | ||
314 | rb->snprintf(temp, 2, "%02d", memos[changed].day); | ||
315 | rb->write(fq,temp,2); | ||
316 | rb->snprintf(temp, 2, "%02d", memos[changed].month); | ||
317 | rb->write(fq,temp,2); | ||
318 | rb->snprintf(temp, 4, "%04d", memos[changed].year); | ||
319 | rb->write(fq,temp,4); | ||
320 | rb->snprintf(temp, 1, "%01d", memos[changed].wday); | ||
321 | rb->write(fq,temp,1); | ||
322 | rb->snprintf(temp, 1, "%01d", memos[changed].type); | ||
323 | rb->write(fq,temp,1); | ||
324 | rb->snprintf(temp, rb->strlen(memos[changed].message)+1, "%s\n", | ||
325 | memos[changed].message); | ||
326 | rb->write(fq,temp,rb->strlen(temp)); | ||
327 | } | ||
328 | else | ||
329 | { | ||
330 | for (i = 0; i < memos[changed].file_pointer_start; i++) | ||
331 | { | ||
332 | rb->read(fp, temp, 1); | ||
333 | rb->write(fq,temp,1); | ||
334 | } | ||
335 | if (new_mod) | ||
336 | { | ||
337 | rb->snprintf(temp, 2, "%02d", memos[changed].day); | ||
338 | rb->write(fq,temp,2); | ||
339 | rb->snprintf(temp, 2, "%02d", memos[changed].month); | ||
340 | rb->write(fq,temp,2); | ||
341 | rb->snprintf(temp, 4, "%04d", memos[changed].year); | ||
342 | rb->write(fq,temp,4); | ||
343 | rb->snprintf(temp, 1, "%01d", memos[changed].wday); | ||
344 | rb->write(fq,temp,1); | ||
345 | rb->snprintf(temp, 1, "%01d", memos[changed].type); | ||
346 | rb->write(fq,temp,1); | ||
347 | rb->snprintf(temp, rb->strlen(memos[changed].message)+1, | ||
348 | "%s\n", memos[changed].message); | ||
349 | rb->write(fq,temp, rb->strlen(temp)); | ||
350 | } | ||
351 | rb->lseek(fp, memos[changed].file_pointer_end, SEEK_SET); | ||
352 | for (i = memos[changed].file_pointer_end; | ||
353 | i < rb->filesize(fp); i++) | ||
354 | { | ||
355 | rb->read(fp, temp, 1); | ||
356 | rb->write(fq,temp,1); | ||
357 | } | ||
358 | rb->close(fp); | ||
359 | fp = rb->open("/.rockbox/.memo",O_WRONLY | O_CREAT | O_TRUNC); | ||
360 | rb->lseek(fp, 0, SEEK_SET); | ||
361 | rb->lseek(fq, 0, SEEK_SET); | ||
362 | for (i = 0; i < rb->filesize(fq); i++) | ||
363 | { | ||
364 | rb->read(fq, temp, 1); | ||
365 | rb->write(fp,temp,1); | ||
366 | } | ||
367 | rb->close(fp); | ||
368 | } | ||
369 | rb->close(fq); | ||
370 | rb->remove("/.rockbox/~temp"); | ||
371 | load_memo(shown); | ||
372 | return true; | ||
373 | } | ||
374 | else if (fp != -1) | ||
375 | rb->close(fp); | ||
376 | else if (fq != -1) | ||
377 | rb->close(fq); | ||
378 | return false; | ||
379 | } | ||
380 | |||
381 | static void add_memo(struct shown *shown, int type) | ||
382 | { | ||
383 | bool saved = false; | ||
384 | if (rb->kbd_input(memos[memos_in_memory].message, | ||
385 | sizeof memos[memos_in_memory].message) != -1) | ||
386 | { | ||
387 | if (memos[memos_in_memory].message != "") | ||
388 | { | ||
389 | memos[memos_in_memory].file_pointer_start = 0; | ||
390 | memos[memos_in_memory].file_pointer_end = 0; | ||
391 | memos[memos_in_memory].day = shown->mday; | ||
392 | memos[memos_in_memory].month = shown->mon; | ||
393 | memos[memos_in_memory].wday = shown->wday; | ||
394 | memos[memos_in_memory].year = shown->year; | ||
395 | memos[memos_in_memory].type = type; | ||
396 | if (save_memo(memos_in_memory,true,shown)) | ||
397 | { | ||
398 | saved = true; | ||
399 | memos_in_memory++; | ||
400 | } | ||
401 | else | ||
402 | { | ||
403 | memos[memos_in_memory].file_pointer_start = 0; | ||
404 | memos[memos_in_memory].file_pointer_end = 0; | ||
405 | memos[memos_in_memory].day = 0; | ||
406 | memos[memos_in_memory].month = 0; | ||
407 | memos[memos_in_memory].year = 0; | ||
408 | memos[memos_in_memory].type = 0; | ||
409 | memos[memos_in_memory].wday = 0; | ||
410 | } | ||
411 | } | ||
412 | } | ||
413 | rb->lcd_clear_display(); | ||
414 | if (saved) | ||
415 | rb->lcd_puts(0,0,"Event added"); | ||
416 | else | ||
417 | rb->lcd_puts(0,0,"Event not added"); | ||
418 | rb->lcd_update(); | ||
419 | rb->sleep(HZ/2); | ||
420 | } | ||
421 | |||
422 | static bool edit_memo(int change, struct shown *shown) | ||
423 | { | ||
424 | bool exit = false; | ||
425 | rb->lcd_clear_display(); | ||
426 | if (memos_in_shown_memory > 0) | ||
427 | { | ||
428 | rb->lcd_puts(0,0,"Remove : Up"); | ||
429 | rb->lcd_puts(0,1,"Edit : Down"); | ||
430 | rb->lcd_puts(0,2,"New :"); | ||
431 | rb->lcd_puts(6,3,"weekly : Left"); | ||
432 | rb->lcd_puts(6,4,"monthly : Play"); | ||
433 | rb->lcd_puts(6,5,"annually : Right"); | ||
434 | rb->lcd_puts(6,6,"one off : On"); | ||
435 | } | ||
436 | else | ||
437 | { | ||
438 | rb->lcd_puts(0,0,"New :"); | ||
439 | rb->lcd_puts(6,1,"weekly : Left"); | ||
440 | rb->lcd_puts(6,2,"monthly : Play"); | ||
441 | rb->lcd_puts(6,3,"anualy : Right"); | ||
442 | rb->lcd_puts(6,4,"one off : On"); | ||
443 | } | ||
444 | rb->lcd_update(); | ||
445 | while (!exit) | ||
446 | { | ||
447 | switch (rb->button_get(true)) | ||
448 | { | ||
449 | case BUTTON_OFF: | ||
450 | return false; | ||
451 | |||
452 | case BUTTON_LEFT: | ||
453 | add_memo(shown,0); | ||
454 | return false; | ||
455 | |||
456 | case BUTTON_PLAY: | ||
457 | add_memo(shown,1); | ||
458 | return false; | ||
459 | |||
460 | case BUTTON_RIGHT: | ||
461 | add_memo(shown,2); | ||
462 | return false; | ||
463 | |||
464 | case BUTTON_ON: | ||
465 | add_memo(shown,3); | ||
466 | return false; | ||
467 | |||
468 | case BUTTON_DOWN: | ||
469 | if (memos_in_shown_memory > 0) | ||
470 | { | ||
471 | if(rb->kbd_input(memos[pointer_array[change]].message, | ||
472 | sizeof memos[pointer_array[change]].message) != -1) | ||
473 | save_memo(pointer_array[change],true,shown); | ||
474 | exit = true; | ||
475 | } | ||
476 | break; | ||
477 | |||
478 | case BUTTON_UP: | ||
479 | if (memos_in_shown_memory > 0) | ||
480 | { | ||
481 | save_memo(pointer_array[change],false,shown); | ||
482 | exit = true; | ||
483 | } | ||
484 | break; | ||
485 | |||
486 | case SYS_USB_CONNECTED: | ||
487 | return true; | ||
488 | } | ||
489 | } | ||
490 | return false; | ||
491 | } | ||
492 | |||
493 | static int start = 0; | ||
494 | |||
495 | static void show_lines(int selected, struct shown *shown) | ||
496 | { | ||
497 | int j = 1,w,h,i,k = 0, pos = 1,m = 0; | ||
498 | rb->lcd_getstringsize("A",&w,&h); | ||
499 | int lines = (LCD_HEIGHT / h) - 1; | ||
500 | char temp[MAX_CHAR_MEMO_LEN + 12]; | ||
501 | |||
502 | rb->lcd_clear_display(); | ||
503 | rb->lcd_puts(0,0,"Events (play : menu)"); | ||
504 | |||
505 | while (selected >= (lines + start)) | ||
506 | start++; | ||
507 | while (selected < start) | ||
508 | start--; | ||
509 | i = start; | ||
510 | while ( (i < memos_in_shown_memory) && (k < lines) ) | ||
511 | { | ||
512 | if (memos[pointer_array[i]].type == 2) | ||
513 | rb->snprintf(temp, sizeof temp, "%s (%d yrs)", | ||
514 | memos[pointer_array[i]].message, | ||
515 | shown->year - memos[pointer_array[i]].year); | ||
516 | else | ||
517 | rb->snprintf(temp, sizeof temp, "%s", | ||
518 | memos[pointer_array[i]].message); | ||
519 | m = 0; | ||
520 | if (i == selected) | ||
521 | { | ||
522 | pos = k + 1; | ||
523 | rb->lcd_puts_scroll(m,j++,temp); | ||
524 | } | ||
525 | else | ||
526 | rb->lcd_puts(m,j++,temp); | ||
527 | k++; | ||
528 | i++; | ||
529 | } | ||
530 | rb->lcd_invertrect(0, (pos) * h, LCD_WIDTH, h); | ||
531 | } | ||
532 | |||
533 | static void update_memos_shown(struct shown *shown) | ||
534 | { | ||
535 | memos_in_shown_memory = 0; | ||
536 | start = 0; | ||
537 | int i; | ||
538 | for (i = 0; i < memos_in_memory; i++) | ||
539 | if ( | ||
540 | (memos[i].day == shown->mday) | ||
541 | || | ||
542 | ( | ||
543 | (memos[i].type < 1) | ||
544 | && | ||
545 | (memos[i].wday == shown->wday) | ||
546 | ) | ||
547 | ) | ||
548 | pointer_array[memos_in_shown_memory++] = i; | ||
549 | } | ||
550 | |||
551 | static bool any_events(struct shown *shown, bool force) | ||
552 | { | ||
553 | update_memos_shown(shown); | ||
554 | int lines_displayed = 0; | ||
555 | if (memos_in_shown_memory > 0) | ||
556 | show_lines(lines_displayed,shown); | ||
557 | else if (force) | ||
558 | return edit_memo(lines_displayed, shown); | ||
559 | else | ||
560 | return false; | ||
561 | rb->lcd_update(); | ||
562 | bool exit = false; | ||
563 | while (!exit) | ||
564 | { | ||
565 | switch (rb->button_get(true)) | ||
566 | { | ||
567 | case BUTTON_DOWN: | ||
568 | if (memos_in_shown_memory > 0) | ||
569 | { | ||
570 | lines_displayed++; | ||
571 | if (lines_displayed >= memos_in_shown_memory) | ||
572 | lines_displayed = memos_in_shown_memory - 1; | ||
573 | show_lines(lines_displayed,shown); | ||
574 | rb->lcd_update(); | ||
575 | } | ||
576 | break; | ||
577 | |||
578 | case BUTTON_UP: | ||
579 | if (memos_in_shown_memory > 0) | ||
580 | { | ||
581 | lines_displayed--; | ||
582 | if (lines_displayed < 0) | ||
583 | lines_displayed = 0; | ||
584 | show_lines(lines_displayed,shown); | ||
585 | rb->lcd_update(); | ||
586 | } | ||
587 | break; | ||
588 | |||
589 | case BUTTON_PLAY: | ||
590 | return edit_memo(lines_displayed, shown); | ||
591 | |||
592 | case BUTTON_OFF: | ||
593 | return false; | ||
594 | |||
595 | case SYS_USB_CONNECTED: | ||
596 | return true; | ||
597 | } | ||
598 | } | ||
599 | return false; | ||
600 | } | ||
601 | |||
602 | static void next_month(struct shown *shown, int step) | ||
603 | { | ||
604 | shown->mon++; | ||
605 | if (shown->mon > 12) | ||
606 | { | ||
607 | shown->mon=1; | ||
608 | shown->year++; | ||
609 | leap_year = is_leap_year(shown->year); | ||
610 | } | ||
611 | else if (step > 0) | ||
612 | shown->mday = shown->mday - days_in_month[leap_year][shown->mon-1]; | ||
613 | else if (shown->mday > days_in_month[leap_year][shown->mon]) | ||
614 | shown->mday = days_in_month[leap_year][shown->mon]; | ||
615 | shown->firstday = shown->lastday; | ||
616 | load_memo(shown); | ||
617 | draw_calendar(shown); | ||
618 | } | ||
619 | |||
620 | static void prev_month(struct shown *shown, int step) | ||
621 | { | ||
622 | shown->mon--; | ||
623 | if (shown->mon < 1) | ||
624 | { | ||
625 | shown->mon = 12; | ||
626 | shown->year--; | ||
627 | leap_year = is_leap_year(shown->year); | ||
628 | } | ||
629 | if (step > 0) | ||
630 | shown->mday = shown->mday + days_in_month[leap_year][shown->mon]; | ||
631 | else if (shown->mday > days_in_month[leap_year][shown->mon]) | ||
632 | shown->mday = days_in_month[leap_year][shown->mon]; | ||
633 | shown->firstday += 7 - (days_in_month[leap_year][shown->mon] % 7); | ||
634 | load_memo(shown); | ||
635 | draw_calendar(shown); | ||
636 | } | ||
637 | |||
638 | static void next_day(struct shown *shown, int step) | ||
639 | { | ||
640 | shown->mday += step; | ||
641 | if (shown->mday > days_in_month[leap_year][shown->mon]) | ||
642 | next_month(shown, step); | ||
643 | else | ||
644 | draw_calendar(shown); | ||
645 | } | ||
646 | |||
647 | static void prev_day(struct shown *shown, int step) | ||
648 | { | ||
649 | shown->mday -= step; | ||
650 | if (shown->mday < 1) | ||
651 | prev_month(shown, step); | ||
652 | else | ||
653 | draw_calendar(shown); | ||
654 | } | ||
655 | |||
656 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
657 | { | ||
658 | TEST_PLUGIN_API(api); | ||
659 | (void)(parameter); | ||
660 | rb = api; | ||
661 | |||
662 | struct today today; | ||
663 | struct shown shown; | ||
664 | |||
665 | calendar_init(&today, &shown); | ||
666 | load_memo(&shown); | ||
667 | any_events(&shown, false); | ||
668 | draw_calendar(&shown); | ||
669 | bool exit = false; | ||
670 | while (!exit) | ||
671 | { | ||
672 | switch (rb->button_get(true)) | ||
673 | { | ||
674 | case BUTTON_OFF: | ||
675 | return false; | ||
676 | |||
677 | case BUTTON_ON | BUTTON_DOWN: | ||
678 | case BUTTON_ON | BUTTON_DOWN | BUTTON_REPEAT: | ||
679 | next_month(&shown, 0); | ||
680 | break; | ||
681 | |||
682 | case BUTTON_ON | BUTTON_UP: | ||
683 | case BUTTON_ON | BUTTON_UP | BUTTON_REPEAT: | ||
684 | prev_month(&shown, 0); | ||
685 | break; | ||
686 | |||
687 | case BUTTON_DOWN: | ||
688 | case BUTTON_DOWN | BUTTON_REPEAT: | ||
689 | next_day(&shown, 7); | ||
690 | break; | ||
691 | |||
692 | case BUTTON_UP: | ||
693 | case BUTTON_UP | BUTTON_REPEAT: | ||
694 | prev_day(&shown, 7); | ||
695 | break; | ||
696 | |||
697 | case BUTTON_LEFT: | ||
698 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
699 | prev_day(&shown, 1); | ||
700 | break; | ||
701 | |||
702 | case BUTTON_RIGHT: | ||
703 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
704 | next_day(&shown, 1); | ||
705 | break; | ||
706 | |||
707 | case BUTTON_PLAY: | ||
708 | if (any_events(&shown, true)) | ||
709 | rb->usb_screen(); | ||
710 | draw_calendar(&shown); | ||
711 | break; | ||
712 | |||
713 | case SYS_USB_CONNECTED: | ||
714 | rb->usb_screen(); | ||
715 | draw_calendar(&shown); | ||
716 | break; | ||
717 | } | ||
718 | } | ||
719 | return false; | ||
720 | } | ||
721 | |||
722 | #endif | ||