2.0 alpha
[apps/core/preloaded/calendar.git] / src / view-main-year.c
1 /*
2   *
3   *  Copyright 2012  Samsung Electronics Co., Ltd
4   *
5   *  Licensed under the Flora License, Version 1.0 (the "License");
6   *  you may not use this file except in compliance with the License.
7   *  You may obtain a copy of the License at
8   *
9   *       http://www.tizenopensource.org/license
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17
18
19 #include <Ecore_X.h>
20
21 #include "view.h"
22
23 #define ANIMATION_TIME 0.2
24
25 typedef enum year_index {
26         CAL_YEAR_PREV_YEAR = -1,
27         CAL_YEAR_CURR_YEAR,
28         CAL_YEAR_NEXT_YEAR,
29 }year_index;
30
31 static const char *_name = NULL;
32
33 typedef struct {
34         const char *name;
35         struct appdata *ad;
36         Evas_Object *parent;
37         Evas_Object *ly; // self
38         Evas_Object *handle_base;
39
40         struct _year* prev_year;
41         struct _year* cur_year;
42         struct _year* next_year;
43
44         Eina_Bool ignore_mouse_down; // block mouse down event during flick
45         int downed;
46         Evas_Coord_Rectangle rect;
47         Evas_Coord_Point down1,down2;
48         Evas_Coord_Point move1,move2;
49
50         int multi_touched;
51         int down_d;
52
53         int pos_selected;
54         int pos_down;
55
56         Evas_Coord_Rectangle mouse_down_position;
57         Evas_Coord_Rectangle mouse_up_position;
58         Evas_Coord_Rectangle pos_to;
59         Ecore_Animator *ani;
60         double ani_start;
61         struct tm tm_to;
62
63         char wday[8][7];//To reduce get text time
64         char month[12][32];//To reduce get text time
65
66         Ecore_Idler* idler; //To make prev & next year object
67
68         Evas_Object* edje_handle[12];
69 } cal_view_main_year_data;
70
71 struct _year{
72         int year;
73         Evas_Object* image;
74         Evas* evas;
75         Evas_Object* edj;
76         Evas_Object* ly;
77         cal_view_main_year_data *p;
78 };
79
80 static char signal_source[32];
81 static struct _year* __cal_year_create_year_object(Evas_Object* parent, cal_view_main_year_data* p, enum year_index);
82 static void __cal_year_delete_year_object(struct _year* y);
83 static void __cal_year_mouse_up(void *data, Evas *e, Evas_Object *ly, void *ei);
84 static void __cal_year_mouse_down(void *data, Evas *e, Evas_Object *ly, void *ei);
85 static void __cal_year_mouse_move(void *data, Evas *e, Evas_Object *ly, void *ei);
86 static void __cal_year_update_select(struct _year *y, int tm_mon);
87 static void __cal_year_delete_edje_handle(cal_view_main_year_data* p);
88
89 static inline void __cal_year_stop_animation(cal_view_main_year_data *p)
90 {
91         c_retm_if(!p, "Input parameter is null.");
92
93         if (p->ani)
94                 ecore_animator_del(p->ani);
95
96         p->ani = NULL;
97 }
98
99 static void __cal_year_delete_layout(void *data, Evas *e, Evas_Object *obj, void *ei)
100 {
101         CAL_FN_START;
102
103         c_retm_if(!data, "Input parameter is null.");
104
105         cal_view_main_year_data *p = data;
106
107         __cal_year_delete_edje_handle(p);
108
109         __cal_year_stop_animation(p);
110
111         if (p->prev_year)
112                 __cal_year_delete_year_object(p->prev_year);
113         if (p->cur_year)
114                 __cal_year_delete_year_object(p->cur_year);
115         if (p->next_year)
116                 __cal_year_delete_year_object(p->next_year);
117
118         if (p->idler)
119                 ecore_idler_del(p->idler);
120
121         free(p);
122 }
123
124 static void __cal_year_set_month_text(struct _year* y)
125 {
126         c_retm_if(!y, "Input parameter is null.");
127
128         int i;
129         cal_view_main_year_data* p = y->p;
130         c_retm_if(!p, "");
131
132
133         for (i = 0; i < 12; i++)
134                 edje_object_part_text_set(y->edj, cal_util_get_part_text("mb/%d/text", i), p->month[i]);
135 }
136
137 static void __cal_year_make_month_text(cal_view_main_year_data* p)
138 {
139         c_retm_if(!p, "Input parameter is null.");
140
141         int i;
142         struct tm tm;
143
144         tm = p->ad->base_tm;
145         cal_util_update_tm_month(&tm, tm.tm_mon*(-1));
146
147         for(i = 0; i < 12 ; i++)
148         {
149                 cal_util_get_time_text(p->month[i], 31, CAL_UTIL_DATE_FORMAT_4, NULL, &tm);
150                 cal_util_update_tm_month(&tm, 1);
151         }
152 }
153
154 static void __cal_year_make_wday_text(cal_view_main_year_data* p)
155 {
156         c_retm_if(!p, "Input parameter is null.");
157
158         int i;
159         struct tm tm;
160
161         tm = p->ad->base_tm;
162         cal_util_update_tm_day(&tm, tm.tm_wday*(-1));
163
164         for(i = 0; i < 7 ; i++) {
165                 cal_util_get_time_text(p->wday[i], 7, CAL_UTIL_DATE_FORMAT_17, NULL, &tm);
166                 cal_util_update_tm_day(&tm, 1);
167         }
168 }
169
170 static void __cal_year_set_wday_text(Evas_Object *month, int start)
171 {
172         c_retm_if(!month, "Input parameter is null.");
173
174         int i;
175
176         cal_view_main_year_data* p = CAL_UTIL_GET_PRIV_DATA(month);
177
178         for (i = 0; i < 7; i++)
179         {
180                 edje_object_part_text_set(month, cal_util_get_part_text("sdh/%d/text", i), p->wday[(i+start)%7]);
181                 if((i+start)%7 == 6)
182                 {
183                         cal_util_emit_signal(month, "satday,%d", i);
184                         continue;
185                 }
186
187                 if((i+start)%7 == 0)
188                         cal_util_emit_signal(month, "sunday,%d", i);
189         }
190 }
191
192 static void __cal_year_update_today(Evas_Object *ly, int tm_year, int tm_mon, int tm_mday, int pos)
193 {
194         c_retm_if(!ly, "Input parameter is null.");
195
196         cal_view_main_year_data *p = CAL_UTIL_GET_PRIV_DATA(ly);
197         c_retm_if(!p, "CAL_UTIL_GET_PRIV_DATA returned null.");
198
199         struct appdata *ad = p->ad;
200         c_retm_if(!ad, "p->ad is null.");
201
202         if (tm_year == ad->today_tm.tm_year && tm_mon == ad->today_tm.tm_mon && tm_mday == ad->today_tm.tm_mday)
203                 cal_util_emit_signal(ly, "today,%d", pos-1);
204 }
205
206
207 static void __cal_year_fill_month(Evas_Object *month, int tm_year, int tm_mon, int *first_wday, int start_wday)
208 {
209         c_retm_if(!month, "Input parameter is null.");
210
211         int i, day, wday;
212         int max;
213
214         wday = *first_wday;
215         max = CAL_UTIL_GET_WDAY(wday - start_wday);
216
217         for (i = 0; i < max; i++)
218         {
219                 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "");
220         }
221
222         day = 1;
223         max = i + cal_util_get_max_days(tm_year, tm_mon);
224         for (; i < max; i++)
225         {
226                 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "%d", day);
227
228                 if (wday == 6)
229                         cal_util_emit_signal(month, "satday,%d", i);
230                 else if (wday == 0)
231                         cal_util_emit_signal(month, "sunday,%d", i);
232
233                 wday = CAL_UTIL_GET_WDAY(wday + 1);
234
235                 __cal_year_update_today(month, tm_year, tm_mon, day-1, i);
236
237                 day++;
238         }
239
240         for (; i < 42; i++)
241         {
242                 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "");
243         }
244
245         *first_wday = wday;
246 }
247
248 static Evas_Object* __cal_year_create_month(struct _year *y, int tm_mon, int *wday, int start)
249 {
250         c_retv_if(!y, NULL);
251
252         Evas_Object *month = edje_object_add(y->evas);
253
254         Eina_Bool r = edje_object_file_set(month, EDJ_FILE, "main/year/cal");
255         if (!r) {
256
257                 ERR("edje_object_file_set(%p, %s, %s) is failed.", month, EDJ_FILE, "main/year/cal");
258
259                 evas_object_del(month);
260
261                 return NULL;
262         }
263
264         evas_object_data_set(month,"priv",y->p);
265
266         __cal_year_set_wday_text(month, start);
267
268         __cal_year_fill_month(month, y->year, tm_mon, wday, start);
269
270         return month;
271 }
272
273 static int __cal_year_get_first_wday(int tm_year)
274 {
275         struct tm tm;
276         time_t t;
277
278         t = time(NULL);
279         localtime_r(&t, &tm);
280
281         tm.tm_year = tm_year;
282         tm.tm_mon = 0;
283         tm.tm_mday = 1;
284
285         t = mktime(&tm);
286         c_retvm_if(t == -1, 0, "mktime() returned -1.");
287
288         return tm.tm_wday;
289 }
290
291 static void __cal_year_fill_months(struct _year* y)
292 {
293         c_retm_if(!y, "Input parameter is null.");
294
295         int i;
296         Evas_Object *month;
297         int first_wday;
298         cal_view_main_year_data* p = y->p;
299
300         first_wday = __cal_year_get_first_wday(y->year);
301
302         __cal_year_make_wday_text(p);
303
304         for (i = 0; i < 12; i++)
305         {
306                 month = __cal_year_create_month(y, i, &first_wday, p->ad->wday_start);
307                 c_retm_if(!month, "");
308
309                 edje_object_part_swallow(y->edj, cal_util_get_part_text("mb/%d/sw", i), month);
310
311                 evas_object_data_set(y->ly, cal_util_get_part_text("mb/%d/sw", i), month);
312         }
313 }
314
315 static inline void __cal_year_move_year_objects(cal_view_main_year_data *p, Evas_Coord x)
316 {
317         c_retm_if(!p, "Input parameter is null.");
318
319         if (x < 0) {
320
321                 if (!p->next_year) {
322
323                         p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
324                         c_retm_if(!p->next_year, "__cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR) returned null");
325                 }
326
327                 evas_object_move(p->cur_year->image, x, p->rect.y);
328
329                 evas_object_move(p->next_year->image, x + p->rect.w, p->rect.y);
330         } else {
331
332                 if (!p->prev_year) {
333
334                         p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
335                         c_retm_if(!p->prev_year, "__cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR) returned null");
336                 }
337
338                 evas_object_move(p->cur_year->image, x, p->rect.y);
339
340                 evas_object_move(p->prev_year->image, x -p->rect.w, p->rect.y);
341         }
342
343         evas_object_move(p->handle_base, x, p->rect.y);
344 }
345
346 static void __cal_year_image_object_mouse_down_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
347 {
348         c_retm_if(!data, "Input parameter is null.");
349
350         cal_view_main_year_data *p = data;
351         struct _year *y = p->cur_year;
352
353         int index = (int)evas_object_data_get(obj, "index");
354
355         snprintf(signal_source, 31, "mb/%d/base", index);
356         edje_object_signal_emit(y->edj, "mouse,down,1", signal_source);
357
358         p->pos_down = index;
359 }
360
361 static void __cal_year_image_object_mouse_up_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
362 {
363         c_retm_if(!data, "Input parameter is null.");
364
365         cal_view_main_year_data *p = data;
366         struct _year *y = p->cur_year;
367         struct appdata* ad = p->ad;
368
369         snprintf(signal_source, 31, "mb/%d/base", p->pos_down);
370         edje_object_signal_emit(y->edj, "mouse,up,1", signal_source);
371
372         if (p->ignore_mouse_down)
373         {
374                 p->ignore_mouse_down = EINA_FALSE;
375                 return;
376         }
377
378         cal_util_update_tm_month(&ad->base_tm, p->pos_down - ad->base_tm.tm_mon);
379
380         cal_main_change_view(p->parent, CV_MONTH);
381 }
382
383 static void __cal_year_delete_edje_handle(cal_view_main_year_data* p)
384 {
385         c_retm_if(!p, "p is null.");
386
387         int i = 0;
388
389         for (i = 0 ; i < 12 ; i++)
390         {
391                 c_retm_if(!p->edje_handle[i], "p->edje_handle[%d] is null.", i);
392
393                 evas_object_event_callback_del(p->edje_handle[i], EVAS_CALLBACK_MOUSE_DOWN, __cal_year_image_object_mouse_down_callback);
394                 evas_object_event_callback_del(p->edje_handle[i], EVAS_CALLBACK_MOUSE_UP, __cal_year_image_object_mouse_up_callback);
395
396                 evas_object_del(p->edje_handle[i]);
397         }
398
399         c_retm_if(!p->handle_base, "p->handle_base is null.");
400         evas_object_del(p->handle_base);
401 }
402
403 static inline int __cal_year_update_view(cal_view_main_year_data *p)
404 {
405         CAL_FN_START;
406
407         c_retvm_if(!p, -1, "Input parameter is null.");
408         c_retvm_if(!p->ad, -1, "p->ad is null.");
409
410         struct appdata* ad = p->ad;
411
412         int d = p->tm_to.tm_year - p->ad->base_tm.tm_year;
413
414         ad->base_tm = p->tm_to;
415
416         cal_util_emit_signal(p->cur_year->edj, "unselect,%d", p->pos_selected);
417
418         elm_object_part_content_unset(p->ly, "content");
419         elm_object_part_content_unset(p->ly, "content/left");
420         elm_object_part_content_unset(p->ly, "content/right");
421
422         if (d > 0) {
423
424                 if (p->prev_year) {
425                         evas_object_del(p->prev_year->image);
426                         __cal_year_delete_year_object(p->prev_year);
427                 }
428
429                 p->prev_year = p->cur_year;
430                 p->cur_year = p->next_year;
431                 p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
432
433         } else if ( d < 0) {
434
435                 if (p->next_year) {
436                         evas_object_del(p->next_year->image);
437                         __cal_year_delete_year_object(p->next_year);
438                 }
439
440                 p->next_year = p->cur_year;
441                 p->cur_year = p->prev_year;
442                 p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
443         }
444
445         elm_object_part_content_set(p->ly, "content", p->cur_year->image);
446
447         if (p->prev_year)
448                 elm_object_part_content_set(p->ly, "content/left", p->prev_year->image);
449
450         if (p->next_year)
451                 elm_object_part_content_set(p->ly, "content/right", p->next_year->image);
452
453         cal_main_update_title_text(ad->title, CV_YEAR, &ad->base_tm, ad->wday_start);
454
455         __cal_year_update_select(p->cur_year, ad->base_tm.tm_mon);
456
457         __cal_year_move_year_objects(p, 0);
458
459         if (p->ignore_mouse_down)
460                 p->ignore_mouse_down = EINA_FALSE;
461
462         return 0;
463 }
464
465 static Eina_Bool __cal_year_animation(void *data, double pos)
466 {
467         c_retvm_if(!data, ECORE_CALLBACK_CANCEL, "Input parameter is null.");
468
469         cal_view_main_year_data *p = data;
470         Evas_Coord dx;
471
472         dx = (p->mouse_up_position.x - p->pos_to.x) * cal_util_nsin(1.0 - pos);
473         __cal_year_move_year_objects(p, p->pos_to.x + dx);
474
475         if ((dx + p->pos_to.x)%p->rect.w == 0)
476         {
477                 p->ani = NULL;
478                 __cal_year_update_view(p);
479                 return ECORE_CALLBACK_CANCEL;
480         }
481
482         return ECORE_CALLBACK_RENEW;
483 }
484
485 static inline void __cal_year_start_animation(cal_view_main_year_data *p)
486 {
487         c_retm_if(!p, "Input parameter is null.");
488
489         if (p->mouse_up_position.x == p->pos_to.x)
490                 return;
491
492         if (!p->ani)
493                 p->ani = ecore_animator_timeline_add(ANIMATION_TIME, __cal_year_animation, p);
494
495         p->ani_start = ecore_time_get();
496 }
497
498 static void inline __cal_year_set_go(cal_view_main_year_data *p, int d)
499 {
500         c_retm_if(!p, "Input parameter is null.");
501
502         int r = 0;
503
504         p->tm_to = p->ad->base_tm;
505         p->pos_to = p->rect;
506
507         if(d != 0)
508                 r = cal_util_update_tm_year(&p->tm_to, d);
509         if (r == -1)
510                 return;
511
512         p->pos_to.x = p->rect.w * (d * -1);
513 }
514
515 static void __cal_year_mouse_up(void *data, Evas *e, Evas_Object *ly, void *ei)
516 {
517         c_retm_if(!data, "Input parameter is null.");
518
519         Evas_Event_Mouse_Up *ev = ei;
520         cal_view_main_year_data *p = data;
521
522         if (!p->downed)
523                 return;
524
525         p->downed = 0;
526
527         cal_util_get_geometry(&p->mouse_up_position, p->cur_year->image);
528
529         if (p->mouse_up_position.x > (p->rect.w >> 2))
530                 __cal_year_set_go(p, -1);
531         else if (p->mouse_up_position.x < (p->rect.w >> 2) * -1)
532                 __cal_year_set_go(p, 1);
533         else
534         {
535                 Evas_Coord x = ev->canvas.x - p->down1.x;
536
537                 if (x < 3 && x > -3 && p->mouse_up_position.x ==0)
538                         return;
539
540                 __cal_year_set_go(p, 0);
541         }
542
543         __cal_year_start_animation(p);
544 }
545
546 static void __cal_year_mouse_move(void *data, Evas *e, Evas_Object *ly, void *ei)
547 {
548         c_retm_if(!data, "Input parameter is null.");
549
550         cal_view_main_year_data *p = data;
551
552         Evas_Event_Mouse_Move *ev = ei;
553         Evas_Coord x;
554         static int cnt = 0;
555         Evas_Coord th = elm_finger_size_get();
556         Evas_Coord dx;
557
558         p->move1.x = ev->cur.canvas.x;
559         p->move1.y = ev->cur.canvas.y;
560
561         if (!p->downed || p->multi_touched)
562                 return;
563
564         cnt++;
565         if ((cnt & 0x7) != 0) // Workaround
566                 return;
567
568         dx = p->move1.x - p->down1.x;
569         if (th < abs(dx)) {
570                 x = p->mouse_down_position.x + p->move1.x - p->down1.x;
571
572                 __cal_year_move_year_objects(p, x);
573
574                 p->ignore_mouse_down = EINA_TRUE;
575         }
576
577 }
578
579 static void __cal_year_mouse_down(void *data, Evas *e, Evas_Object *ly, void *ei)
580 {
581         c_retm_if(!data, "Input parameter is null.");
582
583         cal_view_main_year_data *p = data;
584         struct _year *y = p->cur_year;
585
586         Evas_Event_Mouse_Down *ev = ei;
587
588         p->down1.x = p->move1.x = ev->canvas.x;
589         p->down1.y = p->move1.y = ev->canvas.y;
590
591         cal_util_get_geometry(&p->mouse_down_position, y->image);
592
593         __cal_year_stop_animation(p);
594
595         p->downed = 1;
596         p->multi_touched = 0;
597 }
598
599 static void __cal_year_update_select(struct _year *y, int tm_mon)
600 {
601         c_retm_if(!y, "Input parameter is null.");
602
603         cal_view_main_year_data* p = y->p;
604
605         if (p->pos_selected != -1)
606                 cal_util_emit_signal(y->edj, "unselect,%d", p->pos_selected);
607
608         cal_util_emit_signal(y->edj, "select,%d", tm_mon);
609
610         p->pos_selected = tm_mon;
611 }
612
613 static Evas_Object *__cal_year_create_image(Evas_Object *parent, Eina_Bool is_landscape_mode)
614 {
615         c_retvm_if(!parent, NULL, "Input parameter is null.");
616
617         Evas_Object *img;
618         Evas *e;
619         Ecore_Evas *ee;
620         Evas_Coord w, h;
621
622         ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
623
624         if (is_landscape_mode) {
625                 w = w + h;
626                 h = w - h;
627                 w = w -h;
628         }
629
630         e = evas_object_evas_get(parent);
631         ee = ecore_evas_ecore_evas_get(e);
632
633         img = ecore_evas_object_image_new(ee);
634         if (!img)
635                 return NULL;
636
637         evas_object_image_alpha_set(img, EINA_TRUE);
638         evas_object_image_size_set(img, w, h);
639         evas_object_image_fill_set(img, 0, 0, w, h);
640
641         evas_object_show(img);
642
643         return img;
644 }
645
646 static Evas_Object *__cal_year_add_edje(Evas *e, const char *grp, Evas_Coord w, Evas_Coord h)
647 {
648         c_retv_if(!e, NULL);
649
650         Evas_Object *eo = edje_object_add(e);
651         c_retv_if(!eo, NULL);
652
653         Eina_Bool r = edje_object_file_set(eo, EDJ_FILE, grp);
654         if (!r) {
655
656                 ERR("edje_object_file_set(%p, %s, %s) is failed.", eo, EDJ_FILE, grp);
657
658                 evas_object_del(eo);
659
660                 return NULL;
661         }
662
663         evas_object_freeze_events_set(eo, EINA_TRUE);
664
665         evas_object_resize(eo, w, h);
666         evas_object_move(eo, 0, 0);
667         evas_object_show(eo);
668
669         return eo;
670 }
671
672 static void __cal_year_image_object_resize_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
673 {
674         c_retm_if(!data, "Input parameter is null.");
675
676         struct _year *y = data;
677         c_retm_if(!y->edj, "y->edj is null.");
678         c_retm_if(!y->p, "y->p is null.");
679
680         cal_view_main_year_data *p = y->p;
681
682         cal_util_get_geometry(&p->rect, obj);
683
684         evas_object_resize(y->edj, p->rect.w, p->rect.h);
685         evas_object_move(y->edj, 0, 0);
686 }
687
688 static void __cal_year_image_object_move_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
689 {
690         c_retm_if(!data, "Input parameter is null.");
691
692         struct _year *y = data;
693
694         evas_object_move(y->edj, 0, 0);
695 }
696
697 static void __cal_year_delete_year_object(struct _year* y)
698 {
699         CAL_FN_START;
700
701         c_retm_if(!y, "Input parameter is null.");
702
703         evas_object_del(y->edj);
704
705         free(y);
706 }
707
708 static struct _year* __cal_year_create_year_object(Evas_Object* ly, cal_view_main_year_data* p, enum year_index year)
709 {
710         c_retvm_if(!ly, NULL, "Input parameter is null.");
711         c_retvm_if(!p, NULL, "Input parameter is null.");
712         c_retvm_if(!p->ad, NULL, "p->ad is null.");
713
714         struct appdata* ad = p->ad;
715         c_retv_if(!ad, NULL);
716
717         struct tm tm = ad->base_tm;
718
719         int r = cal_util_update_tm_year(&tm, year);
720         c_retvm_if(r < 0, NULL, "cal_util_update_tm_year(%d, %d is failed", tm.tm_year, year);
721
722         struct _year* y = calloc(1, sizeof(struct _year));
723         c_retv_if(!y, NULL);
724
725         y->image = __cal_year_create_image(ly, ad->is_landscape_mode);
726
727         y->evas = ecore_evas_object_evas_get(y->image);
728
729         y->edj = __cal_year_add_edje(y->evas, p->name, p->rect.w, p->rect.h);
730
731         y->p = p;
732
733         if(year > 0)
734                 elm_object_part_content_set(ly, "content/right", y->image);
735         else if( year < 0)
736                 elm_object_part_content_set(ly, "content/left", y->image);
737         else
738                 elm_object_part_content_set(ly, "content", y->image);
739
740         y->ly = ly;
741         y->year = tm.tm_year;
742
743         evas_object_event_callback_add(y->image, EVAS_CALLBACK_RESIZE, __cal_year_image_object_resize_callback, y);
744         evas_object_event_callback_add(y->image, EVAS_CALLBACK_MOVE, __cal_year_image_object_move_callback, y);
745
746         __cal_year_set_month_text(y);
747         __cal_year_fill_months(y);
748
749         return y;
750 }
751
752 static void __cal_year_create_edje_handle(cal_view_main_year_data* p)
753 {
754         c_retm_if(!p, "p is null.");
755
756         Evas * e = evas_object_evas_get(p->ly);
757         int i = 0;
758         Evas_Object *ly = NULL;
759         Evas_Object *handle = NULL;
760         char part[16];
761
762         if (!p->ad->is_landscape_mode) {
763                 ly = cal_util_add_layout(p->ly, "year/edje/handle");
764         } else {
765                 ly = cal_util_add_layout(p->ly, "year/edje/handle/l");
766         }
767
768         c_retm_if(!ly, "ly is null.");
769
770         for (i = 0 ; i < 12 ; i++)
771         {
772                 handle = evas_object_rectangle_add(e);
773                 c_retm_if(!handle, "evas_object_rectangle_add returned null.");
774
775                 evas_object_color_set(handle, 0, 0, 0, 0);
776                 evas_object_data_set(handle, "index", (void*)i);
777                 snprintf(part, sizeof(part), "handle/%d/sw", i);
778                 elm_object_part_content_set(ly, part, handle);
779
780                 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN, __cal_year_image_object_mouse_down_callback, p);
781                 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_UP, __cal_year_image_object_mouse_up_callback, p);
782
783                 p->edje_handle[i] = handle;
784         }
785
786         elm_object_part_content_set(p->ly, "edje/handle", ly);
787
788         p->handle_base = ly;
789
790 }
791
792 Evas_Object* cal_year_create_view(struct appdata *ad, Evas_Object *main)
793 {
794         c_retvm_if(!ad, NULL, "Input parameter is null.");
795         c_retvm_if(!main, NULL, "Input parameter is null.");
796
797         cal_view_main_year_data *p;
798         Evas_Object* ly = NULL;
799
800         CAL_CALLOC(p, 1, cal_view_main_year_data);
801
802         if (!ad->is_landscape_mode) {
803                 p->name = _name = "main/year/months";
804         } else {
805                 p->name = _name = "main/year/months/l";
806         }
807
808         p->ad = ad;
809         p->parent = main;
810
811         edje_object_part_geometry_get(CAL_UTIL_GET_EDJ_DATA(ad->main), "cont", NULL, NULL, &p->rect.w, &p->rect.h);
812
813         memset(p->wday, 0, 8*7);
814         memset(p->month, 0, 32*12);
815
816         __cal_year_make_month_text(p);
817
818         ly = cal_util_add_layout(p->ad->nv, "year/layout");
819         if (!ly)
820         {
821                 free(p);
822                 return NULL;
823         }
824
825         evas_object_data_set(ly, "priv", p);
826         p->ly = ly;
827
828         p->pos_selected = -1;
829
830         __cal_year_create_edje_handle(p);
831
832         evas_object_event_callback_add(ly, EVAS_CALLBACK_DEL, __cal_year_delete_layout, p);
833         evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_DOWN, __cal_year_mouse_down, p);
834         evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_UP, __cal_year_mouse_up, p);
835         evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_MOVE, __cal_year_mouse_move, p);
836
837         return p->ly;
838 }
839
840 static Eina_Bool __cal_year_create_year_with_idler(void* data)
841 {
842         CAL_FN_START;
843
844         c_retvm_if(!data, ECORE_CALLBACK_CANCEL, "Input param is null.");
845
846         cal_view_main_year_data* p = data;
847
848         c_retvm_if(!p->ad, ECORE_CALLBACK_CANCEL, "p->ad is null.");
849
850         if(p->prev_year)
851                 __cal_year_delete_year_object(p->prev_year);
852
853         p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
854         c_retvm_if(!p->prev_year, ECORE_CALLBACK_CANCEL, "__cal_year_create_year_object returned null.");
855
856         if(p->next_year)
857                 __cal_year_delete_year_object(p->next_year);
858
859         p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
860         c_retvm_if(!p->next_year, ECORE_CALLBACK_CANCEL, "__cal_year_create_year_object returned null.");
861
862         p->idler = NULL;
863
864         return ECORE_CALLBACK_CANCEL;
865 }
866
867 static void __cal_year_update_current_year(cal_view_main_year_data* p)
868 {
869         CAL_FN_START;
870
871         c_retm_if(!p, "Input parameter is null.");
872
873         p->cur_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_CURR_YEAR);
874         c_retm_if(!p->cur_year, "__cal_year_create_year_object returned null.");
875
876         elm_object_part_content_set(p->ly, "content", p->cur_year->image);
877 }
878
879 void cal_year_update_view(Evas_Object *ly)
880 {
881         CAL_FN_START;
882
883         c_retm_if(!ly, "Input parameter is null.");
884
885         cal_view_main_year_data *p;
886         struct appdata *ad;
887
888         p = CAL_UTIL_GET_PRIV_DATA(ly);
889         c_retm_if(!p, "p is null.");
890
891         ad = p->ad;
892         c_retm_if(!ad, "p->ad is null.");
893
894         if (!p || CAL_STRCMP(p->name, _name)) {
895                 ERR("update year view: Invalid object");
896                 return;
897         }
898
899         __cal_year_update_current_year(p);
900
901         if(p->idler)
902         {
903                 ecore_idler_del(p->idler);
904                 p->idler = NULL;
905         }
906
907         p->idler = ecore_idler_add(__cal_year_create_year_with_idler, (void*)p);
908
909         __cal_year_update_select(p->cur_year, ad->base_tm.tm_mon);
910 }
911