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