4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Youngjae Shin <yj99.shin@samsung.com>
7 * Taeho Kang <taeho84.kang@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
26 #define ANIMATION_TIME 0.2
28 typedef enum year_index {
29 CAL_YEAR_PREV_YEAR = -1,
34 static const char *_name = "main/year/months";
40 Evas_Object *ly; // self
41 Evas_Object *handle_base;
43 struct _year* prev_year;
44 struct _year* cur_year;
45 struct _year* next_year;
47 Eina_Bool ignore_mouse_down; // block mouse down event during flick
49 Evas_Coord_Rectangle rect;
50 Evas_Coord_Point down1,down2;
51 Evas_Coord_Point move1,move2;
56 Evas_Coord_Rectangle mouse_down_position;
57 Evas_Coord_Rectangle mouse_up_position;
58 Evas_Coord_Rectangle pos_to;
63 char wday[8][7];//To reduce get text time
64 char month[12][32];//To reduce get text time
66 Ecore_Idler* idler; //To make prev & next year object
68 Evas_Object* edje_handle[12];
69 } cal_view_main_year_data;
77 cal_view_main_year_data *p;
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);
89 static inline void __cal_year_stop_animation(cal_view_main_year_data *p)
91 c_retm_if(!p, "Input parameter is null.");
94 ecore_animator_del(p->ani);
99 static void __cal_year_delete_layout(void *data, Evas *e, Evas_Object *obj, void *ei)
103 c_retm_if(!data, "Input parameter is null.");
105 cal_view_main_year_data *p = data;
107 __cal_year_delete_edje_handle(p);
109 __cal_year_stop_animation(p);
112 __cal_year_delete_year_object(p->prev_year);
114 __cal_year_delete_year_object(p->cur_year);
116 __cal_year_delete_year_object(p->next_year);
119 ecore_idler_del(p->idler);
124 static void __cal_year_set_month_text(struct _year* y)
126 c_retm_if(!y, "Input parameter is null.");
129 cal_view_main_year_data* p = y->p;
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]);
137 static void __cal_year_make_month_text(cal_view_main_year_data* p)
139 c_retm_if(!p, "Input parameter is null.");
145 cal_util_update_tm_month(&tm, tm.tm_mon*(-1));
147 for(i = 0; i < 12 ; i++)
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);
154 static void __cal_year_make_wday_text(cal_view_main_year_data* p)
156 c_retm_if(!p, "Input parameter is null.");
162 cal_util_update_tm_day(&tm, tm.tm_wday*(-1));
164 for(i = 0; i < 7 ; i++)
166 cal_util_get_time_text(p->wday[i], 7, CAL_UTIL_DATE_FORMAT_2, NULL, &tm);
167 cal_util_update_tm_day(&tm, 1);
171 static void __cal_year_set_wday_text(Evas_Object *month, int start)
173 c_retm_if(!month, "Input parameter is null.");
177 cal_view_main_year_data* p = CAL_UTIL_GET_PRIV_DATA(month);
179 for (i = 0; i < 7; i++)
181 edje_object_part_text_set(month, cal_util_get_part_text("sdh/%d/text", i), p->wday[(i+start)%7]);
184 cal_util_emit_signal(month, "satday,%d", i);
189 cal_util_emit_signal(month, "sunday,%d", i);
193 static void __cal_year_update_today(Evas_Object *ly, int tm_year, int tm_mon, int tm_mday, int pos)
195 c_retm_if(!ly, "Input parameter is null.");
197 cal_view_main_year_data *p = CAL_UTIL_GET_PRIV_DATA(ly);
198 c_retm_if(!p, "CAL_UTIL_GET_PRIV_DATA returned null.");
200 struct appdata *ad = p->ad;
201 c_retm_if(!ad, "p->ad is null.");
203 if (tm_year == ad->today_tm.tm_year && tm_mon == ad->today_tm.tm_mon && tm_mday == ad->today_tm.tm_mday)
204 cal_util_emit_signal(ly, "today,%d", pos-1);
208 static void __cal_year_fill_month(Evas_Object *month, int tm_year, int tm_mon, int *first_wday, int start_wday)
210 c_retm_if(!month, "Input parameter is null.");
216 max = CAL_UTIL_GET_WDAY(wday - start_wday);
218 for (i = 0; i < max; i++)
220 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "");
224 max = i + cal_util_get_max_days(tm_year, tm_mon);
227 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "%d", day);
230 cal_util_emit_signal(month, "satday,%d", i);
232 cal_util_emit_signal(month, "sunday,%d", i);
234 wday = CAL_UTIL_GET_WDAY(wday + 1);
236 __cal_year_update_today(month, tm_year, tm_mon, day-1, i);
243 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "");
249 static Evas_Object* __cal_year_create_month(struct _year *y, int tm_mon, int *wday, int start)
251 c_retvm_if(!y, NULL, "Input parameter is null.");
255 month = edje_object_add(y->evas);
257 if(cal_util_black_theme_check()){
258 edje_object_file_set(month, EDJ_FILE, "main/year/cal");
261 edje_object_file_set(month, EDJ_FILE_WHITE, "main/year/cal");
264 evas_object_data_set(month,"priv",y->p);
266 __cal_year_set_wday_text(month, start);
267 __cal_year_fill_month(month, y->year, tm_mon, wday, start);
272 static int __cal_year_get_first_wday(int tm_year)
278 localtime_r(&t, &tm);
280 tm.tm_year = tm_year;
285 c_retvm_if(t == -1, 0, "mktime() returned -1.");
290 static void __cal_year_fill_months(struct _year* y)
292 c_retm_if(!y, "Input parameter is null.");
297 cal_view_main_year_data* p = y->p;
299 first_wday = __cal_year_get_first_wday(y->year);
301 __cal_year_make_wday_text(p);
303 for (i = 0; i < 12; i++)
305 month = __cal_year_create_month(y, i, &first_wday, p->ad->wday_start);
306 c_retm_if(!month, "");
308 edje_object_part_swallow(y->edj, cal_util_get_part_text("mb/%d/sw", i), month);
310 evas_object_data_set(y->ly, cal_util_get_part_text("mb/%d/sw", i), month);
314 static inline void __cal_year_move_year_objects(cal_view_main_year_data *p, Evas_Coord x)
316 c_retm_if(!p, "Input parameter is null.");
322 p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
323 c_retm_if(!p->next_year, "__cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR) returned null");
326 evas_object_move(p->cur_year->image, x, p->rect.y);
328 evas_object_move(p->next_year->image, x + p->rect.w, p->rect.y);
333 p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
334 c_retm_if(!p->prev_year, "__cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR) returned null");
337 evas_object_move(p->cur_year->image, x, p->rect.y);
339 evas_object_move(p->prev_year->image, x -p->rect.w, p->rect.y);
342 evas_object_move(p->handle_base, x, p->rect.y);
345 static void __cal_year_image_object_mouse_down_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
347 c_retm_if(!data, "Input parameter is null.");
349 cal_view_main_year_data *p = data;
350 struct _year *y = p->cur_year;
352 int index = (int)evas_object_data_get(obj, "index");
354 snprintf(signal_source, 31, "mb/%d/base", index);
355 edje_object_signal_emit(y->edj, "mouse,down,1", signal_source);
360 static void __cal_year_image_object_mouse_up_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
362 c_retm_if(!data, "Input parameter is null.");
364 cal_view_main_year_data *p = data;
365 struct _year *y = p->cur_year;
366 struct appdata* ad = p->ad;
368 snprintf(signal_source, 31, "mb/%d/base", p->pos_down);
369 edje_object_signal_emit(y->edj, "mouse,up,1", signal_source);
371 if (p->ignore_mouse_down)
373 p->ignore_mouse_down = EINA_FALSE;
377 cal_util_update_tm_month(&ad->base_tm, p->pos_down - ad->base_tm.tm_mon);
379 if (p->pos_down != p->pos_selected)
381 cal_util_emit_signal(y->edj, "unselect,%d", p->pos_selected);
383 cal_util_emit_signal(y->edj, "select,%d", p->pos_down);
385 p->pos_selected = p->pos_down;
389 cal_main_change_view(p->parent, CV_MONTH);
393 static void __cal_year_delete_edje_handle(cal_view_main_year_data* p)
395 c_retm_if(!p, "p is null.");
399 for (i = 0 ; i < 12 ; i++)
401 c_retm_if(!p->edje_handle[i], "p->edje_handle[%d] is null.", i);
403 evas_object_event_callback_del(p->edje_handle[i], EVAS_CALLBACK_MOUSE_DOWN, __cal_year_image_object_mouse_down_callback);
404 evas_object_event_callback_del(p->edje_handle[i], EVAS_CALLBACK_MOUSE_UP, __cal_year_image_object_mouse_up_callback);
406 evas_object_del(p->edje_handle[i]);
409 c_retm_if(!p->handle_base, "p->handle_base is null.");
410 evas_object_del(p->handle_base);
413 static inline int __cal_year_update_view(cal_view_main_year_data *p)
417 c_retvm_if(!p, -1, "Input parameter is null.");
418 c_retvm_if(!p->ad, -1, "p->ad is null.");
420 struct appdata* ad = p->ad;
422 int d = p->tm_to.tm_year - p->ad->base_tm.tm_year;
424 ad->base_tm = p->tm_to;
426 cal_util_emit_signal(p->cur_year->edj, "unselect,%d", p->pos_selected);
428 elm_object_part_content_unset(p->ly, "content");
429 elm_object_part_content_unset(p->ly, "content/left");
430 elm_object_part_content_unset(p->ly, "content/right");
435 __cal_year_delete_year_object(p->prev_year);
437 p->prev_year = p->cur_year;
438 p->cur_year = p->next_year;
439 p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
444 __cal_year_delete_year_object(p->next_year);
446 p->next_year = p->cur_year;
447 p->cur_year = p->prev_year;
448 p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
451 elm_object_part_content_set(p->ly, "content", p->cur_year->image);
454 elm_object_part_content_set(p->ly, "content/left", p->prev_year->image);
457 elm_object_part_content_set(p->ly, "content/right", p->next_year->image);
459 cal_main_update_title_text(ad->title, CV_YEAR, &ad->base_tm, ad->wday_start);
461 __cal_year_update_select(p->cur_year, ad->base_tm.tm_mon);
463 __cal_year_move_year_objects(p, 0);
465 if (p->ignore_mouse_down)
466 p->ignore_mouse_down = EINA_FALSE;
471 static Eina_Bool __cal_year_animation(void *data, double pos)
473 c_retvm_if(!data, ECORE_CALLBACK_CANCEL, "Input parameter is null.");
475 cal_view_main_year_data *p = data;
478 dx = (p->mouse_up_position.x - p->pos_to.x) * cal_util_nsin(1.0 - pos);
479 __cal_year_move_year_objects(p, p->pos_to.x + dx);
481 if ((dx + p->pos_to.x)%p->ad->win_w == 0)
484 __cal_year_update_view(p);
485 return ECORE_CALLBACK_CANCEL;
488 return ECORE_CALLBACK_RENEW;
491 static inline void __cal_year_start_animation(cal_view_main_year_data *p)
493 c_retm_if(!p, "Input parameter is null.");
495 if (p->mouse_up_position.x == p->pos_to.x)
499 p->ani = ecore_animator_timeline_add(ANIMATION_TIME, __cal_year_animation, p);
501 p->ani_start = ecore_time_get();
504 static void inline __cal_year_set_go(cal_view_main_year_data *p, int d)
506 c_retm_if(!p, "Input parameter is null.");
510 p->tm_to = p->ad->base_tm;
514 r = cal_util_update_tm_year(&p->tm_to, d);
518 p->pos_to.x = p->rect.w * (d * -1);
521 static void __cal_year_mouse_up(void *data, Evas *e, Evas_Object *ly, void *ei)
523 c_retm_if(!data, "Input parameter is null.");
525 Evas_Event_Mouse_Up *ev = ei;
526 cal_view_main_year_data *p = data;
533 cal_util_get_geometry(&p->mouse_up_position, p->cur_year->image);
535 if (p->mouse_up_position.x > (p->rect.w >> 2))
536 __cal_year_set_go(p, -1);
537 else if (p->mouse_up_position.x < (p->rect.w >> 2) * -1)
538 __cal_year_set_go(p, 1);
541 Evas_Coord x = ev->canvas.x - p->down1.x;
543 if (x < 3 && x > -3 && p->mouse_up_position.x ==0)
546 __cal_year_set_go(p, 0);
549 __cal_year_start_animation(p);
552 static void __cal_year_mouse_move(void *data, Evas *e, Evas_Object *ly, void *ei)
554 c_retm_if(!data, "Input parameter is null.");
556 cal_view_main_year_data *p = data;
558 Evas_Event_Mouse_Move *ev = ei;
566 if ((cnt & 0x7) != 0) // Workaround
569 p->move2.x = ev->cur.canvas.x;
570 p->move2.y = ev->cur.canvas.y;
572 x = p->mouse_down_position.x + p->move2.x - p->down1.x;
574 __cal_year_move_year_objects(p, x);
576 p->ignore_mouse_down = EINA_TRUE;
579 static void __cal_year_mouse_down(void *data, Evas *e, Evas_Object *ly, void *ei)
581 c_retm_if(!data, "Input parameter is null.");
583 cal_view_main_year_data *p = data;
584 struct _year *y = p->cur_year;
586 Evas_Event_Mouse_Down *ev = ei;
588 p->down1.x = p->move1.x = ev->canvas.x;
589 p->down1.y = p->move1.y = ev->canvas.y;
591 cal_util_get_geometry(&p->mouse_down_position, y->image);
593 __cal_year_stop_animation(p);
598 static void __cal_year_update_select(struct _year *y, int tm_mon)
600 c_retm_if(!y, "Input parameter is null.");
602 cal_view_main_year_data* p = y->p;
604 if (p->pos_selected != -1)
605 cal_util_emit_signal(y->edj, "unselect,%d", p->pos_selected);
607 cal_util_emit_signal(y->edj, "select,%d", tm_mon);
609 p->pos_selected = tm_mon;
612 static Evas_Object *__cal_year_create_image(Evas_Object *parent)
614 c_retvm_if(!parent, NULL, "Input parameter is null.");
621 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
623 e = evas_object_evas_get(parent);
624 ee = ecore_evas_ecore_evas_get(e);
626 img = ecore_evas_object_image_new(ee);
630 evas_object_image_alpha_set(img, EINA_TRUE);
631 evas_object_image_size_set(img, w, h);
632 evas_object_image_fill_set(img, 0, 0, w, h);
634 evas_object_show(img);
639 static Evas_Object *__cal_year_add_edje(Evas *e, const char *grp, Evas_Coord w, Evas_Coord h)
641 c_retvm_if(!e, NULL, "Input parameter is null.");
646 eo = edje_object_add(e);
650 if(cal_util_black_theme_check()){
651 r = edje_object_file_set(eo, EDJ_FILE, grp);
654 r = edje_object_file_set(eo, EDJ_FILE_WHITE, grp);
663 evas_object_freeze_events_set(eo, EINA_TRUE);
665 evas_object_resize(eo, w, h);
666 evas_object_move(eo, 0, 0);
667 evas_object_show(eo);
672 static void __cal_year_image_object_resize_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
674 c_retm_if(!data, "Input parameter is null.");
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.");
680 cal_view_main_year_data *p = y->p;
682 cal_util_get_geometry(&p->rect, obj);
684 evas_object_resize(y->edj, p->rect.w, p->rect.h);
685 evas_object_move(y->edj, 0, 0);
688 static void __cal_year_image_object_move_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
690 c_retm_if(!data, "Input parameter is null.");
692 struct _year *y = data;
694 evas_object_move(y->edj, 0, 0);
697 static void __cal_year_delete_year_object(struct _year* y)
701 c_retm_if(!y, "Input parameter is null.");
703 evas_object_del(y->image);
704 evas_object_del(y->edj);
709 static struct _year* __cal_year_create_year_object(Evas_Object* ly, cal_view_main_year_data* p, enum year_index year)
711 c_retvm_if(!ly, NULL, "Input parameter is null.");
712 c_retvm_if(!p, NULL, "Input parameter is null.");
713 c_retvm_if(!p->ad, NULL, "p->ad is null.");
715 struct appdata* ad = p->ad;
716 c_retv_if(!ad, NULL);
718 struct tm tm = ad->base_tm;
720 int r = cal_util_update_tm_year(&tm, year);
721 c_retvm_if(r < 0, NULL, "cal_util_update_tm_year(%d, %d is failed", tm.tm_year, year);
723 struct _year* y = calloc(1, sizeof(struct _year));
726 y->image = __cal_year_create_image(ly);
728 y->evas = ecore_evas_object_evas_get(y->image);
730 y->edj = __cal_year_add_edje(y->evas, "main/year/months", p->rect.w, p->rect.h);
735 elm_object_part_content_set(ly, "content/right", y->image);
737 elm_object_part_content_set(ly, "content/left", y->image);
739 elm_object_part_content_set(ly, "content", y->image);
742 y->year = tm.tm_year;
744 evas_object_event_callback_add(y->image, EVAS_CALLBACK_RESIZE, __cal_year_image_object_resize_callback, y);
745 evas_object_event_callback_add(y->image, EVAS_CALLBACK_MOVE, __cal_year_image_object_move_callback, y);
747 __cal_year_set_month_text(y);
748 __cal_year_fill_months(y);
753 static void __cal_year_create_edje_handle(cal_view_main_year_data* p)
755 c_retm_if(!p, "p is null.");
757 Evas * e = evas_object_evas_get(p->ly);
759 Evas_Object *ly = NULL;
760 Evas_Object *handle = NULL;
763 ly = cal_util_add_layout(p->ly, "year/edje/handle");
764 c_retm_if(!ly, "ly is null.");
766 for (i = 0 ; i < 12 ; i++)
768 handle = evas_object_rectangle_add(e);
769 c_retm_if(!handle, "evas_object_rectangle_add returned null.");
771 evas_object_color_set(handle, 0, 0, 0, 0);
772 evas_object_data_set(handle, "index", (void*)i);
773 snprintf(part, sizeof(part), "handle/%d/sw", i);
774 elm_object_part_content_set(ly, part, handle);
776 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN, __cal_year_image_object_mouse_down_callback, p);
777 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_UP, __cal_year_image_object_mouse_up_callback, p);
779 p->edje_handle[i] = handle;
782 elm_object_part_content_set(p->ly, "edje/handle", ly);
787 Evas_Object* cal_year_create_view(struct appdata *ad, Evas_Object *main)
789 c_retvm_if(!ad, NULL, "Input parameter is null.");
790 c_retvm_if(!main, NULL, "Input parameter is null.");
792 cal_view_main_year_data *p;
793 Evas_Object* ly = NULL;
795 CAL_CALLOC(p, 1, cal_view_main_year_data);
801 edje_object_part_geometry_get(CAL_UTIL_GET_EDJ_DATA(ad->main), "cont", NULL, NULL, &p->rect.w, &p->rect.h);
803 memset(p->wday, 0, 8*7);
804 memset(p->month, 0, 32*12);
806 __cal_year_make_month_text(p);
808 ly = cal_util_add_layout(p->ad->nv, "year/layout");
815 evas_object_data_set(ly, "priv", p);
818 p->pos_selected = -1;
820 __cal_year_create_edje_handle(p);
822 evas_object_event_callback_add(ly, EVAS_CALLBACK_DEL, __cal_year_delete_layout, p);
823 evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_DOWN, __cal_year_mouse_down, p);
824 evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_UP, __cal_year_mouse_up, p);
825 evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_MOVE, __cal_year_mouse_move, p);
830 static Eina_Bool __cal_year_create_year_with_idler(void* data)
834 c_retvm_if(!data, ECORE_CALLBACK_CANCEL, "Input param is null.");
836 cal_view_main_year_data* p = data;
838 c_retvm_if(!p->ad, ECORE_CALLBACK_CANCEL, "p->ad is null.");
841 __cal_year_delete_year_object(p->prev_year);
843 p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
844 c_retvm_if(!p->prev_year, ECORE_CALLBACK_CANCEL, "__cal_year_create_year_object returned null.");
847 __cal_year_delete_year_object(p->next_year);
849 p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
850 c_retvm_if(!p->next_year, ECORE_CALLBACK_CANCEL, "__cal_year_create_year_object returned null.");
854 return ECORE_CALLBACK_CANCEL;
857 static void __cal_year_update_current_year(cal_view_main_year_data* p)
861 c_retm_if(!p, "Input parameter is null.");
863 p->cur_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_CURR_YEAR);
864 c_retm_if(!p->cur_year, "__cal_year_create_year_object returned null.");
866 elm_object_part_content_set(p->ly, "content", p->cur_year->image);
869 void cal_year_update_view(Evas_Object *ly)
873 c_retm_if(!ly, "Input parameter is null.");
875 cal_view_main_year_data *p;
878 p = CAL_UTIL_GET_PRIV_DATA(ly);
879 if (!p || CAL_STRCMP(p->name, _name))
881 ERR("update year view: Invalid object");
886 c_retm_if(!ad, "p->ad is null.");
888 __cal_year_update_current_year(p);
892 ecore_idler_del(p->idler);
896 p->idler = ecore_idler_add(__cal_year_create_year_with_idler, (void*)p);
898 __cal_year_update_select(p->cur_year, ad->base_tm.tm_mon);